@tracelog/lib 2.9.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/browser/tracelog-shopify-pixel.iife.js +1 -1
- package/dist/browser/tracelog-shopify-pixel.iife.js.map +1 -1
- package/dist/browser/tracelog.esm.js +663 -451
- 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/pixel/index.cjs +2 -2
- package/dist/pixel/index.cjs.map +1 -1
- package/dist/pixel/index.js +2 -2
- package/dist/pixel/index.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 +159 -7
- package/dist/public-api.d.ts +159 -7
- 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 pr = 9e5;
|
|
2
|
+
const Sr = 120, Er = 49152, Tr = 100, Ir = 500, vr = 200;
|
|
3
|
+
const _r = 1e3, yr = 500, wr = 1e3;
|
|
4
4
|
const b = "data-tlog", bt = [
|
|
5
5
|
"button",
|
|
6
6
|
"a",
|
|
@@ -49,7 +49,7 @@ const b = "data-tlog", bt = [
|
|
|
49
49
|
"code",
|
|
50
50
|
"otp"
|
|
51
51
|
];
|
|
52
|
-
const
|
|
52
|
+
const E = {
|
|
53
53
|
INVALID_SESSION_TIMEOUT: "Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",
|
|
54
54
|
INVALID_SAMPLING_RATE: "Sampling rate must be between 0 and 1",
|
|
55
55
|
INVALID_ERROR_SAMPLING_RATE: "Error sampling must be between 0 and 1",
|
|
@@ -79,7 +79,7 @@ const p = {
|
|
|
79
79
|
/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
|
|
80
80
|
/<embed\b[^>]*>/gi,
|
|
81
81
|
/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi
|
|
82
|
-
],
|
|
82
|
+
], v = "tlog", G = `${v}:qa_mode`, Ie = `${v}:uid`, rt = "tlog_mode", Ue = "qa", He = "qa_off", Ct = (r) => r ? `${v}:${r}:queue` : `${v}:queue`, Rt = (r) => r ? `${v}:${r}:rate_limit` : `${v}:rate_limit`, Nt = (r) => r ? `${v}:${r}:session` : `${v}:session`, Ot = (r) => r ? `${v}:${r}:broadcast` : `${v}:broadcast`, Fe = (r, e) => `${v}:${r}:session_counts:${e}`, xe = 10080 * 60 * 1e3, $e = `${v}:session_counts_last_cleanup`, Be = 3600 * 1e3, me = (r) => r ? `${v}:${r}:identity` : `${v}:identity`, H = `${v}:pending_identity`;
|
|
83
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
85
|
constructor(e, t, s) {
|
|
@@ -99,7 +99,7 @@ class ne extends Error {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
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 || {}), ie = /* @__PURE__ */ ((r) => (r.QA = "qa", r))(ie || {});
|
|
102
|
-
const
|
|
102
|
+
const br = (r) => r.type === u.SCROLL && "scroll_data" in r && r.scroll_data.is_primary === !0, Lr = (r) => r.type === u.SCROLL && "scroll_data" in r && r.scroll_data.is_primary === !1;
|
|
103
103
|
class j extends Error {
|
|
104
104
|
constructor(e, t, s) {
|
|
105
105
|
super(e), this.errorCode = t, this.layer = s, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
@@ -107,7 +107,7 @@ class j extends Error {
|
|
|
107
107
|
errorCode;
|
|
108
108
|
layer;
|
|
109
109
|
}
|
|
110
|
-
class
|
|
110
|
+
class p extends j {
|
|
111
111
|
constructor(e, t = "config") {
|
|
112
112
|
super(e, "APP_CONFIG_INVALID", t);
|
|
113
113
|
}
|
|
@@ -127,7 +127,7 @@ class N extends j {
|
|
|
127
127
|
super(e, "INTEGRATION_INVALID", t);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
-
class
|
|
130
|
+
class Ar extends j {
|
|
131
131
|
constructor(e, t, s = "runtime") {
|
|
132
132
|
super(e, "INITIALIZATION_TIMEOUT", s), this.timeoutMs = t;
|
|
133
133
|
}
|
|
@@ -156,20 +156,20 @@ const nt = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8
|
|
|
156
156
|
if (typeof window > "u" || typeof sessionStorage > "u")
|
|
157
157
|
return !1;
|
|
158
158
|
try {
|
|
159
|
-
return sessionStorage.getItem(
|
|
159
|
+
return sessionStorage.getItem(G) === "true";
|
|
160
160
|
} catch {
|
|
161
161
|
return !1;
|
|
162
162
|
}
|
|
163
163
|
}, a = (r, e, t) => {
|
|
164
|
-
const { error: s, data: n, showToClient: i = !1, style: o, visibility: l } = t ?? {},
|
|
164
|
+
const { error: s, data: n, showToClient: i = !1, style: o, visibility: l } = t ?? {}, d = s ? kt(e, s) : `[TraceLog] ${e}`, c = r === "error" ? "error" : r === "warn" ? "warn" : "log";
|
|
165
165
|
if (!Ut(l, i))
|
|
166
166
|
return;
|
|
167
|
-
const g =
|
|
168
|
-
|
|
169
|
-
}, Ut = (r, e) => r === "critical" ? !0 : r === "qa" || e ? Vt() : !1,
|
|
167
|
+
const g = Ht(l, o), m = n !== void 0 ? ve(n) : void 0;
|
|
168
|
+
Ft(c, d, g, m);
|
|
169
|
+
}, Ut = (r, e) => r === "critical" ? !0 : r === "qa" || e ? Vt() : !1, Ht = (r, e) => e !== void 0 && e !== "" ? e : r === "critical" ? Dt : "", Ft = (r, e, t, s) => {
|
|
170
170
|
const n = t !== void 0 && t !== "", i = n ? `%c${e}` : e;
|
|
171
171
|
s !== void 0 ? n ? console[r](i, t, s) : console[r](i, s) : n ? console[r](i, t) : console[r](i);
|
|
172
|
-
},
|
|
172
|
+
}, ve = (r) => {
|
|
173
173
|
const e = {}, t = ["token", "password", "secret", "key", "apikey", "api_key", "sessionid", "session_id"];
|
|
174
174
|
for (const [s, n] of Object.entries(r)) {
|
|
175
175
|
const i = s.toLowerCase();
|
|
@@ -177,15 +177,15 @@ const nt = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8
|
|
|
177
177
|
e[s] = "[REDACTED]";
|
|
178
178
|
continue;
|
|
179
179
|
}
|
|
180
|
-
n !== null && typeof n == "object" && !Array.isArray(n) ? e[s] =
|
|
181
|
-
(o) => o !== null && typeof o == "object" && !Array.isArray(o) ?
|
|
180
|
+
n !== null && typeof n == "object" && !Array.isArray(n) ? e[s] = ve(n) : Array.isArray(n) ? e[s] = n.map(
|
|
181
|
+
(o) => o !== null && typeof o == "object" && !Array.isArray(o) ? ve(o) : o
|
|
182
182
|
) : e[s] = n;
|
|
183
183
|
}
|
|
184
184
|
return e;
|
|
185
185
|
};
|
|
186
|
-
let
|
|
186
|
+
let _e, ot;
|
|
187
187
|
const xt = () => {
|
|
188
|
-
typeof window < "u" && !
|
|
188
|
+
typeof window < "u" && !_e && (_e = window.matchMedia("(pointer: coarse)"), ot = window.matchMedia("(hover: none)"));
|
|
189
189
|
}, oe = "Unknown", $t = (r) => {
|
|
190
190
|
const e = r.userAgentData?.platform;
|
|
191
191
|
if (e != null && e !== "") {
|
|
@@ -213,16 +213,16 @@ const xt = () => {
|
|
|
213
213
|
try {
|
|
214
214
|
const r = navigator;
|
|
215
215
|
if (r.userAgentData != null && typeof r.userAgentData.mobile == "boolean") {
|
|
216
|
-
const
|
|
217
|
-
return
|
|
216
|
+
const d = r.userAgentData.platform;
|
|
217
|
+
return d != null && d !== "" && /ipad|tablet/i.test(d) ? A.Tablet : r.userAgentData.mobile ? A.Mobile : A.Desktop;
|
|
218
218
|
}
|
|
219
219
|
xt();
|
|
220
|
-
const e = window.innerWidth, t =
|
|
220
|
+
const e = window.innerWidth, t = _e?.matches ?? !1, s = ot?.matches ?? !1, n = "ontouchstart" in window || navigator.maxTouchPoints > 0, i = navigator.userAgent.toLowerCase(), o = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i), l = /tablet|ipad|android(?!.*mobile)/.test(i);
|
|
221
221
|
return e <= 767 || o && n ? A.Mobile : e >= 768 && e <= 1024 || l || t && s && n ? A.Tablet : A.Desktop;
|
|
222
222
|
} catch (r) {
|
|
223
223
|
return a("debug", "Device detection failed, defaulting to desktop", { error: r }), A.Desktop;
|
|
224
224
|
}
|
|
225
|
-
},
|
|
225
|
+
}, Gt = () => {
|
|
226
226
|
try {
|
|
227
227
|
const r = navigator;
|
|
228
228
|
return {
|
|
@@ -254,7 +254,7 @@ const xt = () => {
|
|
|
254
254
|
/:\/\/[^:/]+:([^@]+)@/gi,
|
|
255
255
|
// Sensitive URL query parameters (token=, password=, auth=, secret=, api_key=, etc.)
|
|
256
256
|
/[?&](token|password|passwd|auth|secret|secret_key|private_key|auth_key|api_key|apikey|access_token)=[^&\s]+/gi
|
|
257
|
-
],
|
|
257
|
+
], Ge = 500, Xe = 2e3, je = 5e3, ee = 50, Xt = ee * 2, lt = 1, jt = 1e3, Kt = 10, Ke = 5e3, zt = 6e4, Qt = 64, Mr = {
|
|
258
258
|
LCP: 2500,
|
|
259
259
|
// Good: ≤ 2.5s
|
|
260
260
|
FCP: 1800,
|
|
@@ -290,7 +290,7 @@ const xt = () => {
|
|
|
290
290
|
TTFB: 1800,
|
|
291
291
|
// Poor: > 1800ms
|
|
292
292
|
LONG_TASK: 50
|
|
293
|
-
},
|
|
293
|
+
}, ye = "needs-improvement", Qe = (r = ye) => {
|
|
294
294
|
switch (r) {
|
|
295
295
|
case "all":
|
|
296
296
|
return { LCP: 0, FCP: 0, CLS: 0, INP: 0, TTFB: 0, LONG_TASK: 0 };
|
|
@@ -302,7 +302,7 @@ const xt = () => {
|
|
|
302
302
|
default:
|
|
303
303
|
return ze;
|
|
304
304
|
}
|
|
305
|
-
}, qt = 1e3, Jt = 50, Zt = "2.
|
|
305
|
+
}, qt = 1e3, Jt = 50, Zt = "2.9.0", es = Zt, ct = () => typeof window < "u" && typeof sessionStorage < "u", ts = () => {
|
|
306
306
|
try {
|
|
307
307
|
const r = new URLSearchParams(window.location.search);
|
|
308
308
|
r.delete(rt);
|
|
@@ -314,22 +314,22 @@ const xt = () => {
|
|
|
314
314
|
if (!ct())
|
|
315
315
|
return !1;
|
|
316
316
|
try {
|
|
317
|
-
const e = new URLSearchParams(window.location.search).get(rt), t = sessionStorage.getItem(
|
|
317
|
+
const e = new URLSearchParams(window.location.search).get(rt), t = sessionStorage.getItem(G);
|
|
318
318
|
let s = null;
|
|
319
|
-
return e === Ue ? (s = !0, sessionStorage.setItem(
|
|
319
|
+
return e === Ue ? (s = !0, sessionStorage.setItem(G, "true"), a("info", "QA Mode ACTIVE", {
|
|
320
320
|
visibility: "qa",
|
|
321
321
|
style: nt
|
|
322
|
-
})) : e ===
|
|
322
|
+
})) : e === He && (s = !1, sessionStorage.setItem(G, "false"), a("info", "QA Mode DISABLED", {
|
|
323
323
|
visibility: "qa",
|
|
324
324
|
style: it
|
|
325
|
-
})), (e === Ue || e ===
|
|
325
|
+
})), (e === Ue || e === He) && ts(), s ?? t === "true";
|
|
326
326
|
} catch {
|
|
327
327
|
return !1;
|
|
328
328
|
}
|
|
329
329
|
}, rs = (r) => {
|
|
330
330
|
if (ct())
|
|
331
331
|
try {
|
|
332
|
-
sessionStorage.setItem(
|
|
332
|
+
sessionStorage.setItem(G, r ? "true" : "false"), a("info", r ? "QA Mode ACTIVE" : "QA Mode DISABLED", {
|
|
333
333
|
visibility: "qa",
|
|
334
334
|
style: r ? nt : it
|
|
335
335
|
});
|
|
@@ -354,7 +354,7 @@ const xt = () => {
|
|
|
354
354
|
return r.toLowerCase();
|
|
355
355
|
const t = e.slice(-2).join(".");
|
|
356
356
|
return ns.includes(t) ? e.slice(-3).join(".") : e.slice(-2).join(".");
|
|
357
|
-
}, is = (r, e) => r === e ? !0 : Ye(r) === Ye(e),
|
|
357
|
+
}, is = (r, e) => r === e ? !0 : Ye(r) === Ye(e), ge = () => {
|
|
358
358
|
const r = document.referrer;
|
|
359
359
|
if (!r)
|
|
360
360
|
return "Direct";
|
|
@@ -364,7 +364,7 @@ const xt = () => {
|
|
|
364
364
|
} catch (e) {
|
|
365
365
|
return a("debug", "Failed to parse referrer URL, using raw value", { error: e, data: { referrer: r } }), r;
|
|
366
366
|
}
|
|
367
|
-
},
|
|
367
|
+
}, pe = () => {
|
|
368
368
|
const r = new URLSearchParams(window.location.search), e = {};
|
|
369
369
|
return Lt.forEach((s) => {
|
|
370
370
|
const n = r.get(s);
|
|
@@ -433,15 +433,15 @@ const os = () => {
|
|
|
433
433
|
e.custom = t;
|
|
434
434
|
}
|
|
435
435
|
return e;
|
|
436
|
-
},
|
|
436
|
+
}, we = (r, e = []) => {
|
|
437
437
|
if (!r || typeof r != "string")
|
|
438
438
|
return a("warn", "Invalid URL provided to normalizeUrl", { data: { type: typeof r } }), r || "";
|
|
439
439
|
try {
|
|
440
440
|
const t = new URL(r), s = t.searchParams, n = [.../* @__PURE__ */ new Set([...At, ...e])];
|
|
441
441
|
let i = !1;
|
|
442
442
|
const o = [];
|
|
443
|
-
return n.forEach((
|
|
444
|
-
s.has(
|
|
443
|
+
return n.forEach((d) => {
|
|
444
|
+
s.has(d) && (s.delete(d), i = !0, o.push(d));
|
|
445
445
|
}), !i && r.includes("?") ? r : (t.search = s.toString(), t.toString());
|
|
446
446
|
} catch (t) {
|
|
447
447
|
return a("warn", "URL normalization failed, returning original", { error: t, data: { urlLength: r?.length } }), r;
|
|
@@ -462,7 +462,7 @@ const os = () => {
|
|
|
462
462
|
valueLength: r.length
|
|
463
463
|
}
|
|
464
464
|
}), e.trim();
|
|
465
|
-
},
|
|
465
|
+
}, be = (r, e = 0) => {
|
|
466
466
|
if (r == null)
|
|
467
467
|
return null;
|
|
468
468
|
if (typeof r == "string")
|
|
@@ -474,14 +474,14 @@ const os = () => {
|
|
|
474
474
|
if (e > 10)
|
|
475
475
|
return null;
|
|
476
476
|
if (Array.isArray(r))
|
|
477
|
-
return r.slice(0, 1e3).map((n) =>
|
|
477
|
+
return r.slice(0, 1e3).map((n) => be(n, e + 1)).filter((n) => n !== null);
|
|
478
478
|
if (typeof r == "object") {
|
|
479
479
|
const t = {}, n = Object.entries(r).slice(0, 200);
|
|
480
480
|
for (const [i, o] of n) {
|
|
481
481
|
const l = qe(i);
|
|
482
482
|
if (l) {
|
|
483
|
-
const
|
|
484
|
-
|
|
483
|
+
const d = be(o, e + 1);
|
|
484
|
+
d !== null && (t[l] = d);
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
487
|
return t;
|
|
@@ -491,7 +491,7 @@ const os = () => {
|
|
|
491
491
|
if (typeof r != "object" || r === null)
|
|
492
492
|
return {};
|
|
493
493
|
try {
|
|
494
|
-
const e =
|
|
494
|
+
const e = be(r);
|
|
495
495
|
return typeof e == "object" && e !== null ? e : {};
|
|
496
496
|
} catch (e) {
|
|
497
497
|
const t = e instanceof Error ? e.message : String(e);
|
|
@@ -499,69 +499,79 @@ const os = () => {
|
|
|
499
499
|
}
|
|
500
500
|
}, ds = (r) => {
|
|
501
501
|
if (r !== void 0 && (r === null || typeof r != "object"))
|
|
502
|
-
throw new
|
|
502
|
+
throw new p("Configuration must be an object", "config");
|
|
503
503
|
if (r) {
|
|
504
504
|
if (r.sessionTimeout !== void 0 && (typeof r.sessionTimeout != "number" || r.sessionTimeout < 3e4 || r.sessionTimeout > 864e5))
|
|
505
|
-
throw new Pt(
|
|
505
|
+
throw new Pt(E.INVALID_SESSION_TIMEOUT, "config");
|
|
506
506
|
if (r.globalMetadata !== void 0 && (typeof r.globalMetadata != "object" || r.globalMetadata === null))
|
|
507
|
-
throw new
|
|
507
|
+
throw new p(E.INVALID_GLOBAL_METADATA, "config");
|
|
508
508
|
if (r.integrations && hs(r.integrations), r.sensitiveQueryParams !== void 0) {
|
|
509
509
|
if (!Array.isArray(r.sensitiveQueryParams))
|
|
510
|
-
throw new
|
|
510
|
+
throw new p(E.INVALID_SENSITIVE_QUERY_PARAMS, "config");
|
|
511
511
|
for (const e of r.sensitiveQueryParams)
|
|
512
512
|
if (typeof e != "string")
|
|
513
|
-
throw new
|
|
513
|
+
throw new p("All sensitive query params must be strings", "config");
|
|
514
514
|
}
|
|
515
515
|
if (r.errorSampling !== void 0 && (typeof r.errorSampling != "number" || r.errorSampling < 0 || r.errorSampling > 1))
|
|
516
|
-
throw new We(
|
|
516
|
+
throw new We(E.INVALID_ERROR_SAMPLING_RATE, "config");
|
|
517
517
|
if (r.samplingRate !== void 0 && (typeof r.samplingRate != "number" || r.samplingRate < 0 || r.samplingRate > 1))
|
|
518
|
-
throw new We(
|
|
518
|
+
throw new We(E.INVALID_SAMPLING_RATE, "config");
|
|
519
519
|
if (r.primaryScrollSelector !== void 0) {
|
|
520
520
|
if (typeof r.primaryScrollSelector != "string" || !r.primaryScrollSelector.trim())
|
|
521
|
-
throw new
|
|
521
|
+
throw new p(E.INVALID_PRIMARY_SCROLL_SELECTOR, "config");
|
|
522
522
|
if (r.primaryScrollSelector !== "window")
|
|
523
523
|
try {
|
|
524
524
|
document.querySelector(r.primaryScrollSelector);
|
|
525
525
|
} catch {
|
|
526
|
-
throw new
|
|
527
|
-
`${
|
|
526
|
+
throw new p(
|
|
527
|
+
`${E.INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX}: "${r.primaryScrollSelector}"`,
|
|
528
528
|
"config"
|
|
529
529
|
);
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
532
|
if (r.pageViewThrottleMs !== void 0 && (typeof r.pageViewThrottleMs != "number" || r.pageViewThrottleMs < 0))
|
|
533
|
-
throw new
|
|
533
|
+
throw new p(E.INVALID_PAGE_VIEW_THROTTLE, "config");
|
|
534
534
|
if (r.clickThrottleMs !== void 0 && (typeof r.clickThrottleMs != "number" || r.clickThrottleMs < 0))
|
|
535
|
-
throw new
|
|
535
|
+
throw new p(E.INVALID_CLICK_THROTTLE, "config");
|
|
536
536
|
if (r.maxSameEventPerMinute !== void 0 && (typeof r.maxSameEventPerMinute != "number" || r.maxSameEventPerMinute <= 0))
|
|
537
|
-
throw new
|
|
537
|
+
throw new p(E.INVALID_MAX_SAME_EVENT_PER_MINUTE, "config");
|
|
538
538
|
if (r.sendIntervalMs !== void 0 && (!Number.isFinite(r.sendIntervalMs) || r.sendIntervalMs < 1e3 || r.sendIntervalMs > 6e4))
|
|
539
|
-
throw new
|
|
539
|
+
throw new p(E.INVALID_SEND_INTERVAL, "config");
|
|
540
|
+
if (r.flushOnSpaNavigation !== void 0 && typeof r.flushOnSpaNavigation != "boolean")
|
|
541
|
+
throw new p(
|
|
542
|
+
`Invalid flushOnSpaNavigation type: ${typeof r.flushOnSpaNavigation}. Must be a boolean`,
|
|
543
|
+
"config"
|
|
544
|
+
);
|
|
545
|
+
if (r.flushOnPageHidden !== void 0 && typeof r.flushOnPageHidden != "boolean")
|
|
546
|
+
throw new p(
|
|
547
|
+
`Invalid flushOnPageHidden type: ${typeof r.flushOnPageHidden}. Must be a boolean`,
|
|
548
|
+
"config"
|
|
549
|
+
);
|
|
540
550
|
if (r.viewport !== void 0 && us(r.viewport), r.webVitalsMode !== void 0) {
|
|
541
551
|
if (typeof r.webVitalsMode != "string")
|
|
542
|
-
throw new
|
|
552
|
+
throw new p(
|
|
543
553
|
`Invalid webVitalsMode type: ${typeof r.webVitalsMode}. Must be a string`,
|
|
544
554
|
"config"
|
|
545
555
|
);
|
|
546
556
|
const e = ["all", "needs-improvement", "poor"];
|
|
547
557
|
if (!e.includes(r.webVitalsMode))
|
|
548
|
-
throw new
|
|
558
|
+
throw new p(
|
|
549
559
|
`Invalid webVitalsMode: "${r.webVitalsMode}". Must be one of: ${e.join(", ")}`,
|
|
550
560
|
"config"
|
|
551
561
|
);
|
|
552
562
|
}
|
|
553
563
|
if (r.webVitalsThresholds !== void 0) {
|
|
554
564
|
if (typeof r.webVitalsThresholds != "object" || r.webVitalsThresholds === null || Array.isArray(r.webVitalsThresholds))
|
|
555
|
-
throw new
|
|
565
|
+
throw new p("webVitalsThresholds must be an object", "config");
|
|
556
566
|
const e = ["LCP", "FCP", "CLS", "INP", "TTFB", "LONG_TASK"];
|
|
557
567
|
for (const [t, s] of Object.entries(r.webVitalsThresholds)) {
|
|
558
568
|
if (!e.includes(t))
|
|
559
|
-
throw new
|
|
569
|
+
throw new p(
|
|
560
570
|
`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,
|
|
561
571
|
"config"
|
|
562
572
|
);
|
|
563
573
|
if (typeof s != "number" || !Number.isFinite(s) || s < 0)
|
|
564
|
-
throw new
|
|
574
|
+
throw new p(
|
|
565
575
|
`Invalid Web Vitals threshold value for ${t}: ${s}. Must be a non-negative finite number`,
|
|
566
576
|
"config"
|
|
567
577
|
);
|
|
@@ -570,41 +580,41 @@ const os = () => {
|
|
|
570
580
|
}
|
|
571
581
|
}, us = (r) => {
|
|
572
582
|
if (typeof r != "object" || r === null)
|
|
573
|
-
throw new
|
|
583
|
+
throw new p(E.INVALID_VIEWPORT_CONFIG, "config");
|
|
574
584
|
if (!r.elements || !Array.isArray(r.elements))
|
|
575
|
-
throw new
|
|
585
|
+
throw new p(E.INVALID_VIEWPORT_ELEMENTS, "config");
|
|
576
586
|
if (r.elements.length === 0)
|
|
577
|
-
throw new
|
|
587
|
+
throw new p(E.INVALID_VIEWPORT_ELEMENTS, "config");
|
|
578
588
|
const e = /* @__PURE__ */ new Set();
|
|
579
589
|
for (const t of r.elements) {
|
|
580
590
|
if (!t.selector || typeof t.selector != "string" || !t.selector.trim())
|
|
581
|
-
throw new
|
|
591
|
+
throw new p(E.INVALID_VIEWPORT_ELEMENT, "config");
|
|
582
592
|
const s = t.selector.trim();
|
|
583
593
|
if (e.has(s))
|
|
584
|
-
throw new
|
|
594
|
+
throw new p(
|
|
585
595
|
`Duplicate viewport selector found: "${s}". Each selector should appear only once.`,
|
|
586
596
|
"config"
|
|
587
597
|
);
|
|
588
598
|
if (e.add(s), t.id !== void 0 && (typeof t.id != "string" || !t.id.trim()))
|
|
589
|
-
throw new
|
|
599
|
+
throw new p(E.INVALID_VIEWPORT_ELEMENT_ID, "config");
|
|
590
600
|
if (t.name !== void 0 && (typeof t.name != "string" || !t.name.trim()))
|
|
591
|
-
throw new
|
|
601
|
+
throw new p(E.INVALID_VIEWPORT_ELEMENT_NAME, "config");
|
|
592
602
|
}
|
|
593
603
|
if (r.threshold !== void 0 && (typeof r.threshold != "number" || r.threshold < 0 || r.threshold > 1))
|
|
594
|
-
throw new
|
|
604
|
+
throw new p(E.INVALID_VIEWPORT_THRESHOLD, "config");
|
|
595
605
|
if (r.minDwellTime !== void 0 && (typeof r.minDwellTime != "number" || r.minDwellTime < 0))
|
|
596
|
-
throw new
|
|
606
|
+
throw new p(E.INVALID_VIEWPORT_MIN_DWELL_TIME, "config");
|
|
597
607
|
if (r.cooldownPeriod !== void 0 && (typeof r.cooldownPeriod != "number" || r.cooldownPeriod < 0))
|
|
598
|
-
throw new
|
|
608
|
+
throw new p(E.INVALID_VIEWPORT_COOLDOWN_PERIOD, "config");
|
|
599
609
|
if (r.maxTrackedElements !== void 0 && (typeof r.maxTrackedElements != "number" || r.maxTrackedElements <= 0))
|
|
600
|
-
throw new
|
|
610
|
+
throw new p(E.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS, "config");
|
|
601
611
|
}, hs = (r) => {
|
|
602
612
|
if (r) {
|
|
603
613
|
if (r.tracelog && (!r.tracelog.projectId || typeof r.tracelog.projectId != "string" || r.tracelog.projectId.trim() === ""))
|
|
604
|
-
throw new N(
|
|
614
|
+
throw new N(E.INVALID_TRACELOG_PROJECT_ID, "config");
|
|
605
615
|
if (r.custom) {
|
|
606
616
|
if (!r.custom.collectApiUrl || typeof r.custom.collectApiUrl != "string" || r.custom.collectApiUrl.trim() === "")
|
|
607
|
-
throw new N(
|
|
617
|
+
throw new N(E.INVALID_CUSTOM_API_URL, "config");
|
|
608
618
|
if (r.custom.allowHttp !== void 0 && typeof r.custom.allowHttp != "boolean")
|
|
609
619
|
throw new N("allowHttp must be a boolean", "config");
|
|
610
620
|
const e = r.custom.collectApiUrl.trim();
|
|
@@ -633,7 +643,9 @@ const os = () => {
|
|
|
633
643
|
pageViewThrottleMs: r?.pageViewThrottleMs ?? 1e3,
|
|
634
644
|
clickThrottleMs: r?.clickThrottleMs ?? 300,
|
|
635
645
|
maxSameEventPerMinute: r?.maxSameEventPerMinute ?? 60,
|
|
636
|
-
sendIntervalMs: r?.sendIntervalMs ?? 1e4
|
|
646
|
+
sendIntervalMs: r?.sendIntervalMs ?? 1e4,
|
|
647
|
+
flushOnSpaNavigation: r?.flushOnSpaNavigation ?? !1,
|
|
648
|
+
flushOnPageHidden: r?.flushOnPageHidden ?? !0
|
|
637
649
|
};
|
|
638
650
|
return e.integrations?.custom && (e.integrations.custom = {
|
|
639
651
|
...e.integrations.custom,
|
|
@@ -645,12 +657,12 @@ const os = () => {
|
|
|
645
657
|
cooldownPeriod: e.viewport.cooldownPeriod ?? 6e4,
|
|
646
658
|
maxTrackedElements: e.viewport.maxTrackedElements ?? 100
|
|
647
659
|
}), e;
|
|
648
|
-
},
|
|
660
|
+
}, Le = (r, e = /* @__PURE__ */ new Set()) => {
|
|
649
661
|
if (r == null)
|
|
650
662
|
return !0;
|
|
651
663
|
const t = typeof r;
|
|
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) =>
|
|
653
|
-
}, ms = (r) => typeof r != "object" || r === null ? !1 :
|
|
664
|
+
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) => Le(s, e)) : t === "object" ? Object.values(r).every((s) => Le(s, e)) : !1);
|
|
665
|
+
}, ms = (r) => typeof r != "object" || r === null ? !1 : Le(r), ht = (r) => {
|
|
654
666
|
if (typeof r != "object" || r === null || Array.isArray(r)) return;
|
|
655
667
|
const e = {};
|
|
656
668
|
for (const [t, s] of Object.entries(r))
|
|
@@ -697,24 +709,24 @@ const os = () => {
|
|
|
697
709
|
valid: !1,
|
|
698
710
|
error: `${n}: object has too many keys (max 100 keys).`
|
|
699
711
|
};
|
|
700
|
-
for (const [
|
|
701
|
-
if (Array.isArray(
|
|
702
|
-
if (
|
|
712
|
+
for (const [d, c] of Object.entries(s)) {
|
|
713
|
+
if (Array.isArray(c)) {
|
|
714
|
+
if (c.length > 500)
|
|
703
715
|
return {
|
|
704
716
|
valid: !1,
|
|
705
|
-
error: `${n}: array property "${
|
|
717
|
+
error: `${n}: array property "${d}" is too large (max 500 items).`
|
|
706
718
|
};
|
|
707
|
-
for (const f of
|
|
719
|
+
for (const f of c)
|
|
708
720
|
if (typeof f == "string" && f.length > 500)
|
|
709
721
|
return {
|
|
710
722
|
valid: !1,
|
|
711
|
-
error: `${n}: array property "${
|
|
723
|
+
error: `${n}: array property "${d}" contains strings that are too long (max 500 characters).`
|
|
712
724
|
};
|
|
713
725
|
}
|
|
714
|
-
if (typeof
|
|
726
|
+
if (typeof c == "string" && c.length > 1e3)
|
|
715
727
|
return {
|
|
716
728
|
valid: !1,
|
|
717
|
-
error: `${n}: property "${
|
|
729
|
+
error: `${n}: property "${d}" is too long (max 1000 characters).`
|
|
718
730
|
};
|
|
719
731
|
}
|
|
720
732
|
return {
|
|
@@ -761,7 +773,7 @@ const os = () => {
|
|
|
761
773
|
}
|
|
762
774
|
}), s;
|
|
763
775
|
};
|
|
764
|
-
class
|
|
776
|
+
class Ss {
|
|
765
777
|
listeners = /* @__PURE__ */ new Map();
|
|
766
778
|
/**
|
|
767
779
|
* Subscribes to an event channel
|
|
@@ -889,7 +901,7 @@ function mt(r, e, t) {
|
|
|
889
901
|
}), r;
|
|
890
902
|
}
|
|
891
903
|
}
|
|
892
|
-
function
|
|
904
|
+
function Es(r, e, t) {
|
|
893
905
|
return r.map((s) => mt(s, e, t)).filter((s) => s !== null);
|
|
894
906
|
}
|
|
895
907
|
function gt(r, e, t) {
|
|
@@ -908,7 +920,7 @@ function gt(r, e, t) {
|
|
|
908
920
|
}), r;
|
|
909
921
|
}
|
|
910
922
|
}
|
|
911
|
-
const
|
|
923
|
+
const Se = { config: {} };
|
|
912
924
|
class _ {
|
|
913
925
|
/**
|
|
914
926
|
* Retrieves a value from global state.
|
|
@@ -927,7 +939,7 @@ class _ {
|
|
|
927
939
|
* ```
|
|
928
940
|
*/
|
|
929
941
|
get(e) {
|
|
930
|
-
return
|
|
942
|
+
return Se[e];
|
|
931
943
|
}
|
|
932
944
|
/**
|
|
933
945
|
* Sets a value in global state.
|
|
@@ -947,7 +959,7 @@ class _ {
|
|
|
947
959
|
* ```
|
|
948
960
|
*/
|
|
949
961
|
set(e, t) {
|
|
950
|
-
|
|
962
|
+
Se[e] = t;
|
|
951
963
|
}
|
|
952
964
|
/**
|
|
953
965
|
* Returns an immutable snapshot of the entire global state.
|
|
@@ -964,7 +976,7 @@ class _ {
|
|
|
964
976
|
* ```
|
|
965
977
|
*/
|
|
966
978
|
getState() {
|
|
967
|
-
return { ...
|
|
979
|
+
return { ...Se };
|
|
968
980
|
}
|
|
969
981
|
}
|
|
970
982
|
class Ze extends _ {
|
|
@@ -1373,7 +1385,7 @@ class Ze extends _ {
|
|
|
1373
1385
|
const t = this.transformers.beforeSend;
|
|
1374
1386
|
if (!t)
|
|
1375
1387
|
return e;
|
|
1376
|
-
const s =
|
|
1388
|
+
const s = Es(
|
|
1377
1389
|
e.events,
|
|
1378
1390
|
t,
|
|
1379
1391
|
this.integrationId || "SenderManager"
|
|
@@ -1503,50 +1515,50 @@ class Ze extends _ {
|
|
|
1503
1515
|
}
|
|
1504
1516
|
}), !1;
|
|
1505
1517
|
if (this.consecutiveNetworkFailures >= 3) {
|
|
1506
|
-
const
|
|
1507
|
-
if (
|
|
1518
|
+
const c = Date.now() - this.circuitOpenedAt;
|
|
1519
|
+
if (c < 12e4)
|
|
1508
1520
|
return a("debug", `Network circuit open, skipping send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1509
1521
|
data: {
|
|
1510
1522
|
consecutiveNetworkFailures: this.consecutiveNetworkFailures,
|
|
1511
|
-
cooldownRemainingMs: 12e4 -
|
|
1523
|
+
cooldownRemainingMs: 12e4 - c
|
|
1512
1524
|
}
|
|
1513
1525
|
}), !1;
|
|
1514
1526
|
}
|
|
1515
1527
|
const { url: i, payload: o } = this.prepareRequest(n);
|
|
1516
|
-
let l = !0,
|
|
1517
|
-
for (let
|
|
1528
|
+
let l = !0, d = !1;
|
|
1529
|
+
for (let c = 1; c <= 3; c++)
|
|
1518
1530
|
try {
|
|
1519
|
-
return (await this.sendWithTimeout(i, o)).ok ? (
|
|
1531
|
+
return (await this.sendWithTimeout(i, o)).ok ? (c > 1 && a(
|
|
1520
1532
|
"info",
|
|
1521
|
-
`Send succeeded after ${
|
|
1533
|
+
`Send succeeded after ${c - 1} retry attempt(s)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1522
1534
|
{
|
|
1523
|
-
data: { events: n.events.length, attempt:
|
|
1535
|
+
data: { events: n.events.length, attempt: c }
|
|
1524
1536
|
}
|
|
1525
1537
|
), this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, !0) : !1;
|
|
1526
1538
|
} catch (f) {
|
|
1527
|
-
const g =
|
|
1539
|
+
const g = c === 3;
|
|
1528
1540
|
if (f instanceof O)
|
|
1529
1541
|
throw this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, f;
|
|
1530
1542
|
if (f instanceof re) {
|
|
1531
|
-
this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, l = !1,
|
|
1532
|
-
data: { events: e.events.length, attempt:
|
|
1543
|
+
this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, l = !1, d = !0, this.armRateLimitCooldown(Date.now() + 6e4), a("warn", `Rate limited, skipping retries${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1544
|
+
data: { events: e.events.length, attempt: c, cooldownMs: 6e4 }
|
|
1533
1545
|
});
|
|
1534
1546
|
break;
|
|
1535
1547
|
}
|
|
1536
|
-
if (f instanceof ne || (l = !1), f instanceof TypeError || (
|
|
1548
|
+
if (f instanceof ne || (l = !1), f instanceof TypeError || (d = !0), a(
|
|
1537
1549
|
g ? "error" : "warn",
|
|
1538
|
-
`Send attempt ${
|
|
1550
|
+
`Send attempt ${c} failed${this.integrationId ? ` [${this.integrationId}]` : ""}${g ? " (all retries exhausted)" : ", will retry"}`,
|
|
1539
1551
|
{
|
|
1540
1552
|
error: f,
|
|
1541
1553
|
data: {
|
|
1542
1554
|
events: e.events.length,
|
|
1543
1555
|
url: i.replace(/\/\/[^/]+/, "//[DOMAIN]"),
|
|
1544
|
-
attempt:
|
|
1556
|
+
attempt: c,
|
|
1545
1557
|
maxAttempts: 3
|
|
1546
1558
|
}
|
|
1547
1559
|
}
|
|
1548
1560
|
), !g) {
|
|
1549
|
-
await this.backoffDelay(
|
|
1561
|
+
await this.backoffDelay(c);
|
|
1550
1562
|
continue;
|
|
1551
1563
|
}
|
|
1552
1564
|
return l ? (a(
|
|
@@ -1555,7 +1567,7 @@ class Ze extends _ {
|
|
|
1555
1567
|
{
|
|
1556
1568
|
data: { events: n.events.length }
|
|
1557
1569
|
}
|
|
1558
|
-
), !1) : (
|
|
1570
|
+
), !1) : (d ? (this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0) : (this.consecutiveNetworkFailures = Math.min(
|
|
1559
1571
|
this.consecutiveNetworkFailures + 1,
|
|
1560
1572
|
3
|
|
1561
1573
|
), this.consecutiveNetworkFailures >= 3 && (this.circuitOpenedAt = Date.now())), !1);
|
|
@@ -1606,8 +1618,8 @@ class Ze extends _ {
|
|
|
1606
1618
|
});
|
|
1607
1619
|
if (!l.ok) {
|
|
1608
1620
|
if (l.status >= 400 && l.status < 500 && l.status !== 408 && l.status !== 429) {
|
|
1609
|
-
const
|
|
1610
|
-
throw new O(f, l.status,
|
|
1621
|
+
const c = await this.readTraceLogErrorCode(l), f = c ? `HTTP ${l.status}: ${l.statusText} (${c})` : `HTTP ${l.status}: ${l.statusText}`;
|
|
1622
|
+
throw new O(f, l.status, c);
|
|
1611
1623
|
}
|
|
1612
1624
|
throw l.status === 429 ? new re(`HTTP 429: ${l.statusText}`) : new Error(`HTTP ${l.status}: ${l.statusText}`);
|
|
1613
1625
|
}
|
|
@@ -1678,17 +1690,17 @@ class Ze extends _ {
|
|
|
1678
1690
|
}
|
|
1679
1691
|
}
|
|
1680
1692
|
), this.persistEvents(t), !1;
|
|
1681
|
-
const
|
|
1693
|
+
const d = new Blob([l], { type: "application/json" });
|
|
1682
1694
|
if (!this.isSendBeaconAvailable())
|
|
1683
1695
|
return a(
|
|
1684
1696
|
"warn",
|
|
1685
1697
|
`sendBeacon not available, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1686
1698
|
), this.persistEvents(t), !1;
|
|
1687
|
-
const
|
|
1688
|
-
return
|
|
1699
|
+
const c = navigator.sendBeacon(o, d);
|
|
1700
|
+
return c || (a(
|
|
1689
1701
|
"warn",
|
|
1690
1702
|
`sendBeacon rejected request, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1691
|
-
), this.persistEvents(t)),
|
|
1703
|
+
), this.persistEvents(t)), c;
|
|
1692
1704
|
}
|
|
1693
1705
|
/**
|
|
1694
1706
|
* Prepares request by enriching payload with metadata and serializing to JSON.
|
|
@@ -2064,6 +2076,9 @@ class vs extends _ {
|
|
|
2064
2076
|
rateLimitCounter = 0;
|
|
2065
2077
|
rateLimitWindowStart = 0;
|
|
2066
2078
|
lastSessionId = null;
|
|
2079
|
+
// Set when a sync flush is requested mid-async-send; drained by the async
|
|
2080
|
+
// finally block. See `drainPendingSyncFlush` for the full rationale.
|
|
2081
|
+
pendingSyncFlush = !1;
|
|
2067
2082
|
sessionEventCounts = {
|
|
2068
2083
|
total: 0,
|
|
2069
2084
|
[u.CLICK]: 0,
|
|
@@ -2100,8 +2115,8 @@ class vs extends _ {
|
|
|
2100
2115
|
i,
|
|
2101
2116
|
o
|
|
2102
2117
|
)
|
|
2103
|
-
), this.saveSessionCountsDebounced = this.debounce((
|
|
2104
|
-
this.saveSessionCounts(
|
|
2118
|
+
), this.saveSessionCountsDebounced = this.debounce((d) => {
|
|
2119
|
+
this.saveSessionCounts(d);
|
|
2105
2120
|
}, 500), this.cleanupExpiredSessionCounts();
|
|
2106
2121
|
}
|
|
2107
2122
|
/**
|
|
@@ -2211,8 +2226,8 @@ class vs extends _ {
|
|
|
2211
2226
|
click_data: i,
|
|
2212
2227
|
custom_event: o,
|
|
2213
2228
|
web_vitals: l,
|
|
2214
|
-
error_data:
|
|
2215
|
-
viewport_data:
|
|
2229
|
+
error_data: d,
|
|
2230
|
+
viewport_data: c,
|
|
2216
2231
|
page_view: f
|
|
2217
2232
|
}) {
|
|
2218
2233
|
if (!e) {
|
|
@@ -2237,108 +2252,108 @@ class vs extends _ {
|
|
|
2237
2252
|
click_data: i,
|
|
2238
2253
|
custom_event: o,
|
|
2239
2254
|
web_vitals: l,
|
|
2240
|
-
error_data:
|
|
2241
|
-
viewport_data:
|
|
2255
|
+
error_data: d,
|
|
2256
|
+
viewport_data: c,
|
|
2242
2257
|
page_view: f
|
|
2243
2258
|
});
|
|
2244
2259
|
return;
|
|
2245
2260
|
}
|
|
2246
2261
|
this.lastSessionId !== g && (this.lastSessionId = g, this.sessionEventCounts = this.loadSessionCounts(g));
|
|
2247
|
-
const
|
|
2248
|
-
if (
|
|
2262
|
+
const m = e === u.SESSION_START;
|
|
2263
|
+
if (m && a("debug", "Processing SESSION_START event", {
|
|
2249
2264
|
data: { sessionId: g }
|
|
2250
|
-
}), !
|
|
2265
|
+
}), !m && !this.checkRateLimit())
|
|
2251
2266
|
return;
|
|
2252
|
-
const
|
|
2253
|
-
if (!
|
|
2267
|
+
const S = e;
|
|
2268
|
+
if (!m) {
|
|
2254
2269
|
if (this.sessionEventCounts.total >= 1e3) {
|
|
2255
2270
|
a("warn", "Session event limit reached", {
|
|
2256
2271
|
data: {
|
|
2257
|
-
type:
|
|
2272
|
+
type: S,
|
|
2258
2273
|
total: this.sessionEventCounts.total,
|
|
2259
2274
|
limit: 1e3
|
|
2260
2275
|
}
|
|
2261
2276
|
});
|
|
2262
2277
|
return;
|
|
2263
2278
|
}
|
|
2264
|
-
const
|
|
2265
|
-
if (
|
|
2266
|
-
const
|
|
2267
|
-
if (
|
|
2279
|
+
const I = this.getTypeLimitForEvent(S);
|
|
2280
|
+
if (I) {
|
|
2281
|
+
const fe = this.sessionEventCounts[S];
|
|
2282
|
+
if (fe !== void 0 && fe >= I) {
|
|
2268
2283
|
a("warn", "Session event type limit reached", {
|
|
2269
2284
|
data: {
|
|
2270
|
-
type:
|
|
2271
|
-
count:
|
|
2272
|
-
limit:
|
|
2285
|
+
type: S,
|
|
2286
|
+
count: fe,
|
|
2287
|
+
limit: I
|
|
2273
2288
|
}
|
|
2274
2289
|
});
|
|
2275
2290
|
return;
|
|
2276
2291
|
}
|
|
2277
2292
|
}
|
|
2278
2293
|
}
|
|
2279
|
-
if (
|
|
2280
|
-
const
|
|
2281
|
-
if (!this.checkPerEventRateLimit(o.name,
|
|
2294
|
+
if (S === u.CUSTOM && o?.name) {
|
|
2295
|
+
const I = this.get("config")?.maxSameEventPerMinute ?? 60;
|
|
2296
|
+
if (!this.checkPerEventRateLimit(o.name, I))
|
|
2282
2297
|
return;
|
|
2283
2298
|
}
|
|
2284
|
-
const
|
|
2285
|
-
type:
|
|
2299
|
+
const he = S === u.SESSION_START, Q = t || this.get("pageUrl"), U = this.buildEventPayload({
|
|
2300
|
+
type: S,
|
|
2286
2301
|
page_url: Q,
|
|
2287
2302
|
from_page_url: s,
|
|
2288
2303
|
scroll_data: n,
|
|
2289
2304
|
click_data: i,
|
|
2290
2305
|
custom_event: o,
|
|
2291
2306
|
web_vitals: l,
|
|
2292
|
-
error_data:
|
|
2293
|
-
viewport_data:
|
|
2307
|
+
error_data: d,
|
|
2308
|
+
viewport_data: c,
|
|
2294
2309
|
page_view: f
|
|
2295
2310
|
});
|
|
2296
|
-
if (
|
|
2297
|
-
if (
|
|
2298
|
-
const
|
|
2299
|
-
if (!
|
|
2311
|
+
if (U && !(!m && !this.shouldSample())) {
|
|
2312
|
+
if (he) {
|
|
2313
|
+
const I = this.get("sessionId");
|
|
2314
|
+
if (!I) {
|
|
2300
2315
|
a("error", "Session start event requires sessionId - event will be ignored");
|
|
2301
2316
|
return;
|
|
2302
2317
|
}
|
|
2303
2318
|
if (this.get("hasStartSession")) {
|
|
2304
2319
|
a("debug", "Duplicate session_start detected", {
|
|
2305
|
-
data: { sessionId:
|
|
2320
|
+
data: { sessionId: I }
|
|
2306
2321
|
});
|
|
2307
2322
|
return;
|
|
2308
2323
|
}
|
|
2309
2324
|
this.set("hasStartSession", !0);
|
|
2310
2325
|
}
|
|
2311
|
-
if (!this.isDuplicateEvent(
|
|
2326
|
+
if (!this.isDuplicateEvent(U)) {
|
|
2312
2327
|
if (this.get("mode") === ie.QA) {
|
|
2313
|
-
if (
|
|
2328
|
+
if (S === u.CUSTOM && o) {
|
|
2314
2329
|
a("info", `Custom Event: ${o.name}`, {
|
|
2315
2330
|
visibility: "qa",
|
|
2316
2331
|
data: {
|
|
2317
2332
|
name: o.name,
|
|
2318
2333
|
...o.metadata && { metadata: o.metadata }
|
|
2319
2334
|
}
|
|
2320
|
-
}), this.emitEvent(
|
|
2335
|
+
}), this.emitEvent(U);
|
|
2321
2336
|
return;
|
|
2322
2337
|
}
|
|
2323
|
-
if (
|
|
2324
|
-
const
|
|
2325
|
-
a("info", `Viewport Visible: ${
|
|
2338
|
+
if (S === u.VIEWPORT_VISIBLE && c) {
|
|
2339
|
+
const I = c.name || c.id || c.selector;
|
|
2340
|
+
a("info", `Viewport Visible: ${I}`, {
|
|
2326
2341
|
visibility: "qa",
|
|
2327
2342
|
data: {
|
|
2328
|
-
selector:
|
|
2329
|
-
...
|
|
2330
|
-
...
|
|
2331
|
-
visibilityRatio:
|
|
2332
|
-
dwellTime:
|
|
2343
|
+
selector: c.selector,
|
|
2344
|
+
...c.name && { name: c.name },
|
|
2345
|
+
...c.id && { id: c.id },
|
|
2346
|
+
visibilityRatio: c.visibilityRatio,
|
|
2347
|
+
dwellTime: c.dwellTime
|
|
2333
2348
|
}
|
|
2334
|
-
}), this.emitEvent(
|
|
2349
|
+
}), this.emitEvent(U);
|
|
2335
2350
|
return;
|
|
2336
2351
|
}
|
|
2337
2352
|
}
|
|
2338
|
-
if (this.addToQueue(
|
|
2339
|
-
this.sessionEventCounts.total++, this.sessionEventCounts[
|
|
2340
|
-
const
|
|
2341
|
-
|
|
2353
|
+
if (this.addToQueue(U), !m) {
|
|
2354
|
+
this.sessionEventCounts.total++, this.sessionEventCounts[S] !== void 0 && this.sessionEventCounts[S]++;
|
|
2355
|
+
const I = this.get("sessionId");
|
|
2356
|
+
I && this.saveSessionCountsDebounced && this.saveSessionCountsDebounced(I);
|
|
2342
2357
|
}
|
|
2343
2358
|
}
|
|
2344
2359
|
}
|
|
@@ -2378,7 +2393,7 @@ class vs extends _ {
|
|
|
2378
2393
|
* @see src/managers/README.md (lines 5-75) for cleanup details
|
|
2379
2394
|
*/
|
|
2380
2395
|
stop() {
|
|
2381
|
-
this.clearSendTimeout(), this.sendInProgress = !1, this.consecutiveSendFailures = 0;
|
|
2396
|
+
this.clearSendTimeout(), this.sendInProgress = !1, this.pendingSyncFlush = !1, this.consecutiveSendFailures = 0;
|
|
2382
2397
|
const e = this.get("sessionId");
|
|
2383
2398
|
e && this.saveSessionCounts(e), this.eventsQueue = [], this.pendingEventsBuffer = [], this.recentEventFingerprints.clear(), this.rateLimitCounter = 0, this.rateLimitWindowStart = 0, this.perEventRateLimits.clear(), this.sessionEventCounts = {
|
|
2384
2399
|
total: 0,
|
|
@@ -2411,7 +2426,10 @@ class vs extends _ {
|
|
|
2411
2426
|
* **Note**: For page unload, use `flushImmediatelySync()` instead,
|
|
2412
2427
|
* which uses `sendBeacon()` for guaranteed delivery.
|
|
2413
2428
|
*
|
|
2414
|
-
* @returns Promise resolving to `true` if
|
|
2429
|
+
* @returns Promise resolving to `true` if at least one integration accepted
|
|
2430
|
+
* the batch during this call (optimistic removal — failures
|
|
2431
|
+
* persist per-integration for retry). `false` if no events, all
|
|
2432
|
+
* senders failed, or a flush is already in flight.
|
|
2415
2433
|
*
|
|
2416
2434
|
* @example
|
|
2417
2435
|
* ```typescript
|
|
@@ -2449,7 +2467,14 @@ class vs extends _ {
|
|
|
2449
2467
|
* - No retry on failure (sendBeacon is fire-and-forget)
|
|
2450
2468
|
* - 64KB payload limit (large batches may be truncated)
|
|
2451
2469
|
*
|
|
2452
|
-
*
|
|
2470
|
+
* **In-flight contract**: if an async send is already running this call is
|
|
2471
|
+
* deferred (queued for replay in the async send's `finally` block) and
|
|
2472
|
+
* returns `false` — nothing has been delivered yet at the point of return.
|
|
2473
|
+
* Mirrors `flushImmediately()`'s behaviour for the same condition.
|
|
2474
|
+
*
|
|
2475
|
+
* @returns `true` if at least one integration accepted the beacon batch
|
|
2476
|
+
* *during this call*, `false` otherwise (no events, all senders
|
|
2477
|
+
* failed, or the call was deferred behind an in-flight async send)
|
|
2453
2478
|
*
|
|
2454
2479
|
* @example
|
|
2455
2480
|
* ```typescript
|
|
@@ -2514,7 +2539,7 @@ class vs extends _ {
|
|
|
2514
2539
|
* @internal Used by test-bridge.ts for test inspection
|
|
2515
2540
|
*/
|
|
2516
2541
|
getQueueEvents() {
|
|
2517
|
-
return
|
|
2542
|
+
return this.eventsQueue.map(({ _session_id: e, ...t }) => t);
|
|
2518
2543
|
}
|
|
2519
2544
|
/**
|
|
2520
2545
|
* Triggers immediate queue flush (test utility).
|
|
@@ -2597,107 +2622,221 @@ class vs extends _ {
|
|
|
2597
2622
|
isSuccessfulResult(e) {
|
|
2598
2623
|
return e.status === "fulfilled" && e.value === !0;
|
|
2599
2624
|
}
|
|
2625
|
+
/**
|
|
2626
|
+
* Groups the queue by frozen `_session_id`, preserving insertion order.
|
|
2627
|
+
* Single pass — `buildBatchesWithIds()` builds one batch + one eventIds list
|
|
2628
|
+
* per group, so the grouping cost is O(N) per flush regardless of session
|
|
2629
|
+
* count.
|
|
2630
|
+
*
|
|
2631
|
+
* **Self-heal**: any entry missing `_session_id` (an internal invariant
|
|
2632
|
+
* violation — `buildEventPayload` always stamps it) is removed from the
|
|
2633
|
+
* queue rather than left behind, otherwise a single corrupted entry would
|
|
2634
|
+
* keep `eventsQueue.length > 0` forever and re-trigger periodic sends.
|
|
2635
|
+
*/
|
|
2636
|
+
groupQueuedEventsBySession() {
|
|
2637
|
+
const e = /* @__PURE__ */ new Map(), t = [];
|
|
2638
|
+
for (const s of this.eventsQueue) {
|
|
2639
|
+
if (!s._session_id) {
|
|
2640
|
+
a("debug", "Queued event missing _session_id, dropping", {
|
|
2641
|
+
data: { eventId: s.id, type: s.type }
|
|
2642
|
+
}), t.push(s.id);
|
|
2643
|
+
continue;
|
|
2644
|
+
}
|
|
2645
|
+
const n = e.get(s._session_id);
|
|
2646
|
+
n ? n.push(s) : e.set(s._session_id, [s]);
|
|
2647
|
+
}
|
|
2648
|
+
return t.length > 0 && this.removeProcessedEvents(t), e;
|
|
2649
|
+
}
|
|
2650
|
+
/**
|
|
2651
|
+
* Builds a parallel list of `(batch, eventIds)` for sending. The eventIds are
|
|
2652
|
+
* the original `_session_id`-tagged event IDs in the queue that map to this
|
|
2653
|
+
* batch — used for optimistic removal. We can't read them off the wrapper's
|
|
2654
|
+
* `events[]` because dedup may have removed some signatures.
|
|
2655
|
+
*/
|
|
2656
|
+
buildBatchesWithIds() {
|
|
2657
|
+
const e = this.groupQueuedEventsBySession();
|
|
2658
|
+
if (e.size === 0) return [];
|
|
2659
|
+
const t = [];
|
|
2660
|
+
for (const [s, n] of e)
|
|
2661
|
+
t.push({
|
|
2662
|
+
batch: this.buildBatchFromGroup(s, n),
|
|
2663
|
+
eventIds: n.map((i) => i.id)
|
|
2664
|
+
});
|
|
2665
|
+
return t;
|
|
2666
|
+
}
|
|
2600
2667
|
flushEvents(e) {
|
|
2601
2668
|
if (this.eventsQueue.length === 0)
|
|
2602
2669
|
return e ? !0 : Promise.resolve(!0);
|
|
2603
2670
|
if (!e && this.sendInProgress)
|
|
2604
2671
|
return a("debug", "Async flush skipped: send already in progress"), Promise.resolve(!1);
|
|
2605
|
-
const t = this.
|
|
2606
|
-
if (
|
|
2607
|
-
return
|
|
2608
|
-
if (
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2672
|
+
const t = this.buildBatchesWithIds();
|
|
2673
|
+
if (t.length === 0)
|
|
2674
|
+
return e ? !0 : Promise.resolve(!0);
|
|
2675
|
+
if (this.dataSenders.length === 0) {
|
|
2676
|
+
for (const { batch: s, eventIds: n } of t)
|
|
2677
|
+
this.removeProcessedEvents(n), this.emitEventsQueue(s);
|
|
2678
|
+
return this.clearSendTimeout(), e ? !0 : Promise.resolve(!0);
|
|
2679
|
+
}
|
|
2680
|
+
if (e && this.sendInProgress) {
|
|
2681
|
+
const s = t.reduce((n, i) => n + i.eventIds.length, 0);
|
|
2682
|
+
return this.pendingSyncFlush = !0, a("debug", "Sync flush deferred: async send in-flight, will retry on settle", {
|
|
2683
|
+
data: { eventCount: s }
|
|
2684
|
+
}), !1;
|
|
2685
|
+
}
|
|
2612
2686
|
if (e) {
|
|
2613
|
-
const
|
|
2614
|
-
return
|
|
2615
|
-
data: { eventCount: n.length }
|
|
2616
|
-
})), o;
|
|
2617
|
-
} else {
|
|
2618
|
-
const i = this.dataSenders.map(
|
|
2619
|
-
async (o) => o.sendEventsQueue(t, {
|
|
2620
|
-
onSuccess: () => {
|
|
2621
|
-
},
|
|
2622
|
-
onFailure: () => {
|
|
2623
|
-
}
|
|
2624
|
-
})
|
|
2625
|
-
);
|
|
2626
|
-
return Promise.allSettled(i).then((o) => {
|
|
2627
|
-
const l = o.some((c) => this.isSuccessfulResult(c));
|
|
2628
|
-
return l ? (this.removeProcessedEvents(n), this.clearSendTimeout(), this.emitEventsQueue(t)) : a("debug", "Async flush complete failure, events kept in queue for retry", {
|
|
2629
|
-
data: { eventCount: s.length }
|
|
2630
|
-
}), l;
|
|
2631
|
-
});
|
|
2687
|
+
const s = t.map(({ batch: n, eventIds: i }) => this.sendBatchSync(n, i));
|
|
2688
|
+
return this.settleSendTimeout(), s.some(Boolean);
|
|
2632
2689
|
}
|
|
2690
|
+
return this.sendInProgress = !0, (async () => {
|
|
2691
|
+
try {
|
|
2692
|
+
const s = await Promise.all(
|
|
2693
|
+
t.map(async ({ batch: n, eventIds: i }) => this.sendBatchAsync(n, i))
|
|
2694
|
+
);
|
|
2695
|
+
return this.settleSendTimeout(), s.some(Boolean);
|
|
2696
|
+
} finally {
|
|
2697
|
+
this.sendInProgress = !1, this.drainPendingSyncFlush();
|
|
2698
|
+
}
|
|
2699
|
+
})();
|
|
2700
|
+
}
|
|
2701
|
+
/**
|
|
2702
|
+
* Reconciles the periodic send timer after a flush attempt. Clears the
|
|
2703
|
+
* timer when the queue is empty, otherwise (re)schedules a retry tick.
|
|
2704
|
+
*
|
|
2705
|
+
* **Why**: a `flushImmediately()` / `flushImmediatelySync()` call where all
|
|
2706
|
+
* integrations fail leaves events in `eventsQueue` for retry. The periodic
|
|
2707
|
+
* timer is the safety net that drains them when the backend recovers — if
|
|
2708
|
+
* we cleared it unconditionally here, the queue would sit untouched until
|
|
2709
|
+
* the next tracked event resurrects the timer in `addToQueue`. Mirrors the
|
|
2710
|
+
* pattern in `sendEventsQueue()` (the periodic path).
|
|
2711
|
+
*/
|
|
2712
|
+
settleSendTimeout() {
|
|
2713
|
+
this.eventsQueue.length === 0 ? this.clearSendTimeout() : this.scheduleSendTimeout();
|
|
2714
|
+
}
|
|
2715
|
+
/**
|
|
2716
|
+
* Re-runs a sync flush that was deferred while an async send was in flight.
|
|
2717
|
+
*
|
|
2718
|
+
* Called from the `finally` blocks of `flushEvents(false)` and
|
|
2719
|
+
* `sendEventsQueue()`. If `pendingSyncFlush` is set, clears the flag and
|
|
2720
|
+
* invokes `flushImmediatelySync()` synchronously so any events that arrived
|
|
2721
|
+
* after the deferred sync call are delivered before the next event loop
|
|
2722
|
+
* tick. Critical for high-stakes events tracked mid-async-send.
|
|
2723
|
+
*/
|
|
2724
|
+
drainPendingSyncFlush() {
|
|
2725
|
+
this.pendingSyncFlush && (this.pendingSyncFlush = !1, this.flushImmediatelySync());
|
|
2726
|
+
}
|
|
2727
|
+
/**
|
|
2728
|
+
* Sends one batch synchronously across all integrations (sendBeacon path).
|
|
2729
|
+
* Optimistic removal: if any integration succeeds, we remove the batch's
|
|
2730
|
+
* events from the queue and emit it locally. Failures persist per-integration.
|
|
2731
|
+
*/
|
|
2732
|
+
sendBatchSync(e, t) {
|
|
2733
|
+
const n = this.dataSenders.map((i) => i.sendEventsQueueSync(e)).some((i) => i);
|
|
2734
|
+
return n ? (this.removeProcessedEvents(t), this.emitEventsQueue(e)) : a("debug", "Sync send complete failure, events kept in queue for retry", {
|
|
2735
|
+
data: { eventCount: t.length, sessionId: e.session_id }
|
|
2736
|
+
}), n;
|
|
2737
|
+
}
|
|
2738
|
+
/**
|
|
2739
|
+
* Sends one batch asynchronously across all integrations (fetch path).
|
|
2740
|
+
*/
|
|
2741
|
+
async sendBatchAsync(e, t) {
|
|
2742
|
+
const s = this.dataSenders.map(
|
|
2743
|
+
async (o) => o.sendEventsQueue(e, {
|
|
2744
|
+
onSuccess: () => {
|
|
2745
|
+
},
|
|
2746
|
+
onFailure: () => {
|
|
2747
|
+
}
|
|
2748
|
+
})
|
|
2749
|
+
), n = await Promise.allSettled(s), i = n.some((o) => this.isSuccessfulResult(o));
|
|
2750
|
+
if (i) {
|
|
2751
|
+
this.removeProcessedEvents(t), this.emitEventsQueue(e);
|
|
2752
|
+
const o = n.filter((l) => !this.isSuccessfulResult(l)).length;
|
|
2753
|
+
o > 0 && a("debug", "Async send completed with some failures, removed from queue and persisted per-integration", {
|
|
2754
|
+
data: { eventCount: t.length, failedCount: o, sessionId: e.session_id }
|
|
2755
|
+
});
|
|
2756
|
+
} else
|
|
2757
|
+
a("debug", "Async send complete failure, events kept in queue for retry", {
|
|
2758
|
+
data: { eventCount: t.length, sessionId: e.session_id }
|
|
2759
|
+
});
|
|
2760
|
+
return i;
|
|
2633
2761
|
}
|
|
2634
2762
|
async sendEventsQueue() {
|
|
2635
|
-
if (!(
|
|
2763
|
+
if (!(this.eventsQueue.length === 0 || this.sendInProgress)) {
|
|
2636
2764
|
this.sendInProgress = !0;
|
|
2637
2765
|
try {
|
|
2638
|
-
const e = this.
|
|
2766
|
+
const e = this.buildBatchesWithIds();
|
|
2767
|
+
if (e.length === 0) return;
|
|
2639
2768
|
if (this.dataSenders.length === 0) {
|
|
2640
|
-
|
|
2769
|
+
for (const { batch: n } of e)
|
|
2770
|
+
this.emitEventsQueue(n);
|
|
2641
2771
|
return;
|
|
2642
2772
|
}
|
|
2643
|
-
|
|
2644
|
-
async (
|
|
2645
|
-
|
|
2646
|
-
},
|
|
2647
|
-
onFailure: () => {
|
|
2648
|
-
}
|
|
2649
|
-
})
|
|
2650
|
-
), i = await Promise.allSettled(n);
|
|
2651
|
-
if (i.some((l) => this.isSuccessfulResult(l))) {
|
|
2652
|
-
this.consecutiveSendFailures = 0, this.removeProcessedEvents(s), this.emitEventsQueue(e);
|
|
2653
|
-
const l = i.filter((c) => !this.isSuccessfulResult(c)).length;
|
|
2654
|
-
l > 0 && a("debug", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
|
|
2655
|
-
data: { eventCount: t.length, failedCount: l }
|
|
2656
|
-
});
|
|
2657
|
-
} else
|
|
2658
|
-
this.consecutiveSendFailures = Math.min(this.consecutiveSendFailures + 1, 5), a("debug", "Periodic send complete failure, events kept in queue for retry", {
|
|
2659
|
-
data: { eventCount: t.length }
|
|
2660
|
-
});
|
|
2661
|
-
this.eventsQueue.length === 0 ? this.clearSendTimeout() : this.scheduleSendTimeout();
|
|
2773
|
+
(await Promise.all(
|
|
2774
|
+
e.map(async ({ batch: n, eventIds: i }) => this.sendBatchAsync(n, i))
|
|
2775
|
+
)).some(Boolean) ? this.consecutiveSendFailures = 0 : this.consecutiveSendFailures = Math.min(this.consecutiveSendFailures + 1, 5), this.eventsQueue.length === 0 ? this.clearSendTimeout() : this.scheduleSendTimeout();
|
|
2662
2776
|
} finally {
|
|
2663
|
-
this.sendInProgress = !1;
|
|
2777
|
+
this.sendInProgress = !1, this.drainPendingSyncFlush();
|
|
2664
2778
|
}
|
|
2665
2779
|
}
|
|
2666
2780
|
}
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2781
|
+
/**
|
|
2782
|
+
* Builds a single batch from a per-session group: dedup by signature,
|
|
2783
|
+
* SESSION_START first, then timestamp order, strip `_session_id`, apply
|
|
2784
|
+
* `beforeBatch` transformer when running standalone.
|
|
2785
|
+
*
|
|
2786
|
+
* **Why N batches per flush**: events freeze their `_session_id` at `track()`
|
|
2787
|
+
* time. If the session was renewed (idle timeout) between two `track()`
|
|
2788
|
+
* calls, the queue contains events from multiple sessions. `buildBatchesWithIds()`
|
|
2789
|
+
* emits one batch per session so the backend's `EventsQueueDto.session_id`
|
|
2790
|
+
* remains the single source of truth and stays consistent with the events it
|
|
2791
|
+
* carries.
|
|
2792
|
+
*
|
|
2793
|
+
* **Strip**: `_session_id` is removed from each event in the wrapper's
|
|
2794
|
+
* `events[]` because the backend uses `forbidNonWhitelisted: true` and would
|
|
2795
|
+
* reject the batch if the field leaked through.
|
|
2796
|
+
*
|
|
2797
|
+
* **Transformer note**: `beforeBatch` is invoked **once per session-batch**,
|
|
2798
|
+
* not once per flush. A queue spanning N sessions triggers N invocations.
|
|
2799
|
+
*/
|
|
2800
|
+
buildBatchFromGroup(e, t) {
|
|
2801
|
+
const s = /* @__PURE__ */ new Map(), n = [];
|
|
2802
|
+
for (const m of t) {
|
|
2803
|
+
const S = this.createEventSignature(m);
|
|
2804
|
+
s.has(S) || n.push(S), s.set(S, m);
|
|
2672
2805
|
}
|
|
2673
|
-
const
|
|
2674
|
-
let
|
|
2806
|
+
const i = n.map((m) => s.get(m)).filter((m) => !!m).sort((m, S) => m.type === u.SESSION_START && S.type !== u.SESSION_START ? -1 : S.type === u.SESSION_START && m.type !== u.SESSION_START ? 1 : m.timestamp - S.timestamp).map(({ _session_id: m, ...S }) => S), o = this.get("config")?.globalMetadata, l = this.get("identity");
|
|
2807
|
+
let d = {
|
|
2675
2808
|
user_id: this.get("userId"),
|
|
2676
|
-
session_id:
|
|
2809
|
+
session_id: e,
|
|
2677
2810
|
device: this.get("device"),
|
|
2678
|
-
events:
|
|
2679
|
-
...
|
|
2680
|
-
...
|
|
2811
|
+
events: i,
|
|
2812
|
+
...o && { global_metadata: o },
|
|
2813
|
+
...l && { identify: l }
|
|
2681
2814
|
};
|
|
2682
|
-
const
|
|
2683
|
-
if (!
|
|
2684
|
-
const
|
|
2685
|
-
|
|
2815
|
+
const c = this.get("collectApiUrls"), f = !!(c?.custom || c?.saas), g = this.transformers.beforeBatch;
|
|
2816
|
+
if (!f && g) {
|
|
2817
|
+
const m = gt(d, g, "EventManager");
|
|
2818
|
+
m !== null && (d = m);
|
|
2686
2819
|
}
|
|
2687
|
-
return
|
|
2820
|
+
return d;
|
|
2688
2821
|
}
|
|
2689
2822
|
buildEventPayload(e) {
|
|
2690
|
-
const t =
|
|
2691
|
-
|
|
2692
|
-
|
|
2823
|
+
const t = this.get("sessionId");
|
|
2824
|
+
if (!t)
|
|
2825
|
+
return a("error", "buildEventPayload reached without sessionId — event dropped", {
|
|
2826
|
+
data: { type: e.type },
|
|
2827
|
+
visibility: "critical"
|
|
2828
|
+
}), null;
|
|
2829
|
+
const s = e.page_url ?? this.get("pageUrl"), n = typeof s == "string" && s.length > 0 ? s : "unknown", i = this.timeManager.now(), o = this.timeManager.validateTimestamp(i);
|
|
2830
|
+
o.valid || a("warn", "Event timestamp validation failed", {
|
|
2831
|
+
data: { type: e.type, error: o.error }
|
|
2693
2832
|
});
|
|
2694
|
-
const
|
|
2695
|
-
let
|
|
2833
|
+
const l = this.get("sessionReferrer"), d = this.get("sessionUtm");
|
|
2834
|
+
let c = {
|
|
2696
2835
|
id: os(),
|
|
2697
2836
|
type: e.type,
|
|
2698
|
-
page_url:
|
|
2699
|
-
timestamp:
|
|
2700
|
-
...
|
|
2837
|
+
page_url: n,
|
|
2838
|
+
timestamp: i,
|
|
2839
|
+
...l && { referrer: l },
|
|
2701
2840
|
...e.from_page_url && { from_page_url: e.from_page_url },
|
|
2702
2841
|
...e.scroll_data && { scroll_data: e.scroll_data },
|
|
2703
2842
|
...e.click_data && { click_data: e.click_data },
|
|
@@ -2706,16 +2845,16 @@ class vs extends _ {
|
|
|
2706
2845
|
...e.error_data && { error_data: e.error_data },
|
|
2707
2846
|
...e.viewport_data && { viewport_data: e.viewport_data },
|
|
2708
2847
|
...e.page_view && { page_view: e.page_view },
|
|
2709
|
-
...
|
|
2848
|
+
...d && { utm: d }
|
|
2710
2849
|
};
|
|
2711
|
-
const
|
|
2712
|
-
if (
|
|
2713
|
-
const
|
|
2714
|
-
if (
|
|
2850
|
+
const f = this.get("collectApiUrls"), g = !!f?.custom, m = !!f?.saas, S = g || m, he = g && m, Q = this.transformers.beforeSend;
|
|
2851
|
+
if (Q && (!S || g && !he)) {
|
|
2852
|
+
const I = mt(c, Q, "EventManager");
|
|
2853
|
+
if (I === null)
|
|
2715
2854
|
return null;
|
|
2716
|
-
|
|
2855
|
+
c = I;
|
|
2717
2856
|
}
|
|
2718
|
-
return
|
|
2857
|
+
return { ...c, _session_id: t };
|
|
2719
2858
|
}
|
|
2720
2859
|
isDuplicateEvent(e) {
|
|
2721
2860
|
const t = Date.now(), s = this.createEventFingerprint(e), n = this.recentEventFingerprints.get(s);
|
|
@@ -2808,7 +2947,10 @@ class vs extends _ {
|
|
|
2808
2947
|
this.eventsQueue = this.eventsQueue.filter((s) => !t.has(s.id));
|
|
2809
2948
|
}
|
|
2810
2949
|
emitEvent(e) {
|
|
2811
|
-
|
|
2950
|
+
if (this.emitter) {
|
|
2951
|
+
const { _session_id: t, ...s } = e;
|
|
2952
|
+
this.emitter.emit(se.EVENT, s);
|
|
2953
|
+
}
|
|
2812
2954
|
}
|
|
2813
2955
|
emitEventsQueue(e) {
|
|
2814
2956
|
this.emitter && this.emitter.emit(se.QUEUE, e);
|
|
@@ -2887,7 +3029,7 @@ class vs extends _ {
|
|
|
2887
3029
|
loadSessionCounts(e) {
|
|
2888
3030
|
if (typeof window > "u" || typeof localStorage > "u")
|
|
2889
3031
|
return this.getInitialCounts();
|
|
2890
|
-
const t = this.get("userId") || "anonymous", s =
|
|
3032
|
+
const t = this.get("userId") || "anonymous", s = Fe(t, e);
|
|
2891
3033
|
try {
|
|
2892
3034
|
const n = localStorage.getItem(s);
|
|
2893
3035
|
if (!n)
|
|
@@ -2948,15 +3090,15 @@ class vs extends _ {
|
|
|
2948
3090
|
return;
|
|
2949
3091
|
}
|
|
2950
3092
|
}
|
|
2951
|
-
const t = this.get("userId") || "anonymous", s = `${
|
|
3093
|
+
const t = this.get("userId") || "anonymous", s = `${v}:${t}:session_counts:`, n = [];
|
|
2952
3094
|
for (let i = 0; i < localStorage.length; i++) {
|
|
2953
3095
|
const o = localStorage.key(i);
|
|
2954
3096
|
if (o?.startsWith(s))
|
|
2955
3097
|
try {
|
|
2956
3098
|
const l = localStorage.getItem(o);
|
|
2957
3099
|
if (l) {
|
|
2958
|
-
const
|
|
2959
|
-
|
|
3100
|
+
const d = JSON.parse(l);
|
|
3101
|
+
d._timestamp && Date.now() - d._timestamp > xe && n.push(o);
|
|
2960
3102
|
}
|
|
2961
3103
|
} catch {
|
|
2962
3104
|
}
|
|
@@ -2997,7 +3139,7 @@ class vs extends _ {
|
|
|
2997
3139
|
* @internal
|
|
2998
3140
|
*/
|
|
2999
3141
|
saveSessionCounts(e) {
|
|
3000
|
-
const t = this.get("userId") || "anonymous", s =
|
|
3142
|
+
const t = this.get("userId") || "anonymous", s = Fe(t, e);
|
|
3001
3143
|
try {
|
|
3002
3144
|
const n = {
|
|
3003
3145
|
...this.sessionEventCounts,
|
|
@@ -3031,11 +3173,11 @@ class _s {
|
|
|
3031
3173
|
* @returns Persistent unique user ID (UUID v4 format)
|
|
3032
3174
|
*/
|
|
3033
3175
|
static getId(e) {
|
|
3034
|
-
const t = e.getItem(
|
|
3176
|
+
const t = e.getItem(Ie);
|
|
3035
3177
|
if (t)
|
|
3036
3178
|
return t;
|
|
3037
3179
|
const s = dt();
|
|
3038
|
-
return e.setItem(
|
|
3180
|
+
return e.setItem(Ie, s), s;
|
|
3039
3181
|
}
|
|
3040
3182
|
}
|
|
3041
3183
|
const ys = /^\d{13}-[a-z0-9]{9}$/;
|
|
@@ -3196,9 +3338,9 @@ class ws extends _ {
|
|
|
3196
3338
|
let s, n;
|
|
3197
3339
|
if (e) {
|
|
3198
3340
|
const i = this.loadStoredSession();
|
|
3199
|
-
s = i?.referrer ??
|
|
3341
|
+
s = i?.referrer ?? ge(), n = i?.utm ?? pe();
|
|
3200
3342
|
} else
|
|
3201
|
-
s =
|
|
3343
|
+
s = ge(), n = pe();
|
|
3202
3344
|
a("debug", "Session tracking initialized", {
|
|
3203
3345
|
data: {
|
|
3204
3346
|
sessionId: t,
|
|
@@ -3249,7 +3391,7 @@ class ws extends _ {
|
|
|
3249
3391
|
*/
|
|
3250
3392
|
renewSession() {
|
|
3251
3393
|
this.needsRenewal = !1;
|
|
3252
|
-
const e = this.generateSessionId(), t =
|
|
3394
|
+
const e = this.generateSessionId(), t = ge(), s = pe();
|
|
3253
3395
|
a("debug", "Renewing session after timeout", {
|
|
3254
3396
|
data: { newSessionId: e }
|
|
3255
3397
|
}), 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({
|
|
@@ -3498,7 +3640,7 @@ class Ls extends _ {
|
|
|
3498
3640
|
};
|
|
3499
3641
|
}
|
|
3500
3642
|
trackCurrentPage = () => {
|
|
3501
|
-
const e = window.location.href, t =
|
|
3643
|
+
const e = window.location.href, t = we(e, this.get("config").sensitiveQueryParams);
|
|
3502
3644
|
if (this.get("pageUrl") === t)
|
|
3503
3645
|
return;
|
|
3504
3646
|
const s = Date.now(), n = this.get("config").pageViewThrottleMs ?? 1e3;
|
|
@@ -3513,10 +3655,10 @@ class Ls extends _ {
|
|
|
3513
3655
|
page_url: this.get("pageUrl"),
|
|
3514
3656
|
from_page_url: i,
|
|
3515
3657
|
...o && { page_view: o }
|
|
3516
|
-
});
|
|
3658
|
+
}), this.get("config").flushOnSpaNavigation === !0 && this.eventManager.flushImmediately();
|
|
3517
3659
|
};
|
|
3518
3660
|
trackInitialPageView() {
|
|
3519
|
-
const e =
|
|
3661
|
+
const e = we(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
|
|
3520
3662
|
this.lastPageViewTime = Date.now(), this.eventManager.track({
|
|
3521
3663
|
type: u.PAGE_VIEW,
|
|
3522
3664
|
page_url: e,
|
|
@@ -3567,7 +3709,7 @@ class As extends _ {
|
|
|
3567
3709
|
const i = this.get("config")?.clickThrottleMs ?? 300;
|
|
3568
3710
|
if (i > 0 && !this.checkClickThrottle(n, i))
|
|
3569
3711
|
return;
|
|
3570
|
-
const o = this.findTrackingElement(n), l = this.getRelevantClickElement(n),
|
|
3712
|
+
const o = this.findTrackingElement(n), l = this.getRelevantClickElement(n), d = this.calculateClickCoordinates(t, n);
|
|
3571
3713
|
if (o) {
|
|
3572
3714
|
const f = this.extractTrackingData(o);
|
|
3573
3715
|
if (f) {
|
|
@@ -3581,10 +3723,14 @@ class As extends _ {
|
|
|
3581
3723
|
});
|
|
3582
3724
|
}
|
|
3583
3725
|
}
|
|
3584
|
-
|
|
3726
|
+
if (!d) {
|
|
3727
|
+
a("debug", "Click skipped: invalid coordinates (likely synthetic)");
|
|
3728
|
+
return;
|
|
3729
|
+
}
|
|
3730
|
+
const c = this.generateClickData(n, l, d);
|
|
3585
3731
|
this.eventManager.track({
|
|
3586
3732
|
type: u.CLICK,
|
|
3587
|
-
click_data:
|
|
3733
|
+
click_data: c
|
|
3588
3734
|
});
|
|
3589
3735
|
}, window.addEventListener("click", this.clickHandler, !0));
|
|
3590
3736
|
}
|
|
@@ -3700,8 +3846,11 @@ class As extends _ {
|
|
|
3700
3846
|
return Math.max(0, Math.min(1, Number(e.toFixed(3))));
|
|
3701
3847
|
}
|
|
3702
3848
|
calculateClickCoordinates(e, t) {
|
|
3703
|
-
const s =
|
|
3704
|
-
|
|
3849
|
+
const s = e.clientX, n = e.clientY;
|
|
3850
|
+
if (typeof s != "number" || typeof n != "number" || !Number.isFinite(s) || !Number.isFinite(n) || s === 0 && n === 0 && !e.isTrusted)
|
|
3851
|
+
return null;
|
|
3852
|
+
const i = t.getBoundingClientRect(), o = i.width > 0 ? this.clamp((s - i.left) / i.width) : 0, l = i.height > 0 ? this.clamp((n - i.top) / i.height) : 0;
|
|
3853
|
+
return { x: s, y: n, relativeX: o, relativeY: l };
|
|
3705
3854
|
}
|
|
3706
3855
|
extractTrackingData(e) {
|
|
3707
3856
|
const t = e.getAttribute(`${b}-name`), s = e.getAttribute(`${b}-value`);
|
|
@@ -3713,7 +3862,7 @@ class As extends _ {
|
|
|
3713
3862
|
};
|
|
3714
3863
|
}
|
|
3715
3864
|
generateClickData(e, t, s) {
|
|
3716
|
-
const { x: n, y: i, relativeX: o, relativeY: l } = s,
|
|
3865
|
+
const { x: n, y: i, relativeX: o, relativeY: l } = s, d = this.getRelevantText(e, t), c = this.extractElementAttributes(t);
|
|
3717
3866
|
return {
|
|
3718
3867
|
x: n,
|
|
3719
3868
|
y: i,
|
|
@@ -3722,13 +3871,13 @@ class As extends _ {
|
|
|
3722
3871
|
tag: t.tagName.toLowerCase(),
|
|
3723
3872
|
...t.id && { id: t.id },
|
|
3724
3873
|
...t.className && { class: t.className },
|
|
3725
|
-
...
|
|
3726
|
-
...
|
|
3727
|
-
...
|
|
3728
|
-
...
|
|
3729
|
-
...
|
|
3730
|
-
...
|
|
3731
|
-
...Object.keys(
|
|
3874
|
+
...d && { text: d },
|
|
3875
|
+
...c.href && { href: c.href },
|
|
3876
|
+
...c.title && { title: c.title },
|
|
3877
|
+
...c.alt && { alt: c.alt },
|
|
3878
|
+
...c.role && { role: c.role },
|
|
3879
|
+
...c["aria-label"] && { ariaLabel: c["aria-label"] },
|
|
3880
|
+
...Object.keys(c).length > 0 && { dataAttributes: c }
|
|
3732
3881
|
};
|
|
3733
3882
|
}
|
|
3734
3883
|
/**
|
|
@@ -3892,7 +4041,7 @@ class Ms extends _ {
|
|
|
3892
4041
|
return this.isWindowScrollable() ? e === window : this.containers.length === 0;
|
|
3893
4042
|
}
|
|
3894
4043
|
setupScrollContainer(e, t) {
|
|
3895
|
-
if (this.containers.some((
|
|
4044
|
+
if (this.containers.some((c) => c.element === e) || e !== window && !this.isElementScrollable(e))
|
|
3896
4045
|
return;
|
|
3897
4046
|
const n = this.getScrollTop(e), i = this.calculateScrollDepth(
|
|
3898
4047
|
n,
|
|
@@ -3910,17 +4059,17 @@ class Ms extends _ {
|
|
|
3910
4059
|
maxDepthReached: i,
|
|
3911
4060
|
debounceTimer: null,
|
|
3912
4061
|
listener: null
|
|
3913
|
-
},
|
|
4062
|
+
}, d = () => {
|
|
3914
4063
|
this.get("suppressNextScroll") || (l.firstScrollEventTime === null && (l.firstScrollEventTime = Date.now()), this.clearContainerTimer(l), l.debounceTimer = window.setTimeout(() => {
|
|
3915
|
-
const
|
|
3916
|
-
if (
|
|
4064
|
+
const c = this.calculateScrollData(l);
|
|
4065
|
+
if (c) {
|
|
3917
4066
|
const f = Date.now();
|
|
3918
|
-
this.processScrollEvent(l,
|
|
4067
|
+
this.processScrollEvent(l, c, f);
|
|
3919
4068
|
}
|
|
3920
4069
|
l.debounceTimer = null;
|
|
3921
4070
|
}, 250));
|
|
3922
4071
|
};
|
|
3923
|
-
l.listener =
|
|
4072
|
+
l.listener = d, this.containers.push(l), e === window ? window.addEventListener("scroll", d, { passive: !0 }) : e.addEventListener("scroll", d, { passive: !0 });
|
|
3924
4073
|
}
|
|
3925
4074
|
processScrollEvent(e, t, s) {
|
|
3926
4075
|
if (!this.shouldEmitScrollEvent(e, t, s))
|
|
@@ -3975,14 +4124,14 @@ class Ms extends _ {
|
|
|
3975
4124
|
const { element: t, lastScrollPos: s, lastEventTime: n } = e, i = this.getScrollTop(t), o = Date.now(), l = Math.abs(i - s);
|
|
3976
4125
|
if (l < 10 || t === window && !this.isWindowScrollable())
|
|
3977
4126
|
return null;
|
|
3978
|
-
const
|
|
3979
|
-
let
|
|
3980
|
-
n > 0 ?
|
|
3981
|
-
const
|
|
4127
|
+
const d = this.getViewportHeight(t), c = this.getScrollHeight(t), f = this.getScrollDirection(i, s), g = this.calculateScrollDepth(i, c, d);
|
|
4128
|
+
let m;
|
|
4129
|
+
n > 0 ? m = o - n : e.firstScrollEventTime !== null ? m = o - e.firstScrollEventTime : m = 250;
|
|
4130
|
+
const S = Math.round(l / m * 1e3);
|
|
3982
4131
|
return g > e.maxDepthReached && (e.maxDepthReached = g), e.lastScrollPos = i, {
|
|
3983
4132
|
depth: g,
|
|
3984
4133
|
direction: f,
|
|
3985
|
-
velocity:
|
|
4134
|
+
velocity: S,
|
|
3986
4135
|
max_depth_reached: e.maxDepthReached
|
|
3987
4136
|
};
|
|
3988
4137
|
}
|
|
@@ -4534,7 +4683,7 @@ class Ds extends _ {
|
|
|
4534
4683
|
navigationCounter = 0;
|
|
4535
4684
|
// Counter for handling simultaneous navigations edge case
|
|
4536
4685
|
constructor(e) {
|
|
4537
|
-
super(), this.eventManager = e, this.vitalThresholds = Qe(
|
|
4686
|
+
super(), this.eventManager = e, this.vitalThresholds = Qe(ye);
|
|
4538
4687
|
}
|
|
4539
4688
|
/**
|
|
4540
4689
|
* Starts tracking Web Vitals and performance metrics.
|
|
@@ -4551,7 +4700,7 @@ class Ds extends _ {
|
|
|
4551
4700
|
* @returns Promise that resolves when tracking is initialized
|
|
4552
4701
|
*/
|
|
4553
4702
|
async startTracking() {
|
|
4554
|
-
const e = this.get("config"), t = e?.webVitalsMode ??
|
|
4703
|
+
const e = this.get("config"), t = e?.webVitalsMode ?? ye;
|
|
4555
4704
|
this.vitalThresholds = Qe(t), e?.webVitalsThresholds && (this.vitalThresholds = { ...this.vitalThresholds, ...e.webVitalsThresholds }), await this.initWebVitals(), this.observeLongTasks();
|
|
4556
4705
|
}
|
|
4557
4706
|
/**
|
|
@@ -4622,9 +4771,9 @@ class Ds extends _ {
|
|
|
4622
4771
|
}
|
|
4623
4772
|
async initWebVitals() {
|
|
4624
4773
|
try {
|
|
4625
|
-
const { onLCP: e, onCLS: t, onFCP: s, onTTFB: n, onINP: i } = await Promise.resolve().then(() =>
|
|
4626
|
-
const
|
|
4627
|
-
this.sendVital({ type: l, value:
|
|
4774
|
+
const { onLCP: e, onCLS: t, onFCP: s, onTTFB: n, onINP: i } = await Promise.resolve().then(() => gr), o = (l) => (d) => {
|
|
4775
|
+
const c = Number(d.value.toFixed(2));
|
|
4776
|
+
this.sendVital({ type: l, value: c });
|
|
4628
4777
|
};
|
|
4629
4778
|
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }), s(o("FCP"), { reportAllChanges: !1 }), n(o("TTFB"), { reportAllChanges: !1 }), i(o("INP"), { reportAllChanges: !1 });
|
|
4630
4779
|
} catch (e) {
|
|
@@ -4729,9 +4878,9 @@ class Ds extends _ {
|
|
|
4729
4878
|
const i = new PerformanceObserver((o, l) => {
|
|
4730
4879
|
try {
|
|
4731
4880
|
t(o, l);
|
|
4732
|
-
} catch (
|
|
4881
|
+
} catch (d) {
|
|
4733
4882
|
a("debug", "Observer callback failed", {
|
|
4734
|
-
error:
|
|
4883
|
+
error: d,
|
|
4735
4884
|
data: { type: e }
|
|
4736
4885
|
});
|
|
4737
4886
|
}
|
|
@@ -4808,12 +4957,13 @@ class ae extends _ {
|
|
|
4808
4957
|
const t = this.sanitize(e.message || "Unknown error");
|
|
4809
4958
|
if (this.shouldSuppressError(B.JS_ERROR, t))
|
|
4810
4959
|
return;
|
|
4811
|
-
const s = typeof e.error?.stack == "string" ? this.truncateStack(e.error.stack) : void 0;
|
|
4960
|
+
const s = typeof e.error?.stack == "string" ? this.truncateStack(e.error.stack) : void 0, n = typeof e.error?.name == "string" && e.error.name !== "Error" ? e.error.name : void 0;
|
|
4812
4961
|
this.eventManager.track({
|
|
4813
4962
|
type: u.ERROR,
|
|
4814
4963
|
error_data: {
|
|
4815
4964
|
type: B.JS_ERROR,
|
|
4816
4965
|
message: t,
|
|
4966
|
+
...n !== void 0 && { name: n },
|
|
4817
4967
|
...e.filename !== "" && { filename: e.filename },
|
|
4818
4968
|
...e.lineno !== 0 && { line: e.lineno },
|
|
4819
4969
|
...e.colno !== 0 && { column: e.colno },
|
|
@@ -4827,12 +4977,13 @@ class ae extends _ {
|
|
|
4827
4977
|
const t = this.extractRejectionMessage(e.reason), s = this.sanitize(t);
|
|
4828
4978
|
if (this.shouldSuppressError(B.PROMISE_REJECTION, s))
|
|
4829
4979
|
return;
|
|
4830
|
-
const n = e.reason instanceof Error && typeof e.reason.stack == "string" ? this.truncateStack(e.reason.stack) : void 0;
|
|
4980
|
+
const n = e.reason instanceof Error && typeof e.reason.stack == "string" ? this.truncateStack(e.reason.stack) : void 0, i = e.reason instanceof Error && e.reason.name !== "Error" ? e.reason.name : void 0;
|
|
4831
4981
|
this.eventManager.track({
|
|
4832
4982
|
type: u.ERROR,
|
|
4833
4983
|
error_data: {
|
|
4834
4984
|
type: B.PROMISE_REJECTION,
|
|
4835
4985
|
message: s,
|
|
4986
|
+
...i !== void 0 && { name: i },
|
|
4836
4987
|
...n !== void 0 && { stack: n }
|
|
4837
4988
|
}
|
|
4838
4989
|
});
|
|
@@ -4851,7 +5002,7 @@ class ae extends _ {
|
|
|
4851
5002
|
}
|
|
4852
5003
|
}
|
|
4853
5004
|
sanitize(e) {
|
|
4854
|
-
const t = e.length >
|
|
5005
|
+
const t = e.length > Ge ? e.slice(0, Ge) + "..." : e;
|
|
4855
5006
|
return this.sanitizePii(t);
|
|
4856
5007
|
}
|
|
4857
5008
|
sanitizePii(e) {
|
|
@@ -4864,13 +5015,13 @@ class ae extends _ {
|
|
|
4864
5015
|
}
|
|
4865
5016
|
shouldSuppressError(e, t) {
|
|
4866
5017
|
const s = Date.now(), n = `${e}:${t}`, i = this.recentErrors.get(n);
|
|
4867
|
-
return i !== void 0 && s - i < je ? (this.recentErrors.set(n, s), !0) : (this.recentErrors.set(n, s), this.recentErrors.size >
|
|
5018
|
+
return i !== void 0 && s - i < je ? (this.recentErrors.set(n, s), !0) : (this.recentErrors.set(n, s), this.recentErrors.size > Xt ? (this.recentErrors.clear(), this.recentErrors.set(n, s), !1) : (this.recentErrors.size > ee && this.pruneOldErrors(), !1));
|
|
4868
5019
|
}
|
|
4869
5020
|
static TRUNCATION_SUFFIX = `
|
|
4870
5021
|
...truncated`;
|
|
4871
5022
|
truncateStack(e) {
|
|
4872
|
-
if (e.length <=
|
|
4873
|
-
const t =
|
|
5023
|
+
if (e.length <= Xe) return this.sanitizePii(e);
|
|
5024
|
+
const t = Xe - ae.TRUNCATION_SUFFIX.length, s = e.slice(0, t) + ae.TRUNCATION_SUFFIX;
|
|
4874
5025
|
return this.sanitizePii(s);
|
|
4875
5026
|
}
|
|
4876
5027
|
pruneOldErrors() {
|
|
@@ -4890,7 +5041,9 @@ class ks extends _ {
|
|
|
4890
5041
|
isInitialized = !1;
|
|
4891
5042
|
suppressNextScrollTimer = null;
|
|
4892
5043
|
pageUnloadHandler = null;
|
|
4893
|
-
|
|
5044
|
+
pageShowHandler = null;
|
|
5045
|
+
visibilityFlushHandler = null;
|
|
5046
|
+
emitter = new Ss();
|
|
4894
5047
|
transformers = {};
|
|
4895
5048
|
customHeadersProvider;
|
|
4896
5049
|
managers = {};
|
|
@@ -4930,33 +5083,74 @@ class ks extends _ {
|
|
|
4930
5083
|
}
|
|
4931
5084
|
}
|
|
4932
5085
|
/**
|
|
4933
|
-
*
|
|
5086
|
+
* Asynchronously flushes all pending events in the queue.
|
|
5087
|
+
*
|
|
5088
|
+
* Internally calls `EventManager.flushImmediately()` which uses `fetch()` with retries.
|
|
5089
|
+
* Use when you need to force-send buffered events without waiting for the next send interval
|
|
5090
|
+
* (e.g., before a critical user action like sign-out, or before a SPA route teardown).
|
|
5091
|
+
*
|
|
5092
|
+
* @returns Promise<boolean> — `true` if at least one integration accepted
|
|
5093
|
+
* the batch (optimistic removal — failures persist per-integration
|
|
5094
|
+
* and retry on the next flush). `false` if not initialized,
|
|
5095
|
+
* destroying, another flush is in flight, or all senders failed.
|
|
5096
|
+
* @internal Called from api.flushImmediately()
|
|
5097
|
+
*/
|
|
5098
|
+
async flushImmediately() {
|
|
5099
|
+
return await this.managers.event?.flushImmediately() ?? !1;
|
|
5100
|
+
}
|
|
5101
|
+
/**
|
|
5102
|
+
* Synchronously flushes all pending events using `navigator.sendBeacon()`.
|
|
5103
|
+
*
|
|
5104
|
+
* Use only for page-unload scenarios (or equivalent) where async fetch may be cancelled.
|
|
5105
|
+
* For general flush needs, prefer {@link flushImmediately}.
|
|
5106
|
+
*
|
|
5107
|
+
* @returns `true` if at least one integration accepted the beacon batch
|
|
5108
|
+
* during this call (optimistic removal — failures persist
|
|
5109
|
+
* per-integration). `false` if no events, all senders failed, or
|
|
5110
|
+
* the call was deferred behind an in-flight async send.
|
|
5111
|
+
* @internal Called from api.flushImmediatelySync()
|
|
5112
|
+
*/
|
|
5113
|
+
flushImmediatelySync() {
|
|
5114
|
+
return this.managers.event?.flushImmediatelySync() ?? !1;
|
|
5115
|
+
}
|
|
5116
|
+
/**
|
|
5117
|
+
* Sends a custom event with optional metadata and options.
|
|
4934
5118
|
*
|
|
4935
5119
|
* @param name - Event name
|
|
4936
5120
|
* @param metadata - Optional metadata
|
|
5121
|
+
* @param options - Optional event options. `{ critical: true }` drains the
|
|
5122
|
+
* queue via `navigator.sendBeacon()` immediately after tracking — the
|
|
5123
|
+
* browser guarantees the request is queued for delivery even if the page
|
|
5124
|
+
* is about to unload (typical pattern: tracking a purchase, then
|
|
5125
|
+
* `window.location.href = '/thanks'`). If an async fetch is already in
|
|
5126
|
+
* flight when the critical event is tracked, the sync flush is deferred
|
|
5127
|
+
* and re-runs from the async send's `finally` block so the critical
|
|
5128
|
+
* event is not stranded in the queue.
|
|
4937
5129
|
* @internal Called from api.event()
|
|
4938
5130
|
*/
|
|
4939
|
-
sendCustomEvent(e, t) {
|
|
5131
|
+
sendCustomEvent(e, t, s) {
|
|
4940
5132
|
if (!this.managers.event) {
|
|
4941
5133
|
a("warn", "Cannot send custom event: TraceLog not initialized", { data: { name: e } });
|
|
4942
5134
|
return;
|
|
4943
5135
|
}
|
|
4944
|
-
let
|
|
4945
|
-
t && typeof t == "object" && !Array.isArray(t) && Object.getPrototypeOf(t) !== Object.prototype && (
|
|
4946
|
-
const { valid:
|
|
4947
|
-
if (!
|
|
5136
|
+
let n = t;
|
|
5137
|
+
t && typeof t == "object" && !Array.isArray(t) && Object.getPrototypeOf(t) !== Object.prototype && (n = Object.assign({}, t));
|
|
5138
|
+
const { valid: i, error: o, sanitizedMetadata: l } = ps(e, n);
|
|
5139
|
+
if (!i) {
|
|
4948
5140
|
if (this.get("mode") === ie.QA)
|
|
4949
|
-
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${
|
|
4950
|
-
a("warn", `Custom event "${e}" dropped: ${
|
|
5141
|
+
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${o}`);
|
|
5142
|
+
a("warn", `Custom event "${e}" dropped: ${o}`);
|
|
4951
5143
|
return;
|
|
4952
5144
|
}
|
|
4953
5145
|
this.managers.event.track({
|
|
4954
5146
|
type: u.CUSTOM,
|
|
4955
5147
|
custom_event: {
|
|
4956
5148
|
name: e,
|
|
4957
|
-
...
|
|
5149
|
+
...l && { metadata: l }
|
|
4958
5150
|
}
|
|
4959
|
-
})
|
|
5151
|
+
}), s?.critical === !0 && (this.managers.event.flushImmediatelySync() || a("debug", "Critical event flush returned false (deferred to in-flight send or empty queue)", {
|
|
5152
|
+
data: { name: e }
|
|
5153
|
+
}));
|
|
4960
5154
|
}
|
|
4961
5155
|
on(e, t) {
|
|
4962
5156
|
this.emitter.on(e, t);
|
|
@@ -5009,7 +5203,7 @@ class ks extends _ {
|
|
|
5009
5203
|
} catch (s) {
|
|
5010
5204
|
a("warn", "Failed to stop tracking", { error: s });
|
|
5011
5205
|
}
|
|
5012
|
-
}), this.suppressNextScrollTimer && (clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = null), this.pageUnloadHandler && (window.removeEventListener("pagehide", this.pageUnloadHandler), window.removeEventListener("beforeunload", this.pageUnloadHandler), this.pageUnloadHandler = null), this.managers.event?.flushImmediatelySync(), this.managers.event?.stop(), this.emitter.removeAllListeners(), this.transformers.beforeSend = void 0, this.transformers.beforeBatch = void 0, this.customHeadersProvider = void 0, this.set("suppressNextScroll", !1), this.set("sessionId", null), this.set("identity", void 0), this.clearPersistedIdentity(), this.integrationInstances.shopifyCartLinker?.deactivate(), this.integrationInstances = {}, this.isInitialized = !1, this.handlers = {}, this.managers = {});
|
|
5206
|
+
}), this.suppressNextScrollTimer && (clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = null), this.pageUnloadHandler && (window.removeEventListener("pagehide", this.pageUnloadHandler), window.removeEventListener("beforeunload", this.pageUnloadHandler), this.pageUnloadHandler = null), this.pageShowHandler && (window.removeEventListener("pageshow", this.pageShowHandler), this.pageShowHandler = null), this.visibilityFlushHandler && (document.removeEventListener("visibilitychange", this.visibilityFlushHandler), this.visibilityFlushHandler = null), this.managers.event?.flushImmediatelySync(), this.managers.event?.stop(), this.emitter.removeAllListeners(), this.transformers.beforeSend = void 0, this.transformers.beforeBatch = void 0, this.customHeadersProvider = void 0, this.set("suppressNextScroll", !1), this.set("sessionId", null), this.set("identity", void 0), this.clearPersistedIdentity(), this.integrationInstances.shopifyCartLinker?.deactivate(), this.integrationInstances = {}, this.isInitialized = !1, this.handlers = {}, this.managers = {});
|
|
5013
5207
|
}
|
|
5014
5208
|
setupState(e = {}) {
|
|
5015
5209
|
this.set("config", e);
|
|
@@ -5017,9 +5211,9 @@ class ks extends _ {
|
|
|
5017
5211
|
this.set("userId", t);
|
|
5018
5212
|
const s = ls(e);
|
|
5019
5213
|
this.set("collectApiUrls", s);
|
|
5020
|
-
const n =
|
|
5214
|
+
const n = Gt();
|
|
5021
5215
|
this.set("device", n);
|
|
5022
|
-
const i =
|
|
5216
|
+
const i = we(window.location.href, e.sensitiveQueryParams);
|
|
5023
5217
|
this.set("pageUrl", i), ss() && this.set("mode", ie.QA);
|
|
5024
5218
|
}
|
|
5025
5219
|
/**
|
|
@@ -5058,6 +5252,15 @@ class ks extends _ {
|
|
|
5058
5252
|
getSessionId() {
|
|
5059
5253
|
return this.get("sessionId");
|
|
5060
5254
|
}
|
|
5255
|
+
/**
|
|
5256
|
+
* Returns the current user ID.
|
|
5257
|
+
*
|
|
5258
|
+
* @returns The user ID string, or null if not yet initialized
|
|
5259
|
+
* @internal Used by api.getUserId()
|
|
5260
|
+
*/
|
|
5261
|
+
getUserId() {
|
|
5262
|
+
return this.get("userId");
|
|
5263
|
+
}
|
|
5061
5264
|
/**
|
|
5062
5265
|
* Validates metadata object structure and values.
|
|
5063
5266
|
*
|
|
@@ -5158,7 +5361,7 @@ class ks extends _ {
|
|
|
5158
5361
|
async resetIdentity() {
|
|
5159
5362
|
await this.managers.event?.flushImmediately(), this.set("identity", void 0), this.clearPersistedIdentity();
|
|
5160
5363
|
const e = dt();
|
|
5161
|
-
this.managers.storage.setItem(
|
|
5364
|
+
this.managers.storage.setItem(Ie, 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");
|
|
5162
5365
|
}
|
|
5163
5366
|
/**
|
|
5164
5367
|
* Returns the project ID used for identity storage scoping.
|
|
@@ -5172,7 +5375,7 @@ class ks extends _ {
|
|
|
5172
5375
|
*/
|
|
5173
5376
|
persistIdentity(e) {
|
|
5174
5377
|
try {
|
|
5175
|
-
const t = this.getProjectId(), s =
|
|
5378
|
+
const t = this.getProjectId(), s = me(t);
|
|
5176
5379
|
this.managers.storage.setItem(s, JSON.stringify(e));
|
|
5177
5380
|
} catch {
|
|
5178
5381
|
a("debug", "Failed to persist identity to localStorage");
|
|
@@ -5183,12 +5386,12 @@ class ks extends _ {
|
|
|
5183
5386
|
* Also migrates pending identity (set before init) to the project-scoped key.
|
|
5184
5387
|
*/
|
|
5185
5388
|
loadPersistedIdentity() {
|
|
5186
|
-
const e = this.managers.storage, t = this.getProjectId(), s =
|
|
5389
|
+
const e = this.managers.storage, t = this.getProjectId(), s = me(t);
|
|
5187
5390
|
try {
|
|
5188
|
-
const n = e.getItem(
|
|
5391
|
+
const n = e.getItem(H);
|
|
5189
5392
|
if (n) {
|
|
5190
5393
|
const i = JSON.parse(n);
|
|
5191
|
-
if (e.removeItem(
|
|
5394
|
+
if (e.removeItem(H), !this.isValidIdentityData(i)) {
|
|
5192
5395
|
a("debug", "Invalid pending identity in localStorage, discarded");
|
|
5193
5396
|
return;
|
|
5194
5397
|
}
|
|
@@ -5197,7 +5400,7 @@ class ks extends _ {
|
|
|
5197
5400
|
return;
|
|
5198
5401
|
}
|
|
5199
5402
|
} catch {
|
|
5200
|
-
e.removeItem(
|
|
5403
|
+
e.removeItem(H);
|
|
5201
5404
|
}
|
|
5202
5405
|
try {
|
|
5203
5406
|
const n = e.getItem(s);
|
|
@@ -5235,7 +5438,7 @@ class ks extends _ {
|
|
|
5235
5438
|
clearPersistedIdentity() {
|
|
5236
5439
|
try {
|
|
5237
5440
|
const e = this.managers.storage, t = this.getProjectId();
|
|
5238
|
-
e.removeItem(
|
|
5441
|
+
e.removeItem(me(t)), e.removeItem(H);
|
|
5239
5442
|
} catch {
|
|
5240
5443
|
a("debug", "Failed to clear persisted identity");
|
|
5241
5444
|
}
|
|
@@ -5243,7 +5446,13 @@ class ks extends _ {
|
|
|
5243
5446
|
setupPageLifecycleListeners() {
|
|
5244
5447
|
this.pageUnloadHandler = () => {
|
|
5245
5448
|
this.managers.event?.flushImmediatelySync();
|
|
5246
|
-
},
|
|
5449
|
+
}, this.pageShowHandler = (e) => {
|
|
5450
|
+
e.persisted && this.managers.event?.recoverPersistedEvents().catch((t) => {
|
|
5451
|
+
a("warn", "Failed to recover persisted events on bfcache restore", { error: t });
|
|
5452
|
+
});
|
|
5453
|
+
}, this.visibilityFlushHandler = () => {
|
|
5454
|
+
typeof document > "u" || !document.hidden || this.get("config").flushOnPageHidden !== !1 && this.managers.event?.flushImmediatelySync();
|
|
5455
|
+
}, window.addEventListener("pagehide", this.pageUnloadHandler), window.addEventListener("beforeunload", this.pageUnloadHandler), window.addEventListener("pageshow", this.pageShowHandler), document.addEventListener("visibilitychange", this.visibilityFlushHandler);
|
|
5247
5456
|
}
|
|
5248
5457
|
initializeHandlers() {
|
|
5249
5458
|
const e = this.get("config");
|
|
@@ -5296,15 +5505,15 @@ const Vs = async (r) => typeof window > "u" || typeof document > "u" ? { session
|
|
|
5296
5505
|
} finally {
|
|
5297
5506
|
R = !1, P = null;
|
|
5298
5507
|
}
|
|
5299
|
-
})()), P)), Us = (r, e) => {
|
|
5508
|
+
})()), P)), Us = (r, e, t) => {
|
|
5300
5509
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5301
5510
|
if (!h)
|
|
5302
5511
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5303
5512
|
if (T)
|
|
5304
5513
|
throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
|
|
5305
|
-
h.sendCustomEvent(r, e);
|
|
5514
|
+
h.sendCustomEvent(r, e, t);
|
|
5306
5515
|
}
|
|
5307
|
-
}, Fs = (r, e) => {
|
|
5516
|
+
}, Hs = async () => typeof window > "u" || typeof document > "u" || !h || T ? !1 : h.flushImmediately(), Fs = () => typeof window > "u" || typeof document > "u" || !h || T ? !1 : h.flushImmediatelySync(), xs = (r, e) => {
|
|
5308
5517
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5309
5518
|
if (!h || R) {
|
|
5310
5519
|
k.push({ event: r, callback: e });
|
|
@@ -5312,7 +5521,7 @@ const Vs = async (r) => typeof window > "u" || typeof document > "u" ? { session
|
|
|
5312
5521
|
}
|
|
5313
5522
|
h.on(r, e);
|
|
5314
5523
|
}
|
|
5315
|
-
},
|
|
5524
|
+
}, $s = (r, e) => {
|
|
5316
5525
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5317
5526
|
if (!h) {
|
|
5318
5527
|
const t = k.findIndex((s) => s.event === r && s.callback === e);
|
|
@@ -5322,7 +5531,7 @@ const Vs = async (r) => typeof window > "u" || typeof document > "u" ? { session
|
|
|
5322
5531
|
h.off(r, e);
|
|
5323
5532
|
}
|
|
5324
5533
|
};
|
|
5325
|
-
function
|
|
5534
|
+
function Bs(r, e) {
|
|
5326
5535
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5327
5536
|
if (typeof e != "function")
|
|
5328
5537
|
throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof e}`);
|
|
@@ -5336,7 +5545,7 @@ function xs(r, e) {
|
|
|
5336
5545
|
r === "beforeSend" ? h.setTransformer("beforeSend", e) : h.setTransformer("beforeBatch", e);
|
|
5337
5546
|
}
|
|
5338
5547
|
}
|
|
5339
|
-
const
|
|
5548
|
+
const Ws = (r) => {
|
|
5340
5549
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5341
5550
|
if (!h) {
|
|
5342
5551
|
const e = M.findIndex((t) => t.hook === r);
|
|
@@ -5347,7 +5556,7 @@ const $s = (r) => {
|
|
|
5347
5556
|
throw new Error("[TraceLog] Cannot remove transformers while TraceLog is being destroyed");
|
|
5348
5557
|
h.removeTransformer(r);
|
|
5349
5558
|
}
|
|
5350
|
-
},
|
|
5559
|
+
}, Gs = (r) => {
|
|
5351
5560
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5352
5561
|
if (typeof r != "function")
|
|
5353
5562
|
throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof r}`);
|
|
@@ -5359,7 +5568,7 @@ const $s = (r) => {
|
|
|
5359
5568
|
throw new Error("[TraceLog] Cannot set custom headers while TraceLog is being destroyed");
|
|
5360
5569
|
h.setCustomHeaders(r);
|
|
5361
5570
|
}
|
|
5362
|
-
},
|
|
5571
|
+
}, Xs = () => {
|
|
5363
5572
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5364
5573
|
if (!h) {
|
|
5365
5574
|
D = null;
|
|
@@ -5369,7 +5578,7 @@ const $s = (r) => {
|
|
|
5369
5578
|
throw new Error("[TraceLog] Cannot remove custom headers while TraceLog is being destroyed");
|
|
5370
5579
|
h.removeCustomHeaders();
|
|
5371
5580
|
}
|
|
5372
|
-
},
|
|
5581
|
+
}, js = () => typeof window > "u" || typeof document > "u" ? !1 : h !== null, Ks = () => typeof window > "u" || typeof document > "u" || !h ? null : h.getSessionId(), zs = () => typeof window > "u" || typeof document > "u" || !h ? null : h.getUserId(), Qs = () => {
|
|
5373
5582
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5374
5583
|
if (T)
|
|
5375
5584
|
throw new Error("[TraceLog] Destroy operation already in progress");
|
|
@@ -5384,9 +5593,9 @@ const $s = (r) => {
|
|
|
5384
5593
|
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 });
|
|
5385
5594
|
}
|
|
5386
5595
|
}
|
|
5387
|
-
},
|
|
5596
|
+
}, Ys = (r) => {
|
|
5388
5597
|
typeof window > "u" || typeof document > "u" || rs(r);
|
|
5389
|
-
},
|
|
5598
|
+
}, qs = (r) => {
|
|
5390
5599
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5391
5600
|
if (!h)
|
|
5392
5601
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
@@ -5394,7 +5603,7 @@ const $s = (r) => {
|
|
|
5394
5603
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
5395
5604
|
h.updateGlobalMetadata(r);
|
|
5396
5605
|
}
|
|
5397
|
-
},
|
|
5606
|
+
}, Js = (r) => {
|
|
5398
5607
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5399
5608
|
if (!h)
|
|
5400
5609
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
@@ -5402,7 +5611,7 @@ const $s = (r) => {
|
|
|
5402
5611
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
5403
5612
|
h.mergeGlobalMetadata(r);
|
|
5404
5613
|
}
|
|
5405
|
-
},
|
|
5614
|
+
}, Zs = (r, e) => {
|
|
5406
5615
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5407
5616
|
if (!r || typeof r != "string" || r.trim().length === 0) {
|
|
5408
5617
|
a("warn", "identify() called with invalid userId");
|
|
@@ -5425,16 +5634,16 @@ const $s = (r) => {
|
|
|
5425
5634
|
userId: r.trim(),
|
|
5426
5635
|
...t ? { traits: t } : {}
|
|
5427
5636
|
};
|
|
5428
|
-
localStorage.setItem(
|
|
5637
|
+
localStorage.setItem(H, JSON.stringify(s)), a("debug", "Identity persisted pre-init (will be applied on init)");
|
|
5429
5638
|
} catch {
|
|
5430
5639
|
a("debug", "Failed to persist pre-init identity");
|
|
5431
5640
|
}
|
|
5432
5641
|
}
|
|
5433
|
-
},
|
|
5642
|
+
}, er = async () => {
|
|
5434
5643
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5435
5644
|
if (!h) {
|
|
5436
5645
|
try {
|
|
5437
|
-
localStorage.removeItem(
|
|
5646
|
+
localStorage.removeItem(H);
|
|
5438
5647
|
} catch {
|
|
5439
5648
|
}
|
|
5440
5649
|
return;
|
|
@@ -5443,38 +5652,41 @@ const $s = (r) => {
|
|
|
5443
5652
|
throw new Error("[TraceLog] Cannot reset identity while TraceLog is being destroyed");
|
|
5444
5653
|
await h.resetIdentity();
|
|
5445
5654
|
}
|
|
5446
|
-
},
|
|
5655
|
+
}, Cr = {
|
|
5447
5656
|
init: Vs,
|
|
5448
5657
|
event: Us,
|
|
5449
|
-
on:
|
|
5450
|
-
off:
|
|
5451
|
-
setTransformer:
|
|
5452
|
-
removeTransformer:
|
|
5453
|
-
setCustomHeaders:
|
|
5454
|
-
removeCustomHeaders:
|
|
5455
|
-
isInitialized:
|
|
5456
|
-
getSessionId:
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5658
|
+
on: xs,
|
|
5659
|
+
off: $s,
|
|
5660
|
+
setTransformer: Bs,
|
|
5661
|
+
removeTransformer: Ws,
|
|
5662
|
+
setCustomHeaders: Gs,
|
|
5663
|
+
removeCustomHeaders: Xs,
|
|
5664
|
+
isInitialized: js,
|
|
5665
|
+
getSessionId: Ks,
|
|
5666
|
+
getUserId: zs,
|
|
5667
|
+
destroy: Qs,
|
|
5668
|
+
setQaMode: Ys,
|
|
5669
|
+
updateGlobalMetadata: qs,
|
|
5670
|
+
mergeGlobalMetadata: Js,
|
|
5671
|
+
identify: Zs,
|
|
5672
|
+
resetIdentity: er,
|
|
5673
|
+
flushImmediately: Hs,
|
|
5674
|
+
flushImmediatelySync: Fs
|
|
5463
5675
|
};
|
|
5464
|
-
var
|
|
5676
|
+
var Ae, C, X, pt, le, St = -1, V = function(r) {
|
|
5465
5677
|
addEventListener("pageshow", (function(e) {
|
|
5466
|
-
e.persisted && (
|
|
5678
|
+
e.persisted && (St = e.timeStamp, r(e));
|
|
5467
5679
|
}), !0);
|
|
5468
|
-
},
|
|
5680
|
+
}, De = function() {
|
|
5469
5681
|
var r = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
|
|
5470
5682
|
if (r && r.responseStart > 0 && r.responseStart < performance.now()) return r;
|
|
5471
5683
|
}, de = function() {
|
|
5472
|
-
var r =
|
|
5684
|
+
var r = De();
|
|
5473
5685
|
return r && r.activationStart || 0;
|
|
5474
5686
|
}, y = function(r, e) {
|
|
5475
|
-
var t =
|
|
5476
|
-
return
|
|
5477
|
-
},
|
|
5687
|
+
var t = De(), s = "navigate";
|
|
5688
|
+
return St >= 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 };
|
|
5689
|
+
}, x = function(r, e, t) {
|
|
5478
5690
|
try {
|
|
5479
5691
|
if (PerformanceObserver.supportedEntryTypes.includes(r)) {
|
|
5480
5692
|
var s = new PerformanceObserver((function(n) {
|
|
@@ -5489,11 +5701,11 @@ var Le, C, G, pt, le, Et = -1, V = function(r) {
|
|
|
5489
5701
|
}, w = function(r, e, t, s) {
|
|
5490
5702
|
var n, i;
|
|
5491
5703
|
return function(o) {
|
|
5492
|
-
e.value >= 0 && (o || s) && ((i = e.value - (n || 0)) || n === void 0) && (n = e.value, e.delta = i, e.rating = (function(l,
|
|
5493
|
-
return l >
|
|
5704
|
+
e.value >= 0 && (o || s) && ((i = e.value - (n || 0)) || n === void 0) && (n = e.value, e.delta = i, e.rating = (function(l, d) {
|
|
5705
|
+
return l > d[1] ? "poor" : l > d[0] ? "needs-improvement" : "good";
|
|
5494
5706
|
})(e.value, t), r(e));
|
|
5495
5707
|
};
|
|
5496
|
-
},
|
|
5708
|
+
}, ke = function(r) {
|
|
5497
5709
|
requestAnimationFrame((function() {
|
|
5498
5710
|
return requestAnimationFrame((function() {
|
|
5499
5711
|
return r();
|
|
@@ -5511,12 +5723,12 @@ var Le, C, G, pt, le, Et = -1, V = function(r) {
|
|
|
5511
5723
|
}, F = -1, et = function() {
|
|
5512
5724
|
return document.visibilityState !== "hidden" || document.prerendering ? 1 / 0 : 0;
|
|
5513
5725
|
}, ce = function(r) {
|
|
5514
|
-
document.visibilityState === "hidden" && F > -1 && (F = r.type === "visibilitychange" ? r.timeStamp : 0,
|
|
5726
|
+
document.visibilityState === "hidden" && F > -1 && (F = r.type === "visibilitychange" ? r.timeStamp : 0, tr());
|
|
5515
5727
|
}, tt = function() {
|
|
5516
5728
|
addEventListener("visibilitychange", ce, !0), addEventListener("prerenderingchange", ce, !0);
|
|
5517
|
-
},
|
|
5729
|
+
}, tr = function() {
|
|
5518
5730
|
removeEventListener("visibilitychange", ce, !0), removeEventListener("prerenderingchange", ce, !0);
|
|
5519
|
-
},
|
|
5731
|
+
}, Ve = function() {
|
|
5520
5732
|
return F < 0 && (F = et(), tt(), V((function() {
|
|
5521
5733
|
setTimeout((function() {
|
|
5522
5734
|
F = et(), tt();
|
|
@@ -5528,50 +5740,50 @@ var Le, C, G, pt, le, Et = -1, V = function(r) {
|
|
|
5528
5740
|
document.prerendering ? addEventListener("prerenderingchange", (function() {
|
|
5529
5741
|
return r();
|
|
5530
5742
|
}), !0) : r();
|
|
5531
|
-
},
|
|
5743
|
+
}, Me = [1800, 3e3], Et = function(r, e) {
|
|
5532
5744
|
e = e || {}, z((function() {
|
|
5533
|
-
var t, s =
|
|
5745
|
+
var t, s = Ve(), n = y("FCP"), i = x("paint", (function(o) {
|
|
5534
5746
|
o.forEach((function(l) {
|
|
5535
5747
|
l.name === "first-contentful-paint" && (i.disconnect(), l.startTime < s.firstHiddenTime && (n.value = Math.max(l.startTime - de(), 0), n.entries.push(l), t(!0)));
|
|
5536
5748
|
}));
|
|
5537
5749
|
}));
|
|
5538
|
-
i && (t = w(r, n,
|
|
5539
|
-
n = y("FCP"), t = w(r, n,
|
|
5750
|
+
i && (t = w(r, n, Me, e.reportAllChanges), V((function(o) {
|
|
5751
|
+
n = y("FCP"), t = w(r, n, Me, e.reportAllChanges), ke((function() {
|
|
5540
5752
|
n.value = performance.now() - o.timeStamp, t(!0);
|
|
5541
5753
|
}));
|
|
5542
5754
|
})));
|
|
5543
5755
|
}));
|
|
5544
|
-
},
|
|
5545
|
-
e = e || {},
|
|
5546
|
-
var t, s = y("CLS", 0), n = 0, i = [], o = function(
|
|
5547
|
-
|
|
5548
|
-
if (!
|
|
5756
|
+
}, Ce = [0.1, 0.25], sr = function(r, e) {
|
|
5757
|
+
e = e || {}, Et(ue((function() {
|
|
5758
|
+
var t, s = y("CLS", 0), n = 0, i = [], o = function(d) {
|
|
5759
|
+
d.forEach((function(c) {
|
|
5760
|
+
if (!c.hadRecentInput) {
|
|
5549
5761
|
var f = i[0], g = i[i.length - 1];
|
|
5550
|
-
n &&
|
|
5762
|
+
n && c.startTime - g.startTime < 1e3 && c.startTime - f.startTime < 5e3 ? (n += c.value, i.push(c)) : (n = c.value, i = [c]);
|
|
5551
5763
|
}
|
|
5552
5764
|
})), n > s.value && (s.value = n, s.entries = i, t());
|
|
5553
|
-
}, l =
|
|
5554
|
-
l && (t = w(r, s,
|
|
5765
|
+
}, l = x("layout-shift", o);
|
|
5766
|
+
l && (t = w(r, s, Ce, e.reportAllChanges), K((function() {
|
|
5555
5767
|
o(l.takeRecords()), t(!0);
|
|
5556
5768
|
})), V((function() {
|
|
5557
|
-
n = 0, s = y("CLS", 0), t = w(r, s,
|
|
5769
|
+
n = 0, s = y("CLS", 0), t = w(r, s, Ce, e.reportAllChanges), ke((function() {
|
|
5558
5770
|
return t();
|
|
5559
5771
|
}));
|
|
5560
5772
|
})), setTimeout(t, 0));
|
|
5561
5773
|
})));
|
|
5562
|
-
}, Tt = 0, Ee = 1 / 0, J = 0,
|
|
5774
|
+
}, Tt = 0, Ee = 1 / 0, J = 0, rr = function(r) {
|
|
5563
5775
|
r.forEach((function(e) {
|
|
5564
5776
|
e.interactionId && (Ee = Math.min(Ee, e.interactionId), J = Math.max(J, e.interactionId), Tt = J ? (J - Ee) / 7 + 1 : 0);
|
|
5565
5777
|
}));
|
|
5566
5778
|
}, It = function() {
|
|
5567
|
-
return
|
|
5568
|
-
},
|
|
5569
|
-
"interactionCount" in performance ||
|
|
5570
|
-
}, L = [], te = /* @__PURE__ */ new Map(), vt = 0,
|
|
5779
|
+
return Ae ? Tt : performance.interactionCount || 0;
|
|
5780
|
+
}, nr = function() {
|
|
5781
|
+
"interactionCount" in performance || Ae || (Ae = x("event", rr, { type: "event", buffered: !0, durationThreshold: 0 }));
|
|
5782
|
+
}, L = [], te = /* @__PURE__ */ new Map(), vt = 0, ir = function() {
|
|
5571
5783
|
var r = Math.min(L.length - 1, Math.floor((It() - vt) / 50));
|
|
5572
5784
|
return L[r];
|
|
5573
|
-
},
|
|
5574
|
-
if (
|
|
5785
|
+
}, or = [], ar = function(r) {
|
|
5786
|
+
if (or.forEach((function(n) {
|
|
5575
5787
|
return n(r);
|
|
5576
5788
|
})), r.interactionId || r.entryType === "first-input") {
|
|
5577
5789
|
var e = L[L.length - 1], t = te.get(r.interactionId);
|
|
@@ -5591,71 +5803,71 @@ var Le, C, G, pt, le, Et = -1, V = function(r) {
|
|
|
5591
5803
|
}, _t = function(r) {
|
|
5592
5804
|
var e = self.requestIdleCallback || self.setTimeout, t = -1;
|
|
5593
5805
|
return r = ue(r), document.visibilityState === "hidden" ? r() : (t = e(r), K(r)), t;
|
|
5594
|
-
},
|
|
5806
|
+
}, Re = [200, 500], lr = function(r, e) {
|
|
5595
5807
|
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, z((function() {
|
|
5596
5808
|
var t;
|
|
5597
|
-
|
|
5809
|
+
nr();
|
|
5598
5810
|
var s, n = y("INP"), i = function(l) {
|
|
5599
5811
|
_t((function() {
|
|
5600
|
-
l.forEach(
|
|
5601
|
-
var
|
|
5602
|
-
|
|
5812
|
+
l.forEach(ar);
|
|
5813
|
+
var d = ir();
|
|
5814
|
+
d && d.latency !== n.value && (n.value = d.latency, n.entries = d.entries, s());
|
|
5603
5815
|
}));
|
|
5604
|
-
}, o =
|
|
5605
|
-
s = w(r, n,
|
|
5816
|
+
}, o = x("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
|
|
5817
|
+
s = w(r, n, Re, e.reportAllChanges), o && (o.observe({ type: "first-input", buffered: !0 }), K((function() {
|
|
5606
5818
|
i(o.takeRecords()), s(!0);
|
|
5607
5819
|
})), V((function() {
|
|
5608
|
-
vt = It(), L.length = 0, te.clear(), n = y("INP"), s = w(r, n,
|
|
5820
|
+
vt = It(), L.length = 0, te.clear(), n = y("INP"), s = w(r, n, Re, e.reportAllChanges);
|
|
5609
5821
|
})));
|
|
5610
5822
|
})));
|
|
5611
|
-
},
|
|
5823
|
+
}, Ne = [2500, 4e3], Te = {}, cr = function(r, e) {
|
|
5612
5824
|
e = e || {}, z((function() {
|
|
5613
|
-
var t, s =
|
|
5614
|
-
e.reportAllChanges || (
|
|
5615
|
-
|
|
5825
|
+
var t, s = Ve(), n = y("LCP"), i = function(d) {
|
|
5826
|
+
e.reportAllChanges || (d = d.slice(-1)), d.forEach((function(c) {
|
|
5827
|
+
c.startTime < s.firstHiddenTime && (n.value = Math.max(c.startTime - de(), 0), n.entries = [c], t());
|
|
5616
5828
|
}));
|
|
5617
|
-
}, o =
|
|
5829
|
+
}, o = x("largest-contentful-paint", i);
|
|
5618
5830
|
if (o) {
|
|
5619
|
-
t = w(r, n,
|
|
5831
|
+
t = w(r, n, Ne, e.reportAllChanges);
|
|
5620
5832
|
var l = ue((function() {
|
|
5621
|
-
|
|
5833
|
+
Te[n.id] || (i(o.takeRecords()), o.disconnect(), Te[n.id] = !0, t(!0));
|
|
5622
5834
|
}));
|
|
5623
|
-
["keydown", "click"].forEach((function(
|
|
5624
|
-
addEventListener(
|
|
5835
|
+
["keydown", "click"].forEach((function(d) {
|
|
5836
|
+
addEventListener(d, (function() {
|
|
5625
5837
|
return _t(l);
|
|
5626
5838
|
}), { once: !0, capture: !0 });
|
|
5627
|
-
})), K(l), V((function(
|
|
5628
|
-
n = y("LCP"), t = w(r, n,
|
|
5629
|
-
n.value = performance.now() -
|
|
5839
|
+
})), K(l), V((function(d) {
|
|
5840
|
+
n = y("LCP"), t = w(r, n, Ne, e.reportAllChanges), ke((function() {
|
|
5841
|
+
n.value = performance.now() - d.timeStamp, Te[n.id] = !0, t(!0);
|
|
5630
5842
|
}));
|
|
5631
5843
|
}));
|
|
5632
5844
|
}
|
|
5633
5845
|
}));
|
|
5634
|
-
},
|
|
5846
|
+
}, Oe = [800, 1800], dr = function r(e) {
|
|
5635
5847
|
document.prerendering ? z((function() {
|
|
5636
5848
|
return r(e);
|
|
5637
5849
|
})) : document.readyState !== "complete" ? addEventListener("load", (function() {
|
|
5638
5850
|
return r(e);
|
|
5639
5851
|
}), !0) : setTimeout(e, 0);
|
|
5640
|
-
},
|
|
5852
|
+
}, ur = function(r, e) {
|
|
5641
5853
|
e = e || {};
|
|
5642
|
-
var t = y("TTFB"), s = w(r, t,
|
|
5643
|
-
|
|
5644
|
-
var n =
|
|
5854
|
+
var t = y("TTFB"), s = w(r, t, Oe, e.reportAllChanges);
|
|
5855
|
+
dr((function() {
|
|
5856
|
+
var n = De();
|
|
5645
5857
|
n && (t.value = Math.max(n.responseStart - de(), 0), t.entries = [n], s(!0), V((function() {
|
|
5646
|
-
t = y("TTFB", 0), (s = w(r, t,
|
|
5858
|
+
t = y("TTFB", 0), (s = w(r, t, Oe, e.reportAllChanges))(!0);
|
|
5647
5859
|
})));
|
|
5648
5860
|
}));
|
|
5649
|
-
}, W = { passive: !0, capture: !0 },
|
|
5650
|
-
C || (C = e,
|
|
5861
|
+
}, W = { passive: !0, capture: !0 }, hr = /* @__PURE__ */ new Date(), st = function(r, e) {
|
|
5862
|
+
C || (C = e, X = r, pt = /* @__PURE__ */ new Date(), wt(removeEventListener), yt());
|
|
5651
5863
|
}, yt = function() {
|
|
5652
|
-
if (
|
|
5653
|
-
var r = { entryType: "first-input", name: C.type, target: C.target, cancelable: C.cancelable, startTime: C.timeStamp, processingStart: C.timeStamp +
|
|
5864
|
+
if (X >= 0 && X < pt - hr) {
|
|
5865
|
+
var r = { entryType: "first-input", name: C.type, target: C.target, cancelable: C.cancelable, startTime: C.timeStamp, processingStart: C.timeStamp + X };
|
|
5654
5866
|
le.forEach((function(e) {
|
|
5655
5867
|
e(r);
|
|
5656
5868
|
})), le = [];
|
|
5657
5869
|
}
|
|
5658
|
-
},
|
|
5870
|
+
}, fr = function(r) {
|
|
5659
5871
|
if (r.cancelable) {
|
|
5660
5872
|
var e = (r.timeStamp > 1e12 ? /* @__PURE__ */ new Date() : performance.now()) - r.timeStamp;
|
|
5661
5873
|
r.type == "pointerdown" ? (function(t, s) {
|
|
@@ -5671,56 +5883,56 @@ var Le, C, G, pt, le, Et = -1, V = function(r) {
|
|
|
5671
5883
|
}
|
|
5672
5884
|
}, wt = function(r) {
|
|
5673
5885
|
["mousedown", "keydown", "touchstart", "pointerdown"].forEach((function(e) {
|
|
5674
|
-
return r(e,
|
|
5886
|
+
return r(e, fr, W);
|
|
5675
5887
|
}));
|
|
5676
|
-
},
|
|
5888
|
+
}, Pe = [100, 300], mr = function(r, e) {
|
|
5677
5889
|
e = e || {}, z((function() {
|
|
5678
|
-
var t, s =
|
|
5679
|
-
|
|
5680
|
-
}, o = function(
|
|
5681
|
-
|
|
5682
|
-
}, l =
|
|
5683
|
-
t = w(r, n,
|
|
5890
|
+
var t, s = Ve(), n = y("FID"), i = function(d) {
|
|
5891
|
+
d.startTime < s.firstHiddenTime && (n.value = d.processingStart - d.startTime, n.entries.push(d), t(!0));
|
|
5892
|
+
}, o = function(d) {
|
|
5893
|
+
d.forEach(i);
|
|
5894
|
+
}, l = x("first-input", o);
|
|
5895
|
+
t = w(r, n, Pe, e.reportAllChanges), l && (K(ue((function() {
|
|
5684
5896
|
o(l.takeRecords()), l.disconnect();
|
|
5685
5897
|
}))), V((function() {
|
|
5686
|
-
var
|
|
5687
|
-
n = y("FID"), t = w(r, n,
|
|
5898
|
+
var d;
|
|
5899
|
+
n = y("FID"), t = w(r, n, Pe, e.reportAllChanges), le = [], X = -1, C = null, wt(addEventListener), d = i, le.push(d), yt();
|
|
5688
5900
|
})));
|
|
5689
5901
|
}));
|
|
5690
5902
|
};
|
|
5691
|
-
const
|
|
5903
|
+
const gr = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
5692
5904
|
__proto__: null,
|
|
5693
|
-
CLSThresholds:
|
|
5694
|
-
FCPThresholds:
|
|
5695
|
-
FIDThresholds:
|
|
5696
|
-
INPThresholds:
|
|
5697
|
-
LCPThresholds:
|
|
5698
|
-
TTFBThresholds:
|
|
5699
|
-
onCLS:
|
|
5700
|
-
onFCP:
|
|
5701
|
-
onFID:
|
|
5702
|
-
onINP:
|
|
5703
|
-
onLCP:
|
|
5704
|
-
onTTFB:
|
|
5905
|
+
CLSThresholds: Ce,
|
|
5906
|
+
FCPThresholds: Me,
|
|
5907
|
+
FIDThresholds: Pe,
|
|
5908
|
+
INPThresholds: Re,
|
|
5909
|
+
LCPThresholds: Ne,
|
|
5910
|
+
TTFBThresholds: Oe,
|
|
5911
|
+
onCLS: sr,
|
|
5912
|
+
onFCP: Et,
|
|
5913
|
+
onFID: mr,
|
|
5914
|
+
onINP: lr,
|
|
5915
|
+
onLCP: cr,
|
|
5916
|
+
onTTFB: ur
|
|
5705
5917
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
5706
5918
|
export {
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5919
|
+
p as AppConfigValidationError,
|
|
5920
|
+
pr as DEFAULT_SESSION_TIMEOUT,
|
|
5921
|
+
ye as DEFAULT_WEB_VITALS_MODE,
|
|
5710
5922
|
A as DeviceType,
|
|
5711
5923
|
se as EmitterEvent,
|
|
5712
5924
|
B as ErrorType,
|
|
5713
5925
|
u as EventType,
|
|
5714
|
-
|
|
5926
|
+
Ar as InitializationTimeoutError,
|
|
5715
5927
|
N as IntegrationValidationError,
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5928
|
+
wr as MAX_ARRAY_LENGTH,
|
|
5929
|
+
Ir as MAX_CUSTOM_EVENT_ARRAY_SIZE,
|
|
5930
|
+
Tr as MAX_CUSTOM_EVENT_KEYS,
|
|
5931
|
+
Sr as MAX_CUSTOM_EVENT_NAME_LENGTH,
|
|
5932
|
+
Er as MAX_CUSTOM_EVENT_STRING_SIZE,
|
|
5933
|
+
vr as MAX_NESTED_OBJECT_KEYS,
|
|
5934
|
+
_r as MAX_STRING_LENGTH,
|
|
5935
|
+
yr as MAX_STRING_LENGTH_IN_ARRAY,
|
|
5724
5936
|
ie as Mode,
|
|
5725
5937
|
at as PII_PATTERNS,
|
|
5726
5938
|
O as PermanentError,
|
|
@@ -5731,11 +5943,11 @@ export {
|
|
|
5731
5943
|
$ as SpecialApiUrl,
|
|
5732
5944
|
ne as TimeoutError,
|
|
5733
5945
|
j as TraceLogValidationError,
|
|
5734
|
-
|
|
5946
|
+
Mr as WEB_VITALS_GOOD_THRESHOLDS,
|
|
5735
5947
|
ze as WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS,
|
|
5736
5948
|
Yt as WEB_VITALS_POOR_THRESHOLDS,
|
|
5737
5949
|
Qe as getWebVitalsThresholds,
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5950
|
+
br as isPrimaryScrollEvent,
|
|
5951
|
+
Lr as isSecondaryScrollEvent,
|
|
5952
|
+
Cr as tracelog
|
|
5741
5953
|
};
|