@tracelog/lib 2.3.1 → 2.4.0-rc.85.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/tracelog.esm.js +649 -620
- package/dist/browser/tracelog.esm.js.map +1 -1
- package/dist/browser/tracelog.js +1 -1
- package/dist/browser/tracelog.js.map +1 -1
- package/dist/public-api.cjs +2 -6717
- package/dist/public-api.cjs.map +1 -1
- package/dist/public-api.d.mts +23 -10
- package/dist/public-api.d.ts +23 -10
- package/dist/public-api.js +2 -6684
- package/dist/public-api.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const w = "data-tlog",
|
|
1
|
+
const Br = 9e5;
|
|
2
|
+
const Wr = 120, Gr = 8192, Xr = 10, Qr = 10, jr = 20;
|
|
3
|
+
const zr = 1e3, Kr = 500, Yr = 100;
|
|
4
|
+
const w = "data-tlog", lt = [
|
|
5
5
|
"button",
|
|
6
6
|
"a",
|
|
7
7
|
'input[type="button"]',
|
|
@@ -33,7 +33,7 @@ const w = "data-tlog", at = [
|
|
|
33
33
|
".menu-item",
|
|
34
34
|
"[data-testid]",
|
|
35
35
|
'[tabindex="0"]'
|
|
36
|
-
],
|
|
36
|
+
], ct = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"], ut = [
|
|
37
37
|
"token",
|
|
38
38
|
"auth",
|
|
39
39
|
"key",
|
|
@@ -70,54 +70,55 @@ const m = {
|
|
|
70
70
|
INVALID_VIEWPORT_THRESHOLD: "Viewport threshold must be a number between 0 and 1",
|
|
71
71
|
INVALID_VIEWPORT_MIN_DWELL_TIME: "Viewport minDwellTime must be a non-negative number",
|
|
72
72
|
INVALID_VIEWPORT_COOLDOWN_PERIOD: "Viewport cooldownPeriod must be a non-negative number",
|
|
73
|
-
INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS: "Viewport maxTrackedElements must be a positive number"
|
|
74
|
-
|
|
73
|
+
INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS: "Viewport maxTrackedElements must be a positive number",
|
|
74
|
+
INVALID_SEND_INTERVAL: "Send interval must be between 1000ms (1 second) and 60000ms (60 seconds)"
|
|
75
|
+
}, dt = [
|
|
75
76
|
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
|
76
77
|
/javascript:/gi,
|
|
77
78
|
/on\w+\s*=/gi,
|
|
78
79
|
/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
|
|
79
80
|
/<embed\b[^>]*>/gi,
|
|
80
81
|
/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi
|
|
81
|
-
],
|
|
82
|
-
var
|
|
83
|
-
class
|
|
82
|
+
], I = "tlog", F = `${I}:qa_mode`, be = `${I}:uid`, Ge = "tlog_mode", Le = "qa", Ae = "qa_off", ht = (s) => s ? `${I}:${s}:queue` : `${I}:queue`, ft = (s) => s ? `${I}:${s}:session` : `${I}:session`, mt = (s) => s ? `${I}:${s}:broadcast` : `${I}:broadcast`, Me = (s, e) => `${I}:${s}:session_counts:${e}`, Ce = 10080 * 60 * 1e3, Re = `${I}:session_counts_last_cleanup`, Ne = 3600 * 1e3;
|
|
83
|
+
var H = /* @__PURE__ */ ((s) => (s.Localhost = "localhost:8080", s.Fail = "localhost:9999", s))(H || {}), A = /* @__PURE__ */ ((s) => (s.Mobile = "mobile", s.Tablet = "tablet", s.Desktop = "desktop", s.Unknown = "unknown", s))(A || {}), le = /* @__PURE__ */ ((s) => (s.EVENT = "event", s.QUEUE = "queue", s))(le || {});
|
|
84
|
+
class D extends Error {
|
|
84
85
|
constructor(e, t) {
|
|
85
|
-
super(e), this.statusCode = t, this.name = "PermanentError", Error.captureStackTrace && Error.captureStackTrace(this,
|
|
86
|
+
super(e), this.statusCode = t, this.name = "PermanentError", Error.captureStackTrace && Error.captureStackTrace(this, D);
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
|
-
var d = /* @__PURE__ */ ((s) => (s.PAGE_VIEW = "page_view", s.CLICK = "click", s.SCROLL = "scroll", s.SESSION_START = "session_start", s.CUSTOM = "custom", s.WEB_VITALS = "web_vitals", s.ERROR = "error", s.VIEWPORT_VISIBLE = "viewport_visible", s))(d || {}),
|
|
89
|
-
const
|
|
90
|
-
class
|
|
89
|
+
var d = /* @__PURE__ */ ((s) => (s.PAGE_VIEW = "page_view", s.CLICK = "click", s.SCROLL = "scroll", s.SESSION_START = "session_start", s.CUSTOM = "custom", s.WEB_VITALS = "web_vitals", s.ERROR = "error", s.VIEWPORT_VISIBLE = "viewport_visible", s))(d || {}), j = /* @__PURE__ */ ((s) => (s.UP = "up", s.DOWN = "down", s))(j || {}), x = /* @__PURE__ */ ((s) => (s.JS_ERROR = "js_error", s.PROMISE_REJECTION = "promise_rejection", s))(x || {}), Y = /* @__PURE__ */ ((s) => (s.QA = "qa", s))(Y || {});
|
|
90
|
+
const qr = (s) => s.type === d.SCROLL && "scroll_data" in s && s.scroll_data.is_primary === !0, Jr = (s) => s.type === d.SCROLL && "scroll_data" in s && s.scroll_data.is_primary === !1;
|
|
91
|
+
class $ extends Error {
|
|
91
92
|
constructor(e, t, r) {
|
|
92
93
|
super(e), this.errorCode = t, this.layer = r, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
|
-
class f extends
|
|
96
|
+
class f extends $ {
|
|
96
97
|
constructor(e, t = "config") {
|
|
97
98
|
super(e, "APP_CONFIG_INVALID", t);
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
|
-
class
|
|
101
|
+
class gt extends $ {
|
|
101
102
|
constructor(e, t = "config") {
|
|
102
103
|
super(e, "SESSION_TIMEOUT_INVALID", t);
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
class
|
|
106
|
+
class Oe extends $ {
|
|
106
107
|
constructor(e, t = "config") {
|
|
107
108
|
super(e, "SAMPLING_RATE_INVALID", t);
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
|
-
class
|
|
111
|
+
class P extends $ {
|
|
111
112
|
constructor(e, t = "config") {
|
|
112
113
|
super(e, "INTEGRATION_INVALID", t);
|
|
113
114
|
}
|
|
114
115
|
}
|
|
115
|
-
class
|
|
116
|
+
class Zr extends $ {
|
|
116
117
|
constructor(e, t, r = "runtime") {
|
|
117
118
|
super(e, "INITIALIZATION_TIMEOUT", r), this.timeoutMs = t;
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
|
-
const
|
|
121
|
+
const Xe = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", Qe = "background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", Et = "background: #d32f2f; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", St = (s, e) => {
|
|
121
122
|
if (e) {
|
|
122
123
|
if (e instanceof Error) {
|
|
123
124
|
const t = e.message.replace(/\s+at\s+.*$/gm, "").replace(/\s*\([^()]+:\d+:\d+\)/g, "");
|
|
@@ -136,24 +137,24 @@ const Ge = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8
|
|
|
136
137
|
return `[TraceLog] ${s}: ${String(e)}`;
|
|
137
138
|
}
|
|
138
139
|
return `[TraceLog] ${s}`;
|
|
139
|
-
},
|
|
140
|
+
}, pt = () => {
|
|
140
141
|
if (typeof window > "u" || typeof sessionStorage > "u")
|
|
141
142
|
return !1;
|
|
142
143
|
try {
|
|
143
|
-
return sessionStorage.getItem(
|
|
144
|
+
return sessionStorage.getItem(F) === "true";
|
|
144
145
|
} catch {
|
|
145
146
|
return !1;
|
|
146
147
|
}
|
|
147
|
-
},
|
|
148
|
-
const { error: r, data: n, showToClient: i = !1, style: o, visibility:
|
|
149
|
-
if (!
|
|
148
|
+
}, l = (s, e, t) => {
|
|
149
|
+
const { error: r, data: n, showToClient: i = !1, style: o, visibility: a } = t ?? {}, c = r ? St(e, r) : `[TraceLog] ${e}`, u = s === "error" ? "error" : s === "warn" ? "warn" : "log";
|
|
150
|
+
if (!Tt(a, i))
|
|
150
151
|
return;
|
|
151
|
-
const g =
|
|
152
|
+
const g = _t(a, o), p = n !== void 0 ? ce(n) : void 0;
|
|
152
153
|
vt(u, c, g, p);
|
|
153
|
-
},
|
|
154
|
+
}, Tt = (s, e) => s === "critical" ? !0 : s === "qa" || e ? pt() : !1, _t = (s, e) => e !== void 0 && e !== "" ? e : s === "critical" ? Et : "", vt = (s, e, t, r) => {
|
|
154
155
|
const n = t !== void 0 && t !== "", i = n ? `%c${e}` : e;
|
|
155
156
|
r !== void 0 ? n ? console[s](i, t, r) : console[s](i, r) : n ? console[s](i, t) : console[s](i);
|
|
156
|
-
},
|
|
157
|
+
}, ce = (s) => {
|
|
157
158
|
const e = {}, t = ["token", "password", "secret", "key", "apikey", "api_key", "sessionid", "session_id"];
|
|
158
159
|
for (const [r, n] of Object.entries(s)) {
|
|
159
160
|
const i = r.toLowerCase();
|
|
@@ -161,16 +162,16 @@ const Ge = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8
|
|
|
161
162
|
e[r] = "[REDACTED]";
|
|
162
163
|
continue;
|
|
163
164
|
}
|
|
164
|
-
n !== null && typeof n == "object" && !Array.isArray(n) ? e[r] =
|
|
165
|
-
(o) => o !== null && typeof o == "object" && !Array.isArray(o) ?
|
|
165
|
+
n !== null && typeof n == "object" && !Array.isArray(n) ? e[r] = ce(n) : Array.isArray(n) ? e[r] = n.map(
|
|
166
|
+
(o) => o !== null && typeof o == "object" && !Array.isArray(o) ? ce(o) : o
|
|
166
167
|
) : e[r] = n;
|
|
167
168
|
}
|
|
168
169
|
return e;
|
|
169
170
|
};
|
|
170
|
-
let
|
|
171
|
+
let ue, je;
|
|
171
172
|
const It = () => {
|
|
172
|
-
typeof window < "u" && !
|
|
173
|
-
},
|
|
173
|
+
typeof window < "u" && !ue && (ue = window.matchMedia("(pointer: coarse)"), je = window.matchMedia("(hover: none)"));
|
|
174
|
+
}, q = "Unknown", wt = (s) => {
|
|
174
175
|
const e = s.userAgentData?.platform;
|
|
175
176
|
if (e != null && e !== "") {
|
|
176
177
|
if (/windows/i.test(e)) return "Windows";
|
|
@@ -181,8 +182,8 @@ const It = () => {
|
|
|
181
182
|
if (/ios/i.test(e)) return "iOS";
|
|
182
183
|
}
|
|
183
184
|
const t = navigator.userAgent;
|
|
184
|
-
return /Windows/i.test(t) ? "Windows" : /iPhone|iPad|iPod/i.test(t) ? "iOS" : /Mac OS X|Macintosh/i.test(t) ? "macOS" : /Android/i.test(t) ? "Android" : /CrOS/i.test(t) ? "ChromeOS" : /Linux/i.test(t) ? "Linux" :
|
|
185
|
-
},
|
|
185
|
+
return /Windows/i.test(t) ? "Windows" : /iPhone|iPad|iPod/i.test(t) ? "iOS" : /Mac OS X|Macintosh/i.test(t) ? "macOS" : /Android/i.test(t) ? "Android" : /CrOS/i.test(t) ? "ChromeOS" : /Linux/i.test(t) ? "Linux" : q;
|
|
186
|
+
}, yt = (s) => {
|
|
186
187
|
const e = s.userAgentData?.brands;
|
|
187
188
|
if (e != null && e.length > 0) {
|
|
188
189
|
const n = e.filter((i) => !/not.?a.?brand|chromium/i.test(i.brand))[0];
|
|
@@ -192,8 +193,8 @@ const It = () => {
|
|
|
192
193
|
}
|
|
193
194
|
}
|
|
194
195
|
const t = navigator.userAgent;
|
|
195
|
-
return /Edg\//i.test(t) ? "Edge" : /OPR\//i.test(t) ? "Opera" : /Chrome/i.test(t) ? "Chrome" : /Firefox/i.test(t) ? "Firefox" : /Safari/i.test(t) && !/Chrome/i.test(t) ? "Safari" :
|
|
196
|
-
},
|
|
196
|
+
return /Edg\//i.test(t) ? "Edge" : /OPR\//i.test(t) ? "Opera" : /Chrome/i.test(t) ? "Chrome" : /Firefox/i.test(t) ? "Firefox" : /Safari/i.test(t) && !/Chrome/i.test(t) ? "Safari" : q;
|
|
197
|
+
}, bt = () => {
|
|
197
198
|
try {
|
|
198
199
|
const s = navigator;
|
|
199
200
|
if (s.userAgentData != null && typeof s.userAgentData.mobile == "boolean") {
|
|
@@ -201,27 +202,27 @@ const It = () => {
|
|
|
201
202
|
return c != null && c !== "" && /ipad|tablet/i.test(c) ? A.Tablet : s.userAgentData.mobile ? A.Mobile : A.Desktop;
|
|
202
203
|
}
|
|
203
204
|
It();
|
|
204
|
-
const e = window.innerWidth, t =
|
|
205
|
-
return e <= 767 || o && n ? A.Mobile : e >= 768 && e <= 1024 ||
|
|
205
|
+
const e = window.innerWidth, t = ue?.matches ?? !1, r = je?.matches ?? !1, n = "ontouchstart" in window || navigator.maxTouchPoints > 0, i = navigator.userAgent.toLowerCase(), o = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i), a = /tablet|ipad|android(?!.*mobile)/.test(i);
|
|
206
|
+
return e <= 767 || o && n ? A.Mobile : e >= 768 && e <= 1024 || a || t && r && n ? A.Tablet : A.Desktop;
|
|
206
207
|
} catch (s) {
|
|
207
|
-
return
|
|
208
|
+
return l("debug", "Device detection failed, defaulting to desktop", { error: s }), A.Desktop;
|
|
208
209
|
}
|
|
209
|
-
},
|
|
210
|
+
}, Lt = () => {
|
|
210
211
|
try {
|
|
211
212
|
const s = navigator;
|
|
212
213
|
return {
|
|
213
|
-
type:
|
|
214
|
-
os:
|
|
215
|
-
browser:
|
|
214
|
+
type: bt(),
|
|
215
|
+
os: wt(s),
|
|
216
|
+
browser: yt(s)
|
|
216
217
|
};
|
|
217
218
|
} catch (s) {
|
|
218
|
-
return
|
|
219
|
+
return l("debug", "Device info detection failed, using defaults", { error: s }), {
|
|
219
220
|
type: A.Desktop,
|
|
220
|
-
os:
|
|
221
|
-
browser:
|
|
221
|
+
os: q,
|
|
222
|
+
browser: q
|
|
222
223
|
};
|
|
223
224
|
}
|
|
224
|
-
},
|
|
225
|
+
}, ze = [
|
|
225
226
|
// Email addresses
|
|
226
227
|
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi,
|
|
227
228
|
// US Phone numbers (various formats)
|
|
@@ -236,7 +237,7 @@ const It = () => {
|
|
|
236
237
|
/Bearer\s+[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?(?:\.[A-Za-z0-9_-]+)?/gi,
|
|
237
238
|
// Passwords in connection strings (protocol://user:password@host)
|
|
238
239
|
/:\/\/[^:/]+:([^@]+)@/gi
|
|
239
|
-
],
|
|
240
|
+
], Pe = 500, De = 5e3, z = 50, At = z * 2, Ke = 1, Mt = 1e3, Ct = 10, Ve = 5e3, Rt = 6e4, es = {
|
|
240
241
|
LCP: 2500,
|
|
241
242
|
// Good: ≤ 2.5s
|
|
242
243
|
FCP: 1800,
|
|
@@ -260,7 +261,7 @@ const It = () => {
|
|
|
260
261
|
TTFB: 800,
|
|
261
262
|
// Needs improvement: > 800ms
|
|
262
263
|
LONG_TASK: 50
|
|
263
|
-
},
|
|
264
|
+
}, Nt = {
|
|
264
265
|
LCP: 4e3,
|
|
265
266
|
// Poor: > 4s
|
|
266
267
|
FCP: 3e3,
|
|
@@ -272,7 +273,7 @@ const It = () => {
|
|
|
272
273
|
TTFB: 1800,
|
|
273
274
|
// Poor: > 1800ms
|
|
274
275
|
LONG_TASK: 50
|
|
275
|
-
},
|
|
276
|
+
}, de = "needs-improvement", Ue = (s = de) => {
|
|
276
277
|
switch (s) {
|
|
277
278
|
case "all":
|
|
278
279
|
return { LCP: 0, FCP: 0, CLS: 0, INP: 0, TTFB: 0, LONG_TASK: 0 };
|
|
@@ -280,45 +281,45 @@ const It = () => {
|
|
|
280
281
|
case "needs-improvement":
|
|
281
282
|
return ke;
|
|
282
283
|
case "poor":
|
|
283
|
-
return
|
|
284
|
+
return Nt;
|
|
284
285
|
default:
|
|
285
286
|
return ke;
|
|
286
287
|
}
|
|
287
|
-
},
|
|
288
|
+
}, Ot = 1e3, Pt = 50, Dt = "2.4.0", Vt = Dt, Ye = () => typeof window < "u" && typeof sessionStorage < "u", kt = () => {
|
|
288
289
|
try {
|
|
289
290
|
const s = new URLSearchParams(window.location.search);
|
|
290
|
-
s.delete(
|
|
291
|
+
s.delete(Ge);
|
|
291
292
|
const e = s.toString(), t = window.location.pathname + (e ? "?" + e : "") + window.location.hash;
|
|
292
293
|
window.history.replaceState({}, "", t);
|
|
293
294
|
} catch {
|
|
294
295
|
}
|
|
295
|
-
},
|
|
296
|
-
if (!
|
|
296
|
+
}, Ut = () => {
|
|
297
|
+
if (!Ye())
|
|
297
298
|
return !1;
|
|
298
299
|
try {
|
|
299
|
-
const e = new URLSearchParams(window.location.search).get(
|
|
300
|
+
const e = new URLSearchParams(window.location.search).get(Ge), t = sessionStorage.getItem(F);
|
|
300
301
|
let r = null;
|
|
301
|
-
return e ===
|
|
302
|
-
visibility: "qa",
|
|
303
|
-
style: Ge
|
|
304
|
-
})) : e === Le && (r = !1, sessionStorage.setItem(x, "false"), a("info", "QA Mode DISABLED", {
|
|
302
|
+
return e === Le ? (r = !0, sessionStorage.setItem(F, "true"), l("info", "QA Mode ACTIVE", {
|
|
305
303
|
visibility: "qa",
|
|
306
304
|
style: Xe
|
|
307
|
-
}))
|
|
305
|
+
})) : e === Ae && (r = !1, sessionStorage.setItem(F, "false"), l("info", "QA Mode DISABLED", {
|
|
306
|
+
visibility: "qa",
|
|
307
|
+
style: Qe
|
|
308
|
+
})), (e === Le || e === Ae) && kt(), r ?? t === "true";
|
|
308
309
|
} catch {
|
|
309
310
|
return !1;
|
|
310
311
|
}
|
|
311
|
-
},
|
|
312
|
-
if (
|
|
312
|
+
}, Ht = (s) => {
|
|
313
|
+
if (Ye())
|
|
313
314
|
try {
|
|
314
|
-
sessionStorage.setItem(
|
|
315
|
+
sessionStorage.setItem(F, s ? "true" : "false"), l("info", s ? "QA Mode ACTIVE" : "QA Mode DISABLED", {
|
|
315
316
|
visibility: "qa",
|
|
316
|
-
style: s ?
|
|
317
|
+
style: s ? Xe : Qe
|
|
317
318
|
});
|
|
318
319
|
} catch {
|
|
319
|
-
|
|
320
|
+
l("debug", "Cannot set QA mode: sessionStorage unavailable");
|
|
320
321
|
}
|
|
321
|
-
},
|
|
322
|
+
}, xt = [
|
|
322
323
|
"co.uk",
|
|
323
324
|
"org.uk",
|
|
324
325
|
"com.au",
|
|
@@ -330,40 +331,40 @@ const It = () => {
|
|
|
330
331
|
"co.in",
|
|
331
332
|
"com.cn",
|
|
332
333
|
"co.za"
|
|
333
|
-
],
|
|
334
|
+
], He = (s) => {
|
|
334
335
|
const e = s.toLowerCase().split(".");
|
|
335
336
|
if (e.length <= 2)
|
|
336
337
|
return s.toLowerCase();
|
|
337
338
|
const t = e.slice(-2).join(".");
|
|
338
|
-
return
|
|
339
|
-
},
|
|
339
|
+
return xt.includes(t) ? e.slice(-3).join(".") : e.slice(-2).join(".");
|
|
340
|
+
}, Ft = (s, e) => s === e ? !0 : He(s) === He(e), se = () => {
|
|
340
341
|
const s = document.referrer;
|
|
341
342
|
if (!s)
|
|
342
343
|
return "Direct";
|
|
343
344
|
try {
|
|
344
345
|
const e = new URL(s).hostname.toLowerCase(), t = window.location.hostname.toLowerCase();
|
|
345
|
-
return
|
|
346
|
+
return Ft(e, t) ? "Direct" : s;
|
|
346
347
|
} catch (e) {
|
|
347
|
-
return
|
|
348
|
+
return l("debug", "Failed to parse referrer URL, using raw value", { error: e, data: { referrer: s } }), s;
|
|
348
349
|
}
|
|
349
|
-
},
|
|
350
|
+
}, ne = () => {
|
|
350
351
|
const s = new URLSearchParams(window.location.search), e = {};
|
|
351
|
-
return
|
|
352
|
+
return ct.forEach((r) => {
|
|
352
353
|
const n = s.get(r);
|
|
353
354
|
if (n) {
|
|
354
355
|
const i = r.split("utm_")[1];
|
|
355
356
|
e[i] = n;
|
|
356
357
|
}
|
|
357
358
|
}), Object.keys(e).length ? e : void 0;
|
|
358
|
-
},
|
|
359
|
+
}, $t = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (s) => {
|
|
359
360
|
const e = Math.random() * 16 | 0;
|
|
360
361
|
return (s === "x" ? e : e & 3 | 8).toString(16);
|
|
361
362
|
});
|
|
362
|
-
let
|
|
363
|
-
const
|
|
363
|
+
let G = 0, X = 0;
|
|
364
|
+
const Bt = () => {
|
|
364
365
|
let s = Date.now();
|
|
365
|
-
s <
|
|
366
|
-
const e =
|
|
366
|
+
s < X && (s = X), s === X ? G = (G + 1) % 1e3 : G = 0, X = s;
|
|
367
|
+
const e = G.toString().padStart(3, "0");
|
|
367
368
|
let t = "";
|
|
368
369
|
try {
|
|
369
370
|
if (typeof crypto < "u" && crypto.getRandomValues) {
|
|
@@ -373,14 +374,14 @@ const $t = () => {
|
|
|
373
374
|
} catch {
|
|
374
375
|
}
|
|
375
376
|
return t || (t = Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")), `${s}-${e}-${t}`;
|
|
376
|
-
},
|
|
377
|
+
}, qe = (s, e = !1) => {
|
|
377
378
|
try {
|
|
378
379
|
const t = new URL(s), r = t.protocol === "https:", n = t.protocol === "http:";
|
|
379
380
|
return r || e && n;
|
|
380
381
|
} catch {
|
|
381
382
|
return !1;
|
|
382
383
|
}
|
|
383
|
-
},
|
|
384
|
+
}, Wt = (s) => {
|
|
384
385
|
try {
|
|
385
386
|
const t = new URL(window.location.href).hostname;
|
|
386
387
|
if (!t || typeof t != "string")
|
|
@@ -398,57 +399,57 @@ const $t = () => {
|
|
|
398
399
|
if (r.length === 2 ? n = r.join(".") : n = r.slice(-2).join("."), !n || n.split(".").length < 2)
|
|
399
400
|
throw new Error("Invalid domain structure for SaaS");
|
|
400
401
|
const i = `https://${s}.${n}/collect`;
|
|
401
|
-
if (!
|
|
402
|
+
if (!qe(i))
|
|
402
403
|
throw new Error("Generated URL failed validation");
|
|
403
404
|
return i;
|
|
404
405
|
} catch (e) {
|
|
405
406
|
throw new Error(`Invalid SaaS URL configuration: ${e instanceof Error ? e.message : String(e)}`);
|
|
406
407
|
}
|
|
407
|
-
},
|
|
408
|
+
}, Gt = (s) => {
|
|
408
409
|
const e = {};
|
|
409
|
-
s.integrations?.tracelog?.projectId && (e.saas =
|
|
410
|
+
s.integrations?.tracelog?.projectId && (e.saas = Wt(s.integrations.tracelog.projectId));
|
|
410
411
|
const t = s.integrations?.custom?.collectApiUrl;
|
|
411
412
|
if (t) {
|
|
412
413
|
const r = s.integrations?.custom?.allowHttp ?? !1;
|
|
413
|
-
if (!
|
|
414
|
+
if (!qe(t, r))
|
|
414
415
|
throw new Error("Invalid custom API URL");
|
|
415
416
|
e.custom = t;
|
|
416
417
|
}
|
|
417
418
|
return e;
|
|
418
|
-
},
|
|
419
|
+
}, he = (s, e = []) => {
|
|
419
420
|
if (!s || typeof s != "string")
|
|
420
|
-
return
|
|
421
|
+
return l("warn", "Invalid URL provided to normalizeUrl", { data: { type: typeof s } }), s || "";
|
|
421
422
|
try {
|
|
422
|
-
const t = new URL(s), r = t.searchParams, n = [.../* @__PURE__ */ new Set([...
|
|
423
|
+
const t = new URL(s), r = t.searchParams, n = [.../* @__PURE__ */ new Set([...ut, ...e])];
|
|
423
424
|
let i = !1;
|
|
424
425
|
const o = [];
|
|
425
426
|
return n.forEach((c) => {
|
|
426
427
|
r.has(c) && (r.delete(c), i = !0, o.push(c));
|
|
427
428
|
}), !i && s.includes("?") ? s : (t.search = r.toString(), t.toString());
|
|
428
429
|
} catch (t) {
|
|
429
|
-
return
|
|
430
|
+
return l("warn", "URL normalization failed, returning original", { error: t, data: { urlLength: s?.length } }), s;
|
|
430
431
|
}
|
|
431
|
-
},
|
|
432
|
+
}, xe = (s) => {
|
|
432
433
|
if (!s || typeof s != "string" || s.trim().length === 0)
|
|
433
434
|
return "";
|
|
434
435
|
let e = s;
|
|
435
436
|
s.length > 1e3 && (e = s.slice(0, Math.max(0, 1e3)));
|
|
436
437
|
let t = 0;
|
|
437
|
-
for (const n of
|
|
438
|
+
for (const n of dt) {
|
|
438
439
|
const i = e;
|
|
439
440
|
e = e.replace(n, ""), i !== e && t++;
|
|
440
441
|
}
|
|
441
|
-
return t > 0 &&
|
|
442
|
+
return t > 0 && l("warn", "XSS patterns detected and removed", {
|
|
442
443
|
data: {
|
|
443
444
|
patternMatches: t,
|
|
444
445
|
valueLength: s.length
|
|
445
446
|
}
|
|
446
447
|
}), e.trim();
|
|
447
|
-
},
|
|
448
|
+
}, fe = (s, e = 0) => {
|
|
448
449
|
if (s == null)
|
|
449
450
|
return null;
|
|
450
451
|
if (typeof s == "string")
|
|
451
|
-
return
|
|
452
|
+
return xe(s);
|
|
452
453
|
if (typeof s == "number")
|
|
453
454
|
return !Number.isFinite(s) || s < -Number.MAX_SAFE_INTEGER || s > Number.MAX_SAFE_INTEGER ? 0 : s;
|
|
454
455
|
if (typeof s == "boolean")
|
|
@@ -456,38 +457,38 @@ const $t = () => {
|
|
|
456
457
|
if (e > 10)
|
|
457
458
|
return null;
|
|
458
459
|
if (Array.isArray(s))
|
|
459
|
-
return s.slice(0, 100).map((n) =>
|
|
460
|
+
return s.slice(0, 100).map((n) => fe(n, e + 1)).filter((n) => n !== null);
|
|
460
461
|
if (typeof s == "object") {
|
|
461
462
|
const t = {}, n = Object.entries(s).slice(0, 20);
|
|
462
463
|
for (const [i, o] of n) {
|
|
463
|
-
const
|
|
464
|
-
if (
|
|
465
|
-
const c =
|
|
466
|
-
c !== null && (t[
|
|
464
|
+
const a = xe(i);
|
|
465
|
+
if (a) {
|
|
466
|
+
const c = fe(o, e + 1);
|
|
467
|
+
c !== null && (t[a] = c);
|
|
467
468
|
}
|
|
468
469
|
}
|
|
469
470
|
return t;
|
|
470
471
|
}
|
|
471
472
|
return null;
|
|
472
|
-
},
|
|
473
|
+
}, Xt = (s) => {
|
|
473
474
|
if (typeof s != "object" || s === null)
|
|
474
475
|
return {};
|
|
475
476
|
try {
|
|
476
|
-
const e =
|
|
477
|
+
const e = fe(s);
|
|
477
478
|
return typeof e == "object" && e !== null ? e : {};
|
|
478
479
|
} catch (e) {
|
|
479
480
|
const t = e instanceof Error ? e.message : String(e);
|
|
480
481
|
throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`);
|
|
481
482
|
}
|
|
482
|
-
},
|
|
483
|
+
}, Qt = (s) => {
|
|
483
484
|
if (s !== void 0 && (s === null || typeof s != "object"))
|
|
484
485
|
throw new f("Configuration must be an object", "config");
|
|
485
486
|
if (s) {
|
|
486
487
|
if (s.sessionTimeout !== void 0 && (typeof s.sessionTimeout != "number" || s.sessionTimeout < 3e4 || s.sessionTimeout > 864e5))
|
|
487
|
-
throw new
|
|
488
|
+
throw new gt(m.INVALID_SESSION_TIMEOUT, "config");
|
|
488
489
|
if (s.globalMetadata !== void 0 && (typeof s.globalMetadata != "object" || s.globalMetadata === null))
|
|
489
490
|
throw new f(m.INVALID_GLOBAL_METADATA, "config");
|
|
490
|
-
if (s.integrations &&
|
|
491
|
+
if (s.integrations && zt(s.integrations), s.sensitiveQueryParams !== void 0) {
|
|
491
492
|
if (!Array.isArray(s.sensitiveQueryParams))
|
|
492
493
|
throw new f(m.INVALID_SENSITIVE_QUERY_PARAMS, "config");
|
|
493
494
|
for (const e of s.sensitiveQueryParams)
|
|
@@ -495,9 +496,9 @@ const $t = () => {
|
|
|
495
496
|
throw new f("All sensitive query params must be strings", "config");
|
|
496
497
|
}
|
|
497
498
|
if (s.errorSampling !== void 0 && (typeof s.errorSampling != "number" || s.errorSampling < 0 || s.errorSampling > 1))
|
|
498
|
-
throw new
|
|
499
|
+
throw new Oe(m.INVALID_ERROR_SAMPLING_RATE, "config");
|
|
499
500
|
if (s.samplingRate !== void 0 && (typeof s.samplingRate != "number" || s.samplingRate < 0 || s.samplingRate > 1))
|
|
500
|
-
throw new
|
|
501
|
+
throw new Oe(m.INVALID_SAMPLING_RATE, "config");
|
|
501
502
|
if (s.primaryScrollSelector !== void 0) {
|
|
502
503
|
if (typeof s.primaryScrollSelector != "string" || !s.primaryScrollSelector.trim())
|
|
503
504
|
throw new f(m.INVALID_PRIMARY_SCROLL_SELECTOR, "config");
|
|
@@ -517,7 +518,9 @@ const $t = () => {
|
|
|
517
518
|
throw new f(m.INVALID_CLICK_THROTTLE, "config");
|
|
518
519
|
if (s.maxSameEventPerMinute !== void 0 && (typeof s.maxSameEventPerMinute != "number" || s.maxSameEventPerMinute <= 0))
|
|
519
520
|
throw new f(m.INVALID_MAX_SAME_EVENT_PER_MINUTE, "config");
|
|
520
|
-
if (s.
|
|
521
|
+
if (s.sendIntervalMs !== void 0 && (!Number.isFinite(s.sendIntervalMs) || s.sendIntervalMs < 1e3 || s.sendIntervalMs > 6e4))
|
|
522
|
+
throw new f(m.INVALID_SEND_INTERVAL, "config");
|
|
523
|
+
if (s.viewport !== void 0 && jt(s.viewport), s.webVitalsMode !== void 0) {
|
|
521
524
|
if (typeof s.webVitalsMode != "string")
|
|
522
525
|
throw new f(
|
|
523
526
|
`Invalid webVitalsMode type: ${typeof s.webVitalsMode}. Must be a string`,
|
|
@@ -548,7 +551,7 @@ const $t = () => {
|
|
|
548
551
|
}
|
|
549
552
|
}
|
|
550
553
|
}
|
|
551
|
-
},
|
|
554
|
+
}, jt = (s) => {
|
|
552
555
|
if (typeof s != "object" || s === null)
|
|
553
556
|
throw new f(m.INVALID_VIEWPORT_CONFIG, "config");
|
|
554
557
|
if (!s.elements || !Array.isArray(s.elements))
|
|
@@ -578,37 +581,40 @@ const $t = () => {
|
|
|
578
581
|
throw new f(m.INVALID_VIEWPORT_COOLDOWN_PERIOD, "config");
|
|
579
582
|
if (s.maxTrackedElements !== void 0 && (typeof s.maxTrackedElements != "number" || s.maxTrackedElements <= 0))
|
|
580
583
|
throw new f(m.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS, "config");
|
|
581
|
-
},
|
|
584
|
+
}, zt = (s) => {
|
|
582
585
|
if (s) {
|
|
583
586
|
if (s.tracelog && (!s.tracelog.projectId || typeof s.tracelog.projectId != "string" || s.tracelog.projectId.trim() === ""))
|
|
584
|
-
throw new
|
|
587
|
+
throw new P(m.INVALID_TRACELOG_PROJECT_ID, "config");
|
|
585
588
|
if (s.custom) {
|
|
586
589
|
if (!s.custom.collectApiUrl || typeof s.custom.collectApiUrl != "string" || s.custom.collectApiUrl.trim() === "")
|
|
587
|
-
throw new
|
|
590
|
+
throw new P(m.INVALID_CUSTOM_API_URL, "config");
|
|
588
591
|
if (s.custom.allowHttp !== void 0 && typeof s.custom.allowHttp != "boolean")
|
|
589
|
-
throw new
|
|
592
|
+
throw new P("allowHttp must be a boolean", "config");
|
|
590
593
|
const e = s.custom.collectApiUrl.trim();
|
|
591
594
|
if (!e.startsWith("http://") && !e.startsWith("https://"))
|
|
592
|
-
throw new
|
|
595
|
+
throw new P('Custom API URL must start with "http://" or "https://"', "config");
|
|
593
596
|
if (!(s.custom.allowHttp ?? !1) && e.startsWith("http://"))
|
|
594
|
-
throw new
|
|
597
|
+
throw new P(
|
|
595
598
|
"Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)",
|
|
596
599
|
"config"
|
|
597
600
|
);
|
|
601
|
+
if (s.custom.fetchCredentials !== void 0 && !["include", "same-origin", "omit"].includes(s.custom.fetchCredentials))
|
|
602
|
+
throw new P('fetchCredentials must be "include", "same-origin", or "omit"', "config");
|
|
598
603
|
}
|
|
599
604
|
}
|
|
600
|
-
},
|
|
601
|
-
|
|
605
|
+
}, Kt = (s) => {
|
|
606
|
+
Qt(s);
|
|
602
607
|
const e = {
|
|
603
608
|
...s ?? {},
|
|
604
609
|
sessionTimeout: s?.sessionTimeout ?? 9e5,
|
|
605
610
|
globalMetadata: s?.globalMetadata ?? {},
|
|
606
611
|
sensitiveQueryParams: s?.sensitiveQueryParams ?? [],
|
|
607
|
-
errorSampling: s?.errorSampling ??
|
|
612
|
+
errorSampling: s?.errorSampling ?? Ke,
|
|
608
613
|
samplingRate: s?.samplingRate ?? 1,
|
|
609
614
|
pageViewThrottleMs: s?.pageViewThrottleMs ?? 1e3,
|
|
610
615
|
clickThrottleMs: s?.clickThrottleMs ?? 300,
|
|
611
|
-
maxSameEventPerMinute: s?.maxSameEventPerMinute ?? 60
|
|
616
|
+
maxSameEventPerMinute: s?.maxSameEventPerMinute ?? 60,
|
|
617
|
+
sendIntervalMs: s?.sendIntervalMs ?? 1e4
|
|
612
618
|
};
|
|
613
619
|
return e.integrations?.custom && (e.integrations.custom = {
|
|
614
620
|
...e.integrations.custom,
|
|
@@ -620,12 +626,12 @@ const $t = () => {
|
|
|
620
626
|
cooldownPeriod: e.viewport.cooldownPeriod ?? 6e4,
|
|
621
627
|
maxTrackedElements: e.viewport.maxTrackedElements ?? 100
|
|
622
628
|
}), e;
|
|
623
|
-
},
|
|
629
|
+
}, me = (s, e = /* @__PURE__ */ new Set()) => {
|
|
624
630
|
if (s == null)
|
|
625
631
|
return !0;
|
|
626
632
|
const t = typeof s;
|
|
627
|
-
return t === "string" || t === "number" || t === "boolean" ? !0 : t === "function" || t === "symbol" || t === "bigint" || e.has(s) ? !1 : (e.add(s), Array.isArray(s) ? s.every((r) =>
|
|
628
|
-
},
|
|
633
|
+
return t === "string" || t === "number" || t === "boolean" ? !0 : t === "function" || t === "symbol" || t === "bigint" || e.has(s) ? !1 : (e.add(s), Array.isArray(s) ? s.every((r) => me(r, e)) : t === "object" ? Object.values(s).every((r) => me(r, e)) : !1);
|
|
634
|
+
}, Yt = (s) => typeof s != "object" || s === null ? !1 : me(s), qt = (s) => typeof s != "string" ? {
|
|
629
635
|
valid: !1,
|
|
630
636
|
error: "Event name must be a string"
|
|
631
637
|
} : s.length === 0 ? {
|
|
@@ -640,9 +646,9 @@ const $t = () => {
|
|
|
640
646
|
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(s.toLowerCase()) ? {
|
|
641
647
|
valid: !1,
|
|
642
648
|
error: "Event name cannot be a reserved word"
|
|
643
|
-
} : { valid: !0 },
|
|
644
|
-
const r =
|
|
645
|
-
if (!
|
|
649
|
+
} : { valid: !0 }, Fe = (s, e, t) => {
|
|
650
|
+
const r = Xt(e), n = t && t === "customEvent" ? `${t} "${s}" metadata error` : `${s} metadata error`;
|
|
651
|
+
if (!Yt(r))
|
|
646
652
|
return {
|
|
647
653
|
valid: !1,
|
|
648
654
|
error: `${n}: object has invalid types. Valid types are string, number, boolean or string arrays.`
|
|
@@ -666,31 +672,31 @@ const $t = () => {
|
|
|
666
672
|
valid: !1,
|
|
667
673
|
error: `${n}: object has too many keys (max 10 keys).`
|
|
668
674
|
};
|
|
669
|
-
for (const [
|
|
675
|
+
for (const [a, c] of Object.entries(r)) {
|
|
670
676
|
if (Array.isArray(c)) {
|
|
671
677
|
if (c.length > 10)
|
|
672
678
|
return {
|
|
673
679
|
valid: !1,
|
|
674
|
-
error: `${n}: array property "${
|
|
680
|
+
error: `${n}: array property "${a}" is too large (max 10 items).`
|
|
675
681
|
};
|
|
676
682
|
for (const u of c)
|
|
677
683
|
if (typeof u == "string" && u.length > 500)
|
|
678
684
|
return {
|
|
679
685
|
valid: !1,
|
|
680
|
-
error: `${n}: array property "${
|
|
686
|
+
error: `${n}: array property "${a}" contains strings that are too long (max 500 characters).`
|
|
681
687
|
};
|
|
682
688
|
}
|
|
683
689
|
if (typeof c == "string" && c.length > 1e3)
|
|
684
690
|
return {
|
|
685
691
|
valid: !1,
|
|
686
|
-
error: `${n}: property "${
|
|
692
|
+
error: `${n}: property "${a}" is too long (max 1000 characters).`
|
|
687
693
|
};
|
|
688
694
|
}
|
|
689
695
|
return {
|
|
690
696
|
valid: !0,
|
|
691
697
|
sanitizedMetadata: r
|
|
692
698
|
};
|
|
693
|
-
},
|
|
699
|
+
}, Je = (s, e, t) => {
|
|
694
700
|
if (Array.isArray(e)) {
|
|
695
701
|
const r = [], n = t && t === "customEvent" ? `${t} "${s}" metadata error` : `${s} metadata error`;
|
|
696
702
|
for (let i = 0; i < e.length; i++) {
|
|
@@ -700,37 +706,37 @@ const $t = () => {
|
|
|
700
706
|
valid: !1,
|
|
701
707
|
error: `${n}: array item at index ${i} must be an object.`
|
|
702
708
|
};
|
|
703
|
-
const
|
|
704
|
-
if (!
|
|
709
|
+
const a = Fe(s, o, t);
|
|
710
|
+
if (!a.valid)
|
|
705
711
|
return {
|
|
706
712
|
valid: !1,
|
|
707
|
-
error: `${n}: array item at index ${i} is invalid: ${
|
|
713
|
+
error: `${n}: array item at index ${i} is invalid: ${a.error}`
|
|
708
714
|
};
|
|
709
|
-
|
|
715
|
+
a.sanitizedMetadata && r.push(a.sanitizedMetadata);
|
|
710
716
|
}
|
|
711
717
|
return {
|
|
712
718
|
valid: !0,
|
|
713
719
|
sanitizedMetadata: r
|
|
714
720
|
};
|
|
715
721
|
}
|
|
716
|
-
return
|
|
717
|
-
},
|
|
718
|
-
const t =
|
|
722
|
+
return Fe(s, e, t);
|
|
723
|
+
}, Jt = (s, e) => {
|
|
724
|
+
const t = qt(s);
|
|
719
725
|
if (!t.valid)
|
|
720
|
-
return
|
|
726
|
+
return l("error", "Event name validation failed", {
|
|
721
727
|
data: { eventName: s, error: t.error }
|
|
722
728
|
}), t;
|
|
723
729
|
if (!e)
|
|
724
730
|
return { valid: !0 };
|
|
725
|
-
const r =
|
|
726
|
-
return r.valid ||
|
|
731
|
+
const r = Je(s, e, "customEvent");
|
|
732
|
+
return r.valid || l("error", "Event metadata validation failed", {
|
|
727
733
|
data: {
|
|
728
734
|
eventName: s,
|
|
729
735
|
error: r.error
|
|
730
736
|
}
|
|
731
737
|
}), r;
|
|
732
738
|
};
|
|
733
|
-
class
|
|
739
|
+
class Zt {
|
|
734
740
|
listeners = /* @__PURE__ */ new Map();
|
|
735
741
|
/**
|
|
736
742
|
* Subscribes to an event channel
|
|
@@ -847,38 +853,38 @@ class Jt {
|
|
|
847
853
|
this.listeners.clear();
|
|
848
854
|
}
|
|
849
855
|
}
|
|
850
|
-
function
|
|
856
|
+
function Ze(s, e, t) {
|
|
851
857
|
try {
|
|
852
858
|
const r = e(s);
|
|
853
|
-
return r === null ? null : typeof r == "object" && r !== null && "type" in r ? r : (
|
|
859
|
+
return r === null ? null : typeof r == "object" && r !== null && "type" in r ? r : (l("warn", `beforeSend transformer returned invalid data, using original [${t}]`), s);
|
|
854
860
|
} catch (r) {
|
|
855
|
-
return
|
|
861
|
+
return l("error", `beforeSend transformer threw error, using original event [${t}]`, {
|
|
856
862
|
error: r,
|
|
857
863
|
visibility: "critical"
|
|
858
864
|
}), s;
|
|
859
865
|
}
|
|
860
866
|
}
|
|
861
|
-
function
|
|
862
|
-
return s.map((r) =>
|
|
867
|
+
function er(s, e, t) {
|
|
868
|
+
return s.map((r) => Ze(r, e, t)).filter((r) => r !== null);
|
|
863
869
|
}
|
|
864
|
-
function
|
|
870
|
+
function et(s, e, t) {
|
|
865
871
|
try {
|
|
866
872
|
const r = e(s);
|
|
867
|
-
return r === null ? (
|
|
873
|
+
return r === null ? (l("debug", `Batch filtered by beforeBatch transformer [${t}]`, {
|
|
868
874
|
data: { eventCount: s.events.length }
|
|
869
|
-
}), null) : typeof r == "object" && r !== null && Array.isArray(r.events) ? r : (
|
|
875
|
+
}), null) : typeof r == "object" && r !== null && Array.isArray(r.events) ? r : (l("warn", `beforeBatch transformer returned invalid data, using original [${t}]`, {
|
|
870
876
|
data: { eventCount: s.events.length }
|
|
871
877
|
}), s);
|
|
872
878
|
} catch (r) {
|
|
873
|
-
return
|
|
879
|
+
return l("error", `beforeBatch transformer threw error, using original batch [${t}]`, {
|
|
874
880
|
error: r,
|
|
875
881
|
data: { eventCount: s.events.length },
|
|
876
882
|
visibility: "critical"
|
|
877
883
|
}), s;
|
|
878
884
|
}
|
|
879
885
|
}
|
|
880
|
-
const
|
|
881
|
-
class
|
|
886
|
+
const ie = {};
|
|
887
|
+
class v {
|
|
882
888
|
/**
|
|
883
889
|
* Retrieves a value from global state.
|
|
884
890
|
*
|
|
@@ -896,7 +902,7 @@ class I {
|
|
|
896
902
|
* ```
|
|
897
903
|
*/
|
|
898
904
|
get(e) {
|
|
899
|
-
return
|
|
905
|
+
return ie[e];
|
|
900
906
|
}
|
|
901
907
|
/**
|
|
902
908
|
* Sets a value in global state.
|
|
@@ -916,7 +922,7 @@ class I {
|
|
|
916
922
|
* ```
|
|
917
923
|
*/
|
|
918
924
|
set(e, t) {
|
|
919
|
-
|
|
925
|
+
ie[e] = t;
|
|
920
926
|
}
|
|
921
927
|
/**
|
|
922
928
|
* Returns an immutable snapshot of the entire global state.
|
|
@@ -933,10 +939,10 @@ class I {
|
|
|
933
939
|
* ```
|
|
934
940
|
*/
|
|
935
941
|
getState() {
|
|
936
|
-
return { ...
|
|
942
|
+
return { ...ie };
|
|
937
943
|
}
|
|
938
944
|
}
|
|
939
|
-
class
|
|
945
|
+
class $e extends v {
|
|
940
946
|
storeManager;
|
|
941
947
|
integrationId;
|
|
942
948
|
apiUrl;
|
|
@@ -946,6 +952,7 @@ class Fe extends I {
|
|
|
946
952
|
lastPermanentErrorLog = null;
|
|
947
953
|
recoveryInProgress = !1;
|
|
948
954
|
lastMetadataTimestamp = 0;
|
|
955
|
+
fetchCredentials;
|
|
949
956
|
pendingControllers = /* @__PURE__ */ new Set();
|
|
950
957
|
/**
|
|
951
958
|
* Creates a SenderManager instance.
|
|
@@ -961,10 +968,10 @@ class Fe extends I {
|
|
|
961
968
|
* @param customHeadersProvider - Optional callback for dynamic headers
|
|
962
969
|
* @throws Error if integrationId and apiUrl are not both provided or both undefined
|
|
963
970
|
*/
|
|
964
|
-
constructor(e, t, r, n = {}, i = {}, o) {
|
|
971
|
+
constructor(e, t, r, n = {}, i = {}, o, a = "include") {
|
|
965
972
|
if (super(), t && !r || !t && r)
|
|
966
973
|
throw new Error("SenderManager: integrationId and apiUrl must either both be provided or both be undefined");
|
|
967
|
-
this.storeManager = e, this.integrationId = t, this.apiUrl = r, this.transformers = n, this.staticHeaders = i, this.customHeadersProvider = o;
|
|
974
|
+
this.storeManager = e, this.integrationId = t, this.apiUrl = r, this.transformers = n, this.staticHeaders = i, this.customHeadersProvider = o, this.fetchCredentials = a;
|
|
968
975
|
}
|
|
969
976
|
/**
|
|
970
977
|
* Get the integration ID for this sender
|
|
@@ -1002,16 +1009,16 @@ class Fe extends I {
|
|
|
1002
1009
|
if (this.customHeadersProvider)
|
|
1003
1010
|
try {
|
|
1004
1011
|
const t = this.customHeadersProvider();
|
|
1005
|
-
typeof t == "object" && t !== null && !Array.isArray(t) ? e = t :
|
|
1012
|
+
typeof t == "object" && t !== null && !Array.isArray(t) ? e = t : l("warn", "Custom headers provider returned invalid value, expected object", {
|
|
1006
1013
|
data: { received: typeof t }
|
|
1007
1014
|
});
|
|
1008
1015
|
} catch (t) {
|
|
1009
|
-
|
|
1016
|
+
l("warn", "Custom headers provider threw an error, using static headers only", { error: t });
|
|
1010
1017
|
}
|
|
1011
1018
|
return { ...this.staticHeaders, ...e };
|
|
1012
1019
|
}
|
|
1013
1020
|
getQueueStorageKey() {
|
|
1014
|
-
const e = this.get("userId") || "anonymous", t =
|
|
1021
|
+
const e = this.get("userId") || "anonymous", t = ht(e);
|
|
1015
1022
|
return this.integrationId ? `${t}:${this.integrationId}` : t;
|
|
1016
1023
|
}
|
|
1017
1024
|
/**
|
|
@@ -1041,6 +1048,11 @@ class Fe extends I {
|
|
|
1041
1048
|
* Content-Type header via Blob. For scenarios requiring custom headers, ensure async
|
|
1042
1049
|
* sends complete before page unload.
|
|
1043
1050
|
*
|
|
1051
|
+
* **Credentials Limitation**: The `fetchCredentials` config option is NOT applied to
|
|
1052
|
+
* sendBeacon requests. `sendBeacon()` always sends cookies (equivalent to `credentials: 'include'`)
|
|
1053
|
+
* regardless of the configured value. If `fetchCredentials` is set to `'omit'` or `'same-origin'`,
|
|
1054
|
+
* only async `fetch()` calls honor that setting.
|
|
1055
|
+
*
|
|
1044
1056
|
* @param body - Event queue to send
|
|
1045
1057
|
* @returns `true` if send succeeded or was skipped, `false` if failed
|
|
1046
1058
|
*
|
|
@@ -1048,13 +1060,13 @@ class Fe extends I {
|
|
|
1048
1060
|
* @see src/managers/README.md (lines 82-139) for send details
|
|
1049
1061
|
*/
|
|
1050
1062
|
sendEventsQueueSync(e) {
|
|
1051
|
-
return this.shouldSkipSend() ? !0 : this.apiUrl?.includes(
|
|
1063
|
+
return this.shouldSkipSend() ? !0 : this.apiUrl?.includes(H.Fail) ? (l(
|
|
1052
1064
|
"warn",
|
|
1053
1065
|
`Fail mode: simulating network failure (sync)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1054
1066
|
{
|
|
1055
1067
|
data: { events: e.events.length }
|
|
1056
1068
|
}
|
|
1057
|
-
), !1) : this.apiUrl?.includes(
|
|
1069
|
+
), !1) : this.apiUrl?.includes(H.Localhost) ? (l(
|
|
1058
1070
|
"debug",
|
|
1059
1071
|
`Success mode: simulating successful send (sync)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1060
1072
|
{
|
|
@@ -1096,7 +1108,7 @@ class Fe extends I {
|
|
|
1096
1108
|
const r = await this.send(e);
|
|
1097
1109
|
return r ? (this.clearPersistedEvents(), t?.onSuccess?.(e.events.length, e.events, e)) : (this.persistEvents(e), t?.onFailure?.()), r;
|
|
1098
1110
|
} catch (r) {
|
|
1099
|
-
return r instanceof
|
|
1111
|
+
return r instanceof D ? (this.logPermanentError("Permanent error, not retrying", r), this.clearPersistedEvents(), t?.onFailure?.(), !1) : (this.persistEvents(e), t?.onFailure?.(), !1);
|
|
1100
1112
|
}
|
|
1101
1113
|
}
|
|
1102
1114
|
/**
|
|
@@ -1150,7 +1162,7 @@ class Fe extends I {
|
|
|
1150
1162
|
*/
|
|
1151
1163
|
async recoverPersistedEvents(e) {
|
|
1152
1164
|
if (this.recoveryInProgress) {
|
|
1153
|
-
|
|
1165
|
+
l("debug", "Recovery already in progress, skipping duplicate attempt");
|
|
1154
1166
|
return;
|
|
1155
1167
|
}
|
|
1156
1168
|
this.recoveryInProgress = !0;
|
|
@@ -1163,11 +1175,11 @@ class Fe extends I {
|
|
|
1163
1175
|
const r = this.createRecoveryBody(t);
|
|
1164
1176
|
await this.send(r) ? (this.clearPersistedEvents(), e?.onSuccess?.(t.events.length, t.events, r)) : e?.onFailure?.();
|
|
1165
1177
|
} catch (t) {
|
|
1166
|
-
if (t instanceof
|
|
1178
|
+
if (t instanceof D) {
|
|
1167
1179
|
this.logPermanentError("Permanent error during recovery, clearing persisted events", t), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1168
1180
|
return;
|
|
1169
1181
|
}
|
|
1170
|
-
|
|
1182
|
+
l("error", "Failed to recover persisted events", { error: t });
|
|
1171
1183
|
} finally {
|
|
1172
1184
|
this.recoveryInProgress = !1;
|
|
1173
1185
|
}
|
|
@@ -1217,7 +1229,7 @@ class Fe extends I {
|
|
|
1217
1229
|
const t = this.transformers.beforeSend;
|
|
1218
1230
|
if (!t)
|
|
1219
1231
|
return e;
|
|
1220
|
-
const r =
|
|
1232
|
+
const r = er(
|
|
1221
1233
|
e.events,
|
|
1222
1234
|
t,
|
|
1223
1235
|
this.integrationId || "SenderManager"
|
|
@@ -1262,7 +1274,7 @@ class Fe extends I {
|
|
|
1262
1274
|
if (this.integrationId === "saas")
|
|
1263
1275
|
return e;
|
|
1264
1276
|
const t = this.transformers.beforeBatch;
|
|
1265
|
-
return t ?
|
|
1277
|
+
return t ? et(e, t, this.integrationId || "SenderManager") : e;
|
|
1266
1278
|
}
|
|
1267
1279
|
/**
|
|
1268
1280
|
* Calculates exponential backoff delay with jitter for retry attempts.
|
|
@@ -1330,33 +1342,33 @@ class Fe extends I {
|
|
|
1330
1342
|
const r = this.applyBeforeBatchTransformer(t);
|
|
1331
1343
|
if (!r)
|
|
1332
1344
|
return !0;
|
|
1333
|
-
if (this.apiUrl?.includes(
|
|
1334
|
-
return
|
|
1345
|
+
if (this.apiUrl?.includes(H.Fail))
|
|
1346
|
+
return l("debug", `Fail mode: simulating network failure${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1335
1347
|
data: { events: r.events.length }
|
|
1336
1348
|
}), !1;
|
|
1337
|
-
if (this.apiUrl?.includes(
|
|
1338
|
-
return
|
|
1349
|
+
if (this.apiUrl?.includes(H.Localhost))
|
|
1350
|
+
return l("debug", `Success mode: simulating successful send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1339
1351
|
data: { events: r.events.length }
|
|
1340
1352
|
}), !0;
|
|
1341
1353
|
const { url: n, payload: i } = this.prepareRequest(r);
|
|
1342
1354
|
for (let o = 1; o <= 3; o++)
|
|
1343
1355
|
try {
|
|
1344
|
-
return (await this.sendWithTimeout(n, i)).ok ? (o > 1 &&
|
|
1356
|
+
return (await this.sendWithTimeout(n, i)).ok ? (o > 1 && l(
|
|
1345
1357
|
"info",
|
|
1346
1358
|
`Send succeeded after ${o - 1} retry attempt(s)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1347
1359
|
{
|
|
1348
1360
|
data: { events: r.events.length, attempt: o }
|
|
1349
1361
|
}
|
|
1350
1362
|
), !0) : !1;
|
|
1351
|
-
} catch (
|
|
1363
|
+
} catch (a) {
|
|
1352
1364
|
const c = o === 3;
|
|
1353
|
-
if (
|
|
1354
|
-
throw
|
|
1355
|
-
if (
|
|
1365
|
+
if (a instanceof D)
|
|
1366
|
+
throw a;
|
|
1367
|
+
if (l(
|
|
1356
1368
|
c ? "error" : "warn",
|
|
1357
1369
|
`Send attempt ${o} failed${this.integrationId ? ` [${this.integrationId}]` : ""}${c ? " (all retries exhausted)" : ", will retry"}`,
|
|
1358
1370
|
{
|
|
1359
|
-
error:
|
|
1371
|
+
error: a,
|
|
1360
1372
|
data: {
|
|
1361
1373
|
events: e.events.length,
|
|
1362
1374
|
url: n.replace(/\/\/[^/]+/, "//[DOMAIN]"),
|
|
@@ -1404,7 +1416,7 @@ class Fe extends I {
|
|
|
1404
1416
|
method: "POST",
|
|
1405
1417
|
body: t,
|
|
1406
1418
|
keepalive: !0,
|
|
1407
|
-
credentials:
|
|
1419
|
+
credentials: this.fetchCredentials,
|
|
1408
1420
|
signal: r.signal,
|
|
1409
1421
|
headers: {
|
|
1410
1422
|
...i,
|
|
@@ -1412,7 +1424,7 @@ class Fe extends I {
|
|
|
1412
1424
|
}
|
|
1413
1425
|
});
|
|
1414
1426
|
if (!o.ok)
|
|
1415
|
-
throw o.status >= 400 && o.status < 500 && o.status !== 408 && o.status !== 429 ? new
|
|
1427
|
+
throw o.status >= 400 && o.status < 500 && o.status !== 408 && o.status !== 429 ? new D(`HTTP ${o.status}: ${o.statusText}`, o.status) : new Error(`HTTP ${o.status}: ${o.statusText}`);
|
|
1416
1428
|
return o;
|
|
1417
1429
|
} finally {
|
|
1418
1430
|
clearTimeout(n), this.pendingControllers.delete(r);
|
|
@@ -1447,7 +1459,7 @@ class Fe extends I {
|
|
|
1447
1459
|
return !0;
|
|
1448
1460
|
const { url: n, payload: i } = this.prepareRequest(r);
|
|
1449
1461
|
if (i.length > 65536)
|
|
1450
|
-
return
|
|
1462
|
+
return l(
|
|
1451
1463
|
"warn",
|
|
1452
1464
|
`Payload exceeds sendBeacon limit, persisting for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1453
1465
|
{
|
|
@@ -1460,15 +1472,15 @@ class Fe extends I {
|
|
|
1460
1472
|
), this.persistEvents(r), !1;
|
|
1461
1473
|
const o = new Blob([i], { type: "application/json" });
|
|
1462
1474
|
if (!this.isSendBeaconAvailable())
|
|
1463
|
-
return
|
|
1475
|
+
return l(
|
|
1464
1476
|
"warn",
|
|
1465
1477
|
`sendBeacon not available, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1466
1478
|
), this.persistEvents(r), !1;
|
|
1467
|
-
const
|
|
1468
|
-
return
|
|
1479
|
+
const a = navigator.sendBeacon(n, o);
|
|
1480
|
+
return a || (l(
|
|
1469
1481
|
"warn",
|
|
1470
1482
|
`sendBeacon rejected request, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1471
|
-
), this.persistEvents(r)),
|
|
1483
|
+
), this.persistEvents(r)), a;
|
|
1472
1484
|
}
|
|
1473
1485
|
/**
|
|
1474
1486
|
* Prepares request by enriching payload with metadata and serializing to JSON.
|
|
@@ -1496,7 +1508,7 @@ class Fe extends I {
|
|
|
1496
1508
|
_metadata: {
|
|
1497
1509
|
referer: typeof window < "u" ? window.location.href : void 0,
|
|
1498
1510
|
timestamp: t,
|
|
1499
|
-
client_version:
|
|
1511
|
+
client_version: Vt
|
|
1500
1512
|
}
|
|
1501
1513
|
};
|
|
1502
1514
|
return {
|
|
@@ -1522,7 +1534,7 @@ class Fe extends I {
|
|
|
1522
1534
|
if (t)
|
|
1523
1535
|
return JSON.parse(t);
|
|
1524
1536
|
} catch (e) {
|
|
1525
|
-
|
|
1537
|
+
l("debug", `Failed to parse persisted data${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error: e }), this.clearPersistedEvents();
|
|
1526
1538
|
}
|
|
1527
1539
|
return null;
|
|
1528
1540
|
}
|
|
@@ -1578,7 +1590,7 @@ class Fe extends I {
|
|
|
1578
1590
|
if (t && t.timestamp) {
|
|
1579
1591
|
const i = Date.now() - t.timestamp;
|
|
1580
1592
|
if (i < 1e3)
|
|
1581
|
-
return
|
|
1593
|
+
return l(
|
|
1582
1594
|
"debug",
|
|
1583
1595
|
`Skipping persistence, another tab recently persisted events${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1584
1596
|
{
|
|
@@ -1592,7 +1604,7 @@ class Fe extends I {
|
|
|
1592
1604
|
}, n = this.getQueueStorageKey();
|
|
1593
1605
|
return this.storeManager.setItem(n, JSON.stringify(r)), !!this.storeManager.getItem(n);
|
|
1594
1606
|
} catch (t) {
|
|
1595
|
-
return
|
|
1607
|
+
return l("debug", `Failed to persist events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error: t }), !1;
|
|
1596
1608
|
}
|
|
1597
1609
|
}
|
|
1598
1610
|
clearPersistedEvents() {
|
|
@@ -1600,7 +1612,7 @@ class Fe extends I {
|
|
|
1600
1612
|
const e = this.getQueueStorageKey();
|
|
1601
1613
|
this.storeManager.removeItem(e);
|
|
1602
1614
|
} catch (e) {
|
|
1603
|
-
|
|
1615
|
+
l("debug", `Failed to clear persisted events${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1604
1616
|
error: e
|
|
1605
1617
|
});
|
|
1606
1618
|
}
|
|
@@ -1617,12 +1629,12 @@ class Fe extends I {
|
|
|
1617
1629
|
}
|
|
1618
1630
|
logPermanentError(e, t) {
|
|
1619
1631
|
const r = Date.now();
|
|
1620
|
-
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode || r - this.lastPermanentErrorLog.timestamp >=
|
|
1632
|
+
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode || r - this.lastPermanentErrorLog.timestamp >= Rt) && (l("error", `${e}${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1621
1633
|
data: { status: t.statusCode, message: t.message }
|
|
1622
1634
|
}), this.lastPermanentErrorLog = { statusCode: t.statusCode, timestamp: r });
|
|
1623
1635
|
}
|
|
1624
1636
|
}
|
|
1625
|
-
class
|
|
1637
|
+
class tr extends v {
|
|
1626
1638
|
bootTime;
|
|
1627
1639
|
bootTimestamp;
|
|
1628
1640
|
hasPerformanceNow;
|
|
@@ -1647,12 +1659,12 @@ class er extends I {
|
|
|
1647
1659
|
this.hasPerformanceNow = !1, this.bootTime = 0, this.bootTimestamp = 0;
|
|
1648
1660
|
return;
|
|
1649
1661
|
}
|
|
1650
|
-
this.hasPerformanceNow = typeof performance < "u" && typeof performance.now == "function", this.hasPerformanceNow ? (this.bootTime = performance.now(), this.bootTimestamp = Date.now(),
|
|
1662
|
+
this.hasPerformanceNow = typeof performance < "u" && typeof performance.now == "function", this.hasPerformanceNow ? (this.bootTime = performance.now(), this.bootTimestamp = Date.now(), l("debug", "TimeManager initialized with monotonic clock", {
|
|
1651
1663
|
data: {
|
|
1652
1664
|
bootTime: this.bootTime.toFixed(3),
|
|
1653
1665
|
bootTimestamp: this.bootTimestamp
|
|
1654
1666
|
}
|
|
1655
|
-
})) : (this.bootTime = 0, this.bootTimestamp = Date.now(),
|
|
1667
|
+
})) : (this.bootTime = 0, this.bootTimestamp = Date.now(), l("debug", "performance.now() not available, falling back to Date.now()"));
|
|
1656
1668
|
}
|
|
1657
1669
|
/**
|
|
1658
1670
|
* Returns current timestamp in milliseconds since epoch.
|
|
@@ -1715,7 +1727,7 @@ class er extends I {
|
|
|
1715
1727
|
return this.detectedSkew;
|
|
1716
1728
|
this.lastClockSkewCheck = e;
|
|
1717
1729
|
const t = this.now(), r = Date.now();
|
|
1718
|
-
return this.detectedSkew = r - t, Math.abs(this.detectedSkew) > 3e4 &&
|
|
1730
|
+
return this.detectedSkew = r - t, Math.abs(this.detectedSkew) > 3e4 && l("warn", "Significant clock skew detected", {
|
|
1719
1731
|
data: {
|
|
1720
1732
|
skewMs: this.detectedSkew,
|
|
1721
1733
|
skewMinutes: (this.detectedSkew / 1e3 / 60).toFixed(2),
|
|
@@ -1771,7 +1783,8 @@ class er extends I {
|
|
|
1771
1783
|
};
|
|
1772
1784
|
}
|
|
1773
1785
|
}
|
|
1774
|
-
|
|
1786
|
+
const rr = new Set(Object.values(d));
|
|
1787
|
+
class sr extends v {
|
|
1775
1788
|
dataSenders;
|
|
1776
1789
|
emitter;
|
|
1777
1790
|
transformers;
|
|
@@ -1780,8 +1793,9 @@ class tr extends I {
|
|
|
1780
1793
|
perEventRateLimits = /* @__PURE__ */ new Map();
|
|
1781
1794
|
eventsQueue = [];
|
|
1782
1795
|
pendingEventsBuffer = [];
|
|
1783
|
-
|
|
1796
|
+
sendTimeoutId = null;
|
|
1784
1797
|
sendInProgress = !1;
|
|
1798
|
+
consecutiveSendFailures = 0;
|
|
1785
1799
|
rateLimitCounter = 0;
|
|
1786
1800
|
rateLimitWindowStart = 0;
|
|
1787
1801
|
lastSessionId = null;
|
|
@@ -1806,21 +1820,23 @@ class tr extends I {
|
|
|
1806
1820
|
* @param transformers - Optional event transformation hooks
|
|
1807
1821
|
* @param staticHeaders - Optional static HTTP headers for custom backend (from config)
|
|
1808
1822
|
* @param customHeadersProvider - Optional callback for dynamic headers
|
|
1823
|
+
* @param fetchCredentials - Fetch credentials mode for custom backend. @default 'include'
|
|
1809
1824
|
*/
|
|
1810
|
-
constructor(e, t = null, r = {}, n = {}, i) {
|
|
1811
|
-
super(), this.emitter = t, this.transformers = r, this.timeManager = new
|
|
1812
|
-
const
|
|
1813
|
-
|
|
1814
|
-
new
|
|
1825
|
+
constructor(e, t = null, r = {}, n = {}, i, o = "include") {
|
|
1826
|
+
super(), this.emitter = t, this.transformers = r, this.timeManager = new tr(), this.dataSenders = [];
|
|
1827
|
+
const a = this.get("collectApiUrls");
|
|
1828
|
+
a?.saas && this.dataSenders.push(new $e(e, "saas", a.saas, r)), a?.custom && this.dataSenders.push(
|
|
1829
|
+
new $e(
|
|
1815
1830
|
e,
|
|
1816
1831
|
"custom",
|
|
1817
|
-
|
|
1832
|
+
a.custom,
|
|
1818
1833
|
r,
|
|
1819
1834
|
n,
|
|
1820
|
-
i
|
|
1835
|
+
i,
|
|
1836
|
+
o
|
|
1821
1837
|
)
|
|
1822
|
-
), this.saveSessionCountsDebounced = this.debounce((
|
|
1823
|
-
this.saveSessionCounts(
|
|
1838
|
+
), this.saveSessionCountsDebounced = this.debounce((c) => {
|
|
1839
|
+
this.saveSessionCounts(c);
|
|
1824
1840
|
}, 500), this.cleanupExpiredSessionCounts();
|
|
1825
1841
|
}
|
|
1826
1842
|
/**
|
|
@@ -1852,12 +1868,12 @@ class tr extends I {
|
|
|
1852
1868
|
async (t) => t.recoverPersistedEvents({
|
|
1853
1869
|
onSuccess: (r, n, i) => {
|
|
1854
1870
|
if (n && n.length > 0) {
|
|
1855
|
-
const o = n.map((
|
|
1871
|
+
const o = n.map((a) => a.id);
|
|
1856
1872
|
this.removeProcessedEvents(o), i && this.emitEventsQueue(i);
|
|
1857
1873
|
}
|
|
1858
1874
|
},
|
|
1859
1875
|
onFailure: () => {
|
|
1860
|
-
|
|
1876
|
+
l("debug", "Failed to recover persisted events");
|
|
1861
1877
|
}
|
|
1862
1878
|
})
|
|
1863
1879
|
);
|
|
@@ -1929,18 +1945,24 @@ class tr extends I {
|
|
|
1929
1945
|
scroll_data: n,
|
|
1930
1946
|
click_data: i,
|
|
1931
1947
|
custom_event: o,
|
|
1932
|
-
web_vitals:
|
|
1948
|
+
web_vitals: a,
|
|
1933
1949
|
error_data: c,
|
|
1934
1950
|
viewport_data: u,
|
|
1935
1951
|
page_view: S
|
|
1936
1952
|
}) {
|
|
1937
1953
|
if (!e) {
|
|
1938
|
-
|
|
1954
|
+
l("error", "Event type is required - event will be ignored");
|
|
1955
|
+
return;
|
|
1956
|
+
}
|
|
1957
|
+
if (!rr.has(e)) {
|
|
1958
|
+
l("error", "Invalid event type - event will be ignored", {
|
|
1959
|
+
data: { type: e }
|
|
1960
|
+
});
|
|
1939
1961
|
return;
|
|
1940
1962
|
}
|
|
1941
1963
|
const g = this.get("sessionId");
|
|
1942
1964
|
if (!g) {
|
|
1943
|
-
this.pendingEventsBuffer.length >= 100 && (this.pendingEventsBuffer.shift(),
|
|
1965
|
+
this.pendingEventsBuffer.length >= 100 && (this.pendingEventsBuffer.shift(), l("debug", "Pending events buffer full - dropping oldest event", {
|
|
1944
1966
|
data: { maxBufferSize: 100 }
|
|
1945
1967
|
})), this.pendingEventsBuffer.push({
|
|
1946
1968
|
type: e,
|
|
@@ -1949,7 +1971,7 @@ class tr extends I {
|
|
|
1949
1971
|
scroll_data: n,
|
|
1950
1972
|
click_data: i,
|
|
1951
1973
|
custom_event: o,
|
|
1952
|
-
web_vitals:
|
|
1974
|
+
web_vitals: a,
|
|
1953
1975
|
error_data: c,
|
|
1954
1976
|
viewport_data: u,
|
|
1955
1977
|
page_view: S
|
|
@@ -1958,14 +1980,14 @@ class tr extends I {
|
|
|
1958
1980
|
}
|
|
1959
1981
|
this.lastSessionId !== g && (this.lastSessionId = g, this.sessionEventCounts = this.loadSessionCounts(g));
|
|
1960
1982
|
const p = e === d.SESSION_START;
|
|
1961
|
-
if (p &&
|
|
1983
|
+
if (p && l("debug", "Processing SESSION_START event", {
|
|
1962
1984
|
data: { sessionId: g }
|
|
1963
1985
|
}), !p && !this.checkRateLimit())
|
|
1964
1986
|
return;
|
|
1965
1987
|
const E = e;
|
|
1966
1988
|
if (!p) {
|
|
1967
1989
|
if (this.sessionEventCounts.total >= 1e3) {
|
|
1968
|
-
|
|
1990
|
+
l("warn", "Session event limit reached", {
|
|
1969
1991
|
data: {
|
|
1970
1992
|
type: E,
|
|
1971
1993
|
total: this.sessionEventCounts.total,
|
|
@@ -1976,12 +1998,12 @@ class tr extends I {
|
|
|
1976
1998
|
}
|
|
1977
1999
|
const T = this.getTypeLimitForEvent(E);
|
|
1978
2000
|
if (T) {
|
|
1979
|
-
const
|
|
1980
|
-
if (
|
|
1981
|
-
|
|
2001
|
+
const re = this.sessionEventCounts[E];
|
|
2002
|
+
if (re !== void 0 && re >= T) {
|
|
2003
|
+
l("warn", "Session event type limit reached", {
|
|
1982
2004
|
data: {
|
|
1983
2005
|
type: E,
|
|
1984
|
-
count:
|
|
2006
|
+
count: re,
|
|
1985
2007
|
limit: T
|
|
1986
2008
|
}
|
|
1987
2009
|
});
|
|
@@ -1994,48 +2016,48 @@ class tr extends I {
|
|
|
1994
2016
|
if (!this.checkPerEventRateLimit(o.name, T))
|
|
1995
2017
|
return;
|
|
1996
2018
|
}
|
|
1997
|
-
const
|
|
2019
|
+
const ye = E === d.SESSION_START, W = t || this.get("pageUrl"), U = this.buildEventPayload({
|
|
1998
2020
|
type: E,
|
|
1999
|
-
page_url:
|
|
2021
|
+
page_url: W,
|
|
2000
2022
|
from_page_url: r,
|
|
2001
2023
|
scroll_data: n,
|
|
2002
2024
|
click_data: i,
|
|
2003
2025
|
custom_event: o,
|
|
2004
|
-
web_vitals:
|
|
2026
|
+
web_vitals: a,
|
|
2005
2027
|
error_data: c,
|
|
2006
2028
|
viewport_data: u,
|
|
2007
2029
|
page_view: S
|
|
2008
2030
|
});
|
|
2009
|
-
if (
|
|
2010
|
-
if (
|
|
2031
|
+
if (U && !(!p && !this.shouldSample())) {
|
|
2032
|
+
if (ye) {
|
|
2011
2033
|
const T = this.get("sessionId");
|
|
2012
2034
|
if (!T) {
|
|
2013
|
-
|
|
2035
|
+
l("error", "Session start event requires sessionId - event will be ignored");
|
|
2014
2036
|
return;
|
|
2015
2037
|
}
|
|
2016
2038
|
if (this.get("hasStartSession")) {
|
|
2017
|
-
|
|
2039
|
+
l("debug", "Duplicate session_start detected", {
|
|
2018
2040
|
data: { sessionId: T }
|
|
2019
2041
|
});
|
|
2020
2042
|
return;
|
|
2021
2043
|
}
|
|
2022
2044
|
this.set("hasStartSession", !0);
|
|
2023
2045
|
}
|
|
2024
|
-
if (!this.isDuplicateEvent(
|
|
2025
|
-
if (this.get("mode") ===
|
|
2046
|
+
if (!this.isDuplicateEvent(U)) {
|
|
2047
|
+
if (this.get("mode") === Y.QA) {
|
|
2026
2048
|
if (E === d.CUSTOM && o) {
|
|
2027
|
-
|
|
2049
|
+
l("info", `Custom Event: ${o.name}`, {
|
|
2028
2050
|
visibility: "qa",
|
|
2029
2051
|
data: {
|
|
2030
2052
|
name: o.name,
|
|
2031
2053
|
...o.metadata && { metadata: o.metadata }
|
|
2032
2054
|
}
|
|
2033
|
-
}), this.emitEvent(
|
|
2055
|
+
}), this.emitEvent(U);
|
|
2034
2056
|
return;
|
|
2035
2057
|
}
|
|
2036
2058
|
if (E === d.VIEWPORT_VISIBLE && u) {
|
|
2037
2059
|
const T = u.name || u.id || u.selector;
|
|
2038
|
-
|
|
2060
|
+
l("info", `Viewport Visible: ${T}`, {
|
|
2039
2061
|
visibility: "qa",
|
|
2040
2062
|
data: {
|
|
2041
2063
|
selector: u.selector,
|
|
@@ -2044,11 +2066,11 @@ class tr extends I {
|
|
|
2044
2066
|
visibilityRatio: u.visibilityRatio,
|
|
2045
2067
|
dwellTime: u.dwellTime
|
|
2046
2068
|
}
|
|
2047
|
-
}), this.emitEvent(
|
|
2069
|
+
}), this.emitEvent(U);
|
|
2048
2070
|
return;
|
|
2049
2071
|
}
|
|
2050
2072
|
}
|
|
2051
|
-
if (this.addToQueue(
|
|
2073
|
+
if (this.addToQueue(U), !p) {
|
|
2052
2074
|
this.sessionEventCounts.total++, this.sessionEventCounts[E] !== void 0 && this.sessionEventCounts[E]++;
|
|
2053
2075
|
const T = this.get("sessionId");
|
|
2054
2076
|
T && this.saveSessionCountsDebounced && this.saveSessionCountsDebounced(T);
|
|
@@ -2063,7 +2085,7 @@ class tr extends I {
|
|
|
2063
2085
|
* and allow subsequent init() → destroy() → init() cycles.
|
|
2064
2086
|
*
|
|
2065
2087
|
* **Cleanup Actions**:
|
|
2066
|
-
* 1. **Clear send
|
|
2088
|
+
* 1. **Clear send timeout**: Cancels pending queue flush timeout and resets backoff state
|
|
2067
2089
|
* 2. **Clear all queues and buffers**:
|
|
2068
2090
|
* - `eventsQueue`: Discarded (not sent)
|
|
2069
2091
|
* - `pendingEventsBuffer`: Discarded (events before session init)
|
|
@@ -2073,8 +2095,8 @@ class tr extends I {
|
|
|
2073
2095
|
* 6. **Stop SenderManagers**: Calls `stop()` on all SenderManager instances
|
|
2074
2096
|
*
|
|
2075
2097
|
* **Important Behavior**:
|
|
2076
|
-
* - **No final flush**:
|
|
2077
|
-
* -
|
|
2098
|
+
* - **No final flush**: `stop()` itself does NOT send queued events
|
|
2099
|
+
* - `App.destroy()` calls `flushImmediatelySync()` before `stop()` automatically
|
|
2078
2100
|
*
|
|
2079
2101
|
* **Multi-Integration**:
|
|
2080
2102
|
* - Stops all SenderManager instances (SaaS + Custom)
|
|
@@ -2091,7 +2113,7 @@ class tr extends I {
|
|
|
2091
2113
|
* @see src/managers/README.md (lines 5-75) for cleanup details
|
|
2092
2114
|
*/
|
|
2093
2115
|
stop() {
|
|
2094
|
-
this.
|
|
2116
|
+
this.clearSendTimeout(), this.sendInProgress = !1, this.consecutiveSendFailures = 0;
|
|
2095
2117
|
const e = this.get("sessionId");
|
|
2096
2118
|
e && this.saveSessionCounts(e), this.eventsQueue = [], this.pendingEventsBuffer = [], this.recentEventFingerprints.clear(), this.rateLimitCounter = 0, this.rateLimitWindowStart = 0, this.perEventRateLimits.clear(), this.sessionEventCounts = {
|
|
2097
2119
|
total: 0,
|
|
@@ -2108,7 +2130,7 @@ class tr extends I {
|
|
|
2108
2130
|
* Flushes all events in the queue asynchronously.
|
|
2109
2131
|
*
|
|
2110
2132
|
* **Purpose**: Force immediate sending of queued events without waiting for
|
|
2111
|
-
* the
|
|
2133
|
+
* the scheduled queue flush timeout.
|
|
2112
2134
|
*
|
|
2113
2135
|
* **Use Cases**:
|
|
2114
2136
|
* - Manual flush triggered by user action
|
|
@@ -2294,7 +2316,7 @@ class tr extends I {
|
|
|
2294
2316
|
if (this.pendingEventsBuffer.length === 0)
|
|
2295
2317
|
return;
|
|
2296
2318
|
if (!this.get("sessionId")) {
|
|
2297
|
-
|
|
2319
|
+
l("debug", "Cannot flush pending events: session not initialized - keeping in buffer", {
|
|
2298
2320
|
data: { bufferedEventCount: this.pendingEventsBuffer.length }
|
|
2299
2321
|
});
|
|
2300
2322
|
return;
|
|
@@ -2304,8 +2326,8 @@ class tr extends I {
|
|
|
2304
2326
|
this.track(r);
|
|
2305
2327
|
});
|
|
2306
2328
|
}
|
|
2307
|
-
|
|
2308
|
-
this.
|
|
2329
|
+
clearSendTimeout() {
|
|
2330
|
+
this.sendTimeoutId !== null && (clearTimeout(this.sendTimeoutId), this.sendTimeoutId = null);
|
|
2309
2331
|
}
|
|
2310
2332
|
isSuccessfulResult(e) {
|
|
2311
2333
|
return e.status === "fulfilled" && e.value === !0;
|
|
@@ -2315,10 +2337,10 @@ class tr extends I {
|
|
|
2315
2337
|
return e ? !0 : Promise.resolve(!0);
|
|
2316
2338
|
const t = this.buildEventsPayload(), r = [...this.eventsQueue], n = r.map((i) => i.id);
|
|
2317
2339
|
if (this.dataSenders.length === 0)
|
|
2318
|
-
return this.removeProcessedEvents(n), this.
|
|
2340
|
+
return this.removeProcessedEvents(n), this.clearSendTimeout(), this.emitEventsQueue(t), e ? !0 : Promise.resolve(!0);
|
|
2319
2341
|
if (e) {
|
|
2320
|
-
const o = this.dataSenders.map((
|
|
2321
|
-
return o ? (this.removeProcessedEvents(n), this.
|
|
2342
|
+
const o = this.dataSenders.map((a) => a.sendEventsQueueSync(t)).some((a) => a);
|
|
2343
|
+
return o ? (this.removeProcessedEvents(n), this.clearSendTimeout(), this.emitEventsQueue(t)) : (this.clearSendTimeout(), l("debug", "Sync flush complete failure, events kept in queue for retry", {
|
|
2322
2344
|
data: { eventCount: n.length }
|
|
2323
2345
|
})), o;
|
|
2324
2346
|
} else {
|
|
@@ -2331,10 +2353,10 @@ class tr extends I {
|
|
|
2331
2353
|
})
|
|
2332
2354
|
);
|
|
2333
2355
|
return Promise.allSettled(i).then((o) => {
|
|
2334
|
-
const
|
|
2335
|
-
return
|
|
2356
|
+
const a = o.some((c) => this.isSuccessfulResult(c));
|
|
2357
|
+
return a ? (this.removeProcessedEvents(n), this.clearSendTimeout(), this.emitEventsQueue(t)) : l("debug", "Async flush complete failure, events kept in queue for retry", {
|
|
2336
2358
|
data: { eventCount: r.length }
|
|
2337
|
-
}),
|
|
2359
|
+
}), a;
|
|
2338
2360
|
});
|
|
2339
2361
|
}
|
|
2340
2362
|
}
|
|
@@ -2347,25 +2369,25 @@ class tr extends I {
|
|
|
2347
2369
|
this.emitEventsQueue(e);
|
|
2348
2370
|
return;
|
|
2349
2371
|
}
|
|
2350
|
-
const t = [...this.eventsQueue], r = t.map((
|
|
2351
|
-
async (
|
|
2372
|
+
const t = [...this.eventsQueue], r = t.map((a) => a.id), n = this.dataSenders.map(
|
|
2373
|
+
async (a) => a.sendEventsQueue(e, {
|
|
2352
2374
|
onSuccess: () => {
|
|
2353
2375
|
},
|
|
2354
2376
|
onFailure: () => {
|
|
2355
2377
|
}
|
|
2356
2378
|
})
|
|
2357
2379
|
), i = await Promise.allSettled(n);
|
|
2358
|
-
if (i.some((
|
|
2359
|
-
this.removeProcessedEvents(r), this.emitEventsQueue(e);
|
|
2360
|
-
const
|
|
2361
|
-
|
|
2362
|
-
data: { eventCount: t.length, failedCount:
|
|
2380
|
+
if (i.some((a) => this.isSuccessfulResult(a))) {
|
|
2381
|
+
this.consecutiveSendFailures = 0, this.removeProcessedEvents(r), this.emitEventsQueue(e);
|
|
2382
|
+
const a = i.filter((c) => !this.isSuccessfulResult(c)).length;
|
|
2383
|
+
a > 0 && l("debug", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
|
|
2384
|
+
data: { eventCount: t.length, failedCount: a }
|
|
2363
2385
|
});
|
|
2364
2386
|
} else
|
|
2365
|
-
|
|
2387
|
+
this.consecutiveSendFailures++, l("debug", "Periodic send complete failure, events kept in queue for retry", {
|
|
2366
2388
|
data: { eventCount: t.length }
|
|
2367
2389
|
});
|
|
2368
|
-
this.eventsQueue.length === 0
|
|
2390
|
+
this.eventsQueue.length === 0 ? this.clearSendTimeout() : this.scheduleSendTimeout();
|
|
2369
2391
|
} finally {
|
|
2370
2392
|
this.sendInProgress = !1;
|
|
2371
2393
|
}
|
|
@@ -2385,21 +2407,21 @@ class tr extends I {
|
|
|
2385
2407
|
events: r,
|
|
2386
2408
|
...this.get("config")?.globalMetadata && { global_metadata: this.get("config")?.globalMetadata }
|
|
2387
2409
|
};
|
|
2388
|
-
const i = this.get("collectApiUrls"), o = !!(i?.custom || i?.saas),
|
|
2389
|
-
if (!o &&
|
|
2390
|
-
const c =
|
|
2410
|
+
const i = this.get("collectApiUrls"), o = !!(i?.custom || i?.saas), a = this.transformers.beforeBatch;
|
|
2411
|
+
if (!o && a) {
|
|
2412
|
+
const c = et(n, a, "EventManager");
|
|
2391
2413
|
c !== null && (n = c);
|
|
2392
2414
|
}
|
|
2393
2415
|
return n;
|
|
2394
2416
|
}
|
|
2395
2417
|
buildEventPayload(e) {
|
|
2396
2418
|
const t = e.page_url ?? this.get("pageUrl"), r = this.timeManager.now(), n = this.timeManager.validateTimestamp(r);
|
|
2397
|
-
n.valid ||
|
|
2419
|
+
n.valid || l("warn", "Event timestamp validation failed", {
|
|
2398
2420
|
data: { type: e.type, error: n.error }
|
|
2399
2421
|
});
|
|
2400
2422
|
const i = this.get("sessionReferrer"), o = this.get("sessionUtm");
|
|
2401
|
-
let
|
|
2402
|
-
id:
|
|
2423
|
+
let a = {
|
|
2424
|
+
id: Bt(),
|
|
2403
2425
|
type: e.type,
|
|
2404
2426
|
page_url: t,
|
|
2405
2427
|
timestamp: r,
|
|
@@ -2416,16 +2438,16 @@ class tr extends I {
|
|
|
2416
2438
|
};
|
|
2417
2439
|
const c = this.get("collectApiUrls"), u = !!c?.custom, S = !!c?.saas, g = u || S, p = u && S, E = this.transformers.beforeSend;
|
|
2418
2440
|
if (E && (!g || u && !p)) {
|
|
2419
|
-
const
|
|
2420
|
-
if (
|
|
2441
|
+
const W = Ze(a, E, "EventManager");
|
|
2442
|
+
if (W === null)
|
|
2421
2443
|
return null;
|
|
2422
|
-
|
|
2444
|
+
a = W;
|
|
2423
2445
|
}
|
|
2424
|
-
return
|
|
2446
|
+
return a;
|
|
2425
2447
|
}
|
|
2426
2448
|
isDuplicateEvent(e) {
|
|
2427
2449
|
const t = Date.now(), r = this.createEventFingerprint(e), n = this.recentEventFingerprints.get(r);
|
|
2428
|
-
return n && t - n < 1e3 ? (this.recentEventFingerprints.set(r, t), !0) : (this.recentEventFingerprints.set(r, t), this.recentEventFingerprints.size > 1500 && this.pruneOldFingerprints(), this.recentEventFingerprints.size > 3e3 && (this.recentEventFingerprints.clear(), this.recentEventFingerprints.set(r, t),
|
|
2450
|
+
return n && t - n < 1e3 ? (this.recentEventFingerprints.set(r, t), !0) : (this.recentEventFingerprints.set(r, t), this.recentEventFingerprints.size > 1500 && this.pruneOldFingerprints(), this.recentEventFingerprints.size > 3e3 && (this.recentEventFingerprints.clear(), this.recentEventFingerprints.set(r, t), l("debug", "Event fingerprint cache exceeded hard limit, cleared", {
|
|
2429
2451
|
data: { hardLimit: 3e3 }
|
|
2430
2452
|
})), !1);
|
|
2431
2453
|
}
|
|
@@ -2433,7 +2455,7 @@ class tr extends I {
|
|
|
2433
2455
|
const e = Date.now(), t = 1e3 * 10;
|
|
2434
2456
|
for (const [r, n] of this.recentEventFingerprints.entries())
|
|
2435
2457
|
e - n > t && this.recentEventFingerprints.delete(r);
|
|
2436
|
-
|
|
2458
|
+
l("debug", "Pruned old event fingerprints", {
|
|
2437
2459
|
data: {
|
|
2438
2460
|
remaining: this.recentEventFingerprints.size,
|
|
2439
2461
|
cutoffMs: t
|
|
@@ -2454,7 +2476,7 @@ class tr extends I {
|
|
|
2454
2476
|
addToQueue(e) {
|
|
2455
2477
|
if (this.emitEvent(e), this.eventsQueue.push(e), this.eventsQueue.length > 100) {
|
|
2456
2478
|
const t = this.eventsQueue.findIndex((n) => n.type !== d.SESSION_START), r = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
|
|
2457
|
-
|
|
2479
|
+
l("warn", "Event queue overflow, oldest non-critical event removed", {
|
|
2458
2480
|
data: {
|
|
2459
2481
|
maxLength: 100,
|
|
2460
2482
|
currentLength: this.eventsQueue.length,
|
|
@@ -2463,12 +2485,20 @@ class tr extends I {
|
|
|
2463
2485
|
}
|
|
2464
2486
|
});
|
|
2465
2487
|
}
|
|
2466
|
-
this.
|
|
2488
|
+
this.consecutiveSendFailures >= 5 && (this.consecutiveSendFailures = 0), this.scheduleSendTimeout(), this.eventsQueue.length >= 50 && this.sendEventsQueue();
|
|
2467
2489
|
}
|
|
2468
|
-
|
|
2469
|
-
this.
|
|
2470
|
-
|
|
2471
|
-
|
|
2490
|
+
scheduleSendTimeout() {
|
|
2491
|
+
if (this.sendTimeoutId !== null || this.consecutiveSendFailures >= 5) return;
|
|
2492
|
+
const e = this.calculateSendDelay();
|
|
2493
|
+
this.sendTimeoutId = window.setTimeout(() => {
|
|
2494
|
+
this.sendTimeoutId = null, this.eventsQueue.length > 0 && this.sendEventsQueue();
|
|
2495
|
+
}, e);
|
|
2496
|
+
}
|
|
2497
|
+
calculateSendDelay() {
|
|
2498
|
+
const e = this.get("config")?.sendIntervalMs ?? 1e4;
|
|
2499
|
+
if (this.consecutiveSendFailures === 0) return e;
|
|
2500
|
+
const t = e * Math.pow(2, this.consecutiveSendFailures);
|
|
2501
|
+
return Math.min(t, 12e4);
|
|
2472
2502
|
}
|
|
2473
2503
|
shouldSample() {
|
|
2474
2504
|
const e = this.get("config")?.samplingRate ?? 1;
|
|
@@ -2480,7 +2510,7 @@ class tr extends I {
|
|
|
2480
2510
|
}
|
|
2481
2511
|
checkPerEventRateLimit(e, t) {
|
|
2482
2512
|
const r = Date.now(), i = (this.perEventRateLimits.get(e) ?? []).filter((o) => r - o < 6e4);
|
|
2483
|
-
return i.length >= t ? (
|
|
2513
|
+
return i.length >= t ? (l("warn", "Per-event rate limit exceeded for custom event", {
|
|
2484
2514
|
data: {
|
|
2485
2515
|
eventName: e,
|
|
2486
2516
|
limit: t,
|
|
@@ -2502,10 +2532,10 @@ class tr extends I {
|
|
|
2502
2532
|
this.eventsQueue = this.eventsQueue.filter((r) => !t.has(r.id));
|
|
2503
2533
|
}
|
|
2504
2534
|
emitEvent(e) {
|
|
2505
|
-
this.emitter && this.emitter.emit(
|
|
2535
|
+
this.emitter && this.emitter.emit(le.EVENT, e);
|
|
2506
2536
|
}
|
|
2507
2537
|
emitEventsQueue(e) {
|
|
2508
|
-
this.emitter && this.emitter.emit(
|
|
2538
|
+
this.emitter && this.emitter.emit(le.QUEUE, e);
|
|
2509
2539
|
}
|
|
2510
2540
|
/**
|
|
2511
2541
|
* Creates a debounced version of a function that delays execution until after
|
|
@@ -2581,13 +2611,13 @@ class tr extends I {
|
|
|
2581
2611
|
loadSessionCounts(e) {
|
|
2582
2612
|
if (typeof window > "u" || typeof localStorage > "u")
|
|
2583
2613
|
return this.getInitialCounts();
|
|
2584
|
-
const t = this.get("userId") || "anonymous", r =
|
|
2614
|
+
const t = this.get("userId") || "anonymous", r = Me(t, e);
|
|
2585
2615
|
try {
|
|
2586
2616
|
const n = localStorage.getItem(r);
|
|
2587
2617
|
if (!n)
|
|
2588
2618
|
return this.getInitialCounts();
|
|
2589
2619
|
const i = JSON.parse(n);
|
|
2590
|
-
return i._timestamp && Date.now() - i._timestamp >
|
|
2620
|
+
return i._timestamp && Date.now() - i._timestamp > Ce ? (l("debug", "Session counts expired, clearing", {
|
|
2591
2621
|
data: { sessionId: e, age: Date.now() - i._timestamp }
|
|
2592
2622
|
}), localStorage.removeItem(r), this.getInitialCounts()) : typeof i.total == "number" && typeof i[d.CLICK] == "number" && typeof i[d.PAGE_VIEW] == "number" && typeof i[d.CUSTOM] == "number" && typeof i[d.VIEWPORT_VISIBLE] == "number" && typeof i[d.SCROLL] == "number" ? {
|
|
2593
2623
|
total: i.total,
|
|
@@ -2596,13 +2626,13 @@ class tr extends I {
|
|
|
2596
2626
|
[d.CUSTOM]: i[d.CUSTOM],
|
|
2597
2627
|
[d.VIEWPORT_VISIBLE]: i[d.VIEWPORT_VISIBLE],
|
|
2598
2628
|
[d.SCROLL]: i[d.SCROLL]
|
|
2599
|
-
} : (
|
|
2629
|
+
} : (l("warn", "Invalid session counts structure in localStorage, resetting", {
|
|
2600
2630
|
data: { sessionId: e, parsed: i }
|
|
2601
|
-
}), localStorage.removeItem(r),
|
|
2631
|
+
}), localStorage.removeItem(r), l("debug", "Session counts removed due to invalid/corrupted data", {
|
|
2602
2632
|
data: { sessionId: e, parsed: i }
|
|
2603
2633
|
}), this.getInitialCounts());
|
|
2604
2634
|
} catch (n) {
|
|
2605
|
-
return
|
|
2635
|
+
return l("warn", "Failed to load session counts from localStorage", {
|
|
2606
2636
|
error: n,
|
|
2607
2637
|
data: { sessionId: e }
|
|
2608
2638
|
}), this.getInitialCounts();
|
|
@@ -2632,34 +2662,34 @@ class tr extends I {
|
|
|
2632
2662
|
cleanupExpiredSessionCounts() {
|
|
2633
2663
|
if (!(typeof window > "u" || typeof localStorage > "u"))
|
|
2634
2664
|
try {
|
|
2635
|
-
const e = localStorage.getItem(
|
|
2665
|
+
const e = localStorage.getItem(Re);
|
|
2636
2666
|
if (e) {
|
|
2637
2667
|
const i = Date.now() - parseInt(e, 10);
|
|
2638
|
-
if (i <
|
|
2639
|
-
|
|
2640
|
-
data: { timeSinceLastCleanup: i, throttleMs:
|
|
2668
|
+
if (i < Ne) {
|
|
2669
|
+
l("debug", "Skipping session counts cleanup (throttled)", {
|
|
2670
|
+
data: { timeSinceLastCleanup: i, throttleMs: Ne }
|
|
2641
2671
|
});
|
|
2642
2672
|
return;
|
|
2643
2673
|
}
|
|
2644
2674
|
}
|
|
2645
|
-
const t = this.get("userId") || "anonymous", r = `${
|
|
2675
|
+
const t = this.get("userId") || "anonymous", r = `${I}:${t}:session_counts:`, n = [];
|
|
2646
2676
|
for (let i = 0; i < localStorage.length; i++) {
|
|
2647
2677
|
const o = localStorage.key(i);
|
|
2648
2678
|
if (o?.startsWith(r))
|
|
2649
2679
|
try {
|
|
2650
|
-
const
|
|
2651
|
-
if (
|
|
2652
|
-
const c = JSON.parse(
|
|
2653
|
-
c._timestamp && Date.now() - c._timestamp >
|
|
2680
|
+
const a = localStorage.getItem(o);
|
|
2681
|
+
if (a) {
|
|
2682
|
+
const c = JSON.parse(a);
|
|
2683
|
+
c._timestamp && Date.now() - c._timestamp > Ce && n.push(o);
|
|
2654
2684
|
}
|
|
2655
2685
|
} catch {
|
|
2656
2686
|
}
|
|
2657
2687
|
}
|
|
2658
2688
|
n.forEach((i) => {
|
|
2659
|
-
localStorage.removeItem(i),
|
|
2660
|
-
}), n.length > 0 &&
|
|
2689
|
+
localStorage.removeItem(i), l("debug", "Cleaned up expired session counts", { data: { key: i } });
|
|
2690
|
+
}), n.length > 0 && l("info", `Cleaned up ${n.length} expired session counts entries`), localStorage.setItem(Re, Date.now().toString());
|
|
2661
2691
|
} catch (e) {
|
|
2662
|
-
|
|
2692
|
+
l("warn", "Failed to cleanup expired session counts", { error: e });
|
|
2663
2693
|
}
|
|
2664
2694
|
}
|
|
2665
2695
|
/**
|
|
@@ -2691,7 +2721,7 @@ class tr extends I {
|
|
|
2691
2721
|
* @internal
|
|
2692
2722
|
*/
|
|
2693
2723
|
saveSessionCounts(e) {
|
|
2694
|
-
const t = this.get("userId") || "anonymous", r =
|
|
2724
|
+
const t = this.get("userId") || "anonymous", r = Me(t, e);
|
|
2695
2725
|
try {
|
|
2696
2726
|
const n = {
|
|
2697
2727
|
...this.sessionEventCounts,
|
|
@@ -2700,14 +2730,14 @@ class tr extends I {
|
|
|
2700
2730
|
};
|
|
2701
2731
|
localStorage.setItem(r, JSON.stringify(n));
|
|
2702
2732
|
} catch (n) {
|
|
2703
|
-
|
|
2733
|
+
l("warn", "Failed to persist session counts to localStorage", {
|
|
2704
2734
|
error: n,
|
|
2705
2735
|
data: { sessionId: e }
|
|
2706
2736
|
});
|
|
2707
2737
|
}
|
|
2708
2738
|
}
|
|
2709
2739
|
}
|
|
2710
|
-
class
|
|
2740
|
+
class nr {
|
|
2711
2741
|
/**
|
|
2712
2742
|
* Gets or creates a unique user ID.
|
|
2713
2743
|
*
|
|
@@ -2725,15 +2755,15 @@ class rr {
|
|
|
2725
2755
|
* @returns Persistent unique user ID (UUID v4 format)
|
|
2726
2756
|
*/
|
|
2727
2757
|
static getId(e) {
|
|
2728
|
-
const t = e.getItem(
|
|
2758
|
+
const t = e.getItem(be);
|
|
2729
2759
|
if (t)
|
|
2730
2760
|
return t;
|
|
2731
|
-
const r =
|
|
2732
|
-
return e.setItem(
|
|
2761
|
+
const r = $t();
|
|
2762
|
+
return e.setItem(be, r), r;
|
|
2733
2763
|
}
|
|
2734
2764
|
}
|
|
2735
|
-
const
|
|
2736
|
-
class
|
|
2765
|
+
const ir = /^\d{13}-[a-z0-9]{9}$/;
|
|
2766
|
+
class or extends v {
|
|
2737
2767
|
storageManager;
|
|
2738
2768
|
eventManager;
|
|
2739
2769
|
projectId;
|
|
@@ -2755,13 +2785,13 @@ class nr extends I {
|
|
|
2755
2785
|
}
|
|
2756
2786
|
initCrossTabSync() {
|
|
2757
2787
|
if (typeof BroadcastChannel > "u") {
|
|
2758
|
-
|
|
2788
|
+
l("debug", "BroadcastChannel not supported");
|
|
2759
2789
|
return;
|
|
2760
2790
|
}
|
|
2761
2791
|
const e = this.getProjectId();
|
|
2762
|
-
this.broadcastChannel = new BroadcastChannel(
|
|
2792
|
+
this.broadcastChannel = new BroadcastChannel(mt(e)), this.broadcastChannel.onmessage = (t) => {
|
|
2763
2793
|
const { action: r, sessionId: n, timestamp: i, projectId: o } = t.data ?? {};
|
|
2764
|
-
o === e && (r === "session_start" && n && typeof i == "number" && i > Date.now() - 5e3 ? (this.set("sessionId", n), this.persistSession(n, i), this.isTracking && this.setupSessionTimeout()) : r && r !== "session_start" &&
|
|
2794
|
+
o === e && (r === "session_start" && n && typeof i == "number" && i > Date.now() - 5e3 ? (this.set("sessionId", n), this.persistSession(n, i), this.isTracking && this.setupSessionTimeout()) : r && r !== "session_start" && l("debug", "Ignored BroadcastChannel message with unknown action", { data: { action: r } }));
|
|
2765
2795
|
};
|
|
2766
2796
|
}
|
|
2767
2797
|
shareSession(e) {
|
|
@@ -2779,8 +2809,8 @@ class nr extends I {
|
|
|
2779
2809
|
const e = this.loadStoredSession();
|
|
2780
2810
|
if (!e)
|
|
2781
2811
|
return null;
|
|
2782
|
-
if (!
|
|
2783
|
-
return
|
|
2812
|
+
if (!ir.test(e.id))
|
|
2813
|
+
return l("warn", "Invalid session ID format recovered from storage, clearing", {
|
|
2784
2814
|
data: { sessionId: e.id }
|
|
2785
2815
|
}), this.clearStoredSession(), null;
|
|
2786
2816
|
const t = this.get("config")?.sessionTimeout ?? 9e5;
|
|
@@ -2814,7 +2844,7 @@ class nr extends I {
|
|
|
2814
2844
|
this.storageManager.setItem(t, JSON.stringify(e));
|
|
2815
2845
|
}
|
|
2816
2846
|
getSessionStorageKey() {
|
|
2817
|
-
return
|
|
2847
|
+
return ft(this.getProjectId());
|
|
2818
2848
|
}
|
|
2819
2849
|
getProjectId() {
|
|
2820
2850
|
return this.projectId;
|
|
@@ -2872,17 +2902,17 @@ class nr extends I {
|
|
|
2872
2902
|
*/
|
|
2873
2903
|
startTracking() {
|
|
2874
2904
|
if (this.isTracking) {
|
|
2875
|
-
|
|
2905
|
+
l("debug", "Session tracking already active");
|
|
2876
2906
|
return;
|
|
2877
2907
|
}
|
|
2878
2908
|
const e = this.recoverSession(), t = e ?? this.generateSessionId();
|
|
2879
2909
|
let r, n;
|
|
2880
2910
|
if (e) {
|
|
2881
2911
|
const i = this.loadStoredSession();
|
|
2882
|
-
r = i?.referrer ??
|
|
2912
|
+
r = i?.referrer ?? se(), n = i?.utm ?? ne();
|
|
2883
2913
|
} else
|
|
2884
|
-
r =
|
|
2885
|
-
|
|
2914
|
+
r = se(), n = ne();
|
|
2915
|
+
l("debug", "Session tracking initialized", {
|
|
2886
2916
|
data: {
|
|
2887
2917
|
sessionId: t,
|
|
2888
2918
|
wasRecovered: !!e,
|
|
@@ -2892,9 +2922,9 @@ class nr extends I {
|
|
|
2892
2922
|
}
|
|
2893
2923
|
}), this.isTracking = !0;
|
|
2894
2924
|
try {
|
|
2895
|
-
this.set("sessionId", t), this.set("sessionReferrer", r), this.set("sessionUtm", n), this.persistSession(t, Date.now(), r, n), this.initCrossTabSync(), this.shareSession(t), e ?
|
|
2925
|
+
this.set("sessionId", t), this.set("sessionReferrer", r), this.set("sessionUtm", n), this.persistSession(t, Date.now(), r, n), this.initCrossTabSync(), this.shareSession(t), e ? l("debug", "Session recovered, skipping SESSION_START", {
|
|
2896
2926
|
data: { sessionId: t }
|
|
2897
|
-
}) : (
|
|
2927
|
+
}) : (l("debug", "Emitting SESSION_START event", {
|
|
2898
2928
|
data: { sessionId: t }
|
|
2899
2929
|
}), this.eventManager.track({
|
|
2900
2930
|
type: d.SESSION_START
|
|
@@ -2932,8 +2962,8 @@ class nr extends I {
|
|
|
2932
2962
|
*/
|
|
2933
2963
|
renewSession() {
|
|
2934
2964
|
this.needsRenewal = !1;
|
|
2935
|
-
const e = this.generateSessionId(), t =
|
|
2936
|
-
|
|
2965
|
+
const e = this.generateSessionId(), t = se(), r = ne();
|
|
2966
|
+
l("debug", "Renewing session after timeout", {
|
|
2937
2967
|
data: { newSessionId: e }
|
|
2938
2968
|
}), this.set("sessionId", e), this.set("sessionReferrer", t), this.set("sessionUtm", r), this.persistSession(e, Date.now(), t, r), this.cleanupCrossTabSync(), this.initCrossTabSync(), this.shareSession(e), this.eventManager.track({
|
|
2939
2969
|
type: d.SESSION_START
|
|
@@ -2948,7 +2978,7 @@ class nr extends I {
|
|
|
2948
2978
|
this.clearSessionTimeout();
|
|
2949
2979
|
else {
|
|
2950
2980
|
if (this.isSessionStale()) {
|
|
2951
|
-
|
|
2981
|
+
l("debug", "Session expired during suspend, entering renewal mode"), this.enterRenewalMode();
|
|
2952
2982
|
return;
|
|
2953
2983
|
}
|
|
2954
2984
|
this.get("sessionId") && this.setupSessionTimeout();
|
|
@@ -2977,7 +3007,7 @@ class nr extends I {
|
|
|
2977
3007
|
* Called by session timeout timer.
|
|
2978
3008
|
*/
|
|
2979
3009
|
enterRenewalMode() {
|
|
2980
|
-
this.clearSessionTimeout(), this.cleanupCrossTabSync(), this.clearStoredSession(), this.set("sessionId", null), this.set("hasStartSession", !1), this.set("sessionReferrer", void 0), this.set("sessionUtm", void 0), this.needsRenewal = !0,
|
|
3010
|
+
this.clearSessionTimeout(), this.cleanupCrossTabSync(), this.clearStoredSession(), this.set("sessionId", null), this.set("hasStartSession", !1), this.set("sessionReferrer", void 0), this.set("sessionUtm", void 0), this.needsRenewal = !0, l("debug", "Session timed out, entering renewal mode");
|
|
2981
3011
|
}
|
|
2982
3012
|
/**
|
|
2983
3013
|
* Fully resets session state and cleans up all resources.
|
|
@@ -3053,7 +3083,7 @@ class nr extends I {
|
|
|
3053
3083
|
this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupCrossTabSync(), this.cleanupLifecycleListeners(), this.isTracking = !1, this.needsRenewal = !1, this.set("hasStartSession", !1);
|
|
3054
3084
|
}
|
|
3055
3085
|
}
|
|
3056
|
-
class
|
|
3086
|
+
class ar extends v {
|
|
3057
3087
|
eventManager;
|
|
3058
3088
|
storageManager;
|
|
3059
3089
|
sessionManager = null;
|
|
@@ -3083,12 +3113,12 @@ class ir extends I {
|
|
|
3083
3113
|
if (this.isActive())
|
|
3084
3114
|
return;
|
|
3085
3115
|
if (this.destroyed) {
|
|
3086
|
-
|
|
3116
|
+
l("debug", "Cannot start tracking on destroyed handler");
|
|
3087
3117
|
return;
|
|
3088
3118
|
}
|
|
3089
3119
|
const t = this.get("config")?.integrations?.tracelog?.projectId ?? "custom";
|
|
3090
3120
|
try {
|
|
3091
|
-
this.sessionManager = new
|
|
3121
|
+
this.sessionManager = new or(this.storageManager, this.eventManager, t), this.sessionManager.startTracking(), this.eventManager.flushPendingEvents();
|
|
3092
3122
|
} catch (r) {
|
|
3093
3123
|
if (this.sessionManager) {
|
|
3094
3124
|
try {
|
|
@@ -3097,7 +3127,7 @@ class ir extends I {
|
|
|
3097
3127
|
}
|
|
3098
3128
|
this.sessionManager = null;
|
|
3099
3129
|
}
|
|
3100
|
-
throw
|
|
3130
|
+
throw l("error", "Failed to start session tracking", { error: r }), r;
|
|
3101
3131
|
}
|
|
3102
3132
|
}
|
|
3103
3133
|
isActive() {
|
|
@@ -3141,7 +3171,7 @@ class ir extends I {
|
|
|
3141
3171
|
this.destroyed || (this.sessionManager && (this.sessionManager.destroy(), this.sessionManager = null), this.destroyed = !0);
|
|
3142
3172
|
}
|
|
3143
3173
|
}
|
|
3144
|
-
class
|
|
3174
|
+
class lr extends v {
|
|
3145
3175
|
eventManager;
|
|
3146
3176
|
onTrack;
|
|
3147
3177
|
originalPushState;
|
|
@@ -3181,7 +3211,7 @@ class or extends I {
|
|
|
3181
3211
|
};
|
|
3182
3212
|
}
|
|
3183
3213
|
trackCurrentPage = () => {
|
|
3184
|
-
const e = window.location.href, t =
|
|
3214
|
+
const e = window.location.href, t = he(e, this.get("config").sensitiveQueryParams);
|
|
3185
3215
|
if (this.get("pageUrl") === t)
|
|
3186
3216
|
return;
|
|
3187
3217
|
const r = Date.now(), n = this.get("config").pageViewThrottleMs ?? 1e3;
|
|
@@ -3199,7 +3229,7 @@ class or extends I {
|
|
|
3199
3229
|
});
|
|
3200
3230
|
};
|
|
3201
3231
|
trackInitialPageView() {
|
|
3202
|
-
const e =
|
|
3232
|
+
const e = he(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
|
|
3203
3233
|
this.lastPageViewTime = Date.now(), this.eventManager.track({
|
|
3204
3234
|
type: d.PAGE_VIEW,
|
|
3205
3235
|
page_url: e,
|
|
@@ -3217,7 +3247,7 @@ class or extends I {
|
|
|
3217
3247
|
};
|
|
3218
3248
|
}
|
|
3219
3249
|
}
|
|
3220
|
-
class
|
|
3250
|
+
class cr extends v {
|
|
3221
3251
|
eventManager;
|
|
3222
3252
|
lastClickTimes = /* @__PURE__ */ new Map();
|
|
3223
3253
|
clickHandler;
|
|
@@ -3242,7 +3272,7 @@ class ar extends I {
|
|
|
3242
3272
|
this.clickHandler || (this.clickHandler = (e) => {
|
|
3243
3273
|
const t = e, r = t.target, n = typeof HTMLElement < "u" && r instanceof HTMLElement ? r : typeof HTMLElement < "u" && r instanceof Node && r.parentElement instanceof HTMLElement ? r.parentElement : null;
|
|
3244
3274
|
if (!n) {
|
|
3245
|
-
|
|
3275
|
+
l("debug", "Click target not found or not an element");
|
|
3246
3276
|
return;
|
|
3247
3277
|
}
|
|
3248
3278
|
if (this.shouldIgnoreElement(n))
|
|
@@ -3250,7 +3280,7 @@ class ar extends I {
|
|
|
3250
3280
|
const i = this.get("config")?.clickThrottleMs ?? 300;
|
|
3251
3281
|
if (i > 0 && !this.checkClickThrottle(n, i))
|
|
3252
3282
|
return;
|
|
3253
|
-
const o = this.findTrackingElement(n),
|
|
3283
|
+
const o = this.findTrackingElement(n), a = this.getRelevantClickElement(n), c = this.calculateClickCoordinates(t, n);
|
|
3254
3284
|
if (o) {
|
|
3255
3285
|
const S = this.extractTrackingData(o);
|
|
3256
3286
|
if (S) {
|
|
@@ -3264,7 +3294,7 @@ class ar extends I {
|
|
|
3264
3294
|
});
|
|
3265
3295
|
}
|
|
3266
3296
|
}
|
|
3267
|
-
const u = this.generateClickData(n,
|
|
3297
|
+
const u = this.generateClickData(n, a, c);
|
|
3268
3298
|
this.eventManager.track({
|
|
3269
3299
|
type: d.CLICK,
|
|
3270
3300
|
click_data: u
|
|
@@ -3291,7 +3321,7 @@ class ar extends I {
|
|
|
3291
3321
|
const r = this.getElementSignature(e), n = Date.now();
|
|
3292
3322
|
this.pruneThrottleCache(n);
|
|
3293
3323
|
const i = this.lastClickTimes.get(r);
|
|
3294
|
-
return i !== void 0 && n - i < t ? (
|
|
3324
|
+
return i !== void 0 && n - i < t ? (l("debug", "ClickHandler: Click suppressed by throttle", {
|
|
3295
3325
|
data: {
|
|
3296
3326
|
signature: r,
|
|
3297
3327
|
throttleRemaining: t - (n - i)
|
|
@@ -3311,10 +3341,10 @@ class ar extends I {
|
|
|
3311
3341
|
for (const [r, n] of this.lastClickTimes.entries())
|
|
3312
3342
|
n < t && this.lastClickTimes.delete(r);
|
|
3313
3343
|
if (this.lastClickTimes.size > 1e3) {
|
|
3314
|
-
const r = Array.from(this.lastClickTimes.entries()).sort((o,
|
|
3344
|
+
const r = Array.from(this.lastClickTimes.entries()).sort((o, a) => o[1] - a[1]), n = this.lastClickTimes.size - 1e3, i = r.slice(0, n);
|
|
3315
3345
|
for (const [o] of i)
|
|
3316
3346
|
this.lastClickTimes.delete(o);
|
|
3317
|
-
|
|
3347
|
+
l("debug", "ClickHandler: Pruned throttle cache", {
|
|
3318
3348
|
data: {
|
|
3319
3349
|
removed: i.length,
|
|
3320
3350
|
remaining: this.lastClickTimes.size
|
|
@@ -3355,7 +3385,7 @@ class ar extends I {
|
|
|
3355
3385
|
return e.hasAttribute(`${w}-name`) ? e : e.closest(`[${w}-name]`);
|
|
3356
3386
|
}
|
|
3357
3387
|
getRelevantClickElement(e) {
|
|
3358
|
-
for (const t of
|
|
3388
|
+
for (const t of lt)
|
|
3359
3389
|
try {
|
|
3360
3390
|
if (e.matches(t))
|
|
3361
3391
|
return e;
|
|
@@ -3363,7 +3393,7 @@ class ar extends I {
|
|
|
3363
3393
|
if (r)
|
|
3364
3394
|
return r;
|
|
3365
3395
|
} catch (r) {
|
|
3366
|
-
|
|
3396
|
+
l("debug", "Invalid selector in element search", { error: r, data: { selector: t } });
|
|
3367
3397
|
continue;
|
|
3368
3398
|
}
|
|
3369
3399
|
return e;
|
|
@@ -3383,8 +3413,8 @@ class ar extends I {
|
|
|
3383
3413
|
return Math.max(0, Math.min(1, Number(e.toFixed(3))));
|
|
3384
3414
|
}
|
|
3385
3415
|
calculateClickCoordinates(e, t) {
|
|
3386
|
-
const r = t.getBoundingClientRect(), n = e.clientX, i = e.clientY, o = r.width > 0 ? this.clamp((n - r.left) / r.width) : 0,
|
|
3387
|
-
return { x: n, y: i, relativeX: o, relativeY:
|
|
3416
|
+
const r = t.getBoundingClientRect(), n = e.clientX, i = e.clientY, o = r.width > 0 ? this.clamp((n - r.left) / r.width) : 0, a = r.height > 0 ? this.clamp((i - r.top) / r.height) : 0;
|
|
3417
|
+
return { x: n, y: i, relativeX: o, relativeY: a };
|
|
3388
3418
|
}
|
|
3389
3419
|
extractTrackingData(e) {
|
|
3390
3420
|
const t = e.getAttribute(`${w}-name`), r = e.getAttribute(`${w}-value`);
|
|
@@ -3396,12 +3426,12 @@ class ar extends I {
|
|
|
3396
3426
|
};
|
|
3397
3427
|
}
|
|
3398
3428
|
generateClickData(e, t, r) {
|
|
3399
|
-
const { x: n, y: i, relativeX: o, relativeY:
|
|
3429
|
+
const { x: n, y: i, relativeX: o, relativeY: a } = r, c = this.getRelevantText(e, t), u = this.extractElementAttributes(t);
|
|
3400
3430
|
return {
|
|
3401
3431
|
x: n,
|
|
3402
3432
|
y: i,
|
|
3403
3433
|
relativeX: o,
|
|
3404
|
-
relativeY:
|
|
3434
|
+
relativeY: a,
|
|
3405
3435
|
tag: t.tagName.toLowerCase(),
|
|
3406
3436
|
...t.id && { id: t.id },
|
|
3407
3437
|
...t.className && { class: t.className },
|
|
@@ -3435,7 +3465,7 @@ class ar extends I {
|
|
|
3435
3465
|
*/
|
|
3436
3466
|
sanitizeText(e) {
|
|
3437
3467
|
let t = e;
|
|
3438
|
-
for (const r of
|
|
3468
|
+
for (const r of ze) {
|
|
3439
3469
|
const n = new RegExp(r.source, r.flags);
|
|
3440
3470
|
t = t.replace(n, "[REDACTED]");
|
|
3441
3471
|
}
|
|
@@ -3474,7 +3504,7 @@ class ar extends I {
|
|
|
3474
3504
|
};
|
|
3475
3505
|
}
|
|
3476
3506
|
}
|
|
3477
|
-
class
|
|
3507
|
+
class ur extends v {
|
|
3478
3508
|
eventManager;
|
|
3479
3509
|
containers = [];
|
|
3480
3510
|
limitWarningLogged = !1;
|
|
@@ -3581,29 +3611,29 @@ class lr extends I {
|
|
|
3581
3611
|
n,
|
|
3582
3612
|
this.getScrollHeight(e),
|
|
3583
3613
|
this.getViewportHeight(e)
|
|
3584
|
-
), o = this.determineIfPrimary(e),
|
|
3614
|
+
), o = this.determineIfPrimary(e), a = {
|
|
3585
3615
|
element: e,
|
|
3586
3616
|
selector: t,
|
|
3587
3617
|
isPrimary: o,
|
|
3588
3618
|
lastScrollPos: n,
|
|
3589
3619
|
lastDepth: i,
|
|
3590
|
-
lastDirection:
|
|
3620
|
+
lastDirection: j.DOWN,
|
|
3591
3621
|
lastEventTime: 0,
|
|
3592
3622
|
firstScrollEventTime: null,
|
|
3593
3623
|
maxDepthReached: i,
|
|
3594
3624
|
debounceTimer: null,
|
|
3595
3625
|
listener: null
|
|
3596
3626
|
}, c = () => {
|
|
3597
|
-
this.get("suppressNextScroll") || (
|
|
3598
|
-
const u = this.calculateScrollData(
|
|
3627
|
+
this.get("suppressNextScroll") || (a.firstScrollEventTime === null && (a.firstScrollEventTime = Date.now()), this.clearContainerTimer(a), a.debounceTimer = window.setTimeout(() => {
|
|
3628
|
+
const u = this.calculateScrollData(a);
|
|
3599
3629
|
if (u) {
|
|
3600
3630
|
const S = Date.now();
|
|
3601
|
-
this.processScrollEvent(
|
|
3631
|
+
this.processScrollEvent(a, u, S);
|
|
3602
3632
|
}
|
|
3603
|
-
|
|
3633
|
+
a.debounceTimer = null;
|
|
3604
3634
|
}, 250));
|
|
3605
3635
|
};
|
|
3606
|
-
|
|
3636
|
+
a.listener = c, this.containers.push(a), e === window ? window.addEventListener("scroll", c, { passive: !0 }) : e.addEventListener("scroll", c, { passive: !0 });
|
|
3607
3637
|
}
|
|
3608
3638
|
processScrollEvent(e, t, r) {
|
|
3609
3639
|
if (!this.shouldEmitScrollEvent(e, t, r))
|
|
@@ -3632,7 +3662,7 @@ class lr extends I {
|
|
|
3632
3662
|
return Math.abs(t - e.lastDepth) >= this.minDepthChange;
|
|
3633
3663
|
}
|
|
3634
3664
|
logLimitOnce() {
|
|
3635
|
-
this.limitWarningLogged || (this.limitWarningLogged = !0,
|
|
3665
|
+
this.limitWarningLogged || (this.limitWarningLogged = !0, l("debug", "Max scroll events per session reached", {
|
|
3636
3666
|
data: { limit: this.maxEventsPerSession }
|
|
3637
3667
|
}));
|
|
3638
3668
|
}
|
|
@@ -3646,7 +3676,7 @@ class lr extends I {
|
|
|
3646
3676
|
e.debounceTimer !== null && (clearTimeout(e.debounceTimer), e.debounceTimer = null);
|
|
3647
3677
|
}
|
|
3648
3678
|
getScrollDirection(e, t) {
|
|
3649
|
-
return e > t ?
|
|
3679
|
+
return e > t ? j.DOWN : j.UP;
|
|
3650
3680
|
}
|
|
3651
3681
|
calculateScrollDepth(e, t, r) {
|
|
3652
3682
|
if (t <= r)
|
|
@@ -3655,13 +3685,13 @@ class lr extends I {
|
|
|
3655
3685
|
return Math.min(100, Math.max(0, Math.floor(e / n * 100)));
|
|
3656
3686
|
}
|
|
3657
3687
|
calculateScrollData(e) {
|
|
3658
|
-
const { element: t, lastScrollPos: r, lastEventTime: n } = e, i = this.getScrollTop(t), o = Date.now(),
|
|
3659
|
-
if (
|
|
3688
|
+
const { element: t, lastScrollPos: r, lastEventTime: n } = e, i = this.getScrollTop(t), o = Date.now(), a = Math.abs(i - r);
|
|
3689
|
+
if (a < 10 || t === window && !this.isWindowScrollable())
|
|
3660
3690
|
return null;
|
|
3661
3691
|
const c = this.getViewportHeight(t), u = this.getScrollHeight(t), S = this.getScrollDirection(i, r), g = this.calculateScrollDepth(i, u, c);
|
|
3662
3692
|
let p;
|
|
3663
3693
|
n > 0 ? p = o - n : e.firstScrollEventTime !== null ? p = o - e.firstScrollEventTime : p = 250;
|
|
3664
|
-
const E = Math.round(
|
|
3694
|
+
const E = Math.round(a / p * 1e3);
|
|
3665
3695
|
return g > e.maxDepthReached && (e.maxDepthReached = g), e.lastScrollPos = i, {
|
|
3666
3696
|
depth: g,
|
|
3667
3697
|
direction: S,
|
|
@@ -3689,7 +3719,7 @@ class lr extends I {
|
|
|
3689
3719
|
else {
|
|
3690
3720
|
const n = document.querySelector(e);
|
|
3691
3721
|
if (!(n instanceof HTMLElement)) {
|
|
3692
|
-
|
|
3722
|
+
l("debug", `Selector "${e}" did not match an HTMLElement`);
|
|
3693
3723
|
return;
|
|
3694
3724
|
}
|
|
3695
3725
|
t = n;
|
|
@@ -3702,7 +3732,7 @@ class lr extends I {
|
|
|
3702
3732
|
e.isPrimary = t;
|
|
3703
3733
|
}
|
|
3704
3734
|
}
|
|
3705
|
-
class
|
|
3735
|
+
class dr extends v {
|
|
3706
3736
|
eventManager;
|
|
3707
3737
|
trackedElements = /* @__PURE__ */ new Map();
|
|
3708
3738
|
observer = null;
|
|
@@ -3721,15 +3751,15 @@ class cr extends I {
|
|
|
3721
3751
|
return;
|
|
3722
3752
|
const t = this.config.threshold ?? 0.5, r = this.config.minDwellTime ?? 1e3;
|
|
3723
3753
|
if (t < 0 || t > 1) {
|
|
3724
|
-
|
|
3754
|
+
l("debug", "ViewportHandler: Invalid threshold, must be between 0 and 1");
|
|
3725
3755
|
return;
|
|
3726
3756
|
}
|
|
3727
3757
|
if (r < 0) {
|
|
3728
|
-
|
|
3758
|
+
l("debug", "ViewportHandler: Invalid minDwellTime, must be non-negative");
|
|
3729
3759
|
return;
|
|
3730
3760
|
}
|
|
3731
3761
|
if (typeof IntersectionObserver > "u") {
|
|
3732
|
-
|
|
3762
|
+
l("debug", "ViewportHandler: IntersectionObserver not supported in this browser");
|
|
3733
3763
|
return;
|
|
3734
3764
|
}
|
|
3735
3765
|
this.observer = new IntersectionObserver(this.handleIntersection, {
|
|
@@ -3757,7 +3787,7 @@ class cr extends I {
|
|
|
3757
3787
|
const n = document.querySelectorAll(r.selector);
|
|
3758
3788
|
for (const i of Array.from(n)) {
|
|
3759
3789
|
if (t >= e) {
|
|
3760
|
-
|
|
3790
|
+
l("debug", "ViewportHandler: Maximum tracked elements reached", {
|
|
3761
3791
|
data: {
|
|
3762
3792
|
limit: e,
|
|
3763
3793
|
selector: r.selector,
|
|
@@ -3777,9 +3807,9 @@ class cr extends I {
|
|
|
3777
3807
|
}), this.observer?.observe(i), t++);
|
|
3778
3808
|
}
|
|
3779
3809
|
} catch (n) {
|
|
3780
|
-
|
|
3810
|
+
l("debug", `ViewportHandler: Invalid selector "${r.selector}"`, { error: n });
|
|
3781
3811
|
}
|
|
3782
|
-
|
|
3812
|
+
l("debug", "ViewportHandler: Elements tracked", {
|
|
3783
3813
|
data: { count: t, limit: e }
|
|
3784
3814
|
});
|
|
3785
3815
|
}
|
|
@@ -3807,7 +3837,7 @@ class cr extends I {
|
|
|
3807
3837
|
return;
|
|
3808
3838
|
const n = this.config?.cooldownPeriod ?? 6e4, i = Date.now();
|
|
3809
3839
|
if (e.lastFiredTime !== null && i - e.lastFiredTime < n) {
|
|
3810
|
-
|
|
3840
|
+
l("debug", "ViewportHandler: Event suppressed by cooldown period", {
|
|
3811
3841
|
data: {
|
|
3812
3842
|
selector: e.selector,
|
|
3813
3843
|
cooldownRemaining: n - (i - e.lastFiredTime)
|
|
@@ -3833,7 +3863,7 @@ class cr extends I {
|
|
|
3833
3863
|
setupMutationObserver() {
|
|
3834
3864
|
if (!(!this.config || typeof MutationObserver > "u")) {
|
|
3835
3865
|
if (!document.body) {
|
|
3836
|
-
|
|
3866
|
+
l("debug", "ViewportHandler: document.body not available, skipping MutationObserver setup");
|
|
3837
3867
|
return;
|
|
3838
3868
|
}
|
|
3839
3869
|
this.mutationObserver = new MutationObserver((e) => {
|
|
@@ -3857,20 +3887,20 @@ class cr extends I {
|
|
|
3857
3887
|
if (t.nodeType !== 1) return;
|
|
3858
3888
|
const r = t, n = this.trackedElements.get(r);
|
|
3859
3889
|
n && (n.timeoutId !== null && window.clearTimeout(n.timeoutId), this.observer?.unobserve(r), this.trackedElements.delete(r)), Array.from(this.trackedElements.keys()).filter((o) => r.contains(o)).forEach((o) => {
|
|
3860
|
-
const
|
|
3861
|
-
|
|
3890
|
+
const a = this.trackedElements.get(o);
|
|
3891
|
+
a && a.timeoutId !== null && window.clearTimeout(a.timeoutId), this.observer?.unobserve(o), this.trackedElements.delete(o);
|
|
3862
3892
|
});
|
|
3863
3893
|
});
|
|
3864
3894
|
}
|
|
3865
3895
|
}
|
|
3866
|
-
class
|
|
3896
|
+
class hr {
|
|
3867
3897
|
storage;
|
|
3868
3898
|
sessionStorageRef;
|
|
3869
3899
|
fallbackStorage = /* @__PURE__ */ new Map();
|
|
3870
3900
|
fallbackSessionStorage = /* @__PURE__ */ new Map();
|
|
3871
3901
|
hasQuotaExceededError = !1;
|
|
3872
3902
|
constructor() {
|
|
3873
|
-
this.storage = this.initializeStorage("localStorage"), this.sessionStorageRef = this.initializeStorage("sessionStorage"), this.storage ||
|
|
3903
|
+
this.storage = this.initializeStorage("localStorage"), this.sessionStorageRef = this.initializeStorage("sessionStorage"), this.storage || l("debug", "localStorage not available, using memory fallback"), this.sessionStorageRef || l("debug", "sessionStorage not available, using memory fallback");
|
|
3874
3904
|
}
|
|
3875
3905
|
/**
|
|
3876
3906
|
* Retrieves an item from localStorage.
|
|
@@ -3913,7 +3943,7 @@ class ur {
|
|
|
3913
3943
|
}
|
|
3914
3944
|
} catch (r) {
|
|
3915
3945
|
if (r instanceof DOMException && r.name === "QuotaExceededError" || r instanceof Error && r.name === "QuotaExceededError")
|
|
3916
|
-
if (this.hasQuotaExceededError = !0,
|
|
3946
|
+
if (this.hasQuotaExceededError = !0, l("warn", "localStorage quota exceeded, attempting cleanup", {
|
|
3917
3947
|
data: { key: e, valueSize: t.length }
|
|
3918
3948
|
}), this.cleanupOldData())
|
|
3919
3949
|
try {
|
|
@@ -3922,13 +3952,13 @@ class ur {
|
|
|
3922
3952
|
return;
|
|
3923
3953
|
}
|
|
3924
3954
|
} catch (o) {
|
|
3925
|
-
|
|
3955
|
+
l("error", "localStorage quota exceeded even after cleanup - data will not persist", {
|
|
3926
3956
|
error: o,
|
|
3927
3957
|
data: { key: e, valueSize: t.length }
|
|
3928
3958
|
});
|
|
3929
3959
|
}
|
|
3930
3960
|
else
|
|
3931
|
-
|
|
3961
|
+
l("error", "localStorage quota exceeded and no data to cleanup - data will not persist", {
|
|
3932
3962
|
error: r,
|
|
3933
3963
|
data: { key: e, valueSize: t.length }
|
|
3934
3964
|
});
|
|
@@ -3974,7 +4004,7 @@ class ur {
|
|
|
3974
4004
|
this.storage.removeItem(t);
|
|
3975
4005
|
}), this.fallbackStorage.clear();
|
|
3976
4006
|
} catch (e) {
|
|
3977
|
-
|
|
4007
|
+
l("error", "Failed to clear storage", { error: e }), this.fallbackStorage.clear();
|
|
3978
4008
|
}
|
|
3979
4009
|
}
|
|
3980
4010
|
/**
|
|
@@ -4051,7 +4081,7 @@ class ur {
|
|
|
4051
4081
|
}
|
|
4052
4082
|
}), !0) : !1;
|
|
4053
4083
|
} catch (e) {
|
|
4054
|
-
return
|
|
4084
|
+
return l("error", "Failed to cleanup old data", { error: e }), !1;
|
|
4055
4085
|
}
|
|
4056
4086
|
}
|
|
4057
4087
|
/**
|
|
@@ -4125,7 +4155,7 @@ class ur {
|
|
|
4125
4155
|
return;
|
|
4126
4156
|
}
|
|
4127
4157
|
} catch (r) {
|
|
4128
|
-
(r instanceof DOMException && r.name === "QuotaExceededError" || r instanceof Error && r.name === "QuotaExceededError") &&
|
|
4158
|
+
(r instanceof DOMException && r.name === "QuotaExceededError" || r instanceof Error && r.name === "QuotaExceededError") && l("error", "sessionStorage quota exceeded - data will not persist", {
|
|
4129
4159
|
error: r,
|
|
4130
4160
|
data: { key: e, valueSize: t.length }
|
|
4131
4161
|
});
|
|
@@ -4146,7 +4176,7 @@ class ur {
|
|
|
4146
4176
|
this.fallbackSessionStorage.delete(e);
|
|
4147
4177
|
}
|
|
4148
4178
|
}
|
|
4149
|
-
class
|
|
4179
|
+
class fr extends v {
|
|
4150
4180
|
eventManager;
|
|
4151
4181
|
reportedByNav = /* @__PURE__ */ new Map();
|
|
4152
4182
|
navigationHistory = [];
|
|
@@ -4157,7 +4187,7 @@ class dr extends I {
|
|
|
4157
4187
|
navigationCounter = 0;
|
|
4158
4188
|
// Counter for handling simultaneous navigations edge case
|
|
4159
4189
|
constructor(e) {
|
|
4160
|
-
super(), this.eventManager = e, this.vitalThresholds =
|
|
4190
|
+
super(), this.eventManager = e, this.vitalThresholds = Ue(de);
|
|
4161
4191
|
}
|
|
4162
4192
|
/**
|
|
4163
4193
|
* Starts tracking Web Vitals and performance metrics.
|
|
@@ -4174,8 +4204,8 @@ class dr extends I {
|
|
|
4174
4204
|
* @returns Promise that resolves when tracking is initialized
|
|
4175
4205
|
*/
|
|
4176
4206
|
async startTracking() {
|
|
4177
|
-
const e = this.get("config"), t = e?.webVitalsMode ??
|
|
4178
|
-
this.vitalThresholds =
|
|
4207
|
+
const e = this.get("config"), t = e?.webVitalsMode ?? de;
|
|
4208
|
+
this.vitalThresholds = Ue(t), e?.webVitalsThresholds && (this.vitalThresholds = { ...this.vitalThresholds, ...e.webVitalsThresholds }), await this.initWebVitals(), this.observeLongTasks();
|
|
4179
4209
|
}
|
|
4180
4210
|
/**
|
|
4181
4211
|
* Stops tracking Web Vitals and cleans up resources.
|
|
@@ -4191,7 +4221,7 @@ class dr extends I {
|
|
|
4191
4221
|
try {
|
|
4192
4222
|
e.disconnect();
|
|
4193
4223
|
} catch (r) {
|
|
4194
|
-
|
|
4224
|
+
l("debug", "Failed to disconnect performance observer", { error: r, data: { observerIndex: t } });
|
|
4195
4225
|
}
|
|
4196
4226
|
}), this.observers.length = 0, this.reportedByNav.clear(), this.navigationHistory.length = 0;
|
|
4197
4227
|
}
|
|
@@ -4215,8 +4245,8 @@ class dr extends I {
|
|
|
4215
4245
|
for (const o of i) {
|
|
4216
4246
|
if (o.hadRecentInput === !0)
|
|
4217
4247
|
continue;
|
|
4218
|
-
const
|
|
4219
|
-
e +=
|
|
4248
|
+
const a = typeof o.value == "number" ? o.value : 0;
|
|
4249
|
+
e += a;
|
|
4220
4250
|
}
|
|
4221
4251
|
this.sendVital({ type: "CLS", value: Number(e.toFixed(2)) });
|
|
4222
4252
|
},
|
|
@@ -4235,8 +4265,8 @@ class dr extends I {
|
|
|
4235
4265
|
let n = 0;
|
|
4236
4266
|
const i = r.getEntries();
|
|
4237
4267
|
for (const o of i) {
|
|
4238
|
-
const
|
|
4239
|
-
n = Math.max(n,
|
|
4268
|
+
const a = (o.processingEnd ?? 0) - (o.startTime ?? 0);
|
|
4269
|
+
n = Math.max(n, a);
|
|
4240
4270
|
}
|
|
4241
4271
|
n > 0 && this.sendVital({ type: "INP", value: Number(n.toFixed(2)) });
|
|
4242
4272
|
},
|
|
@@ -4245,13 +4275,13 @@ class dr extends I {
|
|
|
4245
4275
|
}
|
|
4246
4276
|
async initWebVitals() {
|
|
4247
4277
|
try {
|
|
4248
|
-
const { onLCP: e, onCLS: t, onFCP: r, onTTFB: n, onINP: i } = await Promise.resolve().then(() =>
|
|
4278
|
+
const { onLCP: e, onCLS: t, onFCP: r, onTTFB: n, onINP: i } = await Promise.resolve().then(() => $r), o = (a) => (c) => {
|
|
4249
4279
|
const u = Number(c.value.toFixed(2));
|
|
4250
|
-
this.sendVital({ type:
|
|
4280
|
+
this.sendVital({ type: a, value: u });
|
|
4251
4281
|
};
|
|
4252
4282
|
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }), r(o("FCP"), { reportAllChanges: !1 }), n(o("TTFB"), { reportAllChanges: !1 }), i(o("INP"), { reportAllChanges: !1 });
|
|
4253
4283
|
} catch (e) {
|
|
4254
|
-
|
|
4284
|
+
l("debug", "Failed to load web-vitals library, using fallback", { error: e }), this.observeWebVitalsFallback();
|
|
4255
4285
|
}
|
|
4256
4286
|
}
|
|
4257
4287
|
reportTTFB() {
|
|
@@ -4262,7 +4292,7 @@ class dr extends I {
|
|
|
4262
4292
|
const t = e.responseStart;
|
|
4263
4293
|
typeof t == "number" && Number.isFinite(t) && this.sendVital({ type: "TTFB", value: Number(t.toFixed(2)) });
|
|
4264
4294
|
} catch (e) {
|
|
4265
|
-
|
|
4295
|
+
l("debug", "Failed to report TTFB", { error: e });
|
|
4266
4296
|
}
|
|
4267
4297
|
}
|
|
4268
4298
|
observeLongTasks() {
|
|
@@ -4272,7 +4302,7 @@ class dr extends I {
|
|
|
4272
4302
|
const t = e.getEntries();
|
|
4273
4303
|
for (const r of t) {
|
|
4274
4304
|
const n = Number(r.duration.toFixed(2)), i = Date.now();
|
|
4275
|
-
i - this.lastLongTaskSentAt >=
|
|
4305
|
+
i - this.lastLongTaskSentAt >= Ot && (this.shouldSendVital("LONG_TASK", n) && this.trackWebVital("LONG_TASK", n), this.lastLongTaskSentAt = i);
|
|
4276
4306
|
}
|
|
4277
4307
|
},
|
|
4278
4308
|
{ type: "longtask", buffered: !0 }
|
|
@@ -4288,7 +4318,7 @@ class dr extends I {
|
|
|
4288
4318
|
return;
|
|
4289
4319
|
if (r)
|
|
4290
4320
|
r.add(e.type);
|
|
4291
|
-
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length >
|
|
4321
|
+
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length > Pt) {
|
|
4292
4322
|
const i = this.navigationHistory.shift();
|
|
4293
4323
|
i && this.reportedByNav.delete(i);
|
|
4294
4324
|
}
|
|
@@ -4297,7 +4327,7 @@ class dr extends I {
|
|
|
4297
4327
|
}
|
|
4298
4328
|
trackWebVital(e, t) {
|
|
4299
4329
|
if (!Number.isFinite(t)) {
|
|
4300
|
-
|
|
4330
|
+
l("debug", "Invalid web vital value", { data: { type: e, value: t } });
|
|
4301
4331
|
return;
|
|
4302
4332
|
}
|
|
4303
4333
|
this.eventManager.track({
|
|
@@ -4337,7 +4367,7 @@ class dr extends I {
|
|
|
4337
4367
|
const t = e.startTime || performance.now(), r = ++this.navigationCounter, n = `${t.toFixed(2)}_${window.location.pathname}`;
|
|
4338
4368
|
return r > 1 ? `${n}_${r}` : n;
|
|
4339
4369
|
} catch (e) {
|
|
4340
|
-
return
|
|
4370
|
+
return l("debug", "Failed to get navigation ID", { error: e }), null;
|
|
4341
4371
|
}
|
|
4342
4372
|
}
|
|
4343
4373
|
isObserverSupported(e) {
|
|
@@ -4349,24 +4379,24 @@ class dr extends I {
|
|
|
4349
4379
|
try {
|
|
4350
4380
|
if (!this.isObserverSupported(e))
|
|
4351
4381
|
return !1;
|
|
4352
|
-
const i = new PerformanceObserver((o,
|
|
4382
|
+
const i = new PerformanceObserver((o, a) => {
|
|
4353
4383
|
try {
|
|
4354
|
-
t(o,
|
|
4384
|
+
t(o, a);
|
|
4355
4385
|
} catch (c) {
|
|
4356
|
-
|
|
4386
|
+
l("debug", "Observer callback failed", {
|
|
4357
4387
|
error: c,
|
|
4358
4388
|
data: { type: e }
|
|
4359
4389
|
});
|
|
4360
4390
|
}
|
|
4361
4391
|
if (n)
|
|
4362
4392
|
try {
|
|
4363
|
-
|
|
4393
|
+
a.disconnect();
|
|
4364
4394
|
} catch {
|
|
4365
4395
|
}
|
|
4366
4396
|
});
|
|
4367
4397
|
return i.observe(r ?? { type: e, buffered: !0 }), n || this.observers.push(i), !0;
|
|
4368
4398
|
} catch (i) {
|
|
4369
|
-
return
|
|
4399
|
+
return l("debug", "Failed to create performance observer", {
|
|
4370
4400
|
error: i,
|
|
4371
4401
|
data: { type: e }
|
|
4372
4402
|
}), !1;
|
|
@@ -4374,12 +4404,12 @@ class dr extends I {
|
|
|
4374
4404
|
}
|
|
4375
4405
|
shouldSendVital(e, t) {
|
|
4376
4406
|
if (typeof t != "number" || !Number.isFinite(t))
|
|
4377
|
-
return
|
|
4407
|
+
return l("debug", "Invalid web vital value", { data: { type: e, value: t } }), !1;
|
|
4378
4408
|
const r = this.vitalThresholds[e];
|
|
4379
4409
|
return !(typeof r == "number" && t <= r);
|
|
4380
4410
|
}
|
|
4381
4411
|
}
|
|
4382
|
-
class
|
|
4412
|
+
class mr extends v {
|
|
4383
4413
|
eventManager;
|
|
4384
4414
|
recentErrors = /* @__PURE__ */ new Map();
|
|
4385
4415
|
errorBurstCounter = 0;
|
|
@@ -4415,24 +4445,24 @@ class hr extends I {
|
|
|
4415
4445
|
const e = Date.now();
|
|
4416
4446
|
if (e < this.burstBackoffUntil)
|
|
4417
4447
|
return !1;
|
|
4418
|
-
if (e - this.burstWindowStart >
|
|
4419
|
-
return this.burstBackoffUntil = e +
|
|
4448
|
+
if (e - this.burstWindowStart > Mt && (this.errorBurstCounter = 0, this.burstWindowStart = e), this.errorBurstCounter++, this.errorBurstCounter > Ct)
|
|
4449
|
+
return this.burstBackoffUntil = e + Ve, l("debug", "Error burst detected - entering cooldown", {
|
|
4420
4450
|
data: {
|
|
4421
4451
|
errorsInWindow: this.errorBurstCounter,
|
|
4422
|
-
cooldownMs:
|
|
4452
|
+
cooldownMs: Ve
|
|
4423
4453
|
}
|
|
4424
4454
|
}), !1;
|
|
4425
|
-
const r = this.get("config")?.errorSampling ??
|
|
4455
|
+
const r = this.get("config")?.errorSampling ?? Ke;
|
|
4426
4456
|
return Math.random() < r;
|
|
4427
4457
|
}
|
|
4428
4458
|
handleError = (e) => {
|
|
4429
4459
|
if (!this.shouldSample())
|
|
4430
4460
|
return;
|
|
4431
4461
|
const t = this.sanitize(e.message || "Unknown error");
|
|
4432
|
-
this.shouldSuppressError(
|
|
4462
|
+
this.shouldSuppressError(x.JS_ERROR, t) || this.eventManager.track({
|
|
4433
4463
|
type: d.ERROR,
|
|
4434
4464
|
error_data: {
|
|
4435
|
-
type:
|
|
4465
|
+
type: x.JS_ERROR,
|
|
4436
4466
|
message: t,
|
|
4437
4467
|
...e.filename && { filename: e.filename },
|
|
4438
4468
|
...e.lineno && { line: e.lineno },
|
|
@@ -4444,10 +4474,10 @@ class hr extends I {
|
|
|
4444
4474
|
if (!this.shouldSample())
|
|
4445
4475
|
return;
|
|
4446
4476
|
const t = this.extractRejectionMessage(e.reason), r = this.sanitize(t);
|
|
4447
|
-
this.shouldSuppressError(
|
|
4477
|
+
this.shouldSuppressError(x.PROMISE_REJECTION, r) || this.eventManager.track({
|
|
4448
4478
|
type: d.ERROR,
|
|
4449
4479
|
error_data: {
|
|
4450
|
-
type:
|
|
4480
|
+
type: x.PROMISE_REJECTION,
|
|
4451
4481
|
message: r
|
|
4452
4482
|
}
|
|
4453
4483
|
});
|
|
@@ -4466,8 +4496,8 @@ class hr extends I {
|
|
|
4466
4496
|
}
|
|
4467
4497
|
}
|
|
4468
4498
|
sanitize(e) {
|
|
4469
|
-
let t = e.length >
|
|
4470
|
-
for (const r of
|
|
4499
|
+
let t = e.length > Pe ? e.slice(0, Pe) + "..." : e;
|
|
4500
|
+
for (const r of ze) {
|
|
4471
4501
|
const n = new RegExp(r.source, r.flags);
|
|
4472
4502
|
t = t.replace(n, "[REDACTED]");
|
|
4473
4503
|
}
|
|
@@ -4475,25 +4505,26 @@ class hr extends I {
|
|
|
4475
4505
|
}
|
|
4476
4506
|
shouldSuppressError(e, t) {
|
|
4477
4507
|
const r = Date.now(), n = `${e}:${t}`, i = this.recentErrors.get(n);
|
|
4478
|
-
return i && r - i <
|
|
4508
|
+
return i && r - i < De ? (this.recentErrors.set(n, r), !0) : (this.recentErrors.set(n, r), this.recentErrors.size > At ? (this.recentErrors.clear(), this.recentErrors.set(n, r), !1) : (this.recentErrors.size > z && this.pruneOldErrors(), !1));
|
|
4479
4509
|
}
|
|
4480
4510
|
pruneOldErrors() {
|
|
4481
4511
|
const e = Date.now();
|
|
4482
4512
|
for (const [n, i] of this.recentErrors.entries())
|
|
4483
|
-
e - i >
|
|
4484
|
-
if (this.recentErrors.size <=
|
|
4513
|
+
e - i > De && this.recentErrors.delete(n);
|
|
4514
|
+
if (this.recentErrors.size <= z)
|
|
4485
4515
|
return;
|
|
4486
|
-
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]), r = this.recentErrors.size -
|
|
4516
|
+
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]), r = this.recentErrors.size - z;
|
|
4487
4517
|
for (let n = 0; n < r; n += 1) {
|
|
4488
4518
|
const i = t[n];
|
|
4489
4519
|
i && this.recentErrors.delete(i[0]);
|
|
4490
4520
|
}
|
|
4491
4521
|
}
|
|
4492
4522
|
}
|
|
4493
|
-
class
|
|
4523
|
+
class gr extends v {
|
|
4494
4524
|
isInitialized = !1;
|
|
4495
4525
|
suppressNextScrollTimer = null;
|
|
4496
|
-
|
|
4526
|
+
pageUnloadHandler = null;
|
|
4527
|
+
emitter = new Zt();
|
|
4497
4528
|
transformers = {};
|
|
4498
4529
|
customHeadersProvider;
|
|
4499
4530
|
managers = {};
|
|
@@ -4511,18 +4542,19 @@ class fr extends I {
|
|
|
4511
4542
|
async init(e = {}) {
|
|
4512
4543
|
if (this.isInitialized)
|
|
4513
4544
|
return { sessionId: this.get("sessionId") ?? "" };
|
|
4514
|
-
this.managers.storage = new
|
|
4545
|
+
this.managers.storage = new hr();
|
|
4515
4546
|
try {
|
|
4516
4547
|
this.setupState(e);
|
|
4517
|
-
const t = e.integrations?.custom?.headers ?? {};
|
|
4518
|
-
return this.managers.event = new
|
|
4548
|
+
const t = e.integrations?.custom?.headers ?? {}, r = e.integrations?.custom?.fetchCredentials ?? "include";
|
|
4549
|
+
return this.managers.event = new sr(
|
|
4519
4550
|
this.managers.storage,
|
|
4520
4551
|
this.emitter,
|
|
4521
4552
|
this.transformers,
|
|
4522
4553
|
t,
|
|
4523
|
-
this.customHeadersProvider
|
|
4524
|
-
|
|
4525
|
-
|
|
4554
|
+
this.customHeadersProvider,
|
|
4555
|
+
r
|
|
4556
|
+
), this.initializeHandlers(), this.setupPageLifecycleListeners(), await this.managers.event.recoverPersistedEvents().catch((n) => {
|
|
4557
|
+
l("warn", "Failed to recover persisted events", { error: n });
|
|
4526
4558
|
}), this.isInitialized = !0, { sessionId: this.get("sessionId") ?? "" };
|
|
4527
4559
|
} catch (t) {
|
|
4528
4560
|
this.destroy(!0);
|
|
@@ -4539,15 +4571,16 @@ class fr extends I {
|
|
|
4539
4571
|
*/
|
|
4540
4572
|
sendCustomEvent(e, t) {
|
|
4541
4573
|
if (!this.managers.event) {
|
|
4542
|
-
|
|
4574
|
+
l("warn", "Cannot send custom event: TraceLog not initialized", { data: { name: e } });
|
|
4543
4575
|
return;
|
|
4544
4576
|
}
|
|
4545
4577
|
let r = t;
|
|
4546
4578
|
t && typeof t == "object" && !Array.isArray(t) && Object.getPrototypeOf(t) !== Object.prototype && (r = Object.assign({}, t));
|
|
4547
|
-
const { valid: n, error: i, sanitizedMetadata: o } =
|
|
4579
|
+
const { valid: n, error: i, sanitizedMetadata: o } = Jt(e, r);
|
|
4548
4580
|
if (!n) {
|
|
4549
|
-
if (this.get("mode") ===
|
|
4581
|
+
if (this.get("mode") === Y.QA)
|
|
4550
4582
|
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${i}`);
|
|
4583
|
+
l("warn", `Custom event "${e}" dropped: ${i}`);
|
|
4551
4584
|
return;
|
|
4552
4585
|
}
|
|
4553
4586
|
this.managers.event.track({
|
|
@@ -4607,20 +4640,20 @@ class fr extends I {
|
|
|
4607
4640
|
try {
|
|
4608
4641
|
t.stopTracking();
|
|
4609
4642
|
} catch (r) {
|
|
4610
|
-
|
|
4643
|
+
l("warn", "Failed to stop tracking", { error: r });
|
|
4611
4644
|
}
|
|
4612
|
-
}), this.suppressNextScrollTimer && (clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = null), 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.isInitialized = !1, this.handlers = {}, this.managers = {});
|
|
4645
|
+
}), 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.isInitialized = !1, this.handlers = {}, this.managers = {});
|
|
4613
4646
|
}
|
|
4614
4647
|
setupState(e = {}) {
|
|
4615
4648
|
this.set("config", e);
|
|
4616
|
-
const t =
|
|
4649
|
+
const t = nr.getId(this.managers.storage);
|
|
4617
4650
|
this.set("userId", t);
|
|
4618
|
-
const r =
|
|
4651
|
+
const r = Gt(e);
|
|
4619
4652
|
this.set("collectApiUrls", r);
|
|
4620
|
-
const n =
|
|
4653
|
+
const n = Lt();
|
|
4621
4654
|
this.set("device", n);
|
|
4622
|
-
const i =
|
|
4623
|
-
this.set("pageUrl", i),
|
|
4655
|
+
const i = he(window.location.href, e.sensitiveQueryParams);
|
|
4656
|
+
this.set("pageUrl", i), Ut() && this.set("mode", Y.QA);
|
|
4624
4657
|
}
|
|
4625
4658
|
/**
|
|
4626
4659
|
* Returns the current configuration object.
|
|
@@ -4671,7 +4704,7 @@ class fr extends I {
|
|
|
4671
4704
|
valid: !1,
|
|
4672
4705
|
error: "Global metadata must be a plain object"
|
|
4673
4706
|
};
|
|
4674
|
-
const t =
|
|
4707
|
+
const t = Je("Global", e, "globalMetadata");
|
|
4675
4708
|
return t.valid ? { valid: !0 } : {
|
|
4676
4709
|
valid: !1,
|
|
4677
4710
|
error: t.error
|
|
@@ -4692,7 +4725,7 @@ class fr extends I {
|
|
|
4692
4725
|
...this.get("config"),
|
|
4693
4726
|
globalMetadata: e
|
|
4694
4727
|
};
|
|
4695
|
-
this.set("config", n),
|
|
4728
|
+
this.set("config", n), l("debug", "Global metadata updated (replaced)", { data: { keys: Object.keys(e) } });
|
|
4696
4729
|
}
|
|
4697
4730
|
/**
|
|
4698
4731
|
* Merges new metadata with existing global metadata.
|
|
@@ -4712,11 +4745,16 @@ class fr extends I {
|
|
|
4712
4745
|
...r,
|
|
4713
4746
|
globalMetadata: i
|
|
4714
4747
|
};
|
|
4715
|
-
this.set("config", o),
|
|
4748
|
+
this.set("config", o), l("debug", "Global metadata updated (merged)", { data: { keys: Object.keys(e) } });
|
|
4749
|
+
}
|
|
4750
|
+
setupPageLifecycleListeners() {
|
|
4751
|
+
this.pageUnloadHandler = () => {
|
|
4752
|
+
this.managers.event?.flushImmediatelySync();
|
|
4753
|
+
}, window.addEventListener("pagehide", this.pageUnloadHandler), window.addEventListener("beforeunload", this.pageUnloadHandler);
|
|
4716
4754
|
}
|
|
4717
4755
|
initializeHandlers() {
|
|
4718
4756
|
const e = this.get("config");
|
|
4719
|
-
this.handlers.session = new
|
|
4757
|
+
this.handlers.session = new ar(
|
|
4720
4758
|
this.managers.storage,
|
|
4721
4759
|
this.managers.event
|
|
4722
4760
|
), this.handlers.session.startTracking();
|
|
@@ -4725,34 +4763,25 @@ class fr extends I {
|
|
|
4725
4763
|
this.set("suppressNextScroll", !1);
|
|
4726
4764
|
}, 500);
|
|
4727
4765
|
};
|
|
4728
|
-
this.handlers.pageView = new
|
|
4729
|
-
|
|
4730
|
-
}), this.handlers.error = new
|
|
4766
|
+
this.handlers.pageView = new lr(this.managers.event, t), this.handlers.pageView.startTracking(), this.handlers.click = new cr(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new ur(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new fr(this.managers.event), this.handlers.performance.startTracking().catch((r) => {
|
|
4767
|
+
l("warn", "Failed to start performance tracking", { error: r });
|
|
4768
|
+
}), this.handlers.error = new mr(this.managers.event), this.handlers.error.startTracking(), e.viewport && (this.handlers.viewport = new dr(this.managers.event), this.handlers.viewport.startTracking());
|
|
4731
4769
|
}
|
|
4732
4770
|
}
|
|
4733
|
-
const
|
|
4734
|
-
let
|
|
4735
|
-
const
|
|
4736
|
-
if (typeof window > "u" || typeof document > "u")
|
|
4737
|
-
return { sessionId: "" };
|
|
4738
|
-
if (v = !1, window.__traceLogDisabled === !0)
|
|
4739
|
-
return { sessionId: "" };
|
|
4740
|
-
if (h)
|
|
4741
|
-
return { sessionId: h.getSessionId() ?? "" };
|
|
4742
|
-
if (C)
|
|
4743
|
-
return { sessionId: "" };
|
|
4744
|
-
C = !0;
|
|
4771
|
+
const O = [], M = [];
|
|
4772
|
+
let N = null, h = null, C = !1, _ = !1, R = null;
|
|
4773
|
+
const Er = async (s) => typeof window > "u" || typeof document > "u" ? { sessionId: "" } : (_ = !1, window.__traceLogDisabled === !0 ? { sessionId: "" } : h ? { sessionId: h.getSessionId() ?? "" } : (C && R || (C = !0, R = (async () => {
|
|
4745
4774
|
try {
|
|
4746
|
-
const e =
|
|
4775
|
+
const e = Kt(s ?? {}), t = new gr();
|
|
4747
4776
|
try {
|
|
4748
|
-
|
|
4749
|
-
t.on(o,
|
|
4750
|
-
}),
|
|
4751
|
-
o === "beforeSend" ? t.setTransformer("beforeSend",
|
|
4752
|
-
}), M.length = 0,
|
|
4753
|
-
const r = t.init(e), n = new Promise((o,
|
|
4777
|
+
O.forEach(({ event: o, callback: a }) => {
|
|
4778
|
+
t.on(o, a);
|
|
4779
|
+
}), O.length = 0, M.forEach(({ hook: o, fn: a }) => {
|
|
4780
|
+
o === "beforeSend" ? t.setTransformer("beforeSend", a) : t.setTransformer("beforeBatch", a);
|
|
4781
|
+
}), M.length = 0, N && (t.setCustomHeaders(N), N = null);
|
|
4782
|
+
const r = t.init(e), n = new Promise((o, a) => {
|
|
4754
4783
|
setTimeout(() => {
|
|
4755
|
-
|
|
4784
|
+
a(new Error("[TraceLog] Initialization timeout after 10000ms"));
|
|
4756
4785
|
}, 1e4);
|
|
4757
4786
|
}), i = await Promise.race([r, n]);
|
|
4758
4787
|
return h = t, i;
|
|
@@ -4760,42 +4789,42 @@ const mr = async (s) => {
|
|
|
4760
4789
|
try {
|
|
4761
4790
|
t.destroy(!0);
|
|
4762
4791
|
} catch (n) {
|
|
4763
|
-
|
|
4792
|
+
l("error", "Failed to cleanup partially initialized app", { error: n });
|
|
4764
4793
|
}
|
|
4765
4794
|
throw r;
|
|
4766
4795
|
}
|
|
4767
4796
|
} catch (e) {
|
|
4768
4797
|
throw h = null, e;
|
|
4769
4798
|
} finally {
|
|
4770
|
-
C = !1;
|
|
4799
|
+
C = !1, R = null;
|
|
4771
4800
|
}
|
|
4772
|
-
},
|
|
4801
|
+
})()), R)), Sr = (s, e) => {
|
|
4773
4802
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4774
4803
|
if (!h)
|
|
4775
4804
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
4776
|
-
if (
|
|
4805
|
+
if (_)
|
|
4777
4806
|
throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
|
|
4778
4807
|
h.sendCustomEvent(s, e);
|
|
4779
4808
|
}
|
|
4780
|
-
},
|
|
4809
|
+
}, pr = (s, e) => {
|
|
4781
4810
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4782
4811
|
if (!h || C) {
|
|
4783
|
-
|
|
4812
|
+
O.push({ event: s, callback: e });
|
|
4784
4813
|
return;
|
|
4785
4814
|
}
|
|
4786
4815
|
h.on(s, e);
|
|
4787
4816
|
}
|
|
4788
|
-
},
|
|
4817
|
+
}, Tr = (s, e) => {
|
|
4789
4818
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4790
4819
|
if (!h) {
|
|
4791
|
-
const t =
|
|
4792
|
-
t !== -1 &&
|
|
4820
|
+
const t = O.findIndex((r) => r.event === s && r.callback === e);
|
|
4821
|
+
t !== -1 && O.splice(t, 1);
|
|
4793
4822
|
return;
|
|
4794
4823
|
}
|
|
4795
4824
|
h.off(s, e);
|
|
4796
4825
|
}
|
|
4797
4826
|
};
|
|
4798
|
-
function
|
|
4827
|
+
function _r(s, e) {
|
|
4799
4828
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4800
4829
|
if (typeof e != "function")
|
|
4801
4830
|
throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof e}`);
|
|
@@ -4804,107 +4833,107 @@ function pr(s, e) {
|
|
|
4804
4833
|
t !== -1 && M.splice(t, 1), M.push({ hook: s, fn: e });
|
|
4805
4834
|
return;
|
|
4806
4835
|
}
|
|
4807
|
-
if (
|
|
4836
|
+
if (_)
|
|
4808
4837
|
throw new Error("[TraceLog] Cannot set transformers while TraceLog is being destroyed");
|
|
4809
4838
|
s === "beforeSend" ? h.setTransformer("beforeSend", e) : h.setTransformer("beforeBatch", e);
|
|
4810
4839
|
}
|
|
4811
4840
|
}
|
|
4812
|
-
const
|
|
4841
|
+
const vr = (s) => {
|
|
4813
4842
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4814
4843
|
if (!h) {
|
|
4815
4844
|
const e = M.findIndex((t) => t.hook === s);
|
|
4816
4845
|
e !== -1 && M.splice(e, 1);
|
|
4817
4846
|
return;
|
|
4818
4847
|
}
|
|
4819
|
-
if (
|
|
4848
|
+
if (_)
|
|
4820
4849
|
throw new Error("[TraceLog] Cannot remove transformers while TraceLog is being destroyed");
|
|
4821
4850
|
h.removeTransformer(s);
|
|
4822
4851
|
}
|
|
4823
|
-
},
|
|
4852
|
+
}, Ir = (s) => {
|
|
4824
4853
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4825
4854
|
if (typeof s != "function")
|
|
4826
4855
|
throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof s}`);
|
|
4827
4856
|
if (!h || C) {
|
|
4828
|
-
|
|
4857
|
+
N = s;
|
|
4829
4858
|
return;
|
|
4830
4859
|
}
|
|
4831
|
-
if (
|
|
4860
|
+
if (_)
|
|
4832
4861
|
throw new Error("[TraceLog] Cannot set custom headers while TraceLog is being destroyed");
|
|
4833
4862
|
h.setCustomHeaders(s);
|
|
4834
4863
|
}
|
|
4835
|
-
},
|
|
4864
|
+
}, wr = () => {
|
|
4836
4865
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4837
4866
|
if (!h) {
|
|
4838
|
-
|
|
4867
|
+
N = null;
|
|
4839
4868
|
return;
|
|
4840
4869
|
}
|
|
4841
|
-
if (
|
|
4870
|
+
if (_)
|
|
4842
4871
|
throw new Error("[TraceLog] Cannot remove custom headers while TraceLog is being destroyed");
|
|
4843
4872
|
h.removeCustomHeaders();
|
|
4844
4873
|
}
|
|
4845
|
-
},
|
|
4874
|
+
}, yr = () => typeof window > "u" || typeof document > "u" ? !1 : h !== null, br = () => typeof window > "u" || typeof document > "u" || !h ? null : h.getSessionId(), Lr = () => {
|
|
4846
4875
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4847
|
-
if (
|
|
4876
|
+
if (_)
|
|
4848
4877
|
throw new Error("[TraceLog] Destroy operation already in progress");
|
|
4849
4878
|
if (!h) {
|
|
4850
|
-
|
|
4879
|
+
_ = !1;
|
|
4851
4880
|
return;
|
|
4852
4881
|
}
|
|
4853
|
-
|
|
4882
|
+
_ = !0;
|
|
4854
4883
|
try {
|
|
4855
|
-
h.destroy(), h = null, C = !1,
|
|
4884
|
+
h.destroy(), h = null, C = !1, R = null, O.length = 0, M.length = 0, N = null, _ = !1;
|
|
4856
4885
|
} catch (s) {
|
|
4857
|
-
h = null, C = !1,
|
|
4886
|
+
h = null, C = !1, R = null, O.length = 0, M.length = 0, N = null, _ = !1, l("warn", "Error during destroy, forced cleanup completed", { error: s });
|
|
4858
4887
|
}
|
|
4859
4888
|
}
|
|
4860
|
-
},
|
|
4861
|
-
typeof window > "u" || typeof document > "u" ||
|
|
4862
|
-
},
|
|
4889
|
+
}, Ar = (s) => {
|
|
4890
|
+
typeof window > "u" || typeof document > "u" || Ht(s);
|
|
4891
|
+
}, Mr = (s) => {
|
|
4863
4892
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4864
4893
|
if (!h)
|
|
4865
4894
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
4866
|
-
if (
|
|
4895
|
+
if (_)
|
|
4867
4896
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
4868
4897
|
h.updateGlobalMetadata(s);
|
|
4869
4898
|
}
|
|
4870
|
-
},
|
|
4899
|
+
}, Cr = (s) => {
|
|
4871
4900
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
4872
4901
|
if (!h)
|
|
4873
4902
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
4874
|
-
if (
|
|
4903
|
+
if (_)
|
|
4875
4904
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
4876
4905
|
h.mergeGlobalMetadata(s);
|
|
4877
4906
|
}
|
|
4878
|
-
},
|
|
4879
|
-
init:
|
|
4880
|
-
event:
|
|
4881
|
-
on:
|
|
4882
|
-
off:
|
|
4883
|
-
setTransformer:
|
|
4884
|
-
removeTransformer:
|
|
4885
|
-
setCustomHeaders:
|
|
4886
|
-
removeCustomHeaders:
|
|
4887
|
-
isInitialized:
|
|
4888
|
-
getSessionId:
|
|
4889
|
-
destroy:
|
|
4890
|
-
setQaMode:
|
|
4891
|
-
updateGlobalMetadata:
|
|
4892
|
-
mergeGlobalMetadata:
|
|
4907
|
+
}, ts = {
|
|
4908
|
+
init: Er,
|
|
4909
|
+
event: Sr,
|
|
4910
|
+
on: pr,
|
|
4911
|
+
off: Tr,
|
|
4912
|
+
setTransformer: _r,
|
|
4913
|
+
removeTransformer: vr,
|
|
4914
|
+
setCustomHeaders: Ir,
|
|
4915
|
+
removeCustomHeaders: wr,
|
|
4916
|
+
isInitialized: yr,
|
|
4917
|
+
getSessionId: br,
|
|
4918
|
+
destroy: Lr,
|
|
4919
|
+
setQaMode: Ar,
|
|
4920
|
+
updateGlobalMetadata: Mr,
|
|
4921
|
+
mergeGlobalMetadata: Cr
|
|
4893
4922
|
};
|
|
4894
|
-
var
|
|
4923
|
+
var ge, tt = -1, k = function(s) {
|
|
4895
4924
|
addEventListener("pageshow", (function(e) {
|
|
4896
|
-
e.persisted && (
|
|
4925
|
+
e.persisted && (tt = e.timeStamp, s(e));
|
|
4897
4926
|
}), !0);
|
|
4898
4927
|
}, ve = function() {
|
|
4899
4928
|
var s = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
|
|
4900
4929
|
if (s && s.responseStart > 0 && s.responseStart < performance.now()) return s;
|
|
4901
|
-
},
|
|
4930
|
+
}, Z = function() {
|
|
4902
4931
|
var s = ve();
|
|
4903
4932
|
return s && s.activationStart || 0;
|
|
4904
4933
|
}, b = function(s, e) {
|
|
4905
4934
|
var t = ve(), r = "navigate";
|
|
4906
|
-
return
|
|
4907
|
-
},
|
|
4935
|
+
return tt >= 0 ? r = "back-forward-cache" : t && (document.prerendering || Z() > 0 ? r = "prerender" : document.wasDiscarded ? r = "restore" : t.type && (r = t.type.replace(/_/g, "-"))), { name: s, value: e === void 0 ? -1 : e, rating: "good", delta: 0, entries: [], id: "v4-".concat(Date.now(), "-").concat(Math.floor(8999999999999 * Math.random()) + 1e12), navigationType: r };
|
|
4936
|
+
}, B = function(s, e, t) {
|
|
4908
4937
|
try {
|
|
4909
4938
|
if (PerformanceObserver.supportedEntryTypes.includes(s)) {
|
|
4910
4939
|
var r = new PerformanceObserver((function(n) {
|
|
@@ -4919,8 +4948,8 @@ var me, et = -1, D = function(s) {
|
|
|
4919
4948
|
}, L = function(s, e, t, r) {
|
|
4920
4949
|
var n, i;
|
|
4921
4950
|
return function(o) {
|
|
4922
|
-
e.value >= 0 && (o || r) && ((i = e.value - (n || 0)) || n === void 0) && (n = e.value, e.delta = i, e.rating = (function(
|
|
4923
|
-
return
|
|
4951
|
+
e.value >= 0 && (o || r) && ((i = e.value - (n || 0)) || n === void 0) && (n = e.value, e.delta = i, e.rating = (function(a, c) {
|
|
4952
|
+
return a > c[1] ? "poor" : a > c[0] ? "needs-improvement" : "good";
|
|
4924
4953
|
})(e.value, t), s(e));
|
|
4925
4954
|
};
|
|
4926
4955
|
}, Ie = function(s) {
|
|
@@ -4929,50 +4958,50 @@ var me, et = -1, D = function(s) {
|
|
|
4929
4958
|
return s();
|
|
4930
4959
|
}));
|
|
4931
4960
|
}));
|
|
4932
|
-
},
|
|
4961
|
+
}, ee = function(s) {
|
|
4933
4962
|
document.addEventListener("visibilitychange", (function() {
|
|
4934
4963
|
document.visibilityState === "hidden" && s();
|
|
4935
4964
|
}));
|
|
4936
|
-
},
|
|
4965
|
+
}, we = function(s) {
|
|
4937
4966
|
var e = !1;
|
|
4938
4967
|
return function() {
|
|
4939
4968
|
e || (s(), e = !0);
|
|
4940
4969
|
};
|
|
4941
|
-
},
|
|
4970
|
+
}, V = -1, Be = function() {
|
|
4942
4971
|
return document.visibilityState !== "hidden" || document.prerendering ? 1 / 0 : 0;
|
|
4943
|
-
},
|
|
4944
|
-
document.visibilityState === "hidden" &&
|
|
4945
|
-
},
|
|
4946
|
-
addEventListener("visibilitychange",
|
|
4947
|
-
},
|
|
4948
|
-
removeEventListener("visibilitychange",
|
|
4949
|
-
},
|
|
4950
|
-
return
|
|
4972
|
+
}, J = function(s) {
|
|
4973
|
+
document.visibilityState === "hidden" && V > -1 && (V = s.type === "visibilitychange" ? s.timeStamp : 0, Rr());
|
|
4974
|
+
}, We = function() {
|
|
4975
|
+
addEventListener("visibilitychange", J, !0), addEventListener("prerenderingchange", J, !0);
|
|
4976
|
+
}, Rr = function() {
|
|
4977
|
+
removeEventListener("visibilitychange", J, !0), removeEventListener("prerenderingchange", J, !0);
|
|
4978
|
+
}, rt = function() {
|
|
4979
|
+
return V < 0 && (V = Be(), We(), k((function() {
|
|
4951
4980
|
setTimeout((function() {
|
|
4952
|
-
|
|
4981
|
+
V = Be(), We();
|
|
4953
4982
|
}), 0);
|
|
4954
4983
|
}))), { get firstHiddenTime() {
|
|
4955
|
-
return
|
|
4984
|
+
return V;
|
|
4956
4985
|
} };
|
|
4957
|
-
},
|
|
4986
|
+
}, te = function(s) {
|
|
4958
4987
|
document.prerendering ? addEventListener("prerenderingchange", (function() {
|
|
4959
4988
|
return s();
|
|
4960
4989
|
}), !0) : s();
|
|
4961
|
-
},
|
|
4962
|
-
e = e || {},
|
|
4963
|
-
var t, r =
|
|
4964
|
-
o.forEach((function(
|
|
4965
|
-
|
|
4990
|
+
}, Ee = [1800, 3e3], st = function(s, e) {
|
|
4991
|
+
e = e || {}, te((function() {
|
|
4992
|
+
var t, r = rt(), n = b("FCP"), i = B("paint", (function(o) {
|
|
4993
|
+
o.forEach((function(a) {
|
|
4994
|
+
a.name === "first-contentful-paint" && (i.disconnect(), a.startTime < r.firstHiddenTime && (n.value = Math.max(a.startTime - Z(), 0), n.entries.push(a), t(!0)));
|
|
4966
4995
|
}));
|
|
4967
4996
|
}));
|
|
4968
|
-
i && (t = L(s, n,
|
|
4969
|
-
n = b("FCP"), t = L(s, n,
|
|
4997
|
+
i && (t = L(s, n, Ee, e.reportAllChanges), k((function(o) {
|
|
4998
|
+
n = b("FCP"), t = L(s, n, Ee, e.reportAllChanges), Ie((function() {
|
|
4970
4999
|
n.value = performance.now() - o.timeStamp, t(!0);
|
|
4971
5000
|
}));
|
|
4972
5001
|
})));
|
|
4973
5002
|
}));
|
|
4974
|
-
},
|
|
4975
|
-
e = e || {},
|
|
5003
|
+
}, Se = [0.1, 0.25], Nr = function(s, e) {
|
|
5004
|
+
e = e || {}, st(we((function() {
|
|
4976
5005
|
var t, r = b("CLS", 0), n = 0, i = [], o = function(c) {
|
|
4977
5006
|
c.forEach((function(u) {
|
|
4978
5007
|
if (!u.hadRecentInput) {
|
|
@@ -4980,147 +5009,147 @@ var me, et = -1, D = function(s) {
|
|
|
4980
5009
|
n && u.startTime - g.startTime < 1e3 && u.startTime - S.startTime < 5e3 ? (n += u.value, i.push(u)) : (n = u.value, i = [u]);
|
|
4981
5010
|
}
|
|
4982
5011
|
})), n > r.value && (r.value = n, r.entries = i, t());
|
|
4983
|
-
},
|
|
4984
|
-
|
|
4985
|
-
o(
|
|
4986
|
-
})),
|
|
4987
|
-
n = 0, r = b("CLS", 0), t = L(s, r,
|
|
5012
|
+
}, a = B("layout-shift", o);
|
|
5013
|
+
a && (t = L(s, r, Se, e.reportAllChanges), ee((function() {
|
|
5014
|
+
o(a.takeRecords()), t(!0);
|
|
5015
|
+
})), k((function() {
|
|
5016
|
+
n = 0, r = b("CLS", 0), t = L(s, r, Se, e.reportAllChanges), Ie((function() {
|
|
4988
5017
|
return t();
|
|
4989
5018
|
}));
|
|
4990
5019
|
})), setTimeout(t, 0));
|
|
4991
5020
|
})));
|
|
4992
|
-
},
|
|
5021
|
+
}, nt = 0, oe = 1 / 0, Q = 0, Or = function(s) {
|
|
4993
5022
|
s.forEach((function(e) {
|
|
4994
|
-
e.interactionId && (
|
|
5023
|
+
e.interactionId && (oe = Math.min(oe, e.interactionId), Q = Math.max(Q, e.interactionId), nt = Q ? (Q - oe) / 7 + 1 : 0);
|
|
4995
5024
|
}));
|
|
4996
|
-
},
|
|
4997
|
-
return
|
|
4998
|
-
},
|
|
4999
|
-
"interactionCount" in performance ||
|
|
5000
|
-
}, y = [],
|
|
5001
|
-
var s = Math.min(y.length - 1, Math.floor((
|
|
5025
|
+
}, it = function() {
|
|
5026
|
+
return ge ? nt : performance.interactionCount || 0;
|
|
5027
|
+
}, Pr = function() {
|
|
5028
|
+
"interactionCount" in performance || ge || (ge = B("event", Or, { type: "event", buffered: !0, durationThreshold: 0 }));
|
|
5029
|
+
}, y = [], K = /* @__PURE__ */ new Map(), ot = 0, Dr = function() {
|
|
5030
|
+
var s = Math.min(y.length - 1, Math.floor((it() - ot) / 50));
|
|
5002
5031
|
return y[s];
|
|
5003
|
-
},
|
|
5004
|
-
if (
|
|
5032
|
+
}, Vr = [], kr = function(s) {
|
|
5033
|
+
if (Vr.forEach((function(n) {
|
|
5005
5034
|
return n(s);
|
|
5006
5035
|
})), s.interactionId || s.entryType === "first-input") {
|
|
5007
|
-
var e = y[y.length - 1], t =
|
|
5036
|
+
var e = y[y.length - 1], t = K.get(s.interactionId);
|
|
5008
5037
|
if (t || y.length < 10 || s.duration > e.latency) {
|
|
5009
5038
|
if (t) s.duration > t.latency ? (t.entries = [s], t.latency = s.duration) : s.duration === t.latency && s.startTime === t.entries[0].startTime && t.entries.push(s);
|
|
5010
5039
|
else {
|
|
5011
5040
|
var r = { id: s.interactionId, latency: s.duration, entries: [s] };
|
|
5012
|
-
|
|
5041
|
+
K.set(r.id, r), y.push(r);
|
|
5013
5042
|
}
|
|
5014
5043
|
y.sort((function(n, i) {
|
|
5015
5044
|
return i.latency - n.latency;
|
|
5016
5045
|
})), y.length > 10 && y.splice(10).forEach((function(n) {
|
|
5017
|
-
return
|
|
5046
|
+
return K.delete(n.id);
|
|
5018
5047
|
}));
|
|
5019
5048
|
}
|
|
5020
5049
|
}
|
|
5021
|
-
},
|
|
5050
|
+
}, at = function(s) {
|
|
5022
5051
|
var e = self.requestIdleCallback || self.setTimeout, t = -1;
|
|
5023
|
-
return s =
|
|
5024
|
-
},
|
|
5025
|
-
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {},
|
|
5052
|
+
return s = we(s), document.visibilityState === "hidden" ? s() : (t = e(s), ee(s)), t;
|
|
5053
|
+
}, pe = [200, 500], Ur = function(s, e) {
|
|
5054
|
+
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, te((function() {
|
|
5026
5055
|
var t;
|
|
5027
|
-
|
|
5028
|
-
var r, n = b("INP"), i = function(
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
var c =
|
|
5056
|
+
Pr();
|
|
5057
|
+
var r, n = b("INP"), i = function(a) {
|
|
5058
|
+
at((function() {
|
|
5059
|
+
a.forEach(kr);
|
|
5060
|
+
var c = Dr();
|
|
5032
5061
|
c && c.latency !== n.value && (n.value = c.latency, n.entries = c.entries, r());
|
|
5033
5062
|
}));
|
|
5034
|
-
}, o =
|
|
5035
|
-
r = L(s, n,
|
|
5063
|
+
}, o = B("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
|
|
5064
|
+
r = L(s, n, pe, e.reportAllChanges), o && (o.observe({ type: "first-input", buffered: !0 }), ee((function() {
|
|
5036
5065
|
i(o.takeRecords()), r(!0);
|
|
5037
|
-
})),
|
|
5038
|
-
|
|
5066
|
+
})), k((function() {
|
|
5067
|
+
ot = it(), y.length = 0, K.clear(), n = b("INP"), r = L(s, n, pe, e.reportAllChanges);
|
|
5039
5068
|
})));
|
|
5040
5069
|
})));
|
|
5041
|
-
},
|
|
5042
|
-
e = e || {},
|
|
5043
|
-
var t, r =
|
|
5070
|
+
}, Te = [2500, 4e3], ae = {}, Hr = function(s, e) {
|
|
5071
|
+
e = e || {}, te((function() {
|
|
5072
|
+
var t, r = rt(), n = b("LCP"), i = function(c) {
|
|
5044
5073
|
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(u) {
|
|
5045
|
-
u.startTime < r.firstHiddenTime && (n.value = Math.max(u.startTime -
|
|
5074
|
+
u.startTime < r.firstHiddenTime && (n.value = Math.max(u.startTime - Z(), 0), n.entries = [u], t());
|
|
5046
5075
|
}));
|
|
5047
|
-
}, o =
|
|
5076
|
+
}, o = B("largest-contentful-paint", i);
|
|
5048
5077
|
if (o) {
|
|
5049
|
-
t = L(s, n,
|
|
5050
|
-
var
|
|
5051
|
-
|
|
5078
|
+
t = L(s, n, Te, e.reportAllChanges);
|
|
5079
|
+
var a = we((function() {
|
|
5080
|
+
ae[n.id] || (i(o.takeRecords()), o.disconnect(), ae[n.id] = !0, t(!0));
|
|
5052
5081
|
}));
|
|
5053
5082
|
["keydown", "click"].forEach((function(c) {
|
|
5054
5083
|
addEventListener(c, (function() {
|
|
5055
|
-
return
|
|
5084
|
+
return at(a);
|
|
5056
5085
|
}), { once: !0, capture: !0 });
|
|
5057
|
-
})),
|
|
5058
|
-
n = b("LCP"), t = L(s, n,
|
|
5059
|
-
n.value = performance.now() - c.timeStamp,
|
|
5086
|
+
})), ee(a), k((function(c) {
|
|
5087
|
+
n = b("LCP"), t = L(s, n, Te, e.reportAllChanges), Ie((function() {
|
|
5088
|
+
n.value = performance.now() - c.timeStamp, ae[n.id] = !0, t(!0);
|
|
5060
5089
|
}));
|
|
5061
5090
|
}));
|
|
5062
5091
|
}
|
|
5063
5092
|
}));
|
|
5064
|
-
},
|
|
5065
|
-
document.prerendering ?
|
|
5093
|
+
}, _e = [800, 1800], xr = function s(e) {
|
|
5094
|
+
document.prerendering ? te((function() {
|
|
5066
5095
|
return s(e);
|
|
5067
5096
|
})) : document.readyState !== "complete" ? addEventListener("load", (function() {
|
|
5068
5097
|
return s(e);
|
|
5069
5098
|
}), !0) : setTimeout(e, 0);
|
|
5070
|
-
},
|
|
5099
|
+
}, Fr = function(s, e) {
|
|
5071
5100
|
e = e || {};
|
|
5072
|
-
var t = b("TTFB"), r = L(s, t,
|
|
5073
|
-
|
|
5101
|
+
var t = b("TTFB"), r = L(s, t, _e, e.reportAllChanges);
|
|
5102
|
+
xr((function() {
|
|
5074
5103
|
var n = ve();
|
|
5075
|
-
n && (t.value = Math.max(n.responseStart -
|
|
5076
|
-
t = b("TTFB", 0), (r = L(s, t,
|
|
5104
|
+
n && (t.value = Math.max(n.responseStart - Z(), 0), t.entries = [n], r(!0), k((function() {
|
|
5105
|
+
t = b("TTFB", 0), (r = L(s, t, _e, e.reportAllChanges))(!0);
|
|
5077
5106
|
})));
|
|
5078
5107
|
}));
|
|
5079
5108
|
};
|
|
5080
|
-
const
|
|
5109
|
+
const $r = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
5081
5110
|
__proto__: null,
|
|
5082
|
-
CLSThresholds:
|
|
5083
|
-
FCPThresholds:
|
|
5084
|
-
INPThresholds:
|
|
5085
|
-
LCPThresholds:
|
|
5086
|
-
TTFBThresholds:
|
|
5087
|
-
onCLS:
|
|
5088
|
-
onFCP:
|
|
5089
|
-
onINP:
|
|
5090
|
-
onLCP:
|
|
5091
|
-
onTTFB:
|
|
5111
|
+
CLSThresholds: Se,
|
|
5112
|
+
FCPThresholds: Ee,
|
|
5113
|
+
INPThresholds: pe,
|
|
5114
|
+
LCPThresholds: Te,
|
|
5115
|
+
TTFBThresholds: _e,
|
|
5116
|
+
onCLS: Nr,
|
|
5117
|
+
onFCP: st,
|
|
5118
|
+
onINP: Ur,
|
|
5119
|
+
onLCP: Hr,
|
|
5120
|
+
onTTFB: Fr
|
|
5092
5121
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
5093
5122
|
export {
|
|
5094
5123
|
f as AppConfigValidationError,
|
|
5095
|
-
|
|
5096
|
-
|
|
5124
|
+
Br as DEFAULT_SESSION_TIMEOUT,
|
|
5125
|
+
de as DEFAULT_WEB_VITALS_MODE,
|
|
5097
5126
|
A as DeviceType,
|
|
5098
|
-
|
|
5099
|
-
|
|
5127
|
+
le as EmitterEvent,
|
|
5128
|
+
x as ErrorType,
|
|
5100
5129
|
d as EventType,
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5130
|
+
Zr as InitializationTimeoutError,
|
|
5131
|
+
P as IntegrationValidationError,
|
|
5132
|
+
Yr as MAX_ARRAY_LENGTH,
|
|
5133
|
+
Qr as MAX_CUSTOM_EVENT_ARRAY_SIZE,
|
|
5134
|
+
Xr as MAX_CUSTOM_EVENT_KEYS,
|
|
5135
|
+
Wr as MAX_CUSTOM_EVENT_NAME_LENGTH,
|
|
5136
|
+
Gr as MAX_CUSTOM_EVENT_STRING_SIZE,
|
|
5137
|
+
jr as MAX_NESTED_OBJECT_KEYS,
|
|
5138
|
+
zr as MAX_STRING_LENGTH,
|
|
5139
|
+
Kr as MAX_STRING_LENGTH_IN_ARRAY,
|
|
5140
|
+
Y as Mode,
|
|
5141
|
+
ze as PII_PATTERNS,
|
|
5142
|
+
D as PermanentError,
|
|
5143
|
+
Oe as SamplingRateValidationError,
|
|
5144
|
+
j as ScrollDirection,
|
|
5145
|
+
gt as SessionTimeoutValidationError,
|
|
5146
|
+
H as SpecialApiUrl,
|
|
5147
|
+
$ as TraceLogValidationError,
|
|
5148
|
+
es as WEB_VITALS_GOOD_THRESHOLDS,
|
|
5120
5149
|
ke as WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS,
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5150
|
+
Nt as WEB_VITALS_POOR_THRESHOLDS,
|
|
5151
|
+
Ue as getWebVitalsThresholds,
|
|
5152
|
+
qr as isPrimaryScrollEvent,
|
|
5153
|
+
Jr as isSecondaryScrollEvent,
|
|
5154
|
+
ts as tracelog
|
|
5126
5155
|
};
|