@tracelog/lib 2.8.3 → 2.8.4-rc.104.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/README.md +4 -3
- package/dist/browser/tracelog.esm.js +907 -780
- package/dist/browser/tracelog.esm.js.map +1 -1
- package/dist/browser/tracelog.js +2 -2
- package/dist/browser/tracelog.js.map +1 -1
- package/dist/public-api.cjs +2 -2
- package/dist/public-api.cjs.map +1 -1
- package/dist/public-api.d.mts +2 -1
- package/dist/public-api.d.ts +2 -1
- package/dist/public-api.js +2 -2
- package/dist/public-api.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
1
|
+
const hr = 9e5;
|
|
2
|
+
const fr = 120, mr = 49152, gr = 100, Er = 500, pr = 200;
|
|
3
|
+
const Sr = 1e3, Tr = 500, Ir = 1e3;
|
|
4
4
|
const b = "data-tlog", bt = [
|
|
5
5
|
"button",
|
|
6
6
|
"a",
|
|
@@ -33,7 +33,7 @@ const b = "data-tlog", bt = [
|
|
|
33
33
|
".menu-item",
|
|
34
34
|
"[data-testid]",
|
|
35
35
|
'[tabindex="0"]'
|
|
36
|
-
],
|
|
36
|
+
], Lt = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"], At = [
|
|
37
37
|
"token",
|
|
38
38
|
"auth",
|
|
39
39
|
"key",
|
|
@@ -79,26 +79,27 @@ const E = {
|
|
|
79
79
|
/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
|
|
80
80
|
/<embed\b[^>]*>/gi,
|
|
81
81
|
/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi
|
|
82
|
-
],
|
|
83
|
-
var $ = /* @__PURE__ */ ((r) => (r.Localhost = "localhost:8080", r.Fail = "localhost:9999", r))($ || {}),
|
|
82
|
+
], S = "tlog", X = `${S}:qa_mode`, Te = `${S}:uid`, rt = "tlog_mode", Ue = "qa", Fe = "qa_off", Ct = (r) => r ? `${S}:${r}:queue` : `${S}:queue`, Rt = (r) => r ? `${S}:${r}:rate_limit` : `${S}:rate_limit`, Nt = (r) => r ? `${S}:${r}:session` : `${S}:session`, Ot = (r) => r ? `${S}:${r}:broadcast` : `${S}:broadcast`, He = (r, e) => `${S}:${r}:session_counts:${e}`, xe = 10080 * 60 * 1e3, $e = `${S}:session_counts_last_cleanup`, Be = 3600 * 1e3, fe = (r) => r ? `${S}:${r}:identity` : `${S}:identity`, U = `${S}:pending_identity`;
|
|
83
|
+
var $ = /* @__PURE__ */ ((r) => (r.Localhost = "localhost:8080", r.Fail = "localhost:9999", r))($ || {}), A = /* @__PURE__ */ ((r) => (r.Mobile = "mobile", r.Tablet = "tablet", r.Desktop = "desktop", r.Unknown = "unknown", r))(A || {}), se = /* @__PURE__ */ ((r) => (r.EVENT = "event", r.QUEUE = "queue", r))(se || {});
|
|
84
84
|
class O extends Error {
|
|
85
|
-
constructor(e, t) {
|
|
86
|
-
super(e), this.statusCode = t, this.name = "PermanentError", Error.captureStackTrace && Error.captureStackTrace(this, O);
|
|
85
|
+
constructor(e, t, s) {
|
|
86
|
+
super(e), this.statusCode = t, this.responseCode = s, this.name = "PermanentError", Error.captureStackTrace && Error.captureStackTrace(this, O);
|
|
87
87
|
}
|
|
88
88
|
statusCode;
|
|
89
|
+
responseCode;
|
|
89
90
|
}
|
|
90
91
|
class re extends Error {
|
|
91
92
|
constructor(e) {
|
|
92
93
|
super(e), this.name = "RateLimitError", Error.captureStackTrace && Error.captureStackTrace(this, re);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
|
-
class
|
|
96
|
+
class ie extends Error {
|
|
96
97
|
constructor(e) {
|
|
97
|
-
super(e), this.name = "TimeoutError", Error.captureStackTrace && Error.captureStackTrace(this,
|
|
98
|
+
super(e), this.name = "TimeoutError", Error.captureStackTrace && Error.captureStackTrace(this, ie);
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
|
-
var
|
|
101
|
-
const
|
|
101
|
+
var u = /* @__PURE__ */ ((r) => (r.PAGE_VIEW = "page_view", r.CLICK = "click", r.SCROLL = "scroll", r.SESSION_START = "session_start", r.CUSTOM = "custom", r.WEB_VITALS = "web_vitals", r.ERROR = "error", r.VIEWPORT_VISIBLE = "viewport_visible", r))(u || {}), Z = /* @__PURE__ */ ((r) => (r.UP = "up", r.DOWN = "down", r))(Z || {}), B = /* @__PURE__ */ ((r) => (r.JS_ERROR = "js_error", r.PROMISE_REJECTION = "promise_rejection", r))(B || {}), ne = /* @__PURE__ */ ((r) => (r.QA = "qa", r))(ne || {});
|
|
102
|
+
const vr = (r) => r.type === u.SCROLL && "scroll_data" in r && r.scroll_data.is_primary === !0, _r = (r) => r.type === u.SCROLL && "scroll_data" in r && r.scroll_data.is_primary === !1;
|
|
102
103
|
class j extends Error {
|
|
103
104
|
constructor(e, t, s) {
|
|
104
105
|
super(e), this.errorCode = t, this.layer = s, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
@@ -111,7 +112,7 @@ class m extends j {
|
|
|
111
112
|
super(e, "APP_CONFIG_INVALID", t);
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
|
-
class
|
|
115
|
+
class Pt extends j {
|
|
115
116
|
constructor(e, t = "config") {
|
|
116
117
|
super(e, "SESSION_TIMEOUT_INVALID", t);
|
|
117
118
|
}
|
|
@@ -126,13 +127,13 @@ class N extends j {
|
|
|
126
127
|
super(e, "INTEGRATION_INVALID", t);
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
|
-
class
|
|
130
|
+
class yr extends j {
|
|
130
131
|
constructor(e, t, s = "runtime") {
|
|
131
132
|
super(e, "INITIALIZATION_TIMEOUT", s), this.timeoutMs = t;
|
|
132
133
|
}
|
|
133
134
|
timeoutMs;
|
|
134
135
|
}
|
|
135
|
-
const
|
|
136
|
+
const it = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", nt = "background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", Dt = "background: #d32f2f; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", kt = (r, e) => {
|
|
136
137
|
if (e) {
|
|
137
138
|
if (e instanceof Error) {
|
|
138
139
|
const t = e.message.replace(/\s+at\s+.*$/gm, "").replace(/\s*\([^()]+:\d+:\d+\)/g, "");
|
|
@@ -151,7 +152,7 @@ const nt = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8
|
|
|
151
152
|
return `[TraceLog] ${r}: ${String(e)}`;
|
|
152
153
|
}
|
|
153
154
|
return `[TraceLog] ${r}`;
|
|
154
|
-
},
|
|
155
|
+
}, Vt = () => {
|
|
155
156
|
if (typeof window > "u" || typeof sessionStorage > "u")
|
|
156
157
|
return !1;
|
|
157
158
|
try {
|
|
@@ -160,32 +161,32 @@ const nt = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8
|
|
|
160
161
|
return !1;
|
|
161
162
|
}
|
|
162
163
|
}, a = (r, e, t) => {
|
|
163
|
-
const { error: s, data:
|
|
164
|
-
if (!
|
|
164
|
+
const { error: s, data: i, showToClient: n = !1, style: o, visibility: l } = t ?? {}, c = s ? kt(e, s) : `[TraceLog] ${e}`, d = r === "error" ? "error" : r === "warn" ? "warn" : "log";
|
|
165
|
+
if (!Ut(l, n))
|
|
165
166
|
return;
|
|
166
|
-
const g =
|
|
167
|
-
Ht(
|
|
168
|
-
},
|
|
169
|
-
const
|
|
170
|
-
s !== void 0 ?
|
|
167
|
+
const g = Ft(l, o), I = i !== void 0 ? Ie(i) : void 0;
|
|
168
|
+
Ht(d, c, g, I);
|
|
169
|
+
}, Ut = (r, e) => r === "critical" ? !0 : r === "qa" || e ? Vt() : !1, Ft = (r, e) => e !== void 0 && e !== "" ? e : r === "critical" ? Dt : "", Ht = (r, e, t, s) => {
|
|
170
|
+
const i = t !== void 0 && t !== "", n = i ? `%c${e}` : e;
|
|
171
|
+
s !== void 0 ? i ? console[r](n, t, s) : console[r](n, s) : i ? console[r](n, t) : console[r](n);
|
|
171
172
|
}, Ie = (r) => {
|
|
172
173
|
const e = {}, t = ["token", "password", "secret", "key", "apikey", "api_key", "sessionid", "session_id"];
|
|
173
|
-
for (const [s,
|
|
174
|
-
const
|
|
175
|
-
if (t.some((o) =>
|
|
174
|
+
for (const [s, i] of Object.entries(r)) {
|
|
175
|
+
const n = s.toLowerCase();
|
|
176
|
+
if (t.some((o) => n.includes(o))) {
|
|
176
177
|
e[s] = "[REDACTED]";
|
|
177
178
|
continue;
|
|
178
179
|
}
|
|
179
|
-
|
|
180
|
+
i !== null && typeof i == "object" && !Array.isArray(i) ? e[s] = Ie(i) : Array.isArray(i) ? e[s] = i.map(
|
|
180
181
|
(o) => o !== null && typeof o == "object" && !Array.isArray(o) ? Ie(o) : o
|
|
181
|
-
) : e[s] =
|
|
182
|
+
) : e[s] = i;
|
|
182
183
|
}
|
|
183
184
|
return e;
|
|
184
185
|
};
|
|
185
186
|
let ve, ot;
|
|
186
|
-
const
|
|
187
|
+
const xt = () => {
|
|
187
188
|
typeof window < "u" && !ve && (ve = window.matchMedia("(pointer: coarse)"), ot = window.matchMedia("(hover: none)"));
|
|
188
|
-
}, oe = "Unknown",
|
|
189
|
+
}, oe = "Unknown", $t = (r) => {
|
|
189
190
|
const e = r.userAgentData?.platform;
|
|
190
191
|
if (e != null && e !== "") {
|
|
191
192
|
if (/windows/i.test(e)) return "Windows";
|
|
@@ -197,41 +198,41 @@ const Ft = () => {
|
|
|
197
198
|
}
|
|
198
199
|
const t = navigator.userAgent;
|
|
199
200
|
return /Windows/i.test(t) ? "Windows" : /iPhone|iPad|iPod/i.test(t) ? "iOS" : /Mac OS X|Macintosh/i.test(t) ? "macOS" : /Android/i.test(t) ? "Android" : /CrOS/i.test(t) ? "ChromeOS" : /Linux/i.test(t) ? "Linux" : oe;
|
|
200
|
-
},
|
|
201
|
+
}, Bt = (r) => {
|
|
201
202
|
const e = r.userAgentData?.brands;
|
|
202
203
|
if (e != null && e.length > 0) {
|
|
203
|
-
const
|
|
204
|
-
if (
|
|
205
|
-
const
|
|
206
|
-
return /google chrome/i.test(
|
|
204
|
+
const i = e.filter((n) => !/not.?a.?brand|chromium/i.test(n.brand))[0];
|
|
205
|
+
if (i != null) {
|
|
206
|
+
const n = i.brand;
|
|
207
|
+
return /google chrome/i.test(n) ? "Chrome" : /microsoft edge/i.test(n) ? "Edge" : /opera/i.test(n) ? "Opera" : n;
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
210
|
const t = navigator.userAgent;
|
|
210
211
|
return /Edg\//i.test(t) ? "Edge" : /OPR\//i.test(t) ? "Opera" : /Chrome/i.test(t) ? "Chrome" : /Firefox/i.test(t) ? "Firefox" : /Safari/i.test(t) && !/Chrome/i.test(t) ? "Safari" : oe;
|
|
211
|
-
},
|
|
212
|
+
}, Wt = () => {
|
|
212
213
|
try {
|
|
213
214
|
const r = navigator;
|
|
214
215
|
if (r.userAgentData != null && typeof r.userAgentData.mobile == "boolean") {
|
|
215
216
|
const c = r.userAgentData.platform;
|
|
216
|
-
return c != null && c !== "" && /ipad|tablet/i.test(c) ?
|
|
217
|
+
return c != null && c !== "" && /ipad|tablet/i.test(c) ? A.Tablet : r.userAgentData.mobile ? A.Mobile : A.Desktop;
|
|
217
218
|
}
|
|
218
|
-
|
|
219
|
-
const e = window.innerWidth, t = ve?.matches ?? !1, s = ot?.matches ?? !1,
|
|
220
|
-
return e <= 767 || o &&
|
|
219
|
+
xt();
|
|
220
|
+
const e = window.innerWidth, t = ve?.matches ?? !1, s = ot?.matches ?? !1, i = "ontouchstart" in window || navigator.maxTouchPoints > 0, n = navigator.userAgent.toLowerCase(), o = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(n), l = /tablet|ipad|android(?!.*mobile)/.test(n);
|
|
221
|
+
return e <= 767 || o && i ? A.Mobile : e >= 768 && e <= 1024 || l || t && s && i ? A.Tablet : A.Desktop;
|
|
221
222
|
} catch (r) {
|
|
222
|
-
return a("debug", "Device detection failed, defaulting to desktop", { error: r }),
|
|
223
|
+
return a("debug", "Device detection failed, defaulting to desktop", { error: r }), A.Desktop;
|
|
223
224
|
}
|
|
224
|
-
},
|
|
225
|
+
}, Xt = () => {
|
|
225
226
|
try {
|
|
226
227
|
const r = navigator;
|
|
227
228
|
return {
|
|
228
|
-
type:
|
|
229
|
-
os:
|
|
230
|
-
browser:
|
|
229
|
+
type: Wt(),
|
|
230
|
+
os: $t(r),
|
|
231
|
+
browser: Bt(r)
|
|
231
232
|
};
|
|
232
233
|
} catch (r) {
|
|
233
234
|
return a("debug", "Device info detection failed, using defaults", { error: r }), {
|
|
234
|
-
type:
|
|
235
|
+
type: A.Desktop,
|
|
235
236
|
os: oe,
|
|
236
237
|
browser: oe
|
|
237
238
|
};
|
|
@@ -253,7 +254,7 @@ const Ft = () => {
|
|
|
253
254
|
/:\/\/[^:/]+:([^@]+)@/gi,
|
|
254
255
|
// Sensitive URL query parameters (token=, password=, auth=, secret=, api_key=, etc.)
|
|
255
256
|
/[?&](token|password|passwd|auth|secret|secret_key|private_key|auth_key|api_key|apikey|access_token)=[^&\s]+/gi
|
|
256
|
-
], Xe = 500, Ge = 2e3, je = 5e3, ee = 50,
|
|
257
|
+
], Xe = 500, Ge = 2e3, je = 5e3, ee = 50, Gt = ee * 2, lt = 1, jt = 1e3, zt = 10, ze = 5e3, Kt = 6e4, Qt = 64, wr = {
|
|
257
258
|
LCP: 2500,
|
|
258
259
|
// Good: ≤ 2.5s
|
|
259
260
|
FCP: 1800,
|
|
@@ -265,7 +266,7 @@ const Ft = () => {
|
|
|
265
266
|
TTFB: 800,
|
|
266
267
|
// Good: ≤ 800ms
|
|
267
268
|
LONG_TASK: 50
|
|
268
|
-
},
|
|
269
|
+
}, Ke = {
|
|
269
270
|
LCP: 2500,
|
|
270
271
|
// Needs improvement: > 2.5s (same as good boundary)
|
|
271
272
|
FCP: 1800,
|
|
@@ -277,7 +278,7 @@ const Ft = () => {
|
|
|
277
278
|
TTFB: 800,
|
|
278
279
|
// Needs improvement: > 800ms
|
|
279
280
|
LONG_TASK: 50
|
|
280
|
-
},
|
|
281
|
+
}, Yt = {
|
|
281
282
|
LCP: 4e3,
|
|
282
283
|
// Poor: > 4s
|
|
283
284
|
FCP: 3e3,
|
|
@@ -289,19 +290,19 @@ const Ft = () => {
|
|
|
289
290
|
TTFB: 1800,
|
|
290
291
|
// Poor: > 1800ms
|
|
291
292
|
LONG_TASK: 50
|
|
292
|
-
}, _e = "needs-improvement",
|
|
293
|
+
}, _e = "needs-improvement", Qe = (r = _e) => {
|
|
293
294
|
switch (r) {
|
|
294
295
|
case "all":
|
|
295
296
|
return { LCP: 0, FCP: 0, CLS: 0, INP: 0, TTFB: 0, LONG_TASK: 0 };
|
|
296
297
|
// Track everything
|
|
297
298
|
case "needs-improvement":
|
|
298
|
-
return
|
|
299
|
+
return Ke;
|
|
299
300
|
case "poor":
|
|
300
|
-
return
|
|
301
|
+
return Yt;
|
|
301
302
|
default:
|
|
302
|
-
return
|
|
303
|
+
return Ke;
|
|
303
304
|
}
|
|
304
|
-
},
|
|
305
|
+
}, qt = 1e3, Jt = 50, Zt = "2.8.4", es = Zt, ct = () => typeof window < "u" && typeof sessionStorage < "u", ts = () => {
|
|
305
306
|
try {
|
|
306
307
|
const r = new URLSearchParams(window.location.search);
|
|
307
308
|
r.delete(rt);
|
|
@@ -309,33 +310,33 @@ const Ft = () => {
|
|
|
309
310
|
window.history.replaceState({}, "", t);
|
|
310
311
|
} catch {
|
|
311
312
|
}
|
|
312
|
-
},
|
|
313
|
+
}, ss = () => {
|
|
313
314
|
if (!ct())
|
|
314
315
|
return !1;
|
|
315
316
|
try {
|
|
316
317
|
const e = new URLSearchParams(window.location.search).get(rt), t = sessionStorage.getItem(X);
|
|
317
318
|
let s = null;
|
|
318
319
|
return e === Ue ? (s = !0, sessionStorage.setItem(X, "true"), a("info", "QA Mode ACTIVE", {
|
|
319
|
-
visibility: "qa",
|
|
320
|
-
style: nt
|
|
321
|
-
})) : e === He && (s = !1, sessionStorage.setItem(X, "false"), a("info", "QA Mode DISABLED", {
|
|
322
320
|
visibility: "qa",
|
|
323
321
|
style: it
|
|
324
|
-
}))
|
|
322
|
+
})) : e === Fe && (s = !1, sessionStorage.setItem(X, "false"), a("info", "QA Mode DISABLED", {
|
|
323
|
+
visibility: "qa",
|
|
324
|
+
style: nt
|
|
325
|
+
})), (e === Ue || e === Fe) && ts(), s ?? t === "true";
|
|
325
326
|
} catch {
|
|
326
327
|
return !1;
|
|
327
328
|
}
|
|
328
|
-
},
|
|
329
|
+
}, rs = (r) => {
|
|
329
330
|
if (ct())
|
|
330
331
|
try {
|
|
331
332
|
sessionStorage.setItem(X, r ? "true" : "false"), a("info", r ? "QA Mode ACTIVE" : "QA Mode DISABLED", {
|
|
332
333
|
visibility: "qa",
|
|
333
|
-
style: r ?
|
|
334
|
+
style: r ? it : nt
|
|
334
335
|
});
|
|
335
336
|
} catch {
|
|
336
337
|
a("debug", "Cannot set QA mode: sessionStorage unavailable");
|
|
337
338
|
}
|
|
338
|
-
},
|
|
339
|
+
}, is = [
|
|
339
340
|
"co.uk",
|
|
340
341
|
"org.uk",
|
|
341
342
|
"com.au",
|
|
@@ -352,32 +353,32 @@ const Ft = () => {
|
|
|
352
353
|
if (e.length <= 2)
|
|
353
354
|
return r.toLowerCase();
|
|
354
355
|
const t = e.slice(-2).join(".");
|
|
355
|
-
return
|
|
356
|
-
},
|
|
356
|
+
return is.includes(t) ? e.slice(-3).join(".") : e.slice(-2).join(".");
|
|
357
|
+
}, ns = (r, e) => r === e ? !0 : Ye(r) === Ye(e), me = () => {
|
|
357
358
|
const r = document.referrer;
|
|
358
359
|
if (!r)
|
|
359
360
|
return "Direct";
|
|
360
361
|
try {
|
|
361
362
|
const e = new URL(r).hostname.toLowerCase(), t = window.location.hostname.toLowerCase();
|
|
362
|
-
return
|
|
363
|
+
return ns(e, t) ? "Direct" : r;
|
|
363
364
|
} catch (e) {
|
|
364
365
|
return a("debug", "Failed to parse referrer URL, using raw value", { error: e, data: { referrer: r } }), r;
|
|
365
366
|
}
|
|
366
367
|
}, ge = () => {
|
|
367
368
|
const r = new URLSearchParams(window.location.search), e = {};
|
|
368
|
-
return
|
|
369
|
-
const
|
|
370
|
-
if (
|
|
371
|
-
const
|
|
372
|
-
e[
|
|
369
|
+
return Lt.forEach((s) => {
|
|
370
|
+
const i = r.get(s);
|
|
371
|
+
if (i) {
|
|
372
|
+
const n = s.split("utm_")[1];
|
|
373
|
+
e[n] = i;
|
|
373
374
|
}
|
|
374
375
|
}), Object.keys(e).length ? e : void 0;
|
|
375
|
-
},
|
|
376
|
+
}, dt = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (r) => {
|
|
376
377
|
const e = Math.random() * 16 | 0;
|
|
377
378
|
return (r === "x" ? e : e & 3 | 8).toString(16);
|
|
378
379
|
});
|
|
379
380
|
let Y = 0, q = 0;
|
|
380
|
-
const
|
|
381
|
+
const os = () => {
|
|
381
382
|
let r = Date.now();
|
|
382
383
|
r < q && (r = q), r === q ? Y = (Y + 1) % 1e3 : Y = 0, q = r;
|
|
383
384
|
const e = Y.toString().padStart(3, "0");
|
|
@@ -385,19 +386,19 @@ const ns = () => {
|
|
|
385
386
|
try {
|
|
386
387
|
if (typeof crypto < "u" && crypto.getRandomValues) {
|
|
387
388
|
const s = crypto.getRandomValues(new Uint8Array(3));
|
|
388
|
-
s && (t = Array.from(s, (
|
|
389
|
+
s && (t = Array.from(s, (i) => i.toString(16).padStart(2, "0")).join(""));
|
|
389
390
|
}
|
|
390
391
|
} catch {
|
|
391
392
|
}
|
|
392
393
|
return t || (t = Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")), `${r}-${e}-${t}`;
|
|
393
|
-
},
|
|
394
|
+
}, ut = (r, e = !1) => {
|
|
394
395
|
try {
|
|
395
|
-
const t = new URL(r), s = t.protocol === "https:",
|
|
396
|
-
return s || e &&
|
|
396
|
+
const t = new URL(r), s = t.protocol === "https:", i = t.protocol === "http:";
|
|
397
|
+
return s || e && i;
|
|
397
398
|
} catch {
|
|
398
399
|
return !1;
|
|
399
400
|
}
|
|
400
|
-
},
|
|
401
|
+
}, as = (r) => {
|
|
401
402
|
try {
|
|
402
403
|
const t = new URL(window.location.href).hostname;
|
|
403
404
|
if (!t || typeof t != "string")
|
|
@@ -411,23 +412,23 @@ const ns = () => {
|
|
|
411
412
|
throw new Error("Invalid hostname structure");
|
|
412
413
|
if (s.length === 1)
|
|
413
414
|
throw new Error("Single-part domain not supported for SaaS integration");
|
|
414
|
-
let
|
|
415
|
-
if (s.length === 2 ?
|
|
415
|
+
let i;
|
|
416
|
+
if (s.length === 2 ? i = s.join(".") : i = s.slice(-2).join("."), !i || i.split(".").length < 2)
|
|
416
417
|
throw new Error("Invalid domain structure for SaaS");
|
|
417
|
-
const
|
|
418
|
-
if (!
|
|
418
|
+
const n = `https://${r}.${i}/collect`;
|
|
419
|
+
if (!ut(n))
|
|
419
420
|
throw new Error("Generated URL failed validation");
|
|
420
|
-
return
|
|
421
|
+
return n;
|
|
421
422
|
} catch (e) {
|
|
422
423
|
throw new Error(`Invalid SaaS URL configuration: ${e instanceof Error ? e.message : String(e)}`);
|
|
423
424
|
}
|
|
424
|
-
},
|
|
425
|
+
}, ls = (r) => {
|
|
425
426
|
const e = {};
|
|
426
|
-
r.integrations?.tracelog?.projectId && (e.saas =
|
|
427
|
+
r.integrations?.tracelog?.projectId && (e.saas = as(r.integrations.tracelog.projectId));
|
|
427
428
|
const t = r.integrations?.custom?.collectApiUrl;
|
|
428
429
|
if (t) {
|
|
429
430
|
const s = r.integrations?.custom?.allowHttp ?? !1;
|
|
430
|
-
if (!
|
|
431
|
+
if (!ut(t, s))
|
|
431
432
|
throw new Error("Invalid custom API URL");
|
|
432
433
|
e.custom = t;
|
|
433
434
|
}
|
|
@@ -436,12 +437,12 @@ const ns = () => {
|
|
|
436
437
|
if (!r || typeof r != "string")
|
|
437
438
|
return a("warn", "Invalid URL provided to normalizeUrl", { data: { type: typeof r } }), r || "";
|
|
438
439
|
try {
|
|
439
|
-
const t = new URL(r), s = t.searchParams,
|
|
440
|
-
let
|
|
440
|
+
const t = new URL(r), s = t.searchParams, i = [.../* @__PURE__ */ new Set([...At, ...e])];
|
|
441
|
+
let n = !1;
|
|
441
442
|
const o = [];
|
|
442
|
-
return
|
|
443
|
-
s.has(c) && (s.delete(c),
|
|
444
|
-
}), !
|
|
443
|
+
return i.forEach((c) => {
|
|
444
|
+
s.has(c) && (s.delete(c), n = !0, o.push(c));
|
|
445
|
+
}), !n && r.includes("?") ? r : (t.search = s.toString(), t.toString());
|
|
445
446
|
} catch (t) {
|
|
446
447
|
return a("warn", "URL normalization failed, returning original", { error: t, data: { urlLength: r?.length } }), r;
|
|
447
448
|
}
|
|
@@ -451,9 +452,9 @@ const ns = () => {
|
|
|
451
452
|
let e = r;
|
|
452
453
|
r.length > 1e3 && (e = r.slice(0, Math.max(0, 1e3)));
|
|
453
454
|
let t = 0;
|
|
454
|
-
for (const
|
|
455
|
-
const
|
|
456
|
-
e = e.replace(
|
|
455
|
+
for (const i of Mt) {
|
|
456
|
+
const n = e;
|
|
457
|
+
e = e.replace(i, ""), n !== e && t++;
|
|
457
458
|
}
|
|
458
459
|
return t > 0 && a("warn", "XSS patterns detected and removed", {
|
|
459
460
|
data: {
|
|
@@ -473,11 +474,11 @@ const ns = () => {
|
|
|
473
474
|
if (e > 10)
|
|
474
475
|
return null;
|
|
475
476
|
if (Array.isArray(r))
|
|
476
|
-
return r.slice(0, 1e3).map((
|
|
477
|
+
return r.slice(0, 1e3).map((i) => we(i, e + 1)).filter((i) => i !== null);
|
|
477
478
|
if (typeof r == "object") {
|
|
478
|
-
const t = {},
|
|
479
|
-
for (const [
|
|
480
|
-
const l = qe(
|
|
479
|
+
const t = {}, i = Object.entries(r).slice(0, 200);
|
|
480
|
+
for (const [n, o] of i) {
|
|
481
|
+
const l = qe(n);
|
|
481
482
|
if (l) {
|
|
482
483
|
const c = we(o, e + 1);
|
|
483
484
|
c !== null && (t[l] = c);
|
|
@@ -486,7 +487,7 @@ const ns = () => {
|
|
|
486
487
|
return t;
|
|
487
488
|
}
|
|
488
489
|
return null;
|
|
489
|
-
},
|
|
490
|
+
}, cs = (r) => {
|
|
490
491
|
if (typeof r != "object" || r === null)
|
|
491
492
|
return {};
|
|
492
493
|
try {
|
|
@@ -496,15 +497,15 @@ const ns = () => {
|
|
|
496
497
|
const t = e instanceof Error ? e.message : String(e);
|
|
497
498
|
throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`);
|
|
498
499
|
}
|
|
499
|
-
},
|
|
500
|
+
}, ds = (r) => {
|
|
500
501
|
if (r !== void 0 && (r === null || typeof r != "object"))
|
|
501
502
|
throw new m("Configuration must be an object", "config");
|
|
502
503
|
if (r) {
|
|
503
504
|
if (r.sessionTimeout !== void 0 && (typeof r.sessionTimeout != "number" || r.sessionTimeout < 3e4 || r.sessionTimeout > 864e5))
|
|
504
|
-
throw new
|
|
505
|
+
throw new Pt(E.INVALID_SESSION_TIMEOUT, "config");
|
|
505
506
|
if (r.globalMetadata !== void 0 && (typeof r.globalMetadata != "object" || r.globalMetadata === null))
|
|
506
507
|
throw new m(E.INVALID_GLOBAL_METADATA, "config");
|
|
507
|
-
if (r.integrations &&
|
|
508
|
+
if (r.integrations && hs(r.integrations), r.sensitiveQueryParams !== void 0) {
|
|
508
509
|
if (!Array.isArray(r.sensitiveQueryParams))
|
|
509
510
|
throw new m(E.INVALID_SENSITIVE_QUERY_PARAMS, "config");
|
|
510
511
|
for (const e of r.sensitiveQueryParams)
|
|
@@ -536,7 +537,7 @@ const ns = () => {
|
|
|
536
537
|
throw new m(E.INVALID_MAX_SAME_EVENT_PER_MINUTE, "config");
|
|
537
538
|
if (r.sendIntervalMs !== void 0 && (!Number.isFinite(r.sendIntervalMs) || r.sendIntervalMs < 1e3 || r.sendIntervalMs > 6e4))
|
|
538
539
|
throw new m(E.INVALID_SEND_INTERVAL, "config");
|
|
539
|
-
if (r.viewport !== void 0 &&
|
|
540
|
+
if (r.viewport !== void 0 && us(r.viewport), r.webVitalsMode !== void 0) {
|
|
540
541
|
if (typeof r.webVitalsMode != "string")
|
|
541
542
|
throw new m(
|
|
542
543
|
`Invalid webVitalsMode type: ${typeof r.webVitalsMode}. Must be a string`,
|
|
@@ -567,7 +568,7 @@ const ns = () => {
|
|
|
567
568
|
}
|
|
568
569
|
}
|
|
569
570
|
}
|
|
570
|
-
},
|
|
571
|
+
}, us = (r) => {
|
|
571
572
|
if (typeof r != "object" || r === null)
|
|
572
573
|
throw new m(E.INVALID_VIEWPORT_CONFIG, "config");
|
|
573
574
|
if (!r.elements || !Array.isArray(r.elements))
|
|
@@ -597,7 +598,7 @@ const ns = () => {
|
|
|
597
598
|
throw new m(E.INVALID_VIEWPORT_COOLDOWN_PERIOD, "config");
|
|
598
599
|
if (r.maxTrackedElements !== void 0 && (typeof r.maxTrackedElements != "number" || r.maxTrackedElements <= 0))
|
|
599
600
|
throw new m(E.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS, "config");
|
|
600
|
-
},
|
|
601
|
+
}, hs = (r) => {
|
|
601
602
|
if (r) {
|
|
602
603
|
if (r.tracelog && (!r.tracelog.projectId || typeof r.tracelog.projectId != "string" || r.tracelog.projectId.trim() === ""))
|
|
603
604
|
throw new N(E.INVALID_TRACELOG_PROJECT_ID, "config");
|
|
@@ -620,8 +621,8 @@ const ns = () => {
|
|
|
620
621
|
if (r.tracelog?.shopify !== void 0 && typeof r.tracelog.shopify != "boolean")
|
|
621
622
|
throw new N("tracelog.shopify must be a boolean", "config");
|
|
622
623
|
}
|
|
623
|
-
},
|
|
624
|
-
|
|
624
|
+
}, fs = (r) => {
|
|
625
|
+
ds(r);
|
|
625
626
|
const e = {
|
|
626
627
|
...r ?? {},
|
|
627
628
|
sessionTimeout: r?.sessionTimeout ?? 9e5,
|
|
@@ -649,13 +650,13 @@ const ns = () => {
|
|
|
649
650
|
return !0;
|
|
650
651
|
const t = typeof r;
|
|
651
652
|
return t === "string" || t === "number" || t === "boolean" ? !0 : t === "function" || t === "symbol" || t === "bigint" || e.has(r) ? !1 : (e.add(r), Array.isArray(r) ? r.every((s) => be(s, e)) : t === "object" ? Object.values(r).every((s) => be(s, e)) : !1);
|
|
652
|
-
},
|
|
653
|
+
}, ms = (r) => typeof r != "object" || r === null ? !1 : be(r), ht = (r) => {
|
|
653
654
|
if (typeof r != "object" || r === null || Array.isArray(r)) return;
|
|
654
655
|
const e = {};
|
|
655
656
|
for (const [t, s] of Object.entries(r))
|
|
656
657
|
typeof s == "string" && (e[t] = s);
|
|
657
658
|
return Object.keys(e).length > 0 ? e : void 0;
|
|
658
|
-
},
|
|
659
|
+
}, gs = (r) => typeof r != "string" ? {
|
|
659
660
|
valid: !1,
|
|
660
661
|
error: "Event name must be a string"
|
|
661
662
|
} : r.length === 0 ? {
|
|
@@ -671,49 +672,49 @@ const ns = () => {
|
|
|
671
672
|
valid: !1,
|
|
672
673
|
error: "Event name cannot be a reserved word"
|
|
673
674
|
} : { valid: !0 }, Je = (r, e, t) => {
|
|
674
|
-
const s =
|
|
675
|
-
if (!
|
|
675
|
+
const s = cs(e), i = t && t === "customEvent" ? `${t} "${r}" metadata error` : `${r} metadata error`;
|
|
676
|
+
if (!ms(s))
|
|
676
677
|
return {
|
|
677
678
|
valid: !1,
|
|
678
|
-
error: `${
|
|
679
|
+
error: `${i}: object has invalid types. Valid types are string, number, boolean or string arrays.`
|
|
679
680
|
};
|
|
680
|
-
let
|
|
681
|
+
let n;
|
|
681
682
|
try {
|
|
682
|
-
|
|
683
|
+
n = JSON.stringify(s);
|
|
683
684
|
} catch {
|
|
684
685
|
return {
|
|
685
686
|
valid: !1,
|
|
686
|
-
error: `${
|
|
687
|
+
error: `${i}: object contains circular references or cannot be serialized.`
|
|
687
688
|
};
|
|
688
689
|
}
|
|
689
|
-
if (new TextEncoder().encode(
|
|
690
|
+
if (new TextEncoder().encode(n).byteLength > 49152)
|
|
690
691
|
return {
|
|
691
692
|
valid: !1,
|
|
692
|
-
error: `${
|
|
693
|
+
error: `${i}: object is too large (max ${49152 / 1024} KB).`
|
|
693
694
|
};
|
|
694
695
|
if (Object.keys(s).length > 100)
|
|
695
696
|
return {
|
|
696
697
|
valid: !1,
|
|
697
|
-
error: `${
|
|
698
|
+
error: `${i}: object has too many keys (max 100 keys).`
|
|
698
699
|
};
|
|
699
|
-
for (const [c,
|
|
700
|
-
if (Array.isArray(
|
|
701
|
-
if (
|
|
700
|
+
for (const [c, d] of Object.entries(s)) {
|
|
701
|
+
if (Array.isArray(d)) {
|
|
702
|
+
if (d.length > 500)
|
|
702
703
|
return {
|
|
703
704
|
valid: !1,
|
|
704
|
-
error: `${
|
|
705
|
+
error: `${i}: array property "${c}" is too large (max 500 items).`
|
|
705
706
|
};
|
|
706
|
-
for (const f of
|
|
707
|
+
for (const f of d)
|
|
707
708
|
if (typeof f == "string" && f.length > 500)
|
|
708
709
|
return {
|
|
709
710
|
valid: !1,
|
|
710
|
-
error: `${
|
|
711
|
+
error: `${i}: array property "${c}" contains strings that are too long (max 500 characters).`
|
|
711
712
|
};
|
|
712
713
|
}
|
|
713
|
-
if (typeof
|
|
714
|
+
if (typeof d == "string" && d.length > 1e3)
|
|
714
715
|
return {
|
|
715
716
|
valid: !1,
|
|
716
|
-
error: `${
|
|
717
|
+
error: `${i}: property "${c}" is too long (max 1000 characters).`
|
|
717
718
|
};
|
|
718
719
|
}
|
|
719
720
|
return {
|
|
@@ -722,19 +723,19 @@ const ns = () => {
|
|
|
722
723
|
};
|
|
723
724
|
}, ft = (r, e, t) => {
|
|
724
725
|
if (Array.isArray(e)) {
|
|
725
|
-
const s = [],
|
|
726
|
-
for (let
|
|
727
|
-
const o = e[
|
|
726
|
+
const s = [], i = t && t === "customEvent" ? `${t} "${r}" metadata error` : `${r} metadata error`;
|
|
727
|
+
for (let n = 0; n < e.length; n++) {
|
|
728
|
+
const o = e[n];
|
|
728
729
|
if (typeof o != "object" || o === null || Array.isArray(o))
|
|
729
730
|
return {
|
|
730
731
|
valid: !1,
|
|
731
|
-
error: `${
|
|
732
|
+
error: `${i}: array item at index ${n} must be an object.`
|
|
732
733
|
};
|
|
733
734
|
const l = Je(r, o, t);
|
|
734
735
|
if (!l.valid)
|
|
735
736
|
return {
|
|
736
737
|
valid: !1,
|
|
737
|
-
error: `${
|
|
738
|
+
error: `${i}: array item at index ${n} is invalid: ${l.error}`
|
|
738
739
|
};
|
|
739
740
|
l.sanitizedMetadata && s.push(l.sanitizedMetadata);
|
|
740
741
|
}
|
|
@@ -744,8 +745,8 @@ const ns = () => {
|
|
|
744
745
|
};
|
|
745
746
|
}
|
|
746
747
|
return Je(r, e, t);
|
|
747
|
-
},
|
|
748
|
-
const t =
|
|
748
|
+
}, Es = (r, e) => {
|
|
749
|
+
const t = gs(r);
|
|
749
750
|
if (!t.valid)
|
|
750
751
|
return a("error", "Event name validation failed", {
|
|
751
752
|
data: { eventName: r, error: t.error }
|
|
@@ -760,7 +761,7 @@ const ns = () => {
|
|
|
760
761
|
}
|
|
761
762
|
}), s;
|
|
762
763
|
};
|
|
763
|
-
class
|
|
764
|
+
class ps {
|
|
764
765
|
listeners = /* @__PURE__ */ new Map();
|
|
765
766
|
/**
|
|
766
767
|
* Subscribes to an event channel
|
|
@@ -813,8 +814,8 @@ class gs {
|
|
|
813
814
|
off(e, t) {
|
|
814
815
|
const s = this.listeners.get(e);
|
|
815
816
|
if (s) {
|
|
816
|
-
const
|
|
817
|
-
|
|
817
|
+
const i = s.indexOf(t);
|
|
818
|
+
i > -1 && s.splice(i, 1);
|
|
818
819
|
}
|
|
819
820
|
}
|
|
820
821
|
/**
|
|
@@ -847,8 +848,8 @@ class gs {
|
|
|
847
848
|
*/
|
|
848
849
|
emit(e, t) {
|
|
849
850
|
const s = this.listeners.get(e);
|
|
850
|
-
s && s.forEach((
|
|
851
|
-
|
|
851
|
+
s && s.forEach((i) => {
|
|
852
|
+
i(t);
|
|
852
853
|
});
|
|
853
854
|
}
|
|
854
855
|
/**
|
|
@@ -888,7 +889,7 @@ function mt(r, e, t) {
|
|
|
888
889
|
}), r;
|
|
889
890
|
}
|
|
890
891
|
}
|
|
891
|
-
function
|
|
892
|
+
function Ss(r, e, t) {
|
|
892
893
|
return r.map((s) => mt(s, e, t)).filter((s) => s !== null);
|
|
893
894
|
}
|
|
894
895
|
function gt(r, e, t) {
|
|
@@ -987,6 +988,20 @@ class Ze extends _ {
|
|
|
987
988
|
*/
|
|
988
989
|
consecutiveNetworkFailures = 0;
|
|
989
990
|
circuitOpenedAt = 0;
|
|
991
|
+
/**
|
|
992
|
+
* Timestamp (epoch ms) before which `send()` must skip fetch() calls due to
|
|
993
|
+
* a prior 429 response. Mirrored to `localStorage` (keyed by userId) so the
|
|
994
|
+
* cooldown survives page navigations on traditional server-rendered sites
|
|
995
|
+
* and is discoverable by other tabs on the same origin.
|
|
996
|
+
*/
|
|
997
|
+
rateLimitedUntil = 0;
|
|
998
|
+
/**
|
|
999
|
+
* Storage key used when the current in-memory cooldown was armed. Captured
|
|
1000
|
+
* at arm time so `resetIdentity()` (which changes `userId` mid-cooldown)
|
|
1001
|
+
* can't make persist/clear operations target the wrong key or leave the
|
|
1002
|
+
* old user's cooldown orphaned in storage.
|
|
1003
|
+
*/
|
|
1004
|
+
rateLimitStorageKeyAtArm = null;
|
|
990
1005
|
/**
|
|
991
1006
|
* Creates a SenderManager instance.
|
|
992
1007
|
*
|
|
@@ -1001,10 +1016,10 @@ class Ze extends _ {
|
|
|
1001
1016
|
* @param customHeadersProvider - Optional callback for dynamic headers
|
|
1002
1017
|
* @throws Error if integrationId and apiUrl are not both provided or both undefined
|
|
1003
1018
|
*/
|
|
1004
|
-
constructor(e, t, s,
|
|
1019
|
+
constructor(e, t, s, i = {}, n = {}, o, l = "include") {
|
|
1005
1020
|
if (super(), t && !s || !t && s)
|
|
1006
1021
|
throw new Error("SenderManager: integrationId and apiUrl must either both be provided or both be undefined");
|
|
1007
|
-
this.storeManager = e, this.integrationId = t, this.apiUrl = s, this.transformers =
|
|
1022
|
+
this.storeManager = e, this.integrationId = t, this.apiUrl = s, this.transformers = i, this.staticHeaders = n, this.customHeadersProvider = o, this.fetchCredentials = l, this.rateLimitedUntil = this.loadRateLimitCooldown();
|
|
1008
1023
|
}
|
|
1009
1024
|
/**
|
|
1010
1025
|
* Get the integration ID for this sender
|
|
@@ -1054,6 +1069,64 @@ class Ze extends _ {
|
|
|
1054
1069
|
const e = this.get("userId") || "anonymous", t = Ct(e);
|
|
1055
1070
|
return this.integrationId ? `${t}:${this.integrationId}` : t;
|
|
1056
1071
|
}
|
|
1072
|
+
getRateLimitStorageKey() {
|
|
1073
|
+
const e = this.get("userId") || "anonymous", t = Rt(e);
|
|
1074
|
+
return this.integrationId ? `${t}:${this.integrationId}` : t;
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Returns the storage key bound to the *current* in-memory cooldown. Falls
|
|
1078
|
+
* back to the current-userId key when no cooldown is armed (first read) so
|
|
1079
|
+
* discovery-from-storage paths can still resolve a key.
|
|
1080
|
+
*/
|
|
1081
|
+
getActiveRateLimitKey() {
|
|
1082
|
+
return this.rateLimitStorageKeyAtArm ?? this.getRateLimitStorageKey();
|
|
1083
|
+
}
|
|
1084
|
+
armRateLimitCooldown(e) {
|
|
1085
|
+
this.rateLimitedUntil = e, this.rateLimitStorageKeyAtArm = this.getRateLimitStorageKey(), this.persistRateLimitCooldown(e);
|
|
1086
|
+
}
|
|
1087
|
+
loadRateLimitCooldown() {
|
|
1088
|
+
const e = this.getRateLimitStorageKey();
|
|
1089
|
+
try {
|
|
1090
|
+
const t = this.storeManager.getItem(e);
|
|
1091
|
+
if (!t) return 0;
|
|
1092
|
+
const s = Number(t);
|
|
1093
|
+
return !Number.isFinite(s) || s <= Date.now() ? (this.storeManager.removeItem(e), 0) : (this.rateLimitStorageKeyAtArm = e, s);
|
|
1094
|
+
} catch {
|
|
1095
|
+
return 0;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
persistRateLimitCooldown(e) {
|
|
1099
|
+
const t = this.getActiveRateLimitKey();
|
|
1100
|
+
try {
|
|
1101
|
+
const s = this.storeManager.getItem(t);
|
|
1102
|
+
if (s) {
|
|
1103
|
+
const i = Number(s);
|
|
1104
|
+
if (Number.isFinite(i) && i >= e)
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
this.storeManager.setItem(t, String(e));
|
|
1108
|
+
} catch {
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
clearRateLimitCooldown() {
|
|
1112
|
+
const e = this.getActiveRateLimitKey();
|
|
1113
|
+
try {
|
|
1114
|
+
const t = this.storeManager.getItem(e);
|
|
1115
|
+
if (t) {
|
|
1116
|
+
const s = Number(t);
|
|
1117
|
+
if (Number.isFinite(s) && s > Date.now()) {
|
|
1118
|
+
this.rateLimitedUntil = s;
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
this.storeManager.removeItem(e);
|
|
1123
|
+
} catch {
|
|
1124
|
+
}
|
|
1125
|
+
this.rateLimitedUntil = 0, this.rateLimitStorageKeyAtArm = null;
|
|
1126
|
+
}
|
|
1127
|
+
isRateLimited() {
|
|
1128
|
+
return this.rateLimitedUntil === 0 && (this.rateLimitedUntil = this.loadRateLimitCooldown()), !(this.rateLimitedUntil === 0 || Date.now() >= this.rateLimitedUntil && (this.clearRateLimitCooldown(), this.rateLimitedUntil === 0));
|
|
1129
|
+
}
|
|
1057
1130
|
/**
|
|
1058
1131
|
* Sends events synchronously using `navigator.sendBeacon()`.
|
|
1059
1132
|
*
|
|
@@ -1072,7 +1145,8 @@ class Ze extends _ {
|
|
|
1072
1145
|
*
|
|
1073
1146
|
* **Return Values**:
|
|
1074
1147
|
* - `true`: Send succeeded OR skipped (standalone mode)
|
|
1075
|
-
* - `false`: Send failed (network error, browser rejected beacon)
|
|
1148
|
+
* - `false`: Send failed (network error, browser rejected beacon) OR skipped
|
|
1149
|
+
* due to active rate-limit cooldown (events persisted for later recovery)
|
|
1076
1150
|
*
|
|
1077
1151
|
* **Important**: No retry mechanism. Failed events are persisted to localStorage for
|
|
1078
1152
|
* recovery on next page load via `recoverPersistedEvents()`.
|
|
@@ -1094,7 +1168,23 @@ class Ze extends _ {
|
|
|
1094
1168
|
* @see src/managers/README.md (lines 82-139) for send details
|
|
1095
1169
|
*/
|
|
1096
1170
|
sendEventsQueueSync(e) {
|
|
1097
|
-
|
|
1171
|
+
if (this.shouldSkipSend())
|
|
1172
|
+
return !0;
|
|
1173
|
+
if (this.isRateLimited()) {
|
|
1174
|
+
a(
|
|
1175
|
+
"debug",
|
|
1176
|
+
`Rate-limit cooldown active, skipping sync send${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1177
|
+
{
|
|
1178
|
+
data: {
|
|
1179
|
+
cooldownRemainingMs: this.rateLimitedUntil - Date.now(),
|
|
1180
|
+
events: e.events.length
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
);
|
|
1184
|
+
const t = this.ensureBatchMetadata(e), s = this.getPersistedData(), i = typeof s?.recoveryFailures == "number" && Number.isFinite(s.recoveryFailures) ? s.recoveryFailures : 0;
|
|
1185
|
+
return this.persistEventsWithFailureCount(t, i, !0), !1;
|
|
1186
|
+
}
|
|
1187
|
+
return this.apiUrl?.includes($.Fail) ? (a(
|
|
1098
1188
|
"warn",
|
|
1099
1189
|
`Fail mode: simulating network failure (sync)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1100
1190
|
{
|
|
@@ -1156,10 +1246,10 @@ class Ze extends _ {
|
|
|
1156
1246
|
async sendEventsQueue(e, t) {
|
|
1157
1247
|
const s = this.ensureBatchMetadata(e);
|
|
1158
1248
|
try {
|
|
1159
|
-
const
|
|
1160
|
-
return
|
|
1161
|
-
} catch (
|
|
1162
|
-
return
|
|
1249
|
+
const i = await this.send(s);
|
|
1250
|
+
return i ? (this.clearPersistedEvents(), t?.onSuccess?.(s.events.length, s.events, s)) : (this.persistEvents(s), t?.onFailure?.()), i;
|
|
1251
|
+
} catch (i) {
|
|
1252
|
+
return i instanceof O ? (this.logPermanentError("Permanent error, not retrying", i), this.clearPersistedEvents(), t?.onFailure?.(), !1) : (this.persistEvents(s), t?.onFailure?.(), !1);
|
|
1163
1253
|
}
|
|
1164
1254
|
}
|
|
1165
1255
|
/**
|
|
@@ -1219,26 +1309,36 @@ class Ze extends _ {
|
|
|
1219
1309
|
this.recoveryInProgress = !0;
|
|
1220
1310
|
let t = null, s = 0;
|
|
1221
1311
|
try {
|
|
1222
|
-
const
|
|
1223
|
-
if (!
|
|
1312
|
+
const i = this.getPersistedData();
|
|
1313
|
+
if (!i || !this.isDataRecent(i) || i.events.length === 0) {
|
|
1224
1314
|
this.clearPersistedEvents();
|
|
1225
1315
|
return;
|
|
1226
1316
|
}
|
|
1227
|
-
const
|
|
1228
|
-
if (s = typeof
|
|
1317
|
+
const n = i.recoveryFailures;
|
|
1318
|
+
if (s = typeof n == "number" && Number.isFinite(n) && n >= 0 ? n : 0, s >= 3) {
|
|
1229
1319
|
a(
|
|
1230
1320
|
"debug",
|
|
1231
1321
|
`Discarding persisted events after ${s} failed recovery attempts${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1232
1322
|
), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1233
1323
|
return;
|
|
1234
1324
|
}
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1325
|
+
if (this.isRateLimited()) {
|
|
1326
|
+
a(
|
|
1327
|
+
"debug",
|
|
1328
|
+
`Rate-limit cooldown active, deferring recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1329
|
+
{
|
|
1330
|
+
data: { cooldownRemainingMs: this.rateLimitedUntil - Date.now() }
|
|
1331
|
+
}
|
|
1332
|
+
), e?.onFailure?.();
|
|
1239
1333
|
return;
|
|
1240
1334
|
}
|
|
1241
|
-
|
|
1335
|
+
t = this.ensureBatchMetadata(this.createRecoveryBody(i)), await this.send(t) ? (this.clearPersistedEvents(), e?.onSuccess?.(i.events.length, i.events, t)) : (this.persistEventsWithFailureCount(t, s + 1, !0), e?.onFailure?.());
|
|
1336
|
+
} catch (i) {
|
|
1337
|
+
if (i instanceof O) {
|
|
1338
|
+
this.logPermanentError("Permanent error during recovery, clearing persisted events", i), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
a("error", "Failed to recover persisted events", { error: i }), t && this.persistEventsWithFailureCount(t, s + 1, !0), e?.onFailure?.();
|
|
1242
1342
|
} finally {
|
|
1243
1343
|
this.recoveryInProgress = !1;
|
|
1244
1344
|
}
|
|
@@ -1288,7 +1388,7 @@ class Ze extends _ {
|
|
|
1288
1388
|
const t = this.transformers.beforeSend;
|
|
1289
1389
|
if (!t)
|
|
1290
1390
|
return e;
|
|
1291
|
-
const s =
|
|
1391
|
+
const s = Ss(
|
|
1292
1392
|
e.events,
|
|
1293
1393
|
t,
|
|
1294
1394
|
this.integrationId || "SenderManager"
|
|
@@ -1355,8 +1455,8 @@ class Ze extends _ {
|
|
|
1355
1455
|
* @returns Promise that resolves after calculated delay
|
|
1356
1456
|
*/
|
|
1357
1457
|
async backoffDelay(e) {
|
|
1358
|
-
const t = 100 * Math.pow(2, e), s = Math.random() * 100,
|
|
1359
|
-
return new Promise((
|
|
1458
|
+
const t = 100 * Math.pow(2, e), s = Math.random() * 100, i = t + s;
|
|
1459
|
+
return new Promise((n) => setTimeout(n, i));
|
|
1360
1460
|
}
|
|
1361
1461
|
/**
|
|
1362
1462
|
* Sends event queue with automatic retry logic for transient failures.
|
|
@@ -1401,67 +1501,74 @@ class Ze extends _ {
|
|
|
1401
1501
|
const s = this.applyBeforeBatchTransformer(t);
|
|
1402
1502
|
if (!s)
|
|
1403
1503
|
return !0;
|
|
1404
|
-
const
|
|
1504
|
+
const i = this.ensureBatchMetadata(s, e._metadata?.idempotency_token);
|
|
1405
1505
|
if (this.apiUrl?.includes($.Fail))
|
|
1406
1506
|
return a("debug", `Fail mode: simulating network failure${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1407
|
-
data: { events:
|
|
1507
|
+
data: { events: i.events.length }
|
|
1408
1508
|
}), !1;
|
|
1409
1509
|
if (this.apiUrl?.includes($.Localhost))
|
|
1410
1510
|
return a("debug", `Success mode: simulating successful send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1411
|
-
data: { events:
|
|
1511
|
+
data: { events: i.events.length }
|
|
1412
1512
|
}), !0;
|
|
1513
|
+
if (this.isRateLimited())
|
|
1514
|
+
return a("debug", `Rate-limit cooldown active, skipping send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1515
|
+
data: {
|
|
1516
|
+
cooldownRemainingMs: this.rateLimitedUntil - Date.now(),
|
|
1517
|
+
events: i.events.length
|
|
1518
|
+
}
|
|
1519
|
+
}), !1;
|
|
1413
1520
|
if (this.consecutiveNetworkFailures >= 3) {
|
|
1414
|
-
const
|
|
1415
|
-
if (
|
|
1521
|
+
const d = Date.now() - this.circuitOpenedAt;
|
|
1522
|
+
if (d < 12e4)
|
|
1416
1523
|
return a("debug", `Network circuit open, skipping send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1417
1524
|
data: {
|
|
1418
1525
|
consecutiveNetworkFailures: this.consecutiveNetworkFailures,
|
|
1419
|
-
cooldownRemainingMs: 12e4 -
|
|
1526
|
+
cooldownRemainingMs: 12e4 - d
|
|
1420
1527
|
}
|
|
1421
1528
|
}), !1;
|
|
1422
1529
|
}
|
|
1423
|
-
const { url:
|
|
1530
|
+
const { url: n, payload: o } = this.prepareRequest(i);
|
|
1424
1531
|
let l = !0, c = !1;
|
|
1425
|
-
for (let
|
|
1532
|
+
for (let d = 1; d <= 3; d++)
|
|
1426
1533
|
try {
|
|
1427
|
-
return (await this.sendWithTimeout(
|
|
1534
|
+
return (await this.sendWithTimeout(n, o)).ok ? (d > 1 && a(
|
|
1428
1535
|
"info",
|
|
1429
|
-
`Send succeeded after ${
|
|
1536
|
+
`Send succeeded after ${d - 1} retry attempt(s)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1430
1537
|
{
|
|
1431
|
-
data: { events:
|
|
1538
|
+
data: { events: i.events.length, attempt: d }
|
|
1432
1539
|
}
|
|
1433
1540
|
), this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, !0) : !1;
|
|
1434
1541
|
} catch (f) {
|
|
1435
|
-
const g =
|
|
1542
|
+
const g = d === 3;
|
|
1436
1543
|
if (f instanceof O)
|
|
1437
1544
|
throw this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, f;
|
|
1438
1545
|
if (f instanceof re) {
|
|
1439
|
-
this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, l = !1, c = !0, a("warn", `Rate limited, skipping retries${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1440
|
-
data: { events: e.events.length, attempt:
|
|
1546
|
+
this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, l = !1, c = !0, this.armRateLimitCooldown(Date.now() + 6e4), a("warn", `Rate limited, skipping retries${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1547
|
+
data: { events: e.events.length, attempt: d, cooldownMs: 6e4 }
|
|
1441
1548
|
});
|
|
1442
1549
|
break;
|
|
1443
1550
|
}
|
|
1444
|
-
if (f instanceof
|
|
1551
|
+
if (f instanceof ie || (l = !1), f instanceof TypeError || (c = !0), a(
|
|
1445
1552
|
g ? "error" : "warn",
|
|
1446
|
-
`Send attempt ${
|
|
1553
|
+
`Send attempt ${d} failed${this.integrationId ? ` [${this.integrationId}]` : ""}${g ? " (all retries exhausted)" : ", will retry"}`,
|
|
1447
1554
|
{
|
|
1448
1555
|
error: f,
|
|
1449
1556
|
data: {
|
|
1450
1557
|
events: e.events.length,
|
|
1451
|
-
url:
|
|
1452
|
-
attempt:
|
|
1558
|
+
url: n.replace(/\/\/[^/]+/, "//[DOMAIN]"),
|
|
1559
|
+
attempt: d,
|
|
1453
1560
|
maxAttempts: 3
|
|
1454
1561
|
}
|
|
1455
1562
|
}
|
|
1456
1563
|
), !g) {
|
|
1457
|
-
await this.backoffDelay(
|
|
1564
|
+
await this.backoffDelay(d);
|
|
1458
1565
|
continue;
|
|
1459
1566
|
}
|
|
1460
1567
|
return l ? (a(
|
|
1461
1568
|
"debug",
|
|
1462
1569
|
`All retry attempts timed out, preserving batch for retry${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1463
1570
|
{
|
|
1464
|
-
data: { events:
|
|
1571
|
+
data: { events: i.events.length }
|
|
1465
1572
|
}
|
|
1466
1573
|
), !1) : (c ? (this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0) : (this.consecutiveNetworkFailures = Math.min(
|
|
1467
1574
|
this.consecutiveNetworkFailures + 1,
|
|
@@ -1496,9 +1603,9 @@ class Ze extends _ {
|
|
|
1496
1603
|
async sendWithTimeout(e, t) {
|
|
1497
1604
|
const s = new AbortController();
|
|
1498
1605
|
this.pendingControllers.add(s);
|
|
1499
|
-
let
|
|
1500
|
-
const
|
|
1501
|
-
|
|
1606
|
+
let i = !1;
|
|
1607
|
+
const n = setTimeout(() => {
|
|
1608
|
+
i = !0, s.abort();
|
|
1502
1609
|
}, 15e3);
|
|
1503
1610
|
try {
|
|
1504
1611
|
const o = this.getCustomHeaders(), l = await fetch(e, {
|
|
@@ -1512,13 +1619,35 @@ class Ze extends _ {
|
|
|
1512
1619
|
"Content-Type": "application/json"
|
|
1513
1620
|
}
|
|
1514
1621
|
});
|
|
1515
|
-
if (!l.ok)
|
|
1516
|
-
|
|
1622
|
+
if (!l.ok) {
|
|
1623
|
+
if (l.status >= 400 && l.status < 500 && l.status !== 408 && l.status !== 429) {
|
|
1624
|
+
const d = await this.readTraceLogErrorCode(l), f = d ? `HTTP ${l.status}: ${l.statusText} (${d})` : `HTTP ${l.status}: ${l.statusText}`;
|
|
1625
|
+
throw new O(f, l.status, d);
|
|
1626
|
+
}
|
|
1627
|
+
throw l.status === 429 ? new re(`HTTP 429: ${l.statusText}`) : new Error(`HTTP ${l.status}: ${l.statusText}`);
|
|
1628
|
+
}
|
|
1517
1629
|
return l;
|
|
1518
1630
|
} catch (o) {
|
|
1519
|
-
throw o instanceof O ? o :
|
|
1631
|
+
throw o instanceof O ? o : i ? new ie("Request timed out") : o;
|
|
1520
1632
|
} finally {
|
|
1521
|
-
clearTimeout(
|
|
1633
|
+
clearTimeout(n), this.pendingControllers.delete(s);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
/**
|
|
1637
|
+
* Best-effort extraction of an application `code` from a 4xx response body.
|
|
1638
|
+
*
|
|
1639
|
+
* Used purely for logging context (e.g. `PLAN_LIMIT_EXCEEDED`, `PROJECT_READ_ONLY`).
|
|
1640
|
+
* Status alone already determines retry semantics, so this never affects the
|
|
1641
|
+
* retry/persistence decision. Bounded to {@link MAX_RESPONSE_CODE_LENGTH} chars
|
|
1642
|
+
* to keep noisy/untrusted payloads out of logs without coupling the lib to the
|
|
1643
|
+
* API's evolving code catalogue.
|
|
1644
|
+
*/
|
|
1645
|
+
async readTraceLogErrorCode(e) {
|
|
1646
|
+
try {
|
|
1647
|
+
const t = await e.clone().json();
|
|
1648
|
+
if (typeof t.code == "string" && t.code.length > 0 && t.code.length <= Qt)
|
|
1649
|
+
return t.code;
|
|
1650
|
+
} catch {
|
|
1522
1651
|
}
|
|
1523
1652
|
}
|
|
1524
1653
|
/**
|
|
@@ -1545,10 +1674,10 @@ class Ze extends _ {
|
|
|
1545
1674
|
const t = this.ensureBatchMetadata(e), s = this.applyBeforeSendTransformer(t);
|
|
1546
1675
|
if (!s)
|
|
1547
1676
|
return !0;
|
|
1548
|
-
const
|
|
1549
|
-
if (!
|
|
1677
|
+
const i = this.applyBeforeBatchTransformer(s);
|
|
1678
|
+
if (!i)
|
|
1550
1679
|
return !0;
|
|
1551
|
-
const
|
|
1680
|
+
const n = this.ensureBatchMetadata(i, t._metadata?.idempotency_token), { url: o, payload: l } = this.prepareRequest(n);
|
|
1552
1681
|
if (l.length > 65536)
|
|
1553
1682
|
return a(
|
|
1554
1683
|
"warn",
|
|
@@ -1557,7 +1686,7 @@ class Ze extends _ {
|
|
|
1557
1686
|
data: {
|
|
1558
1687
|
size: l.length,
|
|
1559
1688
|
limit: 65536,
|
|
1560
|
-
events:
|
|
1689
|
+
events: n.events.length
|
|
1561
1690
|
}
|
|
1562
1691
|
}
|
|
1563
1692
|
), this.persistEvents(t), !1;
|
|
@@ -1567,11 +1696,11 @@ class Ze extends _ {
|
|
|
1567
1696
|
"warn",
|
|
1568
1697
|
`sendBeacon not available, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1569
1698
|
), this.persistEvents(t), !1;
|
|
1570
|
-
const
|
|
1571
|
-
return
|
|
1699
|
+
const d = navigator.sendBeacon(o, c);
|
|
1700
|
+
return d || (a(
|
|
1572
1701
|
"warn",
|
|
1573
1702
|
`sendBeacon rejected request, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1574
|
-
), this.persistEvents(t)),
|
|
1703
|
+
), this.persistEvents(t)), d;
|
|
1575
1704
|
}
|
|
1576
1705
|
/**
|
|
1577
1706
|
* Prepares request by enriching payload with metadata and serializing to JSON.
|
|
@@ -1602,7 +1731,7 @@ class Ze extends _ {
|
|
|
1602
1731
|
idempotency_token: e._metadata?.idempotency_token ?? this.computeContentToken(e),
|
|
1603
1732
|
referer: typeof window < "u" ? window.location.href : void 0,
|
|
1604
1733
|
timestamp: t,
|
|
1605
|
-
client_version:
|
|
1734
|
+
client_version: es
|
|
1606
1735
|
}
|
|
1607
1736
|
};
|
|
1608
1737
|
return {
|
|
@@ -1639,11 +1768,11 @@ class Ze extends _ {
|
|
|
1639
1768
|
* @private
|
|
1640
1769
|
*/
|
|
1641
1770
|
computeContentToken(e) {
|
|
1642
|
-
const t = e.events.map((
|
|
1643
|
-
let
|
|
1644
|
-
for (let
|
|
1645
|
-
|
|
1646
|
-
return
|
|
1771
|
+
const t = e.events.map((n) => n.id).sort().join(","), s = `${e.user_id}|${e.session_id}|${t}`;
|
|
1772
|
+
let i = 2166136261;
|
|
1773
|
+
for (let n = 0; n < s.length; n++)
|
|
1774
|
+
i ^= s.charCodeAt(n), i = Math.imul(i, 16777619) >>> 0;
|
|
1775
|
+
return i.toString(16).padStart(8, "0");
|
|
1647
1776
|
}
|
|
1648
1777
|
/**
|
|
1649
1778
|
* Retrieves persisted events from localStorage with error recovery.
|
|
@@ -1693,8 +1822,8 @@ class Ze extends _ {
|
|
|
1693
1822
|
* @private
|
|
1694
1823
|
*/
|
|
1695
1824
|
createRecoveryBody(e) {
|
|
1696
|
-
const { timestamp: t, recoveryFailures: s, ...
|
|
1697
|
-
return
|
|
1825
|
+
const { timestamp: t, recoveryFailures: s, ...i } = e;
|
|
1826
|
+
return i;
|
|
1698
1827
|
}
|
|
1699
1828
|
/**
|
|
1700
1829
|
* Persists failed events to localStorage for next-page-load recovery.
|
|
@@ -1714,7 +1843,8 @@ class Ze extends _ {
|
|
|
1714
1843
|
* @private
|
|
1715
1844
|
*/
|
|
1716
1845
|
persistEvents(e) {
|
|
1717
|
-
|
|
1846
|
+
const t = this.getPersistedData(), s = typeof t?.recoveryFailures == "number" && Number.isFinite(t.recoveryFailures) ? t.recoveryFailures : 0;
|
|
1847
|
+
return this.persistEventsWithFailureCount(e, s);
|
|
1718
1848
|
}
|
|
1719
1849
|
/**
|
|
1720
1850
|
* Persists failed events to localStorage, recording how many consecutive
|
|
@@ -1732,9 +1862,9 @@ class Ze extends _ {
|
|
|
1732
1862
|
*/
|
|
1733
1863
|
persistEventsWithFailureCount(e, t, s = !1) {
|
|
1734
1864
|
try {
|
|
1735
|
-
const
|
|
1736
|
-
if (!s &&
|
|
1737
|
-
const l = Date.now() -
|
|
1865
|
+
const i = this.getPersistedData();
|
|
1866
|
+
if (!s && i && i.timestamp) {
|
|
1867
|
+
const l = Date.now() - i.timestamp;
|
|
1738
1868
|
if (l < 1e3)
|
|
1739
1869
|
return a(
|
|
1740
1870
|
"debug",
|
|
@@ -1744,14 +1874,14 @@ class Ze extends _ {
|
|
|
1744
1874
|
}
|
|
1745
1875
|
), !0;
|
|
1746
1876
|
}
|
|
1747
|
-
const
|
|
1877
|
+
const n = {
|
|
1748
1878
|
...e,
|
|
1749
1879
|
timestamp: Date.now(),
|
|
1750
1880
|
...t > 0 && { recoveryFailures: t }
|
|
1751
1881
|
}, o = this.getQueueStorageKey();
|
|
1752
|
-
return this.storeManager.setItem(o, JSON.stringify(
|
|
1753
|
-
} catch (
|
|
1754
|
-
return a("debug", `Failed to persist events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error:
|
|
1882
|
+
return this.storeManager.setItem(o, JSON.stringify(n)), !!this.storeManager.getItem(o);
|
|
1883
|
+
} catch (i) {
|
|
1884
|
+
return a("debug", `Failed to persist events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error: i }), !1;
|
|
1755
1885
|
}
|
|
1756
1886
|
}
|
|
1757
1887
|
clearPersistedEvents() {
|
|
@@ -1775,13 +1905,13 @@ class Ze extends _ {
|
|
|
1775
1905
|
return typeof navigator < "u" && typeof navigator.sendBeacon == "function";
|
|
1776
1906
|
}
|
|
1777
1907
|
logPermanentError(e, t) {
|
|
1778
|
-
const s = Date.now()
|
|
1779
|
-
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.
|
|
1780
|
-
data: { status: t.statusCode, message: t.message }
|
|
1781
|
-
}), this.lastPermanentErrorLog = {
|
|
1908
|
+
const s = Date.now(), i = `${t.statusCode ?? "unknown"}:${t.responseCode ?? ""}`;
|
|
1909
|
+
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.key !== i || s - this.lastPermanentErrorLog.timestamp >= Kt) && (a("error", `${e}${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1910
|
+
data: { status: t.statusCode, code: t.responseCode, message: t.message }
|
|
1911
|
+
}), this.lastPermanentErrorLog = { key: i, timestamp: s });
|
|
1782
1912
|
}
|
|
1783
1913
|
}
|
|
1784
|
-
class
|
|
1914
|
+
class Ts extends _ {
|
|
1785
1915
|
bootTime;
|
|
1786
1916
|
bootTimestamp;
|
|
1787
1917
|
hasPerformanceNow;
|
|
@@ -1908,10 +2038,10 @@ class ps extends _ {
|
|
|
1908
2038
|
* ```
|
|
1909
2039
|
*/
|
|
1910
2040
|
validateTimestamp(e) {
|
|
1911
|
-
const s = this.now(),
|
|
1912
|
-
return
|
|
2041
|
+
const s = this.now(), i = e - s;
|
|
2042
|
+
return i > 12e4 ? {
|
|
1913
2043
|
valid: !1,
|
|
1914
|
-
error: `Timestamp is ${(
|
|
2044
|
+
error: `Timestamp is ${(i / 1e3 / 60).toFixed(2)} minutes in the future (max allowed: 2 minutes)`
|
|
1915
2045
|
} : { valid: !0 };
|
|
1916
2046
|
}
|
|
1917
2047
|
/**
|
|
@@ -1930,8 +2060,8 @@ class ps extends _ {
|
|
|
1930
2060
|
};
|
|
1931
2061
|
}
|
|
1932
2062
|
}
|
|
1933
|
-
const
|
|
1934
|
-
class
|
|
2063
|
+
const Is = new Set(Object.values(u));
|
|
2064
|
+
class vs extends _ {
|
|
1935
2065
|
dataSenders;
|
|
1936
2066
|
emitter;
|
|
1937
2067
|
transformers;
|
|
@@ -1948,11 +2078,11 @@ class Ts extends _ {
|
|
|
1948
2078
|
lastSessionId = null;
|
|
1949
2079
|
sessionEventCounts = {
|
|
1950
2080
|
total: 0,
|
|
1951
|
-
[
|
|
1952
|
-
[
|
|
1953
|
-
[
|
|
1954
|
-
[
|
|
1955
|
-
[
|
|
2081
|
+
[u.CLICK]: 0,
|
|
2082
|
+
[u.PAGE_VIEW]: 0,
|
|
2083
|
+
[u.CUSTOM]: 0,
|
|
2084
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
2085
|
+
[u.SCROLL]: 0
|
|
1956
2086
|
};
|
|
1957
2087
|
saveSessionCountsDebounced = null;
|
|
1958
2088
|
/**
|
|
@@ -1969,8 +2099,8 @@ class Ts extends _ {
|
|
|
1969
2099
|
* @param customHeadersProvider - Optional callback for dynamic headers
|
|
1970
2100
|
* @param fetchCredentials - Fetch credentials mode for custom backend. @default 'include'
|
|
1971
2101
|
*/
|
|
1972
|
-
constructor(e, t = null, s = {},
|
|
1973
|
-
super(), this.emitter = t, this.transformers = s, this.timeManager = new
|
|
2102
|
+
constructor(e, t = null, s = {}, i = {}, n, o = "include") {
|
|
2103
|
+
super(), this.emitter = t, this.transformers = s, this.timeManager = new Ts(), this.dataSenders = [];
|
|
1974
2104
|
const l = this.get("collectApiUrls");
|
|
1975
2105
|
l?.saas && this.dataSenders.push(new Ze(e, "saas", l.saas, s)), l?.custom && this.dataSenders.push(
|
|
1976
2106
|
new Ze(
|
|
@@ -1978,8 +2108,8 @@ class Ts extends _ {
|
|
|
1978
2108
|
"custom",
|
|
1979
2109
|
l.custom,
|
|
1980
2110
|
s,
|
|
1981
|
-
n,
|
|
1982
2111
|
i,
|
|
2112
|
+
n,
|
|
1983
2113
|
o
|
|
1984
2114
|
)
|
|
1985
2115
|
), this.saveSessionCountsDebounced = this.debounce((c) => {
|
|
@@ -2013,10 +2143,10 @@ class Ts extends _ {
|
|
|
2013
2143
|
async recoverPersistedEvents() {
|
|
2014
2144
|
const e = this.dataSenders.map(
|
|
2015
2145
|
async (t) => t.recoverPersistedEvents({
|
|
2016
|
-
onSuccess: (s,
|
|
2017
|
-
if (
|
|
2018
|
-
const o =
|
|
2019
|
-
this.removeProcessedEvents(o),
|
|
2146
|
+
onSuccess: (s, i, n) => {
|
|
2147
|
+
if (i && i.length > 0) {
|
|
2148
|
+
const o = i.map((l) => l.id);
|
|
2149
|
+
this.removeProcessedEvents(o), n && this.emitEventsQueue(n);
|
|
2020
2150
|
}
|
|
2021
2151
|
},
|
|
2022
2152
|
onFailure: () => {
|
|
@@ -2089,19 +2219,19 @@ class Ts extends _ {
|
|
|
2089
2219
|
type: e,
|
|
2090
2220
|
page_url: t,
|
|
2091
2221
|
from_page_url: s,
|
|
2092
|
-
scroll_data:
|
|
2093
|
-
click_data:
|
|
2222
|
+
scroll_data: i,
|
|
2223
|
+
click_data: n,
|
|
2094
2224
|
custom_event: o,
|
|
2095
2225
|
web_vitals: l,
|
|
2096
2226
|
error_data: c,
|
|
2097
|
-
viewport_data:
|
|
2227
|
+
viewport_data: d,
|
|
2098
2228
|
page_view: f
|
|
2099
2229
|
}) {
|
|
2100
2230
|
if (!e) {
|
|
2101
2231
|
a("error", "Event type is required - event will be ignored");
|
|
2102
2232
|
return;
|
|
2103
2233
|
}
|
|
2104
|
-
if (!
|
|
2234
|
+
if (!Is.has(e)) {
|
|
2105
2235
|
a("error", "Invalid event type - event will be ignored", {
|
|
2106
2236
|
data: { type: e }
|
|
2107
2237
|
});
|
|
@@ -2115,24 +2245,24 @@ class Ts extends _ {
|
|
|
2115
2245
|
type: e,
|
|
2116
2246
|
page_url: t,
|
|
2117
2247
|
from_page_url: s,
|
|
2118
|
-
scroll_data:
|
|
2119
|
-
click_data:
|
|
2248
|
+
scroll_data: i,
|
|
2249
|
+
click_data: n,
|
|
2120
2250
|
custom_event: o,
|
|
2121
2251
|
web_vitals: l,
|
|
2122
2252
|
error_data: c,
|
|
2123
|
-
viewport_data:
|
|
2253
|
+
viewport_data: d,
|
|
2124
2254
|
page_view: f
|
|
2125
2255
|
});
|
|
2126
2256
|
return;
|
|
2127
2257
|
}
|
|
2128
2258
|
this.lastSessionId !== g && (this.lastSessionId = g, this.sessionEventCounts = this.loadSessionCounts(g));
|
|
2129
|
-
const
|
|
2130
|
-
if (
|
|
2259
|
+
const I = e === u.SESSION_START;
|
|
2260
|
+
if (I && a("debug", "Processing SESSION_START event", {
|
|
2131
2261
|
data: { sessionId: g }
|
|
2132
|
-
}), !
|
|
2262
|
+
}), !I && !this.checkRateLimit())
|
|
2133
2263
|
return;
|
|
2134
2264
|
const p = e;
|
|
2135
|
-
if (!
|
|
2265
|
+
if (!I) {
|
|
2136
2266
|
if (this.sessionEventCounts.total >= 1e3) {
|
|
2137
2267
|
a("warn", "Session event limit reached", {
|
|
2138
2268
|
data: {
|
|
@@ -2158,24 +2288,24 @@ class Ts extends _ {
|
|
|
2158
2288
|
}
|
|
2159
2289
|
}
|
|
2160
2290
|
}
|
|
2161
|
-
if (p ===
|
|
2291
|
+
if (p === u.CUSTOM && o?.name) {
|
|
2162
2292
|
const v = this.get("config")?.maxSameEventPerMinute ?? 60;
|
|
2163
2293
|
if (!this.checkPerEventRateLimit(o.name, v))
|
|
2164
2294
|
return;
|
|
2165
2295
|
}
|
|
2166
|
-
const Ve = p ===
|
|
2296
|
+
const Ve = p === u.SESSION_START, Q = t || this.get("pageUrl"), x = this.buildEventPayload({
|
|
2167
2297
|
type: p,
|
|
2168
|
-
page_url:
|
|
2298
|
+
page_url: Q,
|
|
2169
2299
|
from_page_url: s,
|
|
2170
|
-
scroll_data:
|
|
2171
|
-
click_data:
|
|
2300
|
+
scroll_data: i,
|
|
2301
|
+
click_data: n,
|
|
2172
2302
|
custom_event: o,
|
|
2173
2303
|
web_vitals: l,
|
|
2174
2304
|
error_data: c,
|
|
2175
|
-
viewport_data:
|
|
2305
|
+
viewport_data: d,
|
|
2176
2306
|
page_view: f
|
|
2177
2307
|
});
|
|
2178
|
-
if (x && !(!
|
|
2308
|
+
if (x && !(!I && !this.shouldSample())) {
|
|
2179
2309
|
if (Ve) {
|
|
2180
2310
|
const v = this.get("sessionId");
|
|
2181
2311
|
if (!v) {
|
|
@@ -2191,8 +2321,8 @@ class Ts extends _ {
|
|
|
2191
2321
|
this.set("hasStartSession", !0);
|
|
2192
2322
|
}
|
|
2193
2323
|
if (!this.isDuplicateEvent(x)) {
|
|
2194
|
-
if (this.get("mode") ===
|
|
2195
|
-
if (p ===
|
|
2324
|
+
if (this.get("mode") === ne.QA) {
|
|
2325
|
+
if (p === u.CUSTOM && o) {
|
|
2196
2326
|
a("info", `Custom Event: ${o.name}`, {
|
|
2197
2327
|
visibility: "qa",
|
|
2198
2328
|
data: {
|
|
@@ -2202,22 +2332,22 @@ class Ts extends _ {
|
|
|
2202
2332
|
}), this.emitEvent(x);
|
|
2203
2333
|
return;
|
|
2204
2334
|
}
|
|
2205
|
-
if (p ===
|
|
2206
|
-
const v =
|
|
2335
|
+
if (p === u.VIEWPORT_VISIBLE && d) {
|
|
2336
|
+
const v = d.name || d.id || d.selector;
|
|
2207
2337
|
a("info", `Viewport Visible: ${v}`, {
|
|
2208
2338
|
visibility: "qa",
|
|
2209
2339
|
data: {
|
|
2210
|
-
selector:
|
|
2211
|
-
...
|
|
2212
|
-
...
|
|
2213
|
-
visibilityRatio:
|
|
2214
|
-
dwellTime:
|
|
2340
|
+
selector: d.selector,
|
|
2341
|
+
...d.name && { name: d.name },
|
|
2342
|
+
...d.id && { id: d.id },
|
|
2343
|
+
visibilityRatio: d.visibilityRatio,
|
|
2344
|
+
dwellTime: d.dwellTime
|
|
2215
2345
|
}
|
|
2216
2346
|
}), this.emitEvent(x);
|
|
2217
2347
|
return;
|
|
2218
2348
|
}
|
|
2219
2349
|
}
|
|
2220
|
-
if (this.addToQueue(x), !
|
|
2350
|
+
if (this.addToQueue(x), !I) {
|
|
2221
2351
|
this.sessionEventCounts.total++, this.sessionEventCounts[p] !== void 0 && this.sessionEventCounts[p]++;
|
|
2222
2352
|
const v = this.get("sessionId");
|
|
2223
2353
|
v && this.saveSessionCountsDebounced && this.saveSessionCountsDebounced(v);
|
|
@@ -2264,11 +2394,11 @@ class Ts extends _ {
|
|
|
2264
2394
|
const e = this.get("sessionId");
|
|
2265
2395
|
e && this.saveSessionCounts(e), this.eventsQueue = [], this.pendingEventsBuffer = [], this.recentEventFingerprints.clear(), this.rateLimitCounter = 0, this.rateLimitWindowStart = 0, this.perEventRateLimits.clear(), this.sessionEventCounts = {
|
|
2266
2396
|
total: 0,
|
|
2267
|
-
[
|
|
2268
|
-
[
|
|
2269
|
-
[
|
|
2270
|
-
[
|
|
2271
|
-
[
|
|
2397
|
+
[u.CLICK]: 0,
|
|
2398
|
+
[u.PAGE_VIEW]: 0,
|
|
2399
|
+
[u.CUSTOM]: 0,
|
|
2400
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
2401
|
+
[u.SCROLL]: 0
|
|
2272
2402
|
}, this.lastSessionId = null, this.set("hasStartSession", !1), this.dataSenders.forEach((t) => {
|
|
2273
2403
|
t.stop();
|
|
2274
2404
|
});
|
|
@@ -2484,23 +2614,20 @@ class Ts extends _ {
|
|
|
2484
2614
|
return e ? !0 : Promise.resolve(!0);
|
|
2485
2615
|
if (!e && this.sendInProgress)
|
|
2486
2616
|
return a("debug", "Async flush skipped: send already in progress"), Promise.resolve(!1);
|
|
2487
|
-
const t = this.buildEventsPayload(), s = [...this.eventsQueue],
|
|
2617
|
+
const t = this.buildEventsPayload(), s = [...this.eventsQueue], i = s.map((n) => n.id);
|
|
2488
2618
|
if (this.dataSenders.length === 0)
|
|
2489
|
-
return this.removeProcessedEvents(
|
|
2490
|
-
if (e && this.sendInProgress)
|
|
2491
|
-
|
|
2492
|
-
i.
|
|
2493
|
-
return a("debug", "Sync flush deferred: async send in progress, events persisted for recovery", {
|
|
2494
|
-
data: { eventCount: n.length }
|
|
2619
|
+
return this.removeProcessedEvents(i), this.clearSendTimeout(), this.emitEventsQueue(t), e ? !0 : Promise.resolve(!0);
|
|
2620
|
+
if (e && this.sendInProgress)
|
|
2621
|
+
return a("debug", "Sync flush skipped: async send already in-flight, trusting fetch to deliver", {
|
|
2622
|
+
data: { eventCount: i.length }
|
|
2495
2623
|
}), !0;
|
|
2496
|
-
}
|
|
2497
2624
|
if (e) {
|
|
2498
2625
|
const o = this.dataSenders.map((l) => l.sendEventsQueueSync(t)).some((l) => l);
|
|
2499
|
-
return o ? (this.removeProcessedEvents(
|
|
2500
|
-
data: { eventCount:
|
|
2626
|
+
return o ? (this.removeProcessedEvents(i), this.clearSendTimeout(), this.emitEventsQueue(t)) : (this.clearSendTimeout(), a("debug", "Sync flush complete failure, events kept in queue for retry", {
|
|
2627
|
+
data: { eventCount: i.length }
|
|
2501
2628
|
})), o;
|
|
2502
2629
|
} else {
|
|
2503
|
-
const
|
|
2630
|
+
const n = this.dataSenders.map(
|
|
2504
2631
|
async (o) => o.sendEventsQueue(t, {
|
|
2505
2632
|
onSuccess: () => {
|
|
2506
2633
|
},
|
|
@@ -2508,9 +2635,9 @@ class Ts extends _ {
|
|
|
2508
2635
|
}
|
|
2509
2636
|
})
|
|
2510
2637
|
);
|
|
2511
|
-
return Promise.allSettled(
|
|
2638
|
+
return Promise.allSettled(n).then((o) => {
|
|
2512
2639
|
const l = o.some((c) => this.isSuccessfulResult(c));
|
|
2513
|
-
return l ? (this.removeProcessedEvents(
|
|
2640
|
+
return l ? (this.removeProcessedEvents(i), this.clearSendTimeout(), this.emitEventsQueue(t)) : a("debug", "Async flush complete failure, events kept in queue for retry", {
|
|
2514
2641
|
data: { eventCount: s.length }
|
|
2515
2642
|
}), l;
|
|
2516
2643
|
});
|
|
@@ -2525,17 +2652,17 @@ class Ts extends _ {
|
|
|
2525
2652
|
this.emitEventsQueue(e);
|
|
2526
2653
|
return;
|
|
2527
2654
|
}
|
|
2528
|
-
const t = [...this.eventsQueue], s = t.map((l) => l.id),
|
|
2655
|
+
const t = [...this.eventsQueue], s = t.map((l) => l.id), i = this.dataSenders.map(
|
|
2529
2656
|
async (l) => l.sendEventsQueue(e, {
|
|
2530
2657
|
onSuccess: () => {
|
|
2531
2658
|
},
|
|
2532
2659
|
onFailure: () => {
|
|
2533
2660
|
}
|
|
2534
2661
|
})
|
|
2535
|
-
),
|
|
2536
|
-
if (
|
|
2662
|
+
), n = await Promise.allSettled(i);
|
|
2663
|
+
if (n.some((l) => this.isSuccessfulResult(l))) {
|
|
2537
2664
|
this.consecutiveSendFailures = 0, this.removeProcessedEvents(s), this.emitEventsQueue(e);
|
|
2538
|
-
const l =
|
|
2665
|
+
const l = n.filter((c) => !this.isSuccessfulResult(c)).length;
|
|
2539
2666
|
l > 0 && a("debug", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
|
|
2540
2667
|
data: { eventCount: t.length, failedCount: l }
|
|
2541
2668
|
});
|
|
@@ -2552,11 +2679,11 @@ class Ts extends _ {
|
|
|
2552
2679
|
buildEventsPayload() {
|
|
2553
2680
|
const e = /* @__PURE__ */ new Map(), t = [];
|
|
2554
2681
|
for (const c of this.eventsQueue) {
|
|
2555
|
-
const
|
|
2556
|
-
e.has(
|
|
2682
|
+
const d = this.createEventSignature(c);
|
|
2683
|
+
e.has(d) || t.push(d), e.set(d, c);
|
|
2557
2684
|
}
|
|
2558
|
-
const s = t.map((c) => e.get(c)).filter((c) => !!c).sort((c,
|
|
2559
|
-
let
|
|
2685
|
+
const s = t.map((c) => e.get(c)).filter((c) => !!c).sort((c, d) => c.type === u.SESSION_START && d.type !== u.SESSION_START ? -1 : d.type === u.SESSION_START && c.type !== u.SESSION_START ? 1 : c.timestamp - d.timestamp);
|
|
2686
|
+
let i = {
|
|
2560
2687
|
user_id: this.get("userId"),
|
|
2561
2688
|
session_id: this.get("sessionId"),
|
|
2562
2689
|
device: this.get("device"),
|
|
@@ -2564,25 +2691,25 @@ class Ts extends _ {
|
|
|
2564
2691
|
...this.get("config")?.globalMetadata && { global_metadata: this.get("config")?.globalMetadata },
|
|
2565
2692
|
...this.get("identity") && { identify: this.get("identity") }
|
|
2566
2693
|
};
|
|
2567
|
-
const
|
|
2694
|
+
const n = this.get("collectApiUrls"), o = !!(n?.custom || n?.saas), l = this.transformers.beforeBatch;
|
|
2568
2695
|
if (!o && l) {
|
|
2569
|
-
const c = gt(
|
|
2570
|
-
c !== null && (
|
|
2696
|
+
const c = gt(i, l, "EventManager");
|
|
2697
|
+
c !== null && (i = c);
|
|
2571
2698
|
}
|
|
2572
|
-
return
|
|
2699
|
+
return i;
|
|
2573
2700
|
}
|
|
2574
2701
|
buildEventPayload(e) {
|
|
2575
|
-
const t = e.page_url ?? this.get("pageUrl"), s = this.timeManager.now(),
|
|
2576
|
-
|
|
2577
|
-
data: { type: e.type, error:
|
|
2702
|
+
const t = e.page_url ?? this.get("pageUrl"), s = this.timeManager.now(), i = this.timeManager.validateTimestamp(s);
|
|
2703
|
+
i.valid || a("warn", "Event timestamp validation failed", {
|
|
2704
|
+
data: { type: e.type, error: i.error }
|
|
2578
2705
|
});
|
|
2579
|
-
const
|
|
2706
|
+
const n = this.get("sessionReferrer"), o = this.get("sessionUtm");
|
|
2580
2707
|
let l = {
|
|
2581
|
-
id:
|
|
2708
|
+
id: os(),
|
|
2582
2709
|
type: e.type,
|
|
2583
2710
|
page_url: t,
|
|
2584
2711
|
timestamp: s,
|
|
2585
|
-
...
|
|
2712
|
+
...n && { referrer: n },
|
|
2586
2713
|
...e.from_page_url && { from_page_url: e.from_page_url },
|
|
2587
2714
|
...e.scroll_data && { scroll_data: e.scroll_data },
|
|
2588
2715
|
...e.click_data && { click_data: e.click_data },
|
|
@@ -2593,25 +2720,25 @@ class Ts extends _ {
|
|
|
2593
2720
|
...e.page_view && { page_view: e.page_view },
|
|
2594
2721
|
...o && { utm: o }
|
|
2595
2722
|
};
|
|
2596
|
-
const c = this.get("collectApiUrls"),
|
|
2597
|
-
if (p && (!g ||
|
|
2598
|
-
const
|
|
2599
|
-
if (
|
|
2723
|
+
const c = this.get("collectApiUrls"), d = !!c?.custom, f = !!c?.saas, g = d || f, I = d && f, p = this.transformers.beforeSend;
|
|
2724
|
+
if (p && (!g || d && !I)) {
|
|
2725
|
+
const Q = mt(l, p, "EventManager");
|
|
2726
|
+
if (Q === null)
|
|
2600
2727
|
return null;
|
|
2601
|
-
l =
|
|
2728
|
+
l = Q;
|
|
2602
2729
|
}
|
|
2603
2730
|
return l;
|
|
2604
2731
|
}
|
|
2605
2732
|
isDuplicateEvent(e) {
|
|
2606
|
-
const t = Date.now(), s = this.createEventFingerprint(e),
|
|
2607
|
-
return
|
|
2733
|
+
const t = Date.now(), s = this.createEventFingerprint(e), i = this.recentEventFingerprints.get(s);
|
|
2734
|
+
return i && t - i < 1e3 ? (this.recentEventFingerprints.set(s, t), !0) : (this.recentEventFingerprints.set(s, t), this.recentEventFingerprints.size > 1500 && this.pruneOldFingerprints(), this.recentEventFingerprints.size > 3e3 && (this.recentEventFingerprints.clear(), this.recentEventFingerprints.set(s, t), a("debug", "Event fingerprint cache exceeded hard limit, cleared", {
|
|
2608
2735
|
data: { hardLimit: 3e3 }
|
|
2609
2736
|
})), !1);
|
|
2610
2737
|
}
|
|
2611
2738
|
pruneOldFingerprints() {
|
|
2612
2739
|
const e = Date.now(), t = 1e3 * 10;
|
|
2613
|
-
for (const [s,
|
|
2614
|
-
e -
|
|
2740
|
+
for (const [s, i] of this.recentEventFingerprints.entries())
|
|
2741
|
+
e - i > t && this.recentEventFingerprints.delete(s);
|
|
2615
2742
|
a("debug", "Pruned old event fingerprints", {
|
|
2616
2743
|
data: {
|
|
2617
2744
|
remaining: this.recentEventFingerprints.size,
|
|
@@ -2622,8 +2749,8 @@ class Ts extends _ {
|
|
|
2622
2749
|
createEventFingerprint(e) {
|
|
2623
2750
|
let t = `${e.type}_${e.page_url}`;
|
|
2624
2751
|
if (e.click_data) {
|
|
2625
|
-
const s = Math.round((e.click_data.x || 0) / 10) * 10,
|
|
2626
|
-
t += `_click_${s}_${
|
|
2752
|
+
const s = Math.round((e.click_data.x || 0) / 10) * 10, i = Math.round((e.click_data.y || 0) / 10) * 10;
|
|
2753
|
+
t += `_click_${s}_${i}`;
|
|
2627
2754
|
}
|
|
2628
2755
|
return e.scroll_data && (t += `_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`), e.custom_event && (t += `_custom_${e.custom_event.name}`, e.custom_event.metadata && (t += `_${this.stableStringify(e.custom_event.metadata)}`)), e.web_vitals && (t += `_vitals_${e.web_vitals.type}`), e.error_data && (t += `_error_${e.error_data.type}_${e.error_data.message}`), t;
|
|
2629
2756
|
}
|
|
@@ -2632,17 +2759,17 @@ class Ts extends _ {
|
|
|
2632
2759
|
}
|
|
2633
2760
|
/** Deterministic JSON string with sorted keys to ensure consistent fingerprints regardless of property insertion order */
|
|
2634
2761
|
stableStringify(e) {
|
|
2635
|
-
return JSON.stringify(e, (t, s) => s && typeof s == "object" && !Array.isArray(s) ? Object.keys(s).sort().reduce((
|
|
2762
|
+
return JSON.stringify(e, (t, s) => s && typeof s == "object" && !Array.isArray(s) ? Object.keys(s).sort().reduce((i, n) => (i[n] = s[n], i), {}) : s);
|
|
2636
2763
|
}
|
|
2637
2764
|
addToQueue(e) {
|
|
2638
2765
|
if (this.emitEvent(e), this.eventsQueue.push(e), this.eventsQueue.length > 100) {
|
|
2639
|
-
const t = this.eventsQueue.findIndex((
|
|
2766
|
+
const t = this.eventsQueue.findIndex((i) => i.type !== u.SESSION_START), s = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
|
|
2640
2767
|
a("warn", "Event queue overflow, oldest non-critical event removed", {
|
|
2641
2768
|
data: {
|
|
2642
2769
|
maxLength: 100,
|
|
2643
2770
|
currentLength: this.eventsQueue.length,
|
|
2644
2771
|
removedEventType: s?.type,
|
|
2645
|
-
wasCritical: s?.type ===
|
|
2772
|
+
wasCritical: s?.type === u.SESSION_START
|
|
2646
2773
|
}
|
|
2647
2774
|
});
|
|
2648
2775
|
}
|
|
@@ -2670,22 +2797,22 @@ class Ts extends _ {
|
|
|
2670
2797
|
return e - this.rateLimitWindowStart > 1e3 && (this.rateLimitCounter = 0, this.rateLimitWindowStart = e), this.rateLimitCounter >= 50 ? !1 : (this.rateLimitCounter++, !0);
|
|
2671
2798
|
}
|
|
2672
2799
|
checkPerEventRateLimit(e, t) {
|
|
2673
|
-
const s = Date.now(),
|
|
2674
|
-
return
|
|
2800
|
+
const s = Date.now(), n = (this.perEventRateLimits.get(e) ?? []).filter((o) => s - o < 6e4);
|
|
2801
|
+
return n.length >= t ? (a("warn", "Per-event rate limit exceeded for custom event", {
|
|
2675
2802
|
data: {
|
|
2676
2803
|
eventName: e,
|
|
2677
2804
|
limit: t,
|
|
2678
2805
|
window: `${6e4 / 1e3}s`
|
|
2679
2806
|
}
|
|
2680
|
-
}), !1) : (
|
|
2807
|
+
}), !1) : (n.push(s), this.perEventRateLimits.set(e, n), !0);
|
|
2681
2808
|
}
|
|
2682
2809
|
getTypeLimitForEvent(e) {
|
|
2683
2810
|
return {
|
|
2684
|
-
[
|
|
2685
|
-
[
|
|
2686
|
-
[
|
|
2687
|
-
[
|
|
2688
|
-
[
|
|
2811
|
+
[u.CLICK]: 500,
|
|
2812
|
+
[u.PAGE_VIEW]: 100,
|
|
2813
|
+
[u.CUSTOM]: 500,
|
|
2814
|
+
[u.VIEWPORT_VISIBLE]: 200,
|
|
2815
|
+
[u.SCROLL]: 120
|
|
2689
2816
|
}[e] ?? null;
|
|
2690
2817
|
}
|
|
2691
2818
|
removeProcessedEvents(e) {
|
|
@@ -2720,9 +2847,9 @@ class Ts extends _ {
|
|
|
2720
2847
|
*/
|
|
2721
2848
|
debounce(e, t) {
|
|
2722
2849
|
let s = null;
|
|
2723
|
-
return ((...
|
|
2850
|
+
return ((...i) => {
|
|
2724
2851
|
s !== null && clearTimeout(s), s = setTimeout(() => {
|
|
2725
|
-
e(...
|
|
2852
|
+
e(...i), s = null;
|
|
2726
2853
|
}, t);
|
|
2727
2854
|
});
|
|
2728
2855
|
}
|
|
@@ -2739,11 +2866,11 @@ class Ts extends _ {
|
|
|
2739
2866
|
getInitialCounts() {
|
|
2740
2867
|
return {
|
|
2741
2868
|
total: 0,
|
|
2742
|
-
[
|
|
2743
|
-
[
|
|
2744
|
-
[
|
|
2745
|
-
[
|
|
2746
|
-
[
|
|
2869
|
+
[u.CLICK]: 0,
|
|
2870
|
+
[u.PAGE_VIEW]: 0,
|
|
2871
|
+
[u.CUSTOM]: 0,
|
|
2872
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
2873
|
+
[u.SCROLL]: 0
|
|
2747
2874
|
};
|
|
2748
2875
|
}
|
|
2749
2876
|
/**
|
|
@@ -2772,29 +2899,29 @@ class Ts extends _ {
|
|
|
2772
2899
|
loadSessionCounts(e) {
|
|
2773
2900
|
if (typeof window > "u" || typeof localStorage > "u")
|
|
2774
2901
|
return this.getInitialCounts();
|
|
2775
|
-
const t = this.get("userId") || "anonymous", s =
|
|
2902
|
+
const t = this.get("userId") || "anonymous", s = He(t, e);
|
|
2776
2903
|
try {
|
|
2777
|
-
const
|
|
2778
|
-
if (!
|
|
2904
|
+
const i = localStorage.getItem(s);
|
|
2905
|
+
if (!i)
|
|
2779
2906
|
return this.getInitialCounts();
|
|
2780
|
-
const
|
|
2781
|
-
return
|
|
2782
|
-
data: { sessionId: e, age: Date.now() -
|
|
2783
|
-
}), localStorage.removeItem(s), this.getInitialCounts()) : typeof
|
|
2784
|
-
total:
|
|
2785
|
-
[
|
|
2786
|
-
[
|
|
2787
|
-
[
|
|
2788
|
-
[
|
|
2789
|
-
[
|
|
2907
|
+
const n = JSON.parse(i);
|
|
2908
|
+
return n._timestamp && Date.now() - n._timestamp > xe ? (a("debug", "Session counts expired, clearing", {
|
|
2909
|
+
data: { sessionId: e, age: Date.now() - n._timestamp }
|
|
2910
|
+
}), localStorage.removeItem(s), this.getInitialCounts()) : typeof n.total == "number" && typeof n[u.CLICK] == "number" && typeof n[u.PAGE_VIEW] == "number" && typeof n[u.CUSTOM] == "number" && typeof n[u.VIEWPORT_VISIBLE] == "number" && typeof n[u.SCROLL] == "number" ? {
|
|
2911
|
+
total: n.total,
|
|
2912
|
+
[u.CLICK]: n[u.CLICK],
|
|
2913
|
+
[u.PAGE_VIEW]: n[u.PAGE_VIEW],
|
|
2914
|
+
[u.CUSTOM]: n[u.CUSTOM],
|
|
2915
|
+
[u.VIEWPORT_VISIBLE]: n[u.VIEWPORT_VISIBLE],
|
|
2916
|
+
[u.SCROLL]: n[u.SCROLL]
|
|
2790
2917
|
} : (a("warn", "Invalid session counts structure in localStorage, resetting", {
|
|
2791
|
-
data: { sessionId: e, parsed:
|
|
2918
|
+
data: { sessionId: e, parsed: n }
|
|
2792
2919
|
}), localStorage.removeItem(s), a("debug", "Session counts removed due to invalid/corrupted data", {
|
|
2793
|
-
data: { sessionId: e, parsed:
|
|
2920
|
+
data: { sessionId: e, parsed: n }
|
|
2794
2921
|
}), this.getInitialCounts());
|
|
2795
|
-
} catch (
|
|
2922
|
+
} catch (i) {
|
|
2796
2923
|
return a("warn", "Failed to load session counts from localStorage", {
|
|
2797
|
-
error:
|
|
2924
|
+
error: i,
|
|
2798
2925
|
data: { sessionId: e }
|
|
2799
2926
|
}), this.getInitialCounts();
|
|
2800
2927
|
}
|
|
@@ -2825,30 +2952,30 @@ class Ts extends _ {
|
|
|
2825
2952
|
try {
|
|
2826
2953
|
const e = localStorage.getItem($e);
|
|
2827
2954
|
if (e) {
|
|
2828
|
-
const
|
|
2829
|
-
if (
|
|
2955
|
+
const n = Date.now() - parseInt(e, 10);
|
|
2956
|
+
if (n < Be) {
|
|
2830
2957
|
a("debug", "Skipping session counts cleanup (throttled)", {
|
|
2831
|
-
data: { timeSinceLastCleanup:
|
|
2958
|
+
data: { timeSinceLastCleanup: n, throttleMs: Be }
|
|
2832
2959
|
});
|
|
2833
2960
|
return;
|
|
2834
2961
|
}
|
|
2835
2962
|
}
|
|
2836
|
-
const t = this.get("userId") || "anonymous", s = `${
|
|
2837
|
-
for (let
|
|
2838
|
-
const o = localStorage.key(
|
|
2963
|
+
const t = this.get("userId") || "anonymous", s = `${S}:${t}:session_counts:`, i = [];
|
|
2964
|
+
for (let n = 0; n < localStorage.length; n++) {
|
|
2965
|
+
const o = localStorage.key(n);
|
|
2839
2966
|
if (o?.startsWith(s))
|
|
2840
2967
|
try {
|
|
2841
2968
|
const l = localStorage.getItem(o);
|
|
2842
2969
|
if (l) {
|
|
2843
2970
|
const c = JSON.parse(l);
|
|
2844
|
-
c._timestamp && Date.now() - c._timestamp > xe &&
|
|
2971
|
+
c._timestamp && Date.now() - c._timestamp > xe && i.push(o);
|
|
2845
2972
|
}
|
|
2846
2973
|
} catch {
|
|
2847
2974
|
}
|
|
2848
2975
|
}
|
|
2849
|
-
|
|
2850
|
-
localStorage.removeItem(
|
|
2851
|
-
}),
|
|
2976
|
+
i.forEach((n) => {
|
|
2977
|
+
localStorage.removeItem(n), a("debug", "Cleaned up expired session counts", { data: { key: n } });
|
|
2978
|
+
}), i.length > 0 && a("info", `Cleaned up ${i.length} expired session counts entries`), localStorage.setItem($e, Date.now().toString());
|
|
2852
2979
|
} catch (e) {
|
|
2853
2980
|
a("warn", "Failed to cleanup expired session counts", { error: e });
|
|
2854
2981
|
}
|
|
@@ -2882,23 +3009,23 @@ class Ts extends _ {
|
|
|
2882
3009
|
* @internal
|
|
2883
3010
|
*/
|
|
2884
3011
|
saveSessionCounts(e) {
|
|
2885
|
-
const t = this.get("userId") || "anonymous", s =
|
|
3012
|
+
const t = this.get("userId") || "anonymous", s = He(t, e);
|
|
2886
3013
|
try {
|
|
2887
|
-
const
|
|
3014
|
+
const i = {
|
|
2888
3015
|
...this.sessionEventCounts,
|
|
2889
3016
|
_timestamp: Date.now(),
|
|
2890
3017
|
_version: 1
|
|
2891
3018
|
};
|
|
2892
|
-
localStorage.setItem(s, JSON.stringify(
|
|
2893
|
-
} catch (
|
|
3019
|
+
localStorage.setItem(s, JSON.stringify(i));
|
|
3020
|
+
} catch (i) {
|
|
2894
3021
|
a("warn", "Failed to persist session counts to localStorage", {
|
|
2895
|
-
error:
|
|
3022
|
+
error: i,
|
|
2896
3023
|
data: { sessionId: e }
|
|
2897
3024
|
});
|
|
2898
3025
|
}
|
|
2899
3026
|
}
|
|
2900
3027
|
}
|
|
2901
|
-
class
|
|
3028
|
+
class _s {
|
|
2902
3029
|
/**
|
|
2903
3030
|
* Gets or creates a unique user ID.
|
|
2904
3031
|
*
|
|
@@ -2919,12 +3046,12 @@ class Is {
|
|
|
2919
3046
|
const t = e.getItem(Te);
|
|
2920
3047
|
if (t)
|
|
2921
3048
|
return t;
|
|
2922
|
-
const s =
|
|
3049
|
+
const s = dt();
|
|
2923
3050
|
return e.setItem(Te, s), s;
|
|
2924
3051
|
}
|
|
2925
3052
|
}
|
|
2926
|
-
const
|
|
2927
|
-
class
|
|
3053
|
+
const ys = /^\d{13}-[a-z0-9]{9}$/;
|
|
3054
|
+
class ws extends _ {
|
|
2928
3055
|
storageManager;
|
|
2929
3056
|
eventManager;
|
|
2930
3057
|
projectId;
|
|
@@ -2950,9 +3077,9 @@ class _s extends _ {
|
|
|
2950
3077
|
return;
|
|
2951
3078
|
}
|
|
2952
3079
|
const e = this.getProjectId();
|
|
2953
|
-
this.broadcastChannel = new BroadcastChannel(
|
|
2954
|
-
const { action: s, sessionId:
|
|
2955
|
-
o === e && (s === "session_start" &&
|
|
3080
|
+
this.broadcastChannel = new BroadcastChannel(Ot(e)), this.broadcastChannel.onmessage = (t) => {
|
|
3081
|
+
const { action: s, sessionId: i, timestamp: n, projectId: o } = t.data ?? {};
|
|
3082
|
+
o === e && (s === "session_start" && i && typeof n == "number" && n > Date.now() - 5e3 ? (this.set("sessionId", i), this.persistSession(i, n), this.isTracking && this.setupSessionTimeout()) : s && s !== "session_start" && a("debug", "Ignored BroadcastChannel message with unknown action", { data: { action: s } }));
|
|
2956
3083
|
};
|
|
2957
3084
|
}
|
|
2958
3085
|
shareSession(e) {
|
|
@@ -2970,19 +3097,19 @@ class _s extends _ {
|
|
|
2970
3097
|
const e = this.loadStoredSession();
|
|
2971
3098
|
if (!e)
|
|
2972
3099
|
return null;
|
|
2973
|
-
if (!
|
|
3100
|
+
if (!ys.test(e.id))
|
|
2974
3101
|
return a("warn", "Invalid session ID format recovered from storage, clearing", {
|
|
2975
3102
|
data: { sessionId: e.id }
|
|
2976
3103
|
}), this.clearStoredSession(), null;
|
|
2977
3104
|
const t = this.get("config")?.sessionTimeout ?? 9e5;
|
|
2978
3105
|
return Date.now() - e.lastActivity > t ? (this.clearStoredSession(), null) : e.id;
|
|
2979
3106
|
}
|
|
2980
|
-
persistSession(e, t = Date.now(), s,
|
|
3107
|
+
persistSession(e, t = Date.now(), s, i) {
|
|
2981
3108
|
this.saveStoredSession({
|
|
2982
3109
|
id: e,
|
|
2983
3110
|
lastActivity: t,
|
|
2984
3111
|
...s && { referrer: s },
|
|
2985
|
-
...
|
|
3112
|
+
...i && { utm: i }
|
|
2986
3113
|
});
|
|
2987
3114
|
}
|
|
2988
3115
|
clearStoredSession() {
|
|
@@ -2993,18 +3120,18 @@ class _s extends _ {
|
|
|
2993
3120
|
const e = this.getSessionStorageKey(), t = this.storageManager.getItem(e);
|
|
2994
3121
|
if (t !== null)
|
|
2995
3122
|
try {
|
|
2996
|
-
const
|
|
2997
|
-
if (
|
|
2998
|
-
return
|
|
3123
|
+
const i = JSON.parse(t);
|
|
3124
|
+
if (i.id && typeof i.lastActivity == "number")
|
|
3125
|
+
return i;
|
|
2999
3126
|
} catch {
|
|
3000
3127
|
this.storageManager.removeItem(e);
|
|
3001
3128
|
}
|
|
3002
3129
|
const s = this.storageManager.getSessionItem(e);
|
|
3003
3130
|
if (s !== null)
|
|
3004
3131
|
try {
|
|
3005
|
-
const
|
|
3006
|
-
if (
|
|
3007
|
-
return
|
|
3132
|
+
const i = JSON.parse(s);
|
|
3133
|
+
if (i.id && typeof i.lastActivity == "number")
|
|
3134
|
+
return i;
|
|
3008
3135
|
} catch {
|
|
3009
3136
|
this.storageManager.removeSessionItem(e);
|
|
3010
3137
|
}
|
|
@@ -3015,7 +3142,7 @@ class _s extends _ {
|
|
|
3015
3142
|
this.storageManager.setItem(t, s), this.storageManager.setSessionItem(t, s);
|
|
3016
3143
|
}
|
|
3017
3144
|
getSessionStorageKey() {
|
|
3018
|
-
return
|
|
3145
|
+
return Nt(this.getProjectId());
|
|
3019
3146
|
}
|
|
3020
3147
|
getProjectId() {
|
|
3021
3148
|
return this.projectId;
|
|
@@ -3078,31 +3205,31 @@ class _s extends _ {
|
|
|
3078
3205
|
return;
|
|
3079
3206
|
}
|
|
3080
3207
|
const e = this.recoverSession(), t = e ?? this.generateSessionId();
|
|
3081
|
-
let s,
|
|
3208
|
+
let s, i;
|
|
3082
3209
|
if (e) {
|
|
3083
|
-
const
|
|
3084
|
-
s =
|
|
3210
|
+
const n = this.loadStoredSession();
|
|
3211
|
+
s = n?.referrer ?? me(), i = n?.utm ?? ge();
|
|
3085
3212
|
} else
|
|
3086
|
-
s = me(),
|
|
3213
|
+
s = me(), i = ge();
|
|
3087
3214
|
a("debug", "Session tracking initialized", {
|
|
3088
3215
|
data: {
|
|
3089
3216
|
sessionId: t,
|
|
3090
3217
|
wasRecovered: !!e,
|
|
3091
3218
|
willEmitSessionStart: !e,
|
|
3092
3219
|
sessionReferrer: s,
|
|
3093
|
-
hasUtm: !!
|
|
3220
|
+
hasUtm: !!i
|
|
3094
3221
|
}
|
|
3095
3222
|
}), this.isTracking = !0;
|
|
3096
3223
|
try {
|
|
3097
|
-
this.set("sessionId", t), this.set("sessionReferrer", s), this.set("sessionUtm",
|
|
3224
|
+
this.set("sessionId", t), this.set("sessionReferrer", s), this.set("sessionUtm", i), this.persistSession(t, Date.now(), s, i), this.initCrossTabSync(), this.shareSession(t), e ? a("debug", "Session recovered, skipping SESSION_START", {
|
|
3098
3225
|
data: { sessionId: t }
|
|
3099
3226
|
}) : (a("debug", "Emitting SESSION_START event", {
|
|
3100
3227
|
data: { sessionId: t }
|
|
3101
3228
|
}), this.eventManager.track({
|
|
3102
|
-
type:
|
|
3229
|
+
type: u.SESSION_START
|
|
3103
3230
|
})), this.setupSessionTimeout(), this.setupActivityListeners(), this.setupLifecycleListeners();
|
|
3104
|
-
} catch (
|
|
3105
|
-
throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null),
|
|
3231
|
+
} catch (n) {
|
|
3232
|
+
throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null), n;
|
|
3106
3233
|
}
|
|
3107
3234
|
}
|
|
3108
3235
|
generateSessionId() {
|
|
@@ -3138,7 +3265,7 @@ class _s extends _ {
|
|
|
3138
3265
|
a("debug", "Renewing session after timeout", {
|
|
3139
3266
|
data: { newSessionId: e }
|
|
3140
3267
|
}), this.set("sessionId", e), this.set("sessionReferrer", t), this.set("sessionUtm", s), this.persistSession(e, Date.now(), t, s), this.cleanupCrossTabSync(), this.initCrossTabSync(), this.shareSession(e), this.eventManager.track({
|
|
3141
|
-
type:
|
|
3268
|
+
type: u.SESSION_START
|
|
3142
3269
|
}), this.eventManager.flushPendingEvents(), this.setupSessionTimeout();
|
|
3143
3270
|
}
|
|
3144
3271
|
cleanupActivityListeners() {
|
|
@@ -3255,7 +3382,7 @@ class _s extends _ {
|
|
|
3255
3382
|
this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupCrossTabSync(), this.cleanupLifecycleListeners(), this.isTracking = !1, this.needsRenewal = !1, this.set("hasStartSession", !1);
|
|
3256
3383
|
}
|
|
3257
3384
|
}
|
|
3258
|
-
class
|
|
3385
|
+
class bs extends _ {
|
|
3259
3386
|
eventManager;
|
|
3260
3387
|
storageManager;
|
|
3261
3388
|
sessionManager = null;
|
|
@@ -3290,7 +3417,7 @@ class ys extends _ {
|
|
|
3290
3417
|
}
|
|
3291
3418
|
const t = this.get("config")?.integrations?.tracelog?.projectId ?? "custom";
|
|
3292
3419
|
try {
|
|
3293
|
-
this.sessionManager = new
|
|
3420
|
+
this.sessionManager = new ws(this.storageManager, this.eventManager, t), this.sessionManager.startTracking(), this.eventManager.flushPendingEvents();
|
|
3294
3421
|
} catch (s) {
|
|
3295
3422
|
if (this.sessionManager) {
|
|
3296
3423
|
try {
|
|
@@ -3343,7 +3470,7 @@ class ys extends _ {
|
|
|
3343
3470
|
this.destroyed || (this.sessionManager && (this.sessionManager.destroy(), this.sessionManager = null), this.destroyed = !0);
|
|
3344
3471
|
}
|
|
3345
3472
|
}
|
|
3346
|
-
class
|
|
3473
|
+
class Ls extends _ {
|
|
3347
3474
|
eventManager;
|
|
3348
3475
|
onTrack;
|
|
3349
3476
|
originalPushState;
|
|
@@ -3386,40 +3513,40 @@ class ws extends _ {
|
|
|
3386
3513
|
const e = window.location.href, t = ye(e, this.get("config").sensitiveQueryParams);
|
|
3387
3514
|
if (this.get("pageUrl") === t)
|
|
3388
3515
|
return;
|
|
3389
|
-
const s = Date.now(),
|
|
3390
|
-
if (s - this.lastPageViewTime <
|
|
3516
|
+
const s = Date.now(), i = this.get("config").pageViewThrottleMs ?? 1e3;
|
|
3517
|
+
if (s - this.lastPageViewTime < i)
|
|
3391
3518
|
return;
|
|
3392
3519
|
this.lastPageViewTime = s, this.onTrack();
|
|
3393
|
-
const
|
|
3520
|
+
const n = this.get("pageUrl");
|
|
3394
3521
|
this.set("pageUrl", t);
|
|
3395
3522
|
const o = this.extractPageViewData();
|
|
3396
3523
|
this.eventManager.track({
|
|
3397
|
-
type:
|
|
3524
|
+
type: u.PAGE_VIEW,
|
|
3398
3525
|
page_url: this.get("pageUrl"),
|
|
3399
|
-
from_page_url:
|
|
3526
|
+
from_page_url: n,
|
|
3400
3527
|
...o && { page_view: o }
|
|
3401
3528
|
});
|
|
3402
3529
|
};
|
|
3403
3530
|
trackInitialPageView() {
|
|
3404
3531
|
const e = ye(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
|
|
3405
3532
|
this.lastPageViewTime = Date.now(), this.eventManager.track({
|
|
3406
|
-
type:
|
|
3533
|
+
type: u.PAGE_VIEW,
|
|
3407
3534
|
page_url: e,
|
|
3408
3535
|
...t && { page_view: t }
|
|
3409
3536
|
}), this.onTrack();
|
|
3410
3537
|
}
|
|
3411
3538
|
extractPageViewData() {
|
|
3412
|
-
const { pathname: e, search: t, hash: s } = window.location, { referrer:
|
|
3413
|
-
return !
|
|
3414
|
-
...
|
|
3415
|
-
...
|
|
3539
|
+
const { pathname: e, search: t, hash: s } = window.location, { referrer: i } = document, { title: n } = document;
|
|
3540
|
+
return !i && !n && !e && !t && !s ? void 0 : {
|
|
3541
|
+
...i && { referrer: i },
|
|
3542
|
+
...n && { title: n },
|
|
3416
3543
|
...e && { pathname: e },
|
|
3417
3544
|
...t && { search: t },
|
|
3418
3545
|
...s && { hash: s }
|
|
3419
3546
|
};
|
|
3420
3547
|
}
|
|
3421
3548
|
}
|
|
3422
|
-
class
|
|
3549
|
+
class As extends _ {
|
|
3423
3550
|
eventManager;
|
|
3424
3551
|
lastClickTimes = /* @__PURE__ */ new Map();
|
|
3425
3552
|
clickHandler;
|
|
@@ -3442,23 +3569,23 @@ class bs extends _ {
|
|
|
3442
3569
|
*/
|
|
3443
3570
|
startTracking() {
|
|
3444
3571
|
this.clickHandler || (this.clickHandler = (e) => {
|
|
3445
|
-
const t = e, s = t.target,
|
|
3446
|
-
if (!
|
|
3572
|
+
const t = e, s = t.target, i = typeof HTMLElement < "u" && s instanceof HTMLElement ? s : typeof HTMLElement < "u" && s instanceof Node && s.parentElement instanceof HTMLElement ? s.parentElement : null;
|
|
3573
|
+
if (!i) {
|
|
3447
3574
|
a("debug", "Click target not found or not an element");
|
|
3448
3575
|
return;
|
|
3449
3576
|
}
|
|
3450
|
-
if (this.shouldIgnoreElement(
|
|
3577
|
+
if (this.shouldIgnoreElement(i))
|
|
3451
3578
|
return;
|
|
3452
|
-
const
|
|
3453
|
-
if (
|
|
3579
|
+
const n = this.get("config")?.clickThrottleMs ?? 300;
|
|
3580
|
+
if (n > 0 && !this.checkClickThrottle(i, n))
|
|
3454
3581
|
return;
|
|
3455
|
-
const o = this.findTrackingElement(
|
|
3582
|
+
const o = this.findTrackingElement(i), l = this.getRelevantClickElement(i), c = this.calculateClickCoordinates(t, i);
|
|
3456
3583
|
if (o) {
|
|
3457
3584
|
const f = this.extractTrackingData(o);
|
|
3458
3585
|
if (f) {
|
|
3459
3586
|
const g = this.createCustomEventData(f);
|
|
3460
3587
|
this.eventManager.track({
|
|
3461
|
-
type:
|
|
3588
|
+
type: u.CUSTOM,
|
|
3462
3589
|
custom_event: {
|
|
3463
3590
|
name: g.name,
|
|
3464
3591
|
...g.value && { metadata: { value: g.value } }
|
|
@@ -3466,10 +3593,10 @@ class bs extends _ {
|
|
|
3466
3593
|
});
|
|
3467
3594
|
}
|
|
3468
3595
|
}
|
|
3469
|
-
const
|
|
3596
|
+
const d = this.generateClickData(i, l, c);
|
|
3470
3597
|
this.eventManager.track({
|
|
3471
|
-
type:
|
|
3472
|
-
click_data:
|
|
3598
|
+
type: u.CLICK,
|
|
3599
|
+
click_data: d
|
|
3473
3600
|
});
|
|
3474
3601
|
}, window.addEventListener("click", this.clickHandler, !0));
|
|
3475
3602
|
}
|
|
@@ -3490,15 +3617,15 @@ class bs extends _ {
|
|
|
3490
3617
|
* Returns true if the click should be tracked, false if throttled
|
|
3491
3618
|
*/
|
|
3492
3619
|
checkClickThrottle(e, t) {
|
|
3493
|
-
const s = this.getElementSignature(e),
|
|
3494
|
-
this.pruneThrottleCache(
|
|
3495
|
-
const
|
|
3496
|
-
return
|
|
3620
|
+
const s = this.getElementSignature(e), i = Date.now();
|
|
3621
|
+
this.pruneThrottleCache(i);
|
|
3622
|
+
const n = this.lastClickTimes.get(s);
|
|
3623
|
+
return n !== void 0 && i - n < t ? (a("debug", "ClickHandler: Click suppressed by throttle", {
|
|
3497
3624
|
data: {
|
|
3498
3625
|
signature: s,
|
|
3499
|
-
throttleRemaining: t - (
|
|
3626
|
+
throttleRemaining: t - (i - n)
|
|
3500
3627
|
}
|
|
3501
|
-
}), !1) : (this.lastClickTimes.set(s,
|
|
3628
|
+
}), !1) : (this.lastClickTimes.set(s, i), !0);
|
|
3502
3629
|
}
|
|
3503
3630
|
/**
|
|
3504
3631
|
* Prunes stale entries from the throttle cache to prevent memory leaks
|
|
@@ -3510,15 +3637,15 @@ class bs extends _ {
|
|
|
3510
3637
|
return;
|
|
3511
3638
|
this.lastPruneTime = e;
|
|
3512
3639
|
const t = e - 3e5;
|
|
3513
|
-
for (const [s,
|
|
3514
|
-
|
|
3640
|
+
for (const [s, i] of this.lastClickTimes.entries())
|
|
3641
|
+
i < t && this.lastClickTimes.delete(s);
|
|
3515
3642
|
if (this.lastClickTimes.size > 1e3) {
|
|
3516
|
-
const s = Array.from(this.lastClickTimes.entries()).sort((o, l) => o[1] - l[1]),
|
|
3517
|
-
for (const [o] of
|
|
3643
|
+
const s = Array.from(this.lastClickTimes.entries()).sort((o, l) => o[1] - l[1]), i = this.lastClickTimes.size - 1e3, n = s.slice(0, i);
|
|
3644
|
+
for (const [o] of n)
|
|
3518
3645
|
this.lastClickTimes.delete(o);
|
|
3519
3646
|
a("debug", "ClickHandler: Pruned throttle cache", {
|
|
3520
3647
|
data: {
|
|
3521
|
-
removed:
|
|
3648
|
+
removed: n.length,
|
|
3522
3649
|
remaining: this.lastClickTimes.size
|
|
3523
3650
|
}
|
|
3524
3651
|
});
|
|
@@ -3544,12 +3671,12 @@ class bs extends _ {
|
|
|
3544
3671
|
const t = [];
|
|
3545
3672
|
let s = e;
|
|
3546
3673
|
for (; s && s !== document.body; ) {
|
|
3547
|
-
let
|
|
3674
|
+
let i = s.tagName.toLowerCase();
|
|
3548
3675
|
if (s.className) {
|
|
3549
|
-
const
|
|
3550
|
-
|
|
3676
|
+
const n = s.className.split(" ")[0];
|
|
3677
|
+
n && (i += `.${n}`);
|
|
3551
3678
|
}
|
|
3552
|
-
t.unshift(
|
|
3679
|
+
t.unshift(i), s = s.parentElement;
|
|
3553
3680
|
}
|
|
3554
3681
|
return t.join(">") || "unknown";
|
|
3555
3682
|
}
|
|
@@ -3585,8 +3712,8 @@ class bs extends _ {
|
|
|
3585
3712
|
return Math.max(0, Math.min(1, Number(e.toFixed(3))));
|
|
3586
3713
|
}
|
|
3587
3714
|
calculateClickCoordinates(e, t) {
|
|
3588
|
-
const s = t.getBoundingClientRect(),
|
|
3589
|
-
return { x:
|
|
3715
|
+
const s = t.getBoundingClientRect(), i = e.clientX, n = e.clientY, o = s.width > 0 ? this.clamp((i - s.left) / s.width) : 0, l = s.height > 0 ? this.clamp((n - s.top) / s.height) : 0;
|
|
3716
|
+
return { x: i, y: n, relativeX: o, relativeY: l };
|
|
3590
3717
|
}
|
|
3591
3718
|
extractTrackingData(e) {
|
|
3592
3719
|
const t = e.getAttribute(`${b}-name`), s = e.getAttribute(`${b}-value`);
|
|
@@ -3598,22 +3725,22 @@ class bs extends _ {
|
|
|
3598
3725
|
};
|
|
3599
3726
|
}
|
|
3600
3727
|
generateClickData(e, t, s) {
|
|
3601
|
-
const { x:
|
|
3728
|
+
const { x: i, y: n, relativeX: o, relativeY: l } = s, c = this.getRelevantText(e, t), d = this.extractElementAttributes(t);
|
|
3602
3729
|
return {
|
|
3603
|
-
x:
|
|
3604
|
-
y:
|
|
3730
|
+
x: i,
|
|
3731
|
+
y: n,
|
|
3605
3732
|
relativeX: o,
|
|
3606
3733
|
relativeY: l,
|
|
3607
3734
|
tag: t.tagName.toLowerCase(),
|
|
3608
3735
|
...t.id && { id: t.id },
|
|
3609
3736
|
...t.className && { class: t.className },
|
|
3610
3737
|
...c && { text: c },
|
|
3611
|
-
...
|
|
3612
|
-
...
|
|
3613
|
-
...
|
|
3614
|
-
...
|
|
3615
|
-
...
|
|
3616
|
-
...Object.keys(
|
|
3738
|
+
...d.href && { href: d.href },
|
|
3739
|
+
...d.title && { title: d.title },
|
|
3740
|
+
...d.alt && { alt: d.alt },
|
|
3741
|
+
...d.role && { role: d.role },
|
|
3742
|
+
...d["aria-label"] && { ariaLabel: d["aria-label"] },
|
|
3743
|
+
...Object.keys(d).length > 0 && { dataAttributes: d }
|
|
3617
3744
|
};
|
|
3618
3745
|
}
|
|
3619
3746
|
/**
|
|
@@ -3638,17 +3765,17 @@ class bs extends _ {
|
|
|
3638
3765
|
sanitizeText(e) {
|
|
3639
3766
|
let t = e;
|
|
3640
3767
|
for (const s of at) {
|
|
3641
|
-
const
|
|
3642
|
-
t = t.replace(
|
|
3768
|
+
const i = new RegExp(s.source, s.flags);
|
|
3769
|
+
t = t.replace(i, "[REDACTED]");
|
|
3643
3770
|
}
|
|
3644
3771
|
return t;
|
|
3645
3772
|
}
|
|
3646
3773
|
getRelevantText(e, t) {
|
|
3647
|
-
const s = e.textContent?.trim() ?? "",
|
|
3648
|
-
if (!s && !
|
|
3774
|
+
const s = e.textContent?.trim() ?? "", i = t.textContent?.trim() ?? "";
|
|
3775
|
+
if (!s && !i)
|
|
3649
3776
|
return "";
|
|
3650
|
-
let
|
|
3651
|
-
return s && s.length <= 255 ?
|
|
3777
|
+
let n = "";
|
|
3778
|
+
return s && s.length <= 255 ? n = s : i.length <= 255 ? n = i : n = i.slice(0, 252) + "...", this.sanitizeText(n);
|
|
3652
3779
|
}
|
|
3653
3780
|
extractElementAttributes(e) {
|
|
3654
3781
|
const t = [
|
|
@@ -3663,9 +3790,9 @@ class bs extends _ {
|
|
|
3663
3790
|
"alt",
|
|
3664
3791
|
"role"
|
|
3665
3792
|
], s = {};
|
|
3666
|
-
for (const
|
|
3667
|
-
const
|
|
3668
|
-
|
|
3793
|
+
for (const i of t) {
|
|
3794
|
+
const n = e.getAttribute(i);
|
|
3795
|
+
n && (s[i] = n);
|
|
3669
3796
|
}
|
|
3670
3797
|
return s;
|
|
3671
3798
|
}
|
|
@@ -3676,7 +3803,7 @@ class bs extends _ {
|
|
|
3676
3803
|
};
|
|
3677
3804
|
}
|
|
3678
3805
|
}
|
|
3679
|
-
class
|
|
3806
|
+
class Ms extends _ {
|
|
3680
3807
|
eventManager;
|
|
3681
3808
|
containers = [];
|
|
3682
3809
|
limitWarningLogged = !1;
|
|
@@ -3723,8 +3850,8 @@ class As extends _ {
|
|
|
3723
3850
|
const t = this.findScrollableElements();
|
|
3724
3851
|
if (this.isWindowScrollable() && this.setupScrollContainer(window, "window"), t.length > 0) {
|
|
3725
3852
|
for (const s of t) {
|
|
3726
|
-
const
|
|
3727
|
-
this.setupScrollContainer(s,
|
|
3853
|
+
const i = this.getElementSelector(s);
|
|
3854
|
+
this.setupScrollContainer(s, i);
|
|
3728
3855
|
}
|
|
3729
3856
|
this.applyPrimaryScrollSelectorIfConfigured();
|
|
3730
3857
|
return;
|
|
@@ -3745,18 +3872,18 @@ class As extends _ {
|
|
|
3745
3872
|
if (!document.body)
|
|
3746
3873
|
return [];
|
|
3747
3874
|
const e = [], t = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
|
|
3748
|
-
acceptNode: (
|
|
3749
|
-
const
|
|
3750
|
-
if (!
|
|
3875
|
+
acceptNode: (i) => {
|
|
3876
|
+
const n = i;
|
|
3877
|
+
if (!n.isConnected || !n.offsetParent)
|
|
3751
3878
|
return NodeFilter.FILTER_SKIP;
|
|
3752
|
-
const o = getComputedStyle(
|
|
3879
|
+
const o = getComputedStyle(n);
|
|
3753
3880
|
return o.overflowY === "auto" || o.overflowY === "scroll" || o.overflow === "auto" || o.overflow === "scroll" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
3754
3881
|
}
|
|
3755
3882
|
});
|
|
3756
3883
|
let s;
|
|
3757
3884
|
for (; (s = t.nextNode()) && e.length < 10; ) {
|
|
3758
|
-
const
|
|
3759
|
-
this.isElementScrollable(
|
|
3885
|
+
const i = s;
|
|
3886
|
+
this.isElementScrollable(i) && e.push(i);
|
|
3760
3887
|
}
|
|
3761
3888
|
return e;
|
|
3762
3889
|
}
|
|
@@ -3767,7 +3894,7 @@ class As extends _ {
|
|
|
3767
3894
|
if (t.id)
|
|
3768
3895
|
return `#${t.id}`;
|
|
3769
3896
|
if (t.className && typeof t.className == "string") {
|
|
3770
|
-
const s = t.className.split(" ").filter((
|
|
3897
|
+
const s = t.className.split(" ").filter((i) => i.trim())[0];
|
|
3771
3898
|
if (s)
|
|
3772
3899
|
return `.${s}`;
|
|
3773
3900
|
}
|
|
@@ -3777,30 +3904,30 @@ class As extends _ {
|
|
|
3777
3904
|
return this.isWindowScrollable() ? e === window : this.containers.length === 0;
|
|
3778
3905
|
}
|
|
3779
3906
|
setupScrollContainer(e, t) {
|
|
3780
|
-
if (this.containers.some((
|
|
3907
|
+
if (this.containers.some((d) => d.element === e) || e !== window && !this.isElementScrollable(e))
|
|
3781
3908
|
return;
|
|
3782
|
-
const
|
|
3783
|
-
|
|
3909
|
+
const i = this.getScrollTop(e), n = this.calculateScrollDepth(
|
|
3910
|
+
i,
|
|
3784
3911
|
this.getScrollHeight(e),
|
|
3785
3912
|
this.getViewportHeight(e)
|
|
3786
3913
|
), o = this.determineIfPrimary(e), l = {
|
|
3787
3914
|
element: e,
|
|
3788
3915
|
selector: t,
|
|
3789
3916
|
isPrimary: o,
|
|
3790
|
-
lastScrollPos:
|
|
3791
|
-
lastDepth:
|
|
3917
|
+
lastScrollPos: i,
|
|
3918
|
+
lastDepth: n,
|
|
3792
3919
|
lastDirection: Z.DOWN,
|
|
3793
3920
|
lastEventTime: 0,
|
|
3794
3921
|
firstScrollEventTime: null,
|
|
3795
|
-
maxDepthReached:
|
|
3922
|
+
maxDepthReached: n,
|
|
3796
3923
|
debounceTimer: null,
|
|
3797
3924
|
listener: null
|
|
3798
3925
|
}, c = () => {
|
|
3799
3926
|
this.get("suppressNextScroll") || (l.firstScrollEventTime === null && (l.firstScrollEventTime = Date.now()), this.clearContainerTimer(l), l.debounceTimer = window.setTimeout(() => {
|
|
3800
|
-
const
|
|
3801
|
-
if (
|
|
3927
|
+
const d = this.calculateScrollData(l);
|
|
3928
|
+
if (d) {
|
|
3802
3929
|
const f = Date.now();
|
|
3803
|
-
this.processScrollEvent(l,
|
|
3930
|
+
this.processScrollEvent(l, d, f);
|
|
3804
3931
|
}
|
|
3805
3932
|
l.debounceTimer = null;
|
|
3806
3933
|
}, 250));
|
|
@@ -3811,9 +3938,9 @@ class As extends _ {
|
|
|
3811
3938
|
if (!this.shouldEmitScrollEvent(e, t, s))
|
|
3812
3939
|
return;
|
|
3813
3940
|
e.lastEventTime = s, e.lastDepth = t.depth, e.lastDirection = t.direction;
|
|
3814
|
-
const
|
|
3815
|
-
this.set("scrollEventCount",
|
|
3816
|
-
type:
|
|
3941
|
+
const i = this.get("scrollEventCount") ?? 0;
|
|
3942
|
+
this.set("scrollEventCount", i + 1), this.eventManager.track({
|
|
3943
|
+
type: u.SCROLL,
|
|
3817
3944
|
scroll_data: {
|
|
3818
3945
|
...t,
|
|
3819
3946
|
container_selector: e.selector,
|
|
@@ -3853,18 +3980,18 @@ class As extends _ {
|
|
|
3853
3980
|
calculateScrollDepth(e, t, s) {
|
|
3854
3981
|
if (t <= s)
|
|
3855
3982
|
return 0;
|
|
3856
|
-
const
|
|
3857
|
-
return Math.min(100, Math.max(0, Math.floor(e /
|
|
3983
|
+
const i = t - s;
|
|
3984
|
+
return Math.min(100, Math.max(0, Math.floor(e / i * 100)));
|
|
3858
3985
|
}
|
|
3859
3986
|
calculateScrollData(e) {
|
|
3860
|
-
const { element: t, lastScrollPos: s, lastEventTime:
|
|
3987
|
+
const { element: t, lastScrollPos: s, lastEventTime: i } = e, n = this.getScrollTop(t), o = Date.now(), l = Math.abs(n - s);
|
|
3861
3988
|
if (l < 10 || t === window && !this.isWindowScrollable())
|
|
3862
3989
|
return null;
|
|
3863
|
-
const c = this.getViewportHeight(t),
|
|
3864
|
-
let
|
|
3865
|
-
|
|
3866
|
-
const p = Math.round(l /
|
|
3867
|
-
return g > e.maxDepthReached && (e.maxDepthReached = g), e.lastScrollPos =
|
|
3990
|
+
const c = this.getViewportHeight(t), d = this.getScrollHeight(t), f = this.getScrollDirection(n, s), g = this.calculateScrollDepth(n, d, c);
|
|
3991
|
+
let I;
|
|
3992
|
+
i > 0 ? I = o - i : e.firstScrollEventTime !== null ? I = o - e.firstScrollEventTime : I = 250;
|
|
3993
|
+
const p = Math.round(l / I * 1e3);
|
|
3994
|
+
return g > e.maxDepthReached && (e.maxDepthReached = g), e.lastScrollPos = n, {
|
|
3868
3995
|
depth: g,
|
|
3869
3996
|
direction: f,
|
|
3870
3997
|
velocity: p,
|
|
@@ -3881,30 +4008,30 @@ class As extends _ {
|
|
|
3881
4008
|
return e === window ? document.documentElement.scrollHeight : e.scrollHeight;
|
|
3882
4009
|
}
|
|
3883
4010
|
isElementScrollable(e) {
|
|
3884
|
-
const t = getComputedStyle(e), s = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflow === "auto" || t.overflow === "scroll",
|
|
3885
|
-
return s &&
|
|
4011
|
+
const t = getComputedStyle(e), s = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflow === "auto" || t.overflow === "scroll", i = e.scrollHeight > e.clientHeight;
|
|
4012
|
+
return s && i;
|
|
3886
4013
|
}
|
|
3887
4014
|
applyPrimaryScrollSelector(e) {
|
|
3888
4015
|
let t;
|
|
3889
4016
|
if (e === "window")
|
|
3890
4017
|
t = window;
|
|
3891
4018
|
else {
|
|
3892
|
-
const
|
|
3893
|
-
if (!(
|
|
4019
|
+
const i = document.querySelector(e);
|
|
4020
|
+
if (!(i instanceof HTMLElement)) {
|
|
3894
4021
|
a("debug", `Selector "${e}" did not match an HTMLElement`);
|
|
3895
4022
|
return;
|
|
3896
4023
|
}
|
|
3897
|
-
t =
|
|
4024
|
+
t = i;
|
|
3898
4025
|
}
|
|
3899
|
-
this.containers.forEach((
|
|
3900
|
-
this.updateContainerPrimary(
|
|
3901
|
-
}), !this.containers.some((
|
|
4026
|
+
this.containers.forEach((i) => {
|
|
4027
|
+
this.updateContainerPrimary(i, i.element === t);
|
|
4028
|
+
}), !this.containers.some((i) => i.element === t) && t instanceof HTMLElement && this.isElementScrollable(t) && this.setupScrollContainer(t, e);
|
|
3902
4029
|
}
|
|
3903
4030
|
updateContainerPrimary(e, t) {
|
|
3904
4031
|
e.isPrimary = t;
|
|
3905
4032
|
}
|
|
3906
4033
|
}
|
|
3907
|
-
class
|
|
4034
|
+
class Cs extends _ {
|
|
3908
4035
|
eventManager;
|
|
3909
4036
|
trackedElements = /* @__PURE__ */ new Map();
|
|
3910
4037
|
observer = null;
|
|
@@ -3956,8 +4083,8 @@ class Ls extends _ {
|
|
|
3956
4083
|
let t = this.trackedElements.size;
|
|
3957
4084
|
for (const s of this.config.elements)
|
|
3958
4085
|
try {
|
|
3959
|
-
const
|
|
3960
|
-
for (const
|
|
4086
|
+
const i = document.querySelectorAll(s.selector);
|
|
4087
|
+
for (const n of Array.from(i)) {
|
|
3961
4088
|
if (t >= e) {
|
|
3962
4089
|
a("debug", "ViewportHandler: Maximum tracked elements reached", {
|
|
3963
4090
|
data: {
|
|
@@ -3968,18 +4095,18 @@ class Ls extends _ {
|
|
|
3968
4095
|
});
|
|
3969
4096
|
return;
|
|
3970
4097
|
}
|
|
3971
|
-
|
|
3972
|
-
element:
|
|
4098
|
+
n.hasAttribute(`${b}-ignore`) || this.trackedElements.has(n) || (this.trackedElements.set(n, {
|
|
4099
|
+
element: n,
|
|
3973
4100
|
selector: s.selector,
|
|
3974
4101
|
id: s.id,
|
|
3975
4102
|
name: s.name,
|
|
3976
4103
|
startTime: null,
|
|
3977
4104
|
timeoutId: null,
|
|
3978
4105
|
lastFiredTime: null
|
|
3979
|
-
}), this.observer?.observe(
|
|
4106
|
+
}), this.observer?.observe(n), t++);
|
|
3980
4107
|
}
|
|
3981
|
-
} catch (
|
|
3982
|
-
a("debug", `ViewportHandler: Invalid selector "${s.selector}"`, { error:
|
|
4108
|
+
} catch (i) {
|
|
4109
|
+
a("debug", `ViewportHandler: Invalid selector "${s.selector}"`, { error: i });
|
|
3983
4110
|
}
|
|
3984
4111
|
a("debug", "ViewportHandler: Elements tracked", {
|
|
3985
4112
|
data: { count: t, limit: e }
|
|
@@ -3992,11 +4119,11 @@ class Ls extends _ {
|
|
|
3992
4119
|
if (!this.config) return;
|
|
3993
4120
|
const t = this.config.minDwellTime ?? 1e3;
|
|
3994
4121
|
for (const s of e) {
|
|
3995
|
-
const
|
|
3996
|
-
|
|
3997
|
-
const
|
|
3998
|
-
this.fireViewportEvent(
|
|
3999
|
-
}, t)) :
|
|
4122
|
+
const i = this.trackedElements.get(s.target);
|
|
4123
|
+
i && (s.isIntersecting ? i.startTime === null && (i.startTime = performance.now(), i.timeoutId = window.setTimeout(() => {
|
|
4124
|
+
const n = Math.round(s.intersectionRatio * 100) / 100;
|
|
4125
|
+
this.fireViewportEvent(i, n);
|
|
4126
|
+
}, t)) : i.startTime !== null && (i.timeoutId !== null && (window.clearTimeout(i.timeoutId), i.timeoutId = null), i.startTime = null));
|
|
4000
4127
|
}
|
|
4001
4128
|
};
|
|
4002
4129
|
/**
|
|
@@ -4007,12 +4134,12 @@ class Ls extends _ {
|
|
|
4007
4134
|
const s = Math.round(performance.now() - e.startTime);
|
|
4008
4135
|
if (e.element.hasAttribute(`${b}-ignore`))
|
|
4009
4136
|
return;
|
|
4010
|
-
const
|
|
4011
|
-
if (e.lastFiredTime !== null &&
|
|
4137
|
+
const i = this.config?.cooldownPeriod ?? 6e4, n = Date.now();
|
|
4138
|
+
if (e.lastFiredTime !== null && n - e.lastFiredTime < i) {
|
|
4012
4139
|
a("debug", "ViewportHandler: Event suppressed by cooldown period", {
|
|
4013
4140
|
data: {
|
|
4014
4141
|
selector: e.selector,
|
|
4015
|
-
cooldownRemaining:
|
|
4142
|
+
cooldownRemaining: i - (n - e.lastFiredTime)
|
|
4016
4143
|
}
|
|
4017
4144
|
}), e.startTime = null, e.timeoutId = null;
|
|
4018
4145
|
return;
|
|
@@ -4025,9 +4152,9 @@ class Ls extends _ {
|
|
|
4025
4152
|
...e.name !== void 0 && { name: e.name }
|
|
4026
4153
|
};
|
|
4027
4154
|
this.eventManager.track({
|
|
4028
|
-
type:
|
|
4155
|
+
type: u.VIEWPORT_VISIBLE,
|
|
4029
4156
|
viewport_data: o
|
|
4030
|
-
}), e.startTime = null, e.timeoutId = null, e.lastFiredTime =
|
|
4157
|
+
}), e.startTime = null, e.timeoutId = null, e.lastFiredTime = n;
|
|
4031
4158
|
}
|
|
4032
4159
|
/**
|
|
4033
4160
|
* Sets up MutationObserver to detect dynamically added elements
|
|
@@ -4057,16 +4184,16 @@ class Ls extends _ {
|
|
|
4057
4184
|
cleanupRemovedNodes(e) {
|
|
4058
4185
|
e.forEach((t) => {
|
|
4059
4186
|
if (t.nodeType !== 1) return;
|
|
4060
|
-
const s = t,
|
|
4061
|
-
|
|
4187
|
+
const s = t, i = this.trackedElements.get(s);
|
|
4188
|
+
i && (i.timeoutId !== null && window.clearTimeout(i.timeoutId), this.observer?.unobserve(s), this.trackedElements.delete(s)), Array.from(this.trackedElements.keys()).filter((o) => s.contains(o)).forEach((o) => {
|
|
4062
4189
|
const l = this.trackedElements.get(o);
|
|
4063
4190
|
l && l.timeoutId !== null && window.clearTimeout(l.timeoutId), this.observer?.unobserve(o), this.trackedElements.delete(o);
|
|
4064
4191
|
});
|
|
4065
4192
|
});
|
|
4066
4193
|
}
|
|
4067
4194
|
}
|
|
4068
|
-
const
|
|
4069
|
-
class
|
|
4195
|
+
const Rs = "tracelog_session_id";
|
|
4196
|
+
class Ns extends _ {
|
|
4070
4197
|
visibilityHandler = null;
|
|
4071
4198
|
lastSyncedSessionId = null;
|
|
4072
4199
|
activate() {
|
|
@@ -4088,7 +4215,7 @@ class Cs extends _ {
|
|
|
4088
4215
|
fetch("/cart/update.js", {
|
|
4089
4216
|
method: "POST",
|
|
4090
4217
|
headers: { "Content-Type": "application/json" },
|
|
4091
|
-
body: JSON.stringify({ attributes: { [
|
|
4218
|
+
body: JSON.stringify({ attributes: { [Rs]: e } }),
|
|
4092
4219
|
credentials: "same-origin"
|
|
4093
4220
|
}).then((t) => {
|
|
4094
4221
|
t.ok || (this.lastSyncedSessionId = null, a("debug", "Shopify cart attribute update failed", { data: { status: t.status } }));
|
|
@@ -4108,7 +4235,7 @@ class Cs extends _ {
|
|
|
4108
4235
|
this.visibilityHandler && (document.removeEventListener("visibilitychange", this.visibilityHandler), this.visibilityHandler = null);
|
|
4109
4236
|
}
|
|
4110
4237
|
}
|
|
4111
|
-
class
|
|
4238
|
+
class Os {
|
|
4112
4239
|
storage;
|
|
4113
4240
|
sessionStorageRef;
|
|
4114
4241
|
fallbackStorage = /* @__PURE__ */ new Map();
|
|
@@ -4277,19 +4404,19 @@ class Rs {
|
|
|
4277
4404
|
return !1;
|
|
4278
4405
|
try {
|
|
4279
4406
|
const e = [], t = [];
|
|
4280
|
-
for (let
|
|
4281
|
-
const o = this.storage.key(
|
|
4407
|
+
for (let n = 0; n < this.storage.length; n++) {
|
|
4408
|
+
const o = this.storage.key(n);
|
|
4282
4409
|
o?.startsWith("tracelog_") && (e.push(o), o.startsWith("tracelog_persisted_events_") && t.push(o));
|
|
4283
4410
|
}
|
|
4284
4411
|
if (t.length > 0)
|
|
4285
|
-
return t.forEach((
|
|
4412
|
+
return t.forEach((n) => {
|
|
4286
4413
|
try {
|
|
4287
|
-
this.storage.removeItem(
|
|
4414
|
+
this.storage.removeItem(n);
|
|
4288
4415
|
} catch {
|
|
4289
4416
|
}
|
|
4290
4417
|
}), !0;
|
|
4291
|
-
const s = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"],
|
|
4292
|
-
return
|
|
4418
|
+
const s = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"], i = e.filter((n) => !s.some((o) => n.startsWith(o)));
|
|
4419
|
+
return i.length > 0 ? (i.slice(0, 5).forEach((o) => {
|
|
4293
4420
|
try {
|
|
4294
4421
|
this.storage.removeItem(o);
|
|
4295
4422
|
} catch {
|
|
@@ -4391,7 +4518,7 @@ class Rs {
|
|
|
4391
4518
|
this.fallbackSessionStorage.delete(e);
|
|
4392
4519
|
}
|
|
4393
4520
|
}
|
|
4394
|
-
class
|
|
4521
|
+
class Ps extends _ {
|
|
4395
4522
|
eventManager;
|
|
4396
4523
|
reportedByNav = /* @__PURE__ */ new Map();
|
|
4397
4524
|
navigationHistory = [];
|
|
@@ -4402,7 +4529,7 @@ class Ns extends _ {
|
|
|
4402
4529
|
navigationCounter = 0;
|
|
4403
4530
|
// Counter for handling simultaneous navigations edge case
|
|
4404
4531
|
constructor(e) {
|
|
4405
|
-
super(), this.eventManager = e, this.vitalThresholds =
|
|
4532
|
+
super(), this.eventManager = e, this.vitalThresholds = Qe(_e);
|
|
4406
4533
|
}
|
|
4407
4534
|
/**
|
|
4408
4535
|
* Starts tracking Web Vitals and performance metrics.
|
|
@@ -4420,7 +4547,7 @@ class Ns extends _ {
|
|
|
4420
4547
|
*/
|
|
4421
4548
|
async startTracking() {
|
|
4422
4549
|
const e = this.get("config"), t = e?.webVitalsMode ?? _e;
|
|
4423
|
-
this.vitalThresholds =
|
|
4550
|
+
this.vitalThresholds = Qe(t), e?.webVitalsThresholds && (this.vitalThresholds = { ...this.vitalThresholds, ...e.webVitalsThresholds }), await this.initWebVitals(), this.observeLongTasks();
|
|
4424
4551
|
}
|
|
4425
4552
|
/**
|
|
4426
4553
|
* Stops tracking Web Vitals and cleans up resources.
|
|
@@ -4444,8 +4571,8 @@ class Ns extends _ {
|
|
|
4444
4571
|
this.reportTTFB(), this.safeObserve(
|
|
4445
4572
|
"largest-contentful-paint",
|
|
4446
4573
|
(s) => {
|
|
4447
|
-
const
|
|
4448
|
-
|
|
4574
|
+
const i = s.getEntries(), n = i[i.length - 1];
|
|
4575
|
+
n && this.sendVital({ type: "LCP", value: Number(n.startTime.toFixed(2)) });
|
|
4449
4576
|
},
|
|
4450
4577
|
{ type: "largest-contentful-paint", buffered: !0 },
|
|
4451
4578
|
!0
|
|
@@ -4454,10 +4581,10 @@ class Ns extends _ {
|
|
|
4454
4581
|
this.safeObserve(
|
|
4455
4582
|
"layout-shift",
|
|
4456
4583
|
(s) => {
|
|
4457
|
-
const
|
|
4458
|
-
|
|
4459
|
-
const
|
|
4460
|
-
for (const o of
|
|
4584
|
+
const i = this.getNavigationId();
|
|
4585
|
+
i !== t && (e = 0, t = i);
|
|
4586
|
+
const n = s.getEntries();
|
|
4587
|
+
for (const o of n) {
|
|
4461
4588
|
if (o.hadRecentInput === !0)
|
|
4462
4589
|
continue;
|
|
4463
4590
|
const l = typeof o.value == "number" ? o.value : 0;
|
|
@@ -4469,32 +4596,32 @@ class Ns extends _ {
|
|
|
4469
4596
|
), this.safeObserve(
|
|
4470
4597
|
"paint",
|
|
4471
4598
|
(s) => {
|
|
4472
|
-
for (const
|
|
4473
|
-
|
|
4599
|
+
for (const i of s.getEntries())
|
|
4600
|
+
i.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(i.startTime.toFixed(2)) });
|
|
4474
4601
|
},
|
|
4475
4602
|
{ type: "paint", buffered: !0 },
|
|
4476
4603
|
!0
|
|
4477
4604
|
), this.safeObserve(
|
|
4478
4605
|
"event",
|
|
4479
4606
|
(s) => {
|
|
4480
|
-
let
|
|
4481
|
-
const
|
|
4482
|
-
for (const o of
|
|
4607
|
+
let i = 0;
|
|
4608
|
+
const n = s.getEntries();
|
|
4609
|
+
for (const o of n) {
|
|
4483
4610
|
const l = (o.processingEnd ?? 0) - (o.startTime ?? 0);
|
|
4484
|
-
|
|
4611
|
+
i = Math.max(i, l);
|
|
4485
4612
|
}
|
|
4486
|
-
|
|
4613
|
+
i > 0 && this.sendVital({ type: "INP", value: Number(i.toFixed(2)) });
|
|
4487
4614
|
},
|
|
4488
4615
|
{ type: "event", buffered: !0 }
|
|
4489
4616
|
);
|
|
4490
4617
|
}
|
|
4491
4618
|
async initWebVitals() {
|
|
4492
4619
|
try {
|
|
4493
|
-
const { onLCP: e, onCLS: t, onFCP: s, onTTFB:
|
|
4494
|
-
const
|
|
4495
|
-
this.sendVital({ type: l, value:
|
|
4620
|
+
const { onLCP: e, onCLS: t, onFCP: s, onTTFB: i, onINP: n } = await Promise.resolve().then(() => ur), o = (l) => (c) => {
|
|
4621
|
+
const d = Number(c.value.toFixed(2));
|
|
4622
|
+
this.sendVital({ type: l, value: d });
|
|
4496
4623
|
};
|
|
4497
|
-
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }), s(o("FCP"), { reportAllChanges: !1 }),
|
|
4624
|
+
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }), s(o("FCP"), { reportAllChanges: !1 }), i(o("TTFB"), { reportAllChanges: !1 }), n(o("INP"), { reportAllChanges: !1 });
|
|
4498
4625
|
} catch (e) {
|
|
4499
4626
|
a("debug", "Failed to load web-vitals library, using fallback", { error: e }), this.observeWebVitalsFallback();
|
|
4500
4627
|
}
|
|
@@ -4516,8 +4643,8 @@ class Ns extends _ {
|
|
|
4516
4643
|
(e) => {
|
|
4517
4644
|
const t = e.getEntries();
|
|
4518
4645
|
for (const s of t) {
|
|
4519
|
-
const
|
|
4520
|
-
|
|
4646
|
+
const i = Number(s.duration.toFixed(2)), n = Date.now();
|
|
4647
|
+
n - this.lastLongTaskSentAt >= qt && (this.shouldSendVital("LONG_TASK", i) && this.trackWebVital("LONG_TASK", i), this.lastLongTaskSentAt = n);
|
|
4521
4648
|
}
|
|
4522
4649
|
},
|
|
4523
4650
|
{ type: "longtask", buffered: !0 }
|
|
@@ -4533,9 +4660,9 @@ class Ns extends _ {
|
|
|
4533
4660
|
return;
|
|
4534
4661
|
if (s)
|
|
4535
4662
|
s.add(e.type);
|
|
4536
|
-
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length >
|
|
4537
|
-
const
|
|
4538
|
-
|
|
4663
|
+
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length > Jt) {
|
|
4664
|
+
const n = this.navigationHistory.shift();
|
|
4665
|
+
n && this.reportedByNav.delete(n);
|
|
4539
4666
|
}
|
|
4540
4667
|
}
|
|
4541
4668
|
this.trackWebVital(e.type, e.value);
|
|
@@ -4546,7 +4673,7 @@ class Ns extends _ {
|
|
|
4546
4673
|
return;
|
|
4547
4674
|
}
|
|
4548
4675
|
this.eventManager.track({
|
|
4549
|
-
type:
|
|
4676
|
+
type: u.WEB_VITALS,
|
|
4550
4677
|
web_vitals: {
|
|
4551
4678
|
type: e,
|
|
4552
4679
|
value: t
|
|
@@ -4579,8 +4706,8 @@ class Ns extends _ {
|
|
|
4579
4706
|
const e = performance.getEntriesByType("navigation")[0];
|
|
4580
4707
|
if (!e)
|
|
4581
4708
|
return null;
|
|
4582
|
-
const t = e.startTime || performance.now(), s = ++this.navigationCounter,
|
|
4583
|
-
return s > 1 ? `${
|
|
4709
|
+
const t = e.startTime || performance.now(), s = ++this.navigationCounter, i = `${t.toFixed(2)}_${window.location.pathname}`;
|
|
4710
|
+
return s > 1 ? `${i}_${s}` : i;
|
|
4584
4711
|
} catch (e) {
|
|
4585
4712
|
return a("debug", "Failed to get navigation ID", { error: e }), null;
|
|
4586
4713
|
}
|
|
@@ -4590,11 +4717,11 @@ class Ns extends _ {
|
|
|
4590
4717
|
const t = PerformanceObserver.supportedEntryTypes;
|
|
4591
4718
|
return !t || t.includes(e);
|
|
4592
4719
|
}
|
|
4593
|
-
safeObserve(e, t, s,
|
|
4720
|
+
safeObserve(e, t, s, i = !1) {
|
|
4594
4721
|
try {
|
|
4595
4722
|
if (!this.isObserverSupported(e))
|
|
4596
4723
|
return !1;
|
|
4597
|
-
const
|
|
4724
|
+
const n = new PerformanceObserver((o, l) => {
|
|
4598
4725
|
try {
|
|
4599
4726
|
t(o, l);
|
|
4600
4727
|
} catch (c) {
|
|
@@ -4603,16 +4730,16 @@ class Ns extends _ {
|
|
|
4603
4730
|
data: { type: e }
|
|
4604
4731
|
});
|
|
4605
4732
|
}
|
|
4606
|
-
if (
|
|
4733
|
+
if (i)
|
|
4607
4734
|
try {
|
|
4608
4735
|
l.disconnect();
|
|
4609
4736
|
} catch {
|
|
4610
4737
|
}
|
|
4611
4738
|
});
|
|
4612
|
-
return
|
|
4613
|
-
} catch (
|
|
4739
|
+
return n.observe(s ?? { type: e, buffered: !0 }), i || this.observers.push(n), !0;
|
|
4740
|
+
} catch (n) {
|
|
4614
4741
|
return a("debug", "Failed to create performance observer", {
|
|
4615
|
-
error:
|
|
4742
|
+
error: n,
|
|
4616
4743
|
data: { type: e }
|
|
4617
4744
|
}), !1;
|
|
4618
4745
|
}
|
|
@@ -4660,7 +4787,7 @@ class ae extends _ {
|
|
|
4660
4787
|
const e = Date.now();
|
|
4661
4788
|
if (e < this.burstBackoffUntil)
|
|
4662
4789
|
return !1;
|
|
4663
|
-
if (e - this.burstWindowStart >
|
|
4790
|
+
if (e - this.burstWindowStart > jt && (this.errorBurstCounter = 0, this.burstWindowStart = e), this.errorBurstCounter++, this.errorBurstCounter > zt)
|
|
4664
4791
|
return this.burstBackoffUntil = e + ze, a("debug", "Error burst detected - entering cooldown", {
|
|
4665
4792
|
data: {
|
|
4666
4793
|
errorsInWindow: this.errorBurstCounter,
|
|
@@ -4678,7 +4805,7 @@ class ae extends _ {
|
|
|
4678
4805
|
return;
|
|
4679
4806
|
const s = typeof e.error?.stack == "string" ? this.truncateStack(e.error.stack) : void 0;
|
|
4680
4807
|
this.eventManager.track({
|
|
4681
|
-
type:
|
|
4808
|
+
type: u.ERROR,
|
|
4682
4809
|
error_data: {
|
|
4683
4810
|
type: B.JS_ERROR,
|
|
4684
4811
|
message: t,
|
|
@@ -4695,13 +4822,13 @@ class ae extends _ {
|
|
|
4695
4822
|
const t = this.extractRejectionMessage(e.reason), s = this.sanitize(t);
|
|
4696
4823
|
if (this.shouldSuppressError(B.PROMISE_REJECTION, s))
|
|
4697
4824
|
return;
|
|
4698
|
-
const
|
|
4825
|
+
const i = e.reason instanceof Error && typeof e.reason.stack == "string" ? this.truncateStack(e.reason.stack) : void 0;
|
|
4699
4826
|
this.eventManager.track({
|
|
4700
|
-
type:
|
|
4827
|
+
type: u.ERROR,
|
|
4701
4828
|
error_data: {
|
|
4702
4829
|
type: B.PROMISE_REJECTION,
|
|
4703
4830
|
message: s,
|
|
4704
|
-
...
|
|
4831
|
+
...i !== void 0 && { stack: i }
|
|
4705
4832
|
}
|
|
4706
4833
|
});
|
|
4707
4834
|
};
|
|
@@ -4725,14 +4852,14 @@ class ae extends _ {
|
|
|
4725
4852
|
sanitizePii(e) {
|
|
4726
4853
|
let t = e;
|
|
4727
4854
|
for (const s of at) {
|
|
4728
|
-
const
|
|
4729
|
-
t = t.replace(
|
|
4855
|
+
const i = new RegExp(s.source, s.flags);
|
|
4856
|
+
t = t.replace(i, "[REDACTED]");
|
|
4730
4857
|
}
|
|
4731
4858
|
return t;
|
|
4732
4859
|
}
|
|
4733
4860
|
shouldSuppressError(e, t) {
|
|
4734
|
-
const s = Date.now(),
|
|
4735
|
-
return
|
|
4861
|
+
const s = Date.now(), i = `${e}:${t}`, n = this.recentErrors.get(i);
|
|
4862
|
+
return n !== void 0 && s - n < je ? (this.recentErrors.set(i, s), !0) : (this.recentErrors.set(i, s), this.recentErrors.size > Gt ? (this.recentErrors.clear(), this.recentErrors.set(i, s), !1) : (this.recentErrors.size > ee && this.pruneOldErrors(), !1));
|
|
4736
4863
|
}
|
|
4737
4864
|
static TRUNCATION_SUFFIX = `
|
|
4738
4865
|
...truncated`;
|
|
@@ -4743,22 +4870,22 @@ class ae extends _ {
|
|
|
4743
4870
|
}
|
|
4744
4871
|
pruneOldErrors() {
|
|
4745
4872
|
const e = Date.now();
|
|
4746
|
-
for (const [
|
|
4747
|
-
e -
|
|
4873
|
+
for (const [i, n] of this.recentErrors.entries())
|
|
4874
|
+
e - n > je && this.recentErrors.delete(i);
|
|
4748
4875
|
if (this.recentErrors.size <= ee)
|
|
4749
4876
|
return;
|
|
4750
|
-
const t = Array.from(this.recentErrors.entries()).sort((
|
|
4751
|
-
for (let
|
|
4752
|
-
const
|
|
4753
|
-
|
|
4877
|
+
const t = Array.from(this.recentErrors.entries()).sort((i, n) => i[1] - n[1]), s = this.recentErrors.size - ee;
|
|
4878
|
+
for (let i = 0; i < s; i += 1) {
|
|
4879
|
+
const n = t[i];
|
|
4880
|
+
n && this.recentErrors.delete(n[0]);
|
|
4754
4881
|
}
|
|
4755
4882
|
}
|
|
4756
4883
|
}
|
|
4757
|
-
class
|
|
4884
|
+
class Ds extends _ {
|
|
4758
4885
|
isInitialized = !1;
|
|
4759
4886
|
suppressNextScrollTimer = null;
|
|
4760
4887
|
pageUnloadHandler = null;
|
|
4761
|
-
emitter = new
|
|
4888
|
+
emitter = new ps();
|
|
4762
4889
|
transformers = {};
|
|
4763
4890
|
customHeadersProvider;
|
|
4764
4891
|
managers = {};
|
|
@@ -4777,19 +4904,19 @@ class Os extends _ {
|
|
|
4777
4904
|
async init(e = {}) {
|
|
4778
4905
|
if (this.isInitialized)
|
|
4779
4906
|
return { sessionId: this.get("sessionId") ?? "" };
|
|
4780
|
-
this.managers.storage = new
|
|
4907
|
+
this.managers.storage = new Os();
|
|
4781
4908
|
try {
|
|
4782
4909
|
this.setupState(e);
|
|
4783
4910
|
const t = e.integrations?.custom?.headers ?? {}, s = e.integrations?.custom?.fetchCredentials ?? "include";
|
|
4784
|
-
return this.managers.event = new
|
|
4911
|
+
return this.managers.event = new vs(
|
|
4785
4912
|
this.managers.storage,
|
|
4786
4913
|
this.emitter,
|
|
4787
4914
|
this.transformers,
|
|
4788
4915
|
t,
|
|
4789
4916
|
this.customHeadersProvider,
|
|
4790
4917
|
s
|
|
4791
|
-
), this.loadPersistedIdentity(), this.initializeHandlers(), this.setupPageLifecycleListeners(), await this.managers.event.recoverPersistedEvents().catch((
|
|
4792
|
-
a("warn", "Failed to recover persisted events", { error:
|
|
4918
|
+
), this.loadPersistedIdentity(), this.initializeHandlers(), this.setupPageLifecycleListeners(), await this.managers.event.recoverPersistedEvents().catch((i) => {
|
|
4919
|
+
a("warn", "Failed to recover persisted events", { error: i });
|
|
4793
4920
|
}), this.isInitialized = !0, { sessionId: this.get("sessionId") ?? "" };
|
|
4794
4921
|
} catch (t) {
|
|
4795
4922
|
this.destroy(!0);
|
|
@@ -4811,15 +4938,15 @@ class Os extends _ {
|
|
|
4811
4938
|
}
|
|
4812
4939
|
let s = t;
|
|
4813
4940
|
t && typeof t == "object" && !Array.isArray(t) && Object.getPrototypeOf(t) !== Object.prototype && (s = Object.assign({}, t));
|
|
4814
|
-
const { valid:
|
|
4815
|
-
if (!
|
|
4816
|
-
if (this.get("mode") ===
|
|
4817
|
-
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${
|
|
4818
|
-
a("warn", `Custom event "${e}" dropped: ${
|
|
4941
|
+
const { valid: i, error: n, sanitizedMetadata: o } = Es(e, s);
|
|
4942
|
+
if (!i) {
|
|
4943
|
+
if (this.get("mode") === ne.QA)
|
|
4944
|
+
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${n}`);
|
|
4945
|
+
a("warn", `Custom event "${e}" dropped: ${n}`);
|
|
4819
4946
|
return;
|
|
4820
4947
|
}
|
|
4821
4948
|
this.managers.event.track({
|
|
4822
|
-
type:
|
|
4949
|
+
type: u.CUSTOM,
|
|
4823
4950
|
custom_event: {
|
|
4824
4951
|
name: e,
|
|
4825
4952
|
...o && { metadata: o }
|
|
@@ -4881,14 +5008,14 @@ class Os extends _ {
|
|
|
4881
5008
|
}
|
|
4882
5009
|
setupState(e = {}) {
|
|
4883
5010
|
this.set("config", e);
|
|
4884
|
-
const t =
|
|
5011
|
+
const t = _s.getId(this.managers.storage);
|
|
4885
5012
|
this.set("userId", t);
|
|
4886
|
-
const s =
|
|
5013
|
+
const s = ls(e);
|
|
4887
5014
|
this.set("collectApiUrls", s);
|
|
4888
|
-
const
|
|
4889
|
-
this.set("device",
|
|
4890
|
-
const
|
|
4891
|
-
this.set("pageUrl",
|
|
5015
|
+
const i = Xt();
|
|
5016
|
+
this.set("device", i);
|
|
5017
|
+
const n = ye(window.location.href, e.sensitiveQueryParams);
|
|
5018
|
+
this.set("pageUrl", n), ss() && this.set("mode", ne.QA);
|
|
4892
5019
|
}
|
|
4893
5020
|
/**
|
|
4894
5021
|
* Returns the current configuration object.
|
|
@@ -4956,11 +5083,11 @@ class Os extends _ {
|
|
|
4956
5083
|
const t = this.validateGlobalMetadata(e);
|
|
4957
5084
|
if (!t.valid)
|
|
4958
5085
|
throw new Error(`[TraceLog] Invalid global metadata: ${t.error}`);
|
|
4959
|
-
const
|
|
5086
|
+
const i = {
|
|
4960
5087
|
...this.get("config"),
|
|
4961
5088
|
globalMetadata: e
|
|
4962
5089
|
};
|
|
4963
|
-
this.set("config",
|
|
5090
|
+
this.set("config", i), a("debug", "Global metadata updated (replaced)", { data: { keys: Object.keys(e) } });
|
|
4964
5091
|
}
|
|
4965
5092
|
/**
|
|
4966
5093
|
* Merges new metadata with existing global metadata.
|
|
@@ -4973,12 +5100,12 @@ class Os extends _ {
|
|
|
4973
5100
|
const t = this.validateGlobalMetadata(e);
|
|
4974
5101
|
if (!t.valid)
|
|
4975
5102
|
throw new Error(`[TraceLog] Invalid global metadata: ${t.error}`);
|
|
4976
|
-
const s = this.get("config"),
|
|
5103
|
+
const s = this.get("config"), n = {
|
|
4977
5104
|
...s.globalMetadata ?? {},
|
|
4978
5105
|
...e
|
|
4979
5106
|
}, o = {
|
|
4980
5107
|
...s,
|
|
4981
|
-
globalMetadata:
|
|
5108
|
+
globalMetadata: n
|
|
4982
5109
|
};
|
|
4983
5110
|
this.set("config", o), a("debug", "Global metadata updated (merged)", { data: { keys: Object.keys(e) } });
|
|
4984
5111
|
}
|
|
@@ -5006,12 +5133,12 @@ class Os extends _ {
|
|
|
5006
5133
|
a("warn", "identify() userId exceeds 256 characters", { data: { length: e.trim().length } });
|
|
5007
5134
|
return;
|
|
5008
5135
|
}
|
|
5009
|
-
const s = e.trim(),
|
|
5136
|
+
const s = e.trim(), i = ht(t), n = {
|
|
5010
5137
|
userId: s,
|
|
5011
|
-
...
|
|
5138
|
+
...i ? { traits: i } : {}
|
|
5012
5139
|
};
|
|
5013
|
-
this.set("identity",
|
|
5014
|
-
data: { userIdLength: s.length, traitKeys:
|
|
5140
|
+
this.set("identity", n), this.persistIdentity(n), a("debug", "Visitor identified", {
|
|
5141
|
+
data: { userIdLength: s.length, traitKeys: i ? Object.keys(i) : [] }
|
|
5015
5142
|
});
|
|
5016
5143
|
}
|
|
5017
5144
|
/**
|
|
@@ -5025,7 +5152,7 @@ class Os extends _ {
|
|
|
5025
5152
|
*/
|
|
5026
5153
|
async resetIdentity() {
|
|
5027
5154
|
await this.managers.event?.flushImmediately(), this.set("identity", void 0), this.clearPersistedIdentity();
|
|
5028
|
-
const e =
|
|
5155
|
+
const e = dt();
|
|
5029
5156
|
this.managers.storage.setItem(Te, e), this.set("userId", e), this.set("hasStartSession", !1), this.set("sessionId", null), this.handlers.session?.stopTracking(), this.handlers.session?.startTracking(), a("debug", "Identity reset, new UUID generated");
|
|
5030
5157
|
}
|
|
5031
5158
|
/**
|
|
@@ -5053,14 +5180,14 @@ class Os extends _ {
|
|
|
5053
5180
|
loadPersistedIdentity() {
|
|
5054
5181
|
const e = this.managers.storage, t = this.getProjectId(), s = fe(t);
|
|
5055
5182
|
try {
|
|
5056
|
-
const
|
|
5057
|
-
if (
|
|
5058
|
-
const
|
|
5059
|
-
if (e.removeItem(U), !this.isValidIdentityData(
|
|
5183
|
+
const i = e.getItem(U);
|
|
5184
|
+
if (i) {
|
|
5185
|
+
const n = JSON.parse(i);
|
|
5186
|
+
if (e.removeItem(U), !this.isValidIdentityData(n)) {
|
|
5060
5187
|
a("debug", "Invalid pending identity in localStorage, discarded");
|
|
5061
5188
|
return;
|
|
5062
5189
|
}
|
|
5063
|
-
const o = { ...
|
|
5190
|
+
const o = { ...n, userId: n.userId.trim() };
|
|
5064
5191
|
e.setItem(s, JSON.stringify(o)), this.set("identity", o), a("debug", "Migrated pending identity to project-scoped key");
|
|
5065
5192
|
return;
|
|
5066
5193
|
}
|
|
@@ -5068,14 +5195,14 @@ class Os extends _ {
|
|
|
5068
5195
|
e.removeItem(U);
|
|
5069
5196
|
}
|
|
5070
5197
|
try {
|
|
5071
|
-
const
|
|
5072
|
-
if (
|
|
5073
|
-
const
|
|
5074
|
-
if (!this.isValidIdentityData(
|
|
5198
|
+
const i = e.getItem(s);
|
|
5199
|
+
if (i) {
|
|
5200
|
+
const n = JSON.parse(i);
|
|
5201
|
+
if (!this.isValidIdentityData(n)) {
|
|
5075
5202
|
e.removeItem(s), a("debug", "Invalid persisted identity in localStorage, discarded");
|
|
5076
5203
|
return;
|
|
5077
5204
|
}
|
|
5078
|
-
const o = { ...
|
|
5205
|
+
const o = { ...n, userId: n.userId.trim() };
|
|
5079
5206
|
this.set("identity", o), a("debug", "Loaded persisted identity");
|
|
5080
5207
|
}
|
|
5081
5208
|
} catch {
|
|
@@ -5092,8 +5219,8 @@ class Os extends _ {
|
|
|
5092
5219
|
if (typeof t != "string" || t.trim().length === 0 || t.trim().length > 256) return !1;
|
|
5093
5220
|
if (s !== void 0) {
|
|
5094
5221
|
if (typeof s != "object" || s === null || Array.isArray(s)) return !1;
|
|
5095
|
-
for (const
|
|
5096
|
-
if (typeof
|
|
5222
|
+
for (const i of Object.values(s))
|
|
5223
|
+
if (typeof i != "string") return !1;
|
|
5097
5224
|
}
|
|
5098
5225
|
return !0;
|
|
5099
5226
|
}
|
|
@@ -5115,7 +5242,7 @@ class Os extends _ {
|
|
|
5115
5242
|
}
|
|
5116
5243
|
initializeHandlers() {
|
|
5117
5244
|
const e = this.get("config");
|
|
5118
|
-
this.handlers.session = new
|
|
5245
|
+
this.handlers.session = new bs(
|
|
5119
5246
|
this.managers.storage,
|
|
5120
5247
|
this.managers.event
|
|
5121
5248
|
), this.handlers.session.startTracking();
|
|
@@ -5124,38 +5251,38 @@ class Os extends _ {
|
|
|
5124
5251
|
this.set("suppressNextScroll", !1);
|
|
5125
5252
|
}, 500);
|
|
5126
5253
|
};
|
|
5127
|
-
if (this.handlers.pageView = new
|
|
5254
|
+
if (this.handlers.pageView = new Ls(this.managers.event, t), this.handlers.pageView.startTracking(), this.handlers.click = new As(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new Ms(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new Ps(this.managers.event), this.handlers.performance.startTracking().catch((s) => {
|
|
5128
5255
|
a("warn", "Failed to start performance tracking", { error: s });
|
|
5129
|
-
}), this.handlers.error = new ae(this.managers.event), this.handlers.error.startTracking(), e.viewport && (this.handlers.viewport = new
|
|
5130
|
-
const s = new
|
|
5131
|
-
s.activate(), this.integrationInstances.shopifyCartLinker = s, this.emitter.on(se.EVENT, (
|
|
5132
|
-
|
|
5256
|
+
}), this.handlers.error = new ae(this.managers.event), this.handlers.error.startTracking(), e.viewport && (this.handlers.viewport = new Cs(this.managers.event), this.handlers.viewport.startTracking()), e.integrations?.tracelog?.shopify) {
|
|
5257
|
+
const s = new Ns();
|
|
5258
|
+
s.activate(), this.integrationInstances.shopifyCartLinker = s, this.emitter.on(se.EVENT, (i) => {
|
|
5259
|
+
i.type === u.SESSION_START && s.onSessionChange();
|
|
5133
5260
|
});
|
|
5134
5261
|
}
|
|
5135
5262
|
}
|
|
5136
5263
|
}
|
|
5137
5264
|
const k = [], M = [];
|
|
5138
|
-
let D = null, h = null, R = !1,
|
|
5139
|
-
const
|
|
5265
|
+
let D = null, h = null, R = !1, T = !1, P = null;
|
|
5266
|
+
const ks = async (r) => typeof window > "u" || typeof document > "u" ? { sessionId: "" } : (T = !1, window.__traceLogDisabled === !0 ? { sessionId: "" } : h ? { sessionId: h.getSessionId() ?? "" } : (R && P || (R = !0, P = (async () => {
|
|
5140
5267
|
try {
|
|
5141
|
-
const e =
|
|
5268
|
+
const e = fs(r ?? {}), t = new Ds();
|
|
5142
5269
|
try {
|
|
5143
5270
|
k.forEach(({ event: o, callback: l }) => {
|
|
5144
5271
|
t.on(o, l);
|
|
5145
5272
|
}), k.length = 0, M.forEach(({ hook: o, fn: l }) => {
|
|
5146
5273
|
o === "beforeSend" ? t.setTransformer("beforeSend", l) : t.setTransformer("beforeBatch", l);
|
|
5147
5274
|
}), M.length = 0, D && (t.setCustomHeaders(D), D = null);
|
|
5148
|
-
const s = t.init(e),
|
|
5275
|
+
const s = t.init(e), i = new Promise((o, l) => {
|
|
5149
5276
|
setTimeout(() => {
|
|
5150
5277
|
l(new Error("[TraceLog] Initialization timeout after 10000ms"));
|
|
5151
5278
|
}, 1e4);
|
|
5152
|
-
}),
|
|
5153
|
-
return h = t,
|
|
5279
|
+
}), n = await Promise.race([s, i]);
|
|
5280
|
+
return h = t, n;
|
|
5154
5281
|
} catch (s) {
|
|
5155
5282
|
try {
|
|
5156
5283
|
t.destroy(!0);
|
|
5157
|
-
} catch (
|
|
5158
|
-
a("error", "Failed to cleanup partially initialized app", { error:
|
|
5284
|
+
} catch (i) {
|
|
5285
|
+
a("error", "Failed to cleanup partially initialized app", { error: i });
|
|
5159
5286
|
}
|
|
5160
5287
|
throw s;
|
|
5161
5288
|
}
|
|
@@ -5164,15 +5291,15 @@ const Ps = async (r) => typeof window > "u" || typeof document > "u" ? { session
|
|
|
5164
5291
|
} finally {
|
|
5165
5292
|
R = !1, P = null;
|
|
5166
5293
|
}
|
|
5167
|
-
})()), P)),
|
|
5294
|
+
})()), P)), Vs = (r, e) => {
|
|
5168
5295
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5169
5296
|
if (!h)
|
|
5170
5297
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5171
|
-
if (
|
|
5298
|
+
if (T)
|
|
5172
5299
|
throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
|
|
5173
5300
|
h.sendCustomEvent(r, e);
|
|
5174
5301
|
}
|
|
5175
|
-
},
|
|
5302
|
+
}, Us = (r, e) => {
|
|
5176
5303
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5177
5304
|
if (!h || R) {
|
|
5178
5305
|
k.push({ event: r, callback: e });
|
|
@@ -5180,7 +5307,7 @@ const Ps = async (r) => typeof window > "u" || typeof document > "u" ? { session
|
|
|
5180
5307
|
}
|
|
5181
5308
|
h.on(r, e);
|
|
5182
5309
|
}
|
|
5183
|
-
},
|
|
5310
|
+
}, Fs = (r, e) => {
|
|
5184
5311
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5185
5312
|
if (!h) {
|
|
5186
5313
|
const t = k.findIndex((s) => s.event === r && s.callback === e);
|
|
@@ -5190,7 +5317,7 @@ const Ps = async (r) => typeof window > "u" || typeof document > "u" ? { session
|
|
|
5190
5317
|
h.off(r, e);
|
|
5191
5318
|
}
|
|
5192
5319
|
};
|
|
5193
|
-
function
|
|
5320
|
+
function Hs(r, e) {
|
|
5194
5321
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5195
5322
|
if (typeof e != "function")
|
|
5196
5323
|
throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof e}`);
|
|
@@ -5199,23 +5326,23 @@ function Us(r, e) {
|
|
|
5199
5326
|
t !== -1 && M.splice(t, 1), M.push({ hook: r, fn: e });
|
|
5200
5327
|
return;
|
|
5201
5328
|
}
|
|
5202
|
-
if (
|
|
5329
|
+
if (T)
|
|
5203
5330
|
throw new Error("[TraceLog] Cannot set transformers while TraceLog is being destroyed");
|
|
5204
5331
|
r === "beforeSend" ? h.setTransformer("beforeSend", e) : h.setTransformer("beforeBatch", e);
|
|
5205
5332
|
}
|
|
5206
5333
|
}
|
|
5207
|
-
const
|
|
5334
|
+
const xs = (r) => {
|
|
5208
5335
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5209
5336
|
if (!h) {
|
|
5210
5337
|
const e = M.findIndex((t) => t.hook === r);
|
|
5211
5338
|
e !== -1 && M.splice(e, 1);
|
|
5212
5339
|
return;
|
|
5213
5340
|
}
|
|
5214
|
-
if (
|
|
5341
|
+
if (T)
|
|
5215
5342
|
throw new Error("[TraceLog] Cannot remove transformers while TraceLog is being destroyed");
|
|
5216
5343
|
h.removeTransformer(r);
|
|
5217
5344
|
}
|
|
5218
|
-
},
|
|
5345
|
+
}, $s = (r) => {
|
|
5219
5346
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5220
5347
|
if (typeof r != "function")
|
|
5221
5348
|
throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof r}`);
|
|
@@ -5223,54 +5350,54 @@ const Hs = (r) => {
|
|
|
5223
5350
|
D = r;
|
|
5224
5351
|
return;
|
|
5225
5352
|
}
|
|
5226
|
-
if (
|
|
5353
|
+
if (T)
|
|
5227
5354
|
throw new Error("[TraceLog] Cannot set custom headers while TraceLog is being destroyed");
|
|
5228
5355
|
h.setCustomHeaders(r);
|
|
5229
5356
|
}
|
|
5230
|
-
},
|
|
5357
|
+
}, Bs = () => {
|
|
5231
5358
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5232
5359
|
if (!h) {
|
|
5233
5360
|
D = null;
|
|
5234
5361
|
return;
|
|
5235
5362
|
}
|
|
5236
|
-
if (
|
|
5363
|
+
if (T)
|
|
5237
5364
|
throw new Error("[TraceLog] Cannot remove custom headers while TraceLog is being destroyed");
|
|
5238
5365
|
h.removeCustomHeaders();
|
|
5239
5366
|
}
|
|
5240
|
-
},
|
|
5367
|
+
}, Ws = () => typeof window > "u" || typeof document > "u" ? !1 : h !== null, Xs = () => typeof window > "u" || typeof document > "u" || !h ? null : h.getSessionId(), Gs = () => {
|
|
5241
5368
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5242
|
-
if (
|
|
5369
|
+
if (T)
|
|
5243
5370
|
throw new Error("[TraceLog] Destroy operation already in progress");
|
|
5244
5371
|
if (!h) {
|
|
5245
|
-
|
|
5372
|
+
T = !1;
|
|
5246
5373
|
return;
|
|
5247
5374
|
}
|
|
5248
|
-
|
|
5375
|
+
T = !0;
|
|
5249
5376
|
try {
|
|
5250
|
-
h.destroy(), h = null, R = !1, P = null, k.length = 0, M.length = 0, D = null,
|
|
5377
|
+
h.destroy(), h = null, R = !1, P = null, k.length = 0, M.length = 0, D = null, T = !1;
|
|
5251
5378
|
} catch (r) {
|
|
5252
|
-
h = null, R = !1, P = null, k.length = 0, M.length = 0, D = null,
|
|
5379
|
+
h = null, R = !1, P = null, k.length = 0, M.length = 0, D = null, T = !1, a("warn", "Error during destroy, forced cleanup completed", { error: r });
|
|
5253
5380
|
}
|
|
5254
5381
|
}
|
|
5255
|
-
},
|
|
5256
|
-
typeof window > "u" || typeof document > "u" ||
|
|
5257
|
-
},
|
|
5382
|
+
}, js = (r) => {
|
|
5383
|
+
typeof window > "u" || typeof document > "u" || rs(r);
|
|
5384
|
+
}, zs = (r) => {
|
|
5258
5385
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5259
5386
|
if (!h)
|
|
5260
5387
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5261
|
-
if (
|
|
5388
|
+
if (T)
|
|
5262
5389
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
5263
5390
|
h.updateGlobalMetadata(r);
|
|
5264
5391
|
}
|
|
5265
|
-
},
|
|
5392
|
+
}, Ks = (r) => {
|
|
5266
5393
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5267
5394
|
if (!h)
|
|
5268
5395
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5269
|
-
if (
|
|
5396
|
+
if (T)
|
|
5270
5397
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
5271
5398
|
h.mergeGlobalMetadata(r);
|
|
5272
5399
|
}
|
|
5273
|
-
},
|
|
5400
|
+
}, Qs = (r, e) => {
|
|
5274
5401
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5275
5402
|
if (!r || typeof r != "string" || r.trim().length === 0) {
|
|
5276
5403
|
a("warn", "identify() called with invalid userId");
|
|
@@ -5280,7 +5407,7 @@ const Hs = (r) => {
|
|
|
5280
5407
|
a("warn", "identify() userId exceeds 256 characters");
|
|
5281
5408
|
return;
|
|
5282
5409
|
}
|
|
5283
|
-
if (
|
|
5410
|
+
if (T) {
|
|
5284
5411
|
a("warn", "Cannot identify while TraceLog is being destroyed");
|
|
5285
5412
|
return;
|
|
5286
5413
|
}
|
|
@@ -5298,7 +5425,7 @@ const Hs = (r) => {
|
|
|
5298
5425
|
a("debug", "Failed to persist pre-init identity");
|
|
5299
5426
|
}
|
|
5300
5427
|
}
|
|
5301
|
-
},
|
|
5428
|
+
}, Ys = async () => {
|
|
5302
5429
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5303
5430
|
if (!h) {
|
|
5304
5431
|
try {
|
|
@@ -5307,47 +5434,47 @@ const Hs = (r) => {
|
|
|
5307
5434
|
}
|
|
5308
5435
|
return;
|
|
5309
5436
|
}
|
|
5310
|
-
if (
|
|
5437
|
+
if (T)
|
|
5311
5438
|
throw new Error("[TraceLog] Cannot reset identity while TraceLog is being destroyed");
|
|
5312
5439
|
await h.resetIdentity();
|
|
5313
5440
|
}
|
|
5314
|
-
},
|
|
5315
|
-
init:
|
|
5316
|
-
event:
|
|
5317
|
-
on:
|
|
5318
|
-
off:
|
|
5319
|
-
setTransformer:
|
|
5320
|
-
removeTransformer:
|
|
5321
|
-
setCustomHeaders:
|
|
5322
|
-
removeCustomHeaders:
|
|
5323
|
-
isInitialized:
|
|
5324
|
-
getSessionId:
|
|
5325
|
-
destroy:
|
|
5326
|
-
setQaMode:
|
|
5327
|
-
updateGlobalMetadata:
|
|
5328
|
-
mergeGlobalMetadata:
|
|
5329
|
-
identify:
|
|
5330
|
-
resetIdentity:
|
|
5441
|
+
}, br = {
|
|
5442
|
+
init: ks,
|
|
5443
|
+
event: Vs,
|
|
5444
|
+
on: Us,
|
|
5445
|
+
off: Fs,
|
|
5446
|
+
setTransformer: Hs,
|
|
5447
|
+
removeTransformer: xs,
|
|
5448
|
+
setCustomHeaders: $s,
|
|
5449
|
+
removeCustomHeaders: Bs,
|
|
5450
|
+
isInitialized: Ws,
|
|
5451
|
+
getSessionId: Xs,
|
|
5452
|
+
destroy: Gs,
|
|
5453
|
+
setQaMode: js,
|
|
5454
|
+
updateGlobalMetadata: zs,
|
|
5455
|
+
mergeGlobalMetadata: Ks,
|
|
5456
|
+
identify: Qs,
|
|
5457
|
+
resetIdentity: Ys
|
|
5331
5458
|
};
|
|
5332
|
-
var
|
|
5459
|
+
var Le, C, G, Et, le, pt = -1, V = function(r) {
|
|
5333
5460
|
addEventListener("pageshow", (function(e) {
|
|
5334
5461
|
e.persisted && (pt = e.timeStamp, r(e));
|
|
5335
5462
|
}), !0);
|
|
5336
5463
|
}, Pe = function() {
|
|
5337
5464
|
var r = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
|
|
5338
5465
|
if (r && r.responseStart > 0 && r.responseStart < performance.now()) return r;
|
|
5339
|
-
},
|
|
5466
|
+
}, de = function() {
|
|
5340
5467
|
var r = Pe();
|
|
5341
5468
|
return r && r.activationStart || 0;
|
|
5342
5469
|
}, y = function(r, e) {
|
|
5343
5470
|
var t = Pe(), s = "navigate";
|
|
5344
|
-
return pt >= 0 ? s = "back-forward-cache" : t && (document.prerendering ||
|
|
5345
|
-
},
|
|
5471
|
+
return pt >= 0 ? s = "back-forward-cache" : t && (document.prerendering || de() > 0 ? s = "prerender" : document.wasDiscarded ? s = "restore" : t.type && (s = t.type.replace(/_/g, "-"))), { name: r, value: e === void 0 ? -1 : e, rating: "good", delta: 0, entries: [], id: "v4-".concat(Date.now(), "-").concat(Math.floor(8999999999999 * Math.random()) + 1e12), navigationType: s };
|
|
5472
|
+
}, H = function(r, e, t) {
|
|
5346
5473
|
try {
|
|
5347
5474
|
if (PerformanceObserver.supportedEntryTypes.includes(r)) {
|
|
5348
|
-
var s = new PerformanceObserver((function(
|
|
5475
|
+
var s = new PerformanceObserver((function(i) {
|
|
5349
5476
|
Promise.resolve().then((function() {
|
|
5350
|
-
e(
|
|
5477
|
+
e(i.getEntries());
|
|
5351
5478
|
}));
|
|
5352
5479
|
}));
|
|
5353
5480
|
return s.observe(Object.assign({ type: r, buffered: !0 }, t || {})), s;
|
|
@@ -5355,9 +5482,9 @@ var Ae, C, G, Et, le, pt = -1, V = function(r) {
|
|
|
5355
5482
|
} catch {
|
|
5356
5483
|
}
|
|
5357
5484
|
}, w = function(r, e, t, s) {
|
|
5358
|
-
var
|
|
5485
|
+
var i, n;
|
|
5359
5486
|
return function(o) {
|
|
5360
|
-
e.value >= 0 && (o || s) && ((
|
|
5487
|
+
e.value >= 0 && (o || s) && ((n = e.value - (i || 0)) || i === void 0) && (i = e.value, e.delta = n, e.rating = (function(l, c) {
|
|
5361
5488
|
return l > c[1] ? "poor" : l > c[0] ? "needs-improvement" : "good";
|
|
5362
5489
|
})(e.value, t), r(e));
|
|
5363
5490
|
};
|
|
@@ -5371,239 +5498,239 @@ var Ae, C, G, Et, le, pt = -1, V = function(r) {
|
|
|
5371
5498
|
document.addEventListener("visibilitychange", (function() {
|
|
5372
5499
|
document.visibilityState === "hidden" && r();
|
|
5373
5500
|
}));
|
|
5374
|
-
},
|
|
5501
|
+
}, ue = function(r) {
|
|
5375
5502
|
var e = !1;
|
|
5376
5503
|
return function() {
|
|
5377
5504
|
e || (r(), e = !0);
|
|
5378
5505
|
};
|
|
5379
|
-
},
|
|
5506
|
+
}, F = -1, et = function() {
|
|
5380
5507
|
return document.visibilityState !== "hidden" || document.prerendering ? 1 / 0 : 0;
|
|
5381
5508
|
}, ce = function(r) {
|
|
5382
|
-
document.visibilityState === "hidden" &&
|
|
5509
|
+
document.visibilityState === "hidden" && F > -1 && (F = r.type === "visibilitychange" ? r.timeStamp : 0, qs());
|
|
5383
5510
|
}, tt = function() {
|
|
5384
5511
|
addEventListener("visibilitychange", ce, !0), addEventListener("prerenderingchange", ce, !0);
|
|
5385
|
-
},
|
|
5512
|
+
}, qs = function() {
|
|
5386
5513
|
removeEventListener("visibilitychange", ce, !0), removeEventListener("prerenderingchange", ce, !0);
|
|
5387
5514
|
}, ke = function() {
|
|
5388
|
-
return
|
|
5515
|
+
return F < 0 && (F = et(), tt(), V((function() {
|
|
5389
5516
|
setTimeout((function() {
|
|
5390
|
-
|
|
5517
|
+
F = et(), tt();
|
|
5391
5518
|
}), 0);
|
|
5392
5519
|
}))), { get firstHiddenTime() {
|
|
5393
|
-
return
|
|
5520
|
+
return F;
|
|
5394
5521
|
} };
|
|
5395
|
-
},
|
|
5522
|
+
}, K = function(r) {
|
|
5396
5523
|
document.prerendering ? addEventListener("prerenderingchange", (function() {
|
|
5397
5524
|
return r();
|
|
5398
5525
|
}), !0) : r();
|
|
5399
|
-
},
|
|
5400
|
-
e = e || {},
|
|
5401
|
-
var t, s = ke(),
|
|
5526
|
+
}, Ae = [1800, 3e3], St = function(r, e) {
|
|
5527
|
+
e = e || {}, K((function() {
|
|
5528
|
+
var t, s = ke(), i = y("FCP"), n = H("paint", (function(o) {
|
|
5402
5529
|
o.forEach((function(l) {
|
|
5403
|
-
l.name === "first-contentful-paint" && (
|
|
5530
|
+
l.name === "first-contentful-paint" && (n.disconnect(), l.startTime < s.firstHiddenTime && (i.value = Math.max(l.startTime - de(), 0), i.entries.push(l), t(!0)));
|
|
5404
5531
|
}));
|
|
5405
5532
|
}));
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5533
|
+
n && (t = w(r, i, Ae, e.reportAllChanges), V((function(o) {
|
|
5534
|
+
i = y("FCP"), t = w(r, i, Ae, e.reportAllChanges), De((function() {
|
|
5535
|
+
i.value = performance.now() - o.timeStamp, t(!0);
|
|
5409
5536
|
}));
|
|
5410
5537
|
})));
|
|
5411
5538
|
}));
|
|
5412
|
-
}, Me = [0.1, 0.25],
|
|
5413
|
-
e = e || {}, St(
|
|
5414
|
-
var t, s = y("CLS", 0),
|
|
5415
|
-
c.forEach((function(
|
|
5416
|
-
if (!
|
|
5417
|
-
var f =
|
|
5418
|
-
|
|
5539
|
+
}, Me = [0.1, 0.25], Js = function(r, e) {
|
|
5540
|
+
e = e || {}, St(ue((function() {
|
|
5541
|
+
var t, s = y("CLS", 0), i = 0, n = [], o = function(c) {
|
|
5542
|
+
c.forEach((function(d) {
|
|
5543
|
+
if (!d.hadRecentInput) {
|
|
5544
|
+
var f = n[0], g = n[n.length - 1];
|
|
5545
|
+
i && d.startTime - g.startTime < 1e3 && d.startTime - f.startTime < 5e3 ? (i += d.value, n.push(d)) : (i = d.value, n = [d]);
|
|
5419
5546
|
}
|
|
5420
|
-
})),
|
|
5421
|
-
}, l =
|
|
5547
|
+
})), i > s.value && (s.value = i, s.entries = n, t());
|
|
5548
|
+
}, l = H("layout-shift", o);
|
|
5422
5549
|
l && (t = w(r, s, Me, e.reportAllChanges), z((function() {
|
|
5423
5550
|
o(l.takeRecords()), t(!0);
|
|
5424
5551
|
})), V((function() {
|
|
5425
|
-
|
|
5552
|
+
i = 0, s = y("CLS", 0), t = w(r, s, Me, e.reportAllChanges), De((function() {
|
|
5426
5553
|
return t();
|
|
5427
5554
|
}));
|
|
5428
5555
|
})), setTimeout(t, 0));
|
|
5429
5556
|
})));
|
|
5430
|
-
}, Tt = 0, pe = 1 / 0, J = 0,
|
|
5557
|
+
}, Tt = 0, pe = 1 / 0, J = 0, Zs = function(r) {
|
|
5431
5558
|
r.forEach((function(e) {
|
|
5432
5559
|
e.interactionId && (pe = Math.min(pe, e.interactionId), J = Math.max(J, e.interactionId), Tt = J ? (J - pe) / 7 + 1 : 0);
|
|
5433
5560
|
}));
|
|
5434
5561
|
}, It = function() {
|
|
5435
|
-
return
|
|
5436
|
-
},
|
|
5437
|
-
"interactionCount" in performance ||
|
|
5438
|
-
},
|
|
5439
|
-
var r = Math.min(
|
|
5440
|
-
return
|
|
5441
|
-
},
|
|
5442
|
-
if (
|
|
5443
|
-
return
|
|
5562
|
+
return Le ? Tt : performance.interactionCount || 0;
|
|
5563
|
+
}, er = function() {
|
|
5564
|
+
"interactionCount" in performance || Le || (Le = H("event", Zs, { type: "event", buffered: !0, durationThreshold: 0 }));
|
|
5565
|
+
}, L = [], te = /* @__PURE__ */ new Map(), vt = 0, tr = function() {
|
|
5566
|
+
var r = Math.min(L.length - 1, Math.floor((It() - vt) / 50));
|
|
5567
|
+
return L[r];
|
|
5568
|
+
}, sr = [], rr = function(r) {
|
|
5569
|
+
if (sr.forEach((function(i) {
|
|
5570
|
+
return i(r);
|
|
5444
5571
|
})), r.interactionId || r.entryType === "first-input") {
|
|
5445
|
-
var e =
|
|
5446
|
-
if (t ||
|
|
5572
|
+
var e = L[L.length - 1], t = te.get(r.interactionId);
|
|
5573
|
+
if (t || L.length < 10 || r.duration > e.latency) {
|
|
5447
5574
|
if (t) r.duration > t.latency ? (t.entries = [r], t.latency = r.duration) : r.duration === t.latency && r.startTime === t.entries[0].startTime && t.entries.push(r);
|
|
5448
5575
|
else {
|
|
5449
5576
|
var s = { id: r.interactionId, latency: r.duration, entries: [r] };
|
|
5450
|
-
te.set(s.id, s),
|
|
5577
|
+
te.set(s.id, s), L.push(s);
|
|
5451
5578
|
}
|
|
5452
|
-
|
|
5453
|
-
return
|
|
5454
|
-
})),
|
|
5455
|
-
return te.delete(
|
|
5579
|
+
L.sort((function(i, n) {
|
|
5580
|
+
return n.latency - i.latency;
|
|
5581
|
+
})), L.length > 10 && L.splice(10).forEach((function(i) {
|
|
5582
|
+
return te.delete(i.id);
|
|
5456
5583
|
}));
|
|
5457
5584
|
}
|
|
5458
5585
|
}
|
|
5459
5586
|
}, _t = function(r) {
|
|
5460
5587
|
var e = self.requestIdleCallback || self.setTimeout, t = -1;
|
|
5461
|
-
return r =
|
|
5462
|
-
}, Ce = [200, 500],
|
|
5463
|
-
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {},
|
|
5588
|
+
return r = ue(r), document.visibilityState === "hidden" ? r() : (t = e(r), z(r)), t;
|
|
5589
|
+
}, Ce = [200, 500], ir = function(r, e) {
|
|
5590
|
+
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, K((function() {
|
|
5464
5591
|
var t;
|
|
5465
|
-
|
|
5466
|
-
var s,
|
|
5592
|
+
er();
|
|
5593
|
+
var s, i = y("INP"), n = function(l) {
|
|
5467
5594
|
_t((function() {
|
|
5468
|
-
l.forEach(
|
|
5469
|
-
var c =
|
|
5470
|
-
c && c.latency !==
|
|
5595
|
+
l.forEach(rr);
|
|
5596
|
+
var c = tr();
|
|
5597
|
+
c && c.latency !== i.value && (i.value = c.latency, i.entries = c.entries, s());
|
|
5471
5598
|
}));
|
|
5472
|
-
}, o =
|
|
5473
|
-
s = w(r,
|
|
5474
|
-
|
|
5599
|
+
}, o = H("event", n, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
|
|
5600
|
+
s = w(r, i, Ce, e.reportAllChanges), o && (o.observe({ type: "first-input", buffered: !0 }), z((function() {
|
|
5601
|
+
n(o.takeRecords()), s(!0);
|
|
5475
5602
|
})), V((function() {
|
|
5476
|
-
vt = It(),
|
|
5603
|
+
vt = It(), L.length = 0, te.clear(), i = y("INP"), s = w(r, i, Ce, e.reportAllChanges);
|
|
5477
5604
|
})));
|
|
5478
5605
|
})));
|
|
5479
|
-
}, Re = [2500, 4e3], Se = {},
|
|
5480
|
-
e = e || {},
|
|
5481
|
-
var t, s = ke(),
|
|
5482
|
-
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(
|
|
5483
|
-
|
|
5606
|
+
}, Re = [2500, 4e3], Se = {}, nr = function(r, e) {
|
|
5607
|
+
e = e || {}, K((function() {
|
|
5608
|
+
var t, s = ke(), i = y("LCP"), n = function(c) {
|
|
5609
|
+
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(d) {
|
|
5610
|
+
d.startTime < s.firstHiddenTime && (i.value = Math.max(d.startTime - de(), 0), i.entries = [d], t());
|
|
5484
5611
|
}));
|
|
5485
|
-
}, o =
|
|
5612
|
+
}, o = H("largest-contentful-paint", n);
|
|
5486
5613
|
if (o) {
|
|
5487
|
-
t = w(r,
|
|
5488
|
-
var l =
|
|
5489
|
-
Se[
|
|
5614
|
+
t = w(r, i, Re, e.reportAllChanges);
|
|
5615
|
+
var l = ue((function() {
|
|
5616
|
+
Se[i.id] || (n(o.takeRecords()), o.disconnect(), Se[i.id] = !0, t(!0));
|
|
5490
5617
|
}));
|
|
5491
5618
|
["keydown", "click"].forEach((function(c) {
|
|
5492
5619
|
addEventListener(c, (function() {
|
|
5493
5620
|
return _t(l);
|
|
5494
5621
|
}), { once: !0, capture: !0 });
|
|
5495
5622
|
})), z(l), V((function(c) {
|
|
5496
|
-
|
|
5497
|
-
|
|
5623
|
+
i = y("LCP"), t = w(r, i, Re, e.reportAllChanges), De((function() {
|
|
5624
|
+
i.value = performance.now() - c.timeStamp, Se[i.id] = !0, t(!0);
|
|
5498
5625
|
}));
|
|
5499
5626
|
}));
|
|
5500
5627
|
}
|
|
5501
5628
|
}));
|
|
5502
|
-
}, Ne = [800, 1800],
|
|
5503
|
-
document.prerendering ?
|
|
5629
|
+
}, Ne = [800, 1800], or = function r(e) {
|
|
5630
|
+
document.prerendering ? K((function() {
|
|
5504
5631
|
return r(e);
|
|
5505
5632
|
})) : document.readyState !== "complete" ? addEventListener("load", (function() {
|
|
5506
5633
|
return r(e);
|
|
5507
5634
|
}), !0) : setTimeout(e, 0);
|
|
5508
|
-
},
|
|
5635
|
+
}, ar = function(r, e) {
|
|
5509
5636
|
e = e || {};
|
|
5510
5637
|
var t = y("TTFB"), s = w(r, t, Ne, e.reportAllChanges);
|
|
5511
|
-
|
|
5512
|
-
var
|
|
5513
|
-
|
|
5638
|
+
or((function() {
|
|
5639
|
+
var i = Pe();
|
|
5640
|
+
i && (t.value = Math.max(i.responseStart - de(), 0), t.entries = [i], s(!0), V((function() {
|
|
5514
5641
|
t = y("TTFB", 0), (s = w(r, t, Ne, e.reportAllChanges))(!0);
|
|
5515
5642
|
})));
|
|
5516
5643
|
}));
|
|
5517
|
-
}, W = { passive: !0, capture: !0 },
|
|
5644
|
+
}, W = { passive: !0, capture: !0 }, lr = /* @__PURE__ */ new Date(), st = function(r, e) {
|
|
5518
5645
|
C || (C = e, G = r, Et = /* @__PURE__ */ new Date(), wt(removeEventListener), yt());
|
|
5519
5646
|
}, yt = function() {
|
|
5520
|
-
if (G >= 0 && G < Et -
|
|
5647
|
+
if (G >= 0 && G < Et - lr) {
|
|
5521
5648
|
var r = { entryType: "first-input", name: C.type, target: C.target, cancelable: C.cancelable, startTime: C.timeStamp, processingStart: C.timeStamp + G };
|
|
5522
5649
|
le.forEach((function(e) {
|
|
5523
5650
|
e(r);
|
|
5524
5651
|
})), le = [];
|
|
5525
5652
|
}
|
|
5526
|
-
},
|
|
5653
|
+
}, cr = function(r) {
|
|
5527
5654
|
if (r.cancelable) {
|
|
5528
5655
|
var e = (r.timeStamp > 1e12 ? /* @__PURE__ */ new Date() : performance.now()) - r.timeStamp;
|
|
5529
5656
|
r.type == "pointerdown" ? (function(t, s) {
|
|
5530
|
-
var
|
|
5657
|
+
var i = function() {
|
|
5531
5658
|
st(t, s), o();
|
|
5532
|
-
},
|
|
5659
|
+
}, n = function() {
|
|
5533
5660
|
o();
|
|
5534
5661
|
}, o = function() {
|
|
5535
|
-
removeEventListener("pointerup",
|
|
5662
|
+
removeEventListener("pointerup", i, W), removeEventListener("pointercancel", n, W);
|
|
5536
5663
|
};
|
|
5537
|
-
addEventListener("pointerup",
|
|
5664
|
+
addEventListener("pointerup", i, W), addEventListener("pointercancel", n, W);
|
|
5538
5665
|
})(e, r) : st(e, r);
|
|
5539
5666
|
}
|
|
5540
5667
|
}, wt = function(r) {
|
|
5541
5668
|
["mousedown", "keydown", "touchstart", "pointerdown"].forEach((function(e) {
|
|
5542
|
-
return r(e,
|
|
5669
|
+
return r(e, cr, W);
|
|
5543
5670
|
}));
|
|
5544
|
-
}, Oe = [100, 300],
|
|
5545
|
-
e = e || {},
|
|
5546
|
-
var t, s = ke(),
|
|
5547
|
-
c.startTime < s.firstHiddenTime && (
|
|
5671
|
+
}, Oe = [100, 300], dr = function(r, e) {
|
|
5672
|
+
e = e || {}, K((function() {
|
|
5673
|
+
var t, s = ke(), i = y("FID"), n = function(c) {
|
|
5674
|
+
c.startTime < s.firstHiddenTime && (i.value = c.processingStart - c.startTime, i.entries.push(c), t(!0));
|
|
5548
5675
|
}, o = function(c) {
|
|
5549
|
-
c.forEach(
|
|
5550
|
-
}, l =
|
|
5551
|
-
t = w(r,
|
|
5676
|
+
c.forEach(n);
|
|
5677
|
+
}, l = H("first-input", o);
|
|
5678
|
+
t = w(r, i, Oe, e.reportAllChanges), l && (z(ue((function() {
|
|
5552
5679
|
o(l.takeRecords()), l.disconnect();
|
|
5553
5680
|
}))), V((function() {
|
|
5554
5681
|
var c;
|
|
5555
|
-
|
|
5682
|
+
i = y("FID"), t = w(r, i, Oe, e.reportAllChanges), le = [], G = -1, C = null, wt(addEventListener), c = n, le.push(c), yt();
|
|
5556
5683
|
})));
|
|
5557
5684
|
}));
|
|
5558
5685
|
};
|
|
5559
|
-
const
|
|
5686
|
+
const ur = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
5560
5687
|
__proto__: null,
|
|
5561
5688
|
CLSThresholds: Me,
|
|
5562
|
-
FCPThresholds:
|
|
5689
|
+
FCPThresholds: Ae,
|
|
5563
5690
|
FIDThresholds: Oe,
|
|
5564
5691
|
INPThresholds: Ce,
|
|
5565
5692
|
LCPThresholds: Re,
|
|
5566
5693
|
TTFBThresholds: Ne,
|
|
5567
|
-
onCLS:
|
|
5694
|
+
onCLS: Js,
|
|
5568
5695
|
onFCP: St,
|
|
5569
|
-
onFID:
|
|
5570
|
-
onINP:
|
|
5571
|
-
onLCP:
|
|
5572
|
-
onTTFB:
|
|
5696
|
+
onFID: dr,
|
|
5697
|
+
onINP: ir,
|
|
5698
|
+
onLCP: nr,
|
|
5699
|
+
onTTFB: ar
|
|
5573
5700
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
5574
5701
|
export {
|
|
5575
5702
|
m as AppConfigValidationError,
|
|
5576
|
-
|
|
5703
|
+
hr as DEFAULT_SESSION_TIMEOUT,
|
|
5577
5704
|
_e as DEFAULT_WEB_VITALS_MODE,
|
|
5578
|
-
|
|
5705
|
+
A as DeviceType,
|
|
5579
5706
|
se as EmitterEvent,
|
|
5580
5707
|
B as ErrorType,
|
|
5581
|
-
|
|
5582
|
-
|
|
5708
|
+
u as EventType,
|
|
5709
|
+
yr as InitializationTimeoutError,
|
|
5583
5710
|
N as IntegrationValidationError,
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5711
|
+
Ir as MAX_ARRAY_LENGTH,
|
|
5712
|
+
Er as MAX_CUSTOM_EVENT_ARRAY_SIZE,
|
|
5713
|
+
gr as MAX_CUSTOM_EVENT_KEYS,
|
|
5714
|
+
fr as MAX_CUSTOM_EVENT_NAME_LENGTH,
|
|
5715
|
+
mr as MAX_CUSTOM_EVENT_STRING_SIZE,
|
|
5716
|
+
pr as MAX_NESTED_OBJECT_KEYS,
|
|
5717
|
+
Sr as MAX_STRING_LENGTH,
|
|
5718
|
+
Tr as MAX_STRING_LENGTH_IN_ARRAY,
|
|
5719
|
+
ne as Mode,
|
|
5593
5720
|
at as PII_PATTERNS,
|
|
5594
5721
|
O as PermanentError,
|
|
5595
5722
|
re as RateLimitError,
|
|
5596
5723
|
We as SamplingRateValidationError,
|
|
5597
5724
|
Z as ScrollDirection,
|
|
5598
|
-
|
|
5725
|
+
Pt as SessionTimeoutValidationError,
|
|
5599
5726
|
$ as SpecialApiUrl,
|
|
5600
|
-
|
|
5727
|
+
ie as TimeoutError,
|
|
5601
5728
|
j as TraceLogValidationError,
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5729
|
+
wr as WEB_VITALS_GOOD_THRESHOLDS,
|
|
5730
|
+
Ke as WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS,
|
|
5731
|
+
Yt as WEB_VITALS_POOR_THRESHOLDS,
|
|
5732
|
+
Qe as getWebVitalsThresholds,
|
|
5733
|
+
vr as isPrimaryScrollEvent,
|
|
5734
|
+
_r as isSecondaryScrollEvent,
|
|
5735
|
+
br as tracelog
|
|
5609
5736
|
};
|