@tracelog/lib 2.7.3 → 2.8.0-rc.100.11
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 +1158 -1095
- package/dist/browser/tracelog.esm.js.map +1 -1
- package/dist/browser/tracelog.js +2 -2
- package/dist/browser/tracelog.js.map +1 -1
- package/dist/public-api.cjs +2 -2
- package/dist/public-api.cjs.map +1 -1
- package/dist/public-api.d.mts +11 -1
- package/dist/public-api.d.ts +11 -1
- package/dist/public-api.js +2 -2
- package/dist/public-api.js.map +1 -1
- package/package.json +3 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const b = "data-tlog",
|
|
1
|
+
const dr = 9e5;
|
|
2
|
+
const ur = 120, hr = 49152, fr = 100, mr = 500, gr = 200;
|
|
3
|
+
const Er = 1e3, Sr = 500, pr = 1e3;
|
|
4
|
+
const b = "data-tlog", At = [
|
|
5
5
|
"button",
|
|
6
6
|
"a",
|
|
7
7
|
'input[type="button"]',
|
|
@@ -33,7 +33,7 @@ const b = "data-tlog", bt = [
|
|
|
33
33
|
".menu-item",
|
|
34
34
|
"[data-testid]",
|
|
35
35
|
'[tabindex="0"]'
|
|
36
|
-
],
|
|
36
|
+
], Lt = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"], Mt = [
|
|
37
37
|
"token",
|
|
38
38
|
"auth",
|
|
39
39
|
"key",
|
|
@@ -49,7 +49,7 @@ const b = "data-tlog", bt = [
|
|
|
49
49
|
"code",
|
|
50
50
|
"otp"
|
|
51
51
|
];
|
|
52
|
-
const
|
|
52
|
+
const E = {
|
|
53
53
|
INVALID_SESSION_TIMEOUT: "Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",
|
|
54
54
|
INVALID_SAMPLING_RATE: "Sampling rate must be between 0 and 1",
|
|
55
55
|
INVALID_ERROR_SAMPLING_RATE: "Error sampling must be between 0 and 1",
|
|
@@ -72,117 +72,121 @@ const m = {
|
|
|
72
72
|
INVALID_VIEWPORT_COOLDOWN_PERIOD: "Viewport cooldownPeriod must be a non-negative number",
|
|
73
73
|
INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS: "Viewport maxTrackedElements must be a positive number",
|
|
74
74
|
INVALID_SEND_INTERVAL: "Send interval must be between 1000ms (1 second) and 60000ms (60 seconds)"
|
|
75
|
-
},
|
|
75
|
+
}, Ct = [
|
|
76
76
|
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
|
77
77
|
/javascript:/gi,
|
|
78
78
|
/on\w+\s*=/gi,
|
|
79
79
|
/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
|
|
80
80
|
/<embed\b[^>]*>/gi,
|
|
81
81
|
/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi
|
|
82
|
-
], I = "tlog",
|
|
83
|
-
var
|
|
84
|
-
class
|
|
82
|
+
], I = "tlog", X = `${I}:qa_mode`, Te = `${I}:uid`, nt = "tlog_mode", He = "qa", Fe = "qa_off", Rt = (r) => r ? `${I}:${r}:queue` : `${I}:queue`, Nt = (r) => r ? `${I}:${r}:session` : `${I}:session`, Ot = (r) => r ? `${I}:${r}:broadcast` : `${I}:broadcast`, xe = (r, e) => `${I}:${r}:session_counts:${e}`, $e = 10080 * 60 * 1e3, Be = `${I}:session_counts_last_cleanup`, We = 3600 * 1e3, fe = (r) => r ? `${I}:${r}:identity` : `${I}:identity`, U = `${I}:pending_identity`;
|
|
83
|
+
var $ = /* @__PURE__ */ ((r) => (r.Localhost = "localhost:8080", r.Fail = "localhost:9999", r))($ || {}), L = /* @__PURE__ */ ((r) => (r.Mobile = "mobile", r.Tablet = "tablet", r.Desktop = "desktop", r.Unknown = "unknown", r))(L || {}), se = /* @__PURE__ */ ((r) => (r.EVENT = "event", r.QUEUE = "queue", r))(se || {});
|
|
84
|
+
class O extends Error {
|
|
85
85
|
constructor(e, t) {
|
|
86
|
-
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, O);
|
|
87
87
|
}
|
|
88
|
+
statusCode;
|
|
88
89
|
}
|
|
89
|
-
class
|
|
90
|
+
class re extends Error {
|
|
90
91
|
constructor(e) {
|
|
91
|
-
super(e), this.name = "RateLimitError", Error.captureStackTrace && Error.captureStackTrace(this,
|
|
92
|
+
super(e), this.name = "RateLimitError", Error.captureStackTrace && Error.captureStackTrace(this, re);
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
|
-
class
|
|
95
|
+
class ne extends Error {
|
|
95
96
|
constructor(e) {
|
|
96
|
-
super(e), this.name = "TimeoutError", Error.captureStackTrace && Error.captureStackTrace(this,
|
|
97
|
+
super(e), this.name = "TimeoutError", Error.captureStackTrace && Error.captureStackTrace(this, ne);
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
|
-
var
|
|
100
|
-
const
|
|
101
|
-
class
|
|
102
|
-
constructor(e, t,
|
|
103
|
-
super(e), this.errorCode = t, this.layer =
|
|
104
|
-
}
|
|
100
|
+
var u = /* @__PURE__ */ ((r) => (r.PAGE_VIEW = "page_view", r.CLICK = "click", r.SCROLL = "scroll", r.SESSION_START = "session_start", r.CUSTOM = "custom", r.WEB_VITALS = "web_vitals", r.ERROR = "error", r.VIEWPORT_VISIBLE = "viewport_visible", r))(u || {}), Z = /* @__PURE__ */ ((r) => (r.UP = "up", r.DOWN = "down", r))(Z || {}), B = /* @__PURE__ */ ((r) => (r.JS_ERROR = "js_error", r.PROMISE_REJECTION = "promise_rejection", r))(B || {}), ie = /* @__PURE__ */ ((r) => (r.QA = "qa", r))(ie || {});
|
|
101
|
+
const Tr = (r) => r.type === u.SCROLL && "scroll_data" in r && r.scroll_data.is_primary === !0, Ir = (r) => r.type === u.SCROLL && "scroll_data" in r && r.scroll_data.is_primary === !1;
|
|
102
|
+
class j extends Error {
|
|
103
|
+
constructor(e, t, s) {
|
|
104
|
+
super(e), this.errorCode = t, this.layer = s, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
105
|
+
}
|
|
106
|
+
errorCode;
|
|
107
|
+
layer;
|
|
105
108
|
}
|
|
106
|
-
class
|
|
109
|
+
class m extends j {
|
|
107
110
|
constructor(e, t = "config") {
|
|
108
111
|
super(e, "APP_CONFIG_INVALID", t);
|
|
109
112
|
}
|
|
110
113
|
}
|
|
111
|
-
class
|
|
114
|
+
class Pt extends j {
|
|
112
115
|
constructor(e, t = "config") {
|
|
113
116
|
super(e, "SESSION_TIMEOUT_INVALID", t);
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
|
-
class
|
|
119
|
+
class Xe extends j {
|
|
117
120
|
constructor(e, t = "config") {
|
|
118
121
|
super(e, "SAMPLING_RATE_INVALID", t);
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
|
-
class
|
|
124
|
+
class N extends j {
|
|
122
125
|
constructor(e, t = "config") {
|
|
123
126
|
super(e, "INTEGRATION_INVALID", t);
|
|
124
127
|
}
|
|
125
128
|
}
|
|
126
|
-
class
|
|
127
|
-
constructor(e, t,
|
|
128
|
-
super(e, "INITIALIZATION_TIMEOUT",
|
|
129
|
+
class vr extends j {
|
|
130
|
+
constructor(e, t, s = "runtime") {
|
|
131
|
+
super(e, "INITIALIZATION_TIMEOUT", s), this.timeoutMs = t;
|
|
129
132
|
}
|
|
133
|
+
timeoutMs;
|
|
130
134
|
}
|
|
131
|
-
const
|
|
135
|
+
const it = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", ot = "background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", Dt = "background: #d32f2f; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", kt = (r, e) => {
|
|
132
136
|
if (e) {
|
|
133
137
|
if (e instanceof Error) {
|
|
134
138
|
const t = e.message.replace(/\s+at\s+.*$/gm, "").replace(/\s*\([^()]+:\d+:\d+\)/g, "");
|
|
135
|
-
return `[TraceLog] ${
|
|
139
|
+
return `[TraceLog] ${r}: ${t}`;
|
|
136
140
|
}
|
|
137
141
|
if (e instanceof Error)
|
|
138
|
-
return `[TraceLog] ${
|
|
142
|
+
return `[TraceLog] ${r}: ${e.message}`;
|
|
139
143
|
if (typeof e == "string")
|
|
140
|
-
return `[TraceLog] ${
|
|
144
|
+
return `[TraceLog] ${r}: ${e}`;
|
|
141
145
|
if (typeof e == "object")
|
|
142
146
|
try {
|
|
143
|
-
return `[TraceLog] ${
|
|
147
|
+
return `[TraceLog] ${r}: ${JSON.stringify(e)}`;
|
|
144
148
|
} catch {
|
|
145
|
-
return `[TraceLog] ${
|
|
149
|
+
return `[TraceLog] ${r}: [Unable to serialize error]`;
|
|
146
150
|
}
|
|
147
|
-
return `[TraceLog] ${
|
|
151
|
+
return `[TraceLog] ${r}: ${String(e)}`;
|
|
148
152
|
}
|
|
149
|
-
return `[TraceLog] ${
|
|
150
|
-
},
|
|
153
|
+
return `[TraceLog] ${r}`;
|
|
154
|
+
}, Vt = () => {
|
|
151
155
|
if (typeof window > "u" || typeof sessionStorage > "u")
|
|
152
156
|
return !1;
|
|
153
157
|
try {
|
|
154
|
-
return sessionStorage.getItem(
|
|
158
|
+
return sessionStorage.getItem(X) === "true";
|
|
155
159
|
} catch {
|
|
156
160
|
return !1;
|
|
157
161
|
}
|
|
158
|
-
}, a = (
|
|
159
|
-
const { error:
|
|
160
|
-
if (!
|
|
162
|
+
}, a = (r, e, t) => {
|
|
163
|
+
const { error: s, data: n, showToClient: i = !1, style: o, visibility: l } = t ?? {}, c = s ? kt(e, s) : `[TraceLog] ${e}`, d = r === "error" ? "error" : r === "warn" ? "warn" : "log";
|
|
164
|
+
if (!Ut(l, i))
|
|
161
165
|
return;
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
},
|
|
166
|
+
const g = Ht(l, o), T = n !== void 0 ? Ie(n) : void 0;
|
|
167
|
+
Ft(d, c, g, T);
|
|
168
|
+
}, Ut = (r, e) => r === "critical" ? !0 : r === "qa" || e ? Vt() : !1, Ht = (r, e) => e !== void 0 && e !== "" ? e : r === "critical" ? Dt : "", Ft = (r, e, t, s) => {
|
|
165
169
|
const n = t !== void 0 && t !== "", i = n ? `%c${e}` : e;
|
|
166
|
-
|
|
167
|
-
}, Ie = (
|
|
170
|
+
s !== void 0 ? n ? console[r](i, t, s) : console[r](i, s) : n ? console[r](i, t) : console[r](i);
|
|
171
|
+
}, Ie = (r) => {
|
|
168
172
|
const e = {}, t = ["token", "password", "secret", "key", "apikey", "api_key", "sessionid", "session_id"];
|
|
169
|
-
for (const [
|
|
170
|
-
const i =
|
|
173
|
+
for (const [s, n] of Object.entries(r)) {
|
|
174
|
+
const i = s.toLowerCase();
|
|
171
175
|
if (t.some((o) => i.includes(o))) {
|
|
172
|
-
e[
|
|
176
|
+
e[s] = "[REDACTED]";
|
|
173
177
|
continue;
|
|
174
178
|
}
|
|
175
|
-
n !== null && typeof n == "object" && !Array.isArray(n) ? e[
|
|
179
|
+
n !== null && typeof n == "object" && !Array.isArray(n) ? e[s] = Ie(n) : Array.isArray(n) ? e[s] = n.map(
|
|
176
180
|
(o) => o !== null && typeof o == "object" && !Array.isArray(o) ? Ie(o) : o
|
|
177
|
-
) : e[
|
|
181
|
+
) : e[s] = n;
|
|
178
182
|
}
|
|
179
183
|
return e;
|
|
180
184
|
};
|
|
181
|
-
let ve,
|
|
182
|
-
const
|
|
183
|
-
typeof window < "u" && !ve && (ve = window.matchMedia("(pointer: coarse)"),
|
|
184
|
-
},
|
|
185
|
-
const e =
|
|
185
|
+
let ve, at;
|
|
186
|
+
const xt = () => {
|
|
187
|
+
typeof window < "u" && !ve && (ve = window.matchMedia("(pointer: coarse)"), at = window.matchMedia("(hover: none)"));
|
|
188
|
+
}, oe = "Unknown", $t = (r) => {
|
|
189
|
+
const e = r.userAgentData?.platform;
|
|
186
190
|
if (e != null && e !== "") {
|
|
187
191
|
if (/windows/i.test(e)) return "Windows";
|
|
188
192
|
if (/macos/i.test(e)) return "macOS";
|
|
@@ -192,9 +196,9 @@ const Ft = () => {
|
|
|
192
196
|
if (/ios/i.test(e)) return "iOS";
|
|
193
197
|
}
|
|
194
198
|
const t = navigator.userAgent;
|
|
195
|
-
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" :
|
|
196
|
-
},
|
|
197
|
-
const e =
|
|
199
|
+
return /Windows/i.test(t) ? "Windows" : /iPhone|iPad|iPod/i.test(t) ? "iOS" : /Mac OS X|Macintosh/i.test(t) ? "macOS" : /Android/i.test(t) ? "Android" : /CrOS/i.test(t) ? "ChromeOS" : /Linux/i.test(t) ? "Linux" : oe;
|
|
200
|
+
}, Bt = (r) => {
|
|
201
|
+
const e = r.userAgentData?.brands;
|
|
198
202
|
if (e != null && e.length > 0) {
|
|
199
203
|
const n = e.filter((i) => !/not.?a.?brand|chromium/i.test(i.brand))[0];
|
|
200
204
|
if (n != null) {
|
|
@@ -203,36 +207,36 @@ const Ft = () => {
|
|
|
203
207
|
}
|
|
204
208
|
}
|
|
205
209
|
const t = navigator.userAgent;
|
|
206
|
-
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" :
|
|
207
|
-
},
|
|
210
|
+
return /Edg\//i.test(t) ? "Edge" : /OPR\//i.test(t) ? "Opera" : /Chrome/i.test(t) ? "Chrome" : /Firefox/i.test(t) ? "Firefox" : /Safari/i.test(t) && !/Chrome/i.test(t) ? "Safari" : oe;
|
|
211
|
+
}, Wt = () => {
|
|
208
212
|
try {
|
|
209
|
-
const
|
|
210
|
-
if (
|
|
211
|
-
const c =
|
|
212
|
-
return c != null && c !== "" && /ipad|tablet/i.test(c) ? L.Tablet :
|
|
213
|
+
const r = navigator;
|
|
214
|
+
if (r.userAgentData != null && typeof r.userAgentData.mobile == "boolean") {
|
|
215
|
+
const c = r.userAgentData.platform;
|
|
216
|
+
return c != null && c !== "" && /ipad|tablet/i.test(c) ? L.Tablet : r.userAgentData.mobile ? L.Mobile : L.Desktop;
|
|
213
217
|
}
|
|
214
|
-
|
|
215
|
-
const e = window.innerWidth, t = ve?.matches ?? !1,
|
|
216
|
-
return e <= 767 || o && n ? L.Mobile : e >= 768 && e <= 1024 || l || t &&
|
|
217
|
-
} catch (
|
|
218
|
-
return a("debug", "Device detection failed, defaulting to desktop", { error:
|
|
218
|
+
xt();
|
|
219
|
+
const e = window.innerWidth, t = ve?.matches ?? !1, s = at?.matches ?? !1, n = "ontouchstart" in window || navigator.maxTouchPoints > 0, i = navigator.userAgent.toLowerCase(), o = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i), l = /tablet|ipad|android(?!.*mobile)/.test(i);
|
|
220
|
+
return e <= 767 || o && n ? L.Mobile : e >= 768 && e <= 1024 || l || t && s && n ? L.Tablet : L.Desktop;
|
|
221
|
+
} catch (r) {
|
|
222
|
+
return a("debug", "Device detection failed, defaulting to desktop", { error: r }), L.Desktop;
|
|
219
223
|
}
|
|
220
|
-
},
|
|
224
|
+
}, Xt = () => {
|
|
221
225
|
try {
|
|
222
|
-
const
|
|
226
|
+
const r = navigator;
|
|
223
227
|
return {
|
|
224
|
-
type:
|
|
225
|
-
os:
|
|
226
|
-
browser:
|
|
228
|
+
type: Wt(),
|
|
229
|
+
os: $t(r),
|
|
230
|
+
browser: Bt(r)
|
|
227
231
|
};
|
|
228
|
-
} catch (
|
|
229
|
-
return a("debug", "Device info detection failed, using defaults", { error:
|
|
232
|
+
} catch (r) {
|
|
233
|
+
return a("debug", "Device info detection failed, using defaults", { error: r }), {
|
|
230
234
|
type: L.Desktop,
|
|
231
|
-
os:
|
|
232
|
-
browser:
|
|
235
|
+
os: oe,
|
|
236
|
+
browser: oe
|
|
233
237
|
};
|
|
234
238
|
}
|
|
235
|
-
},
|
|
239
|
+
}, lt = [
|
|
236
240
|
// Email addresses
|
|
237
241
|
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi,
|
|
238
242
|
// US Phone numbers (various formats)
|
|
@@ -249,7 +253,7 @@ const Ft = () => {
|
|
|
249
253
|
/:\/\/[^:/]+:([^@]+)@/gi,
|
|
250
254
|
// Sensitive URL query parameters (token=, password=, auth=, secret=, api_key=, etc.)
|
|
251
255
|
/[?&](token|password|passwd|auth|secret|secret_key|private_key|auth_key|api_key|apikey|access_token)=[^&\s]+/gi
|
|
252
|
-
],
|
|
256
|
+
], Ge = 500, je = 2e3, ze = 5e3, ee = 50, Gt = ee * 2, ct = 1, jt = 1e3, zt = 10, Qe = 5e3, Qt = 6e4, _r = {
|
|
253
257
|
LCP: 2500,
|
|
254
258
|
// Good: ≤ 2.5s
|
|
255
259
|
FCP: 1800,
|
|
@@ -261,7 +265,7 @@ const Ft = () => {
|
|
|
261
265
|
TTFB: 800,
|
|
262
266
|
// Good: ≤ 800ms
|
|
263
267
|
LONG_TASK: 50
|
|
264
|
-
},
|
|
268
|
+
}, Ke = {
|
|
265
269
|
LCP: 2500,
|
|
266
270
|
// Needs improvement: > 2.5s (same as good boundary)
|
|
267
271
|
FCP: 1800,
|
|
@@ -273,7 +277,7 @@ const Ft = () => {
|
|
|
273
277
|
TTFB: 800,
|
|
274
278
|
// Needs improvement: > 800ms
|
|
275
279
|
LONG_TASK: 50
|
|
276
|
-
},
|
|
280
|
+
}, Kt = {
|
|
277
281
|
LCP: 4e3,
|
|
278
282
|
// Poor: > 4s
|
|
279
283
|
FCP: 3e3,
|
|
@@ -285,53 +289,53 @@ const Ft = () => {
|
|
|
285
289
|
TTFB: 1800,
|
|
286
290
|
// Poor: > 1800ms
|
|
287
291
|
LONG_TASK: 50
|
|
288
|
-
}, _e = "needs-improvement",
|
|
289
|
-
switch (
|
|
292
|
+
}, _e = "needs-improvement", Ye = (r = _e) => {
|
|
293
|
+
switch (r) {
|
|
290
294
|
case "all":
|
|
291
295
|
return { LCP: 0, FCP: 0, CLS: 0, INP: 0, TTFB: 0, LONG_TASK: 0 };
|
|
292
296
|
// Track everything
|
|
293
297
|
case "needs-improvement":
|
|
294
|
-
return
|
|
298
|
+
return Ke;
|
|
295
299
|
case "poor":
|
|
296
|
-
return
|
|
300
|
+
return Kt;
|
|
297
301
|
default:
|
|
298
|
-
return
|
|
302
|
+
return Ke;
|
|
299
303
|
}
|
|
300
|
-
},
|
|
304
|
+
}, Yt = 1e3, qt = 50, Jt = "2.8.0", Zt = Jt, dt = () => typeof window < "u" && typeof sessionStorage < "u", es = () => {
|
|
301
305
|
try {
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
const e =
|
|
306
|
+
const r = new URLSearchParams(window.location.search);
|
|
307
|
+
r.delete(nt);
|
|
308
|
+
const e = r.toString(), t = window.location.pathname + (e ? "?" + e : "") + window.location.hash;
|
|
305
309
|
window.history.replaceState({}, "", t);
|
|
306
310
|
} catch {
|
|
307
311
|
}
|
|
308
|
-
},
|
|
309
|
-
if (!
|
|
312
|
+
}, ts = () => {
|
|
313
|
+
if (!dt())
|
|
310
314
|
return !1;
|
|
311
315
|
try {
|
|
312
|
-
const e = new URLSearchParams(window.location.search).get(
|
|
313
|
-
let
|
|
314
|
-
return e ===
|
|
315
|
-
visibility: "qa",
|
|
316
|
-
style: nt
|
|
317
|
-
})) : e === He && (r = !1, sessionStorage.setItem(G, "false"), a("info", "QA Mode DISABLED", {
|
|
316
|
+
const e = new URLSearchParams(window.location.search).get(nt), t = sessionStorage.getItem(X);
|
|
317
|
+
let s = null;
|
|
318
|
+
return e === He ? (s = !0, sessionStorage.setItem(X, "true"), a("info", "QA Mode ACTIVE", {
|
|
318
319
|
visibility: "qa",
|
|
319
320
|
style: it
|
|
320
|
-
}))
|
|
321
|
+
})) : e === Fe && (s = !1, sessionStorage.setItem(X, "false"), a("info", "QA Mode DISABLED", {
|
|
322
|
+
visibility: "qa",
|
|
323
|
+
style: ot
|
|
324
|
+
})), (e === He || e === Fe) && es(), s ?? t === "true";
|
|
321
325
|
} catch {
|
|
322
326
|
return !1;
|
|
323
327
|
}
|
|
324
|
-
},
|
|
325
|
-
if (
|
|
328
|
+
}, ss = (r) => {
|
|
329
|
+
if (dt())
|
|
326
330
|
try {
|
|
327
|
-
sessionStorage.setItem(
|
|
331
|
+
sessionStorage.setItem(X, r ? "true" : "false"), a("info", r ? "QA Mode ACTIVE" : "QA Mode DISABLED", {
|
|
328
332
|
visibility: "qa",
|
|
329
|
-
style:
|
|
333
|
+
style: r ? it : ot
|
|
330
334
|
});
|
|
331
335
|
} catch {
|
|
332
336
|
a("debug", "Cannot set QA mode: sessionStorage unavailable");
|
|
333
337
|
}
|
|
334
|
-
},
|
|
338
|
+
}, rs = [
|
|
335
339
|
"co.uk",
|
|
336
340
|
"org.uk",
|
|
337
341
|
"com.au",
|
|
@@ -343,57 +347,57 @@ const Ft = () => {
|
|
|
343
347
|
"co.in",
|
|
344
348
|
"com.cn",
|
|
345
349
|
"co.za"
|
|
346
|
-
],
|
|
347
|
-
const e =
|
|
350
|
+
], qe = (r) => {
|
|
351
|
+
const e = r.toLowerCase().split(".");
|
|
348
352
|
if (e.length <= 2)
|
|
349
|
-
return
|
|
353
|
+
return r.toLowerCase();
|
|
350
354
|
const t = e.slice(-2).join(".");
|
|
351
|
-
return
|
|
352
|
-
},
|
|
353
|
-
const
|
|
354
|
-
if (!
|
|
355
|
+
return rs.includes(t) ? e.slice(-3).join(".") : e.slice(-2).join(".");
|
|
356
|
+
}, ns = (r, e) => r === e ? !0 : qe(r) === qe(e), me = () => {
|
|
357
|
+
const r = document.referrer;
|
|
358
|
+
if (!r)
|
|
355
359
|
return "Direct";
|
|
356
360
|
try {
|
|
357
|
-
const e = new URL(
|
|
358
|
-
return
|
|
361
|
+
const e = new URL(r).hostname.toLowerCase(), t = window.location.hostname.toLowerCase();
|
|
362
|
+
return ns(e, t) ? "Direct" : r;
|
|
359
363
|
} catch (e) {
|
|
360
|
-
return a("debug", "Failed to parse referrer URL, using raw value", { error: e, data: { referrer:
|
|
364
|
+
return a("debug", "Failed to parse referrer URL, using raw value", { error: e, data: { referrer: r } }), r;
|
|
361
365
|
}
|
|
362
|
-
},
|
|
363
|
-
const
|
|
364
|
-
return
|
|
365
|
-
const n =
|
|
366
|
+
}, ge = () => {
|
|
367
|
+
const r = new URLSearchParams(window.location.search), e = {};
|
|
368
|
+
return Lt.forEach((s) => {
|
|
369
|
+
const n = r.get(s);
|
|
366
370
|
if (n) {
|
|
367
|
-
const i =
|
|
371
|
+
const i = s.split("utm_")[1];
|
|
368
372
|
e[i] = n;
|
|
369
373
|
}
|
|
370
374
|
}), Object.keys(e).length ? e : void 0;
|
|
371
|
-
}, ut = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (
|
|
375
|
+
}, ut = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (r) => {
|
|
372
376
|
const e = Math.random() * 16 | 0;
|
|
373
|
-
return (
|
|
377
|
+
return (r === "x" ? e : e & 3 | 8).toString(16);
|
|
374
378
|
});
|
|
375
|
-
let
|
|
376
|
-
const
|
|
377
|
-
let
|
|
378
|
-
|
|
379
|
-
const e =
|
|
379
|
+
let Y = 0, q = 0;
|
|
380
|
+
const ye = () => {
|
|
381
|
+
let r = Date.now();
|
|
382
|
+
r < q && (r = q), r === q ? Y = (Y + 1) % 1e3 : Y = 0, q = r;
|
|
383
|
+
const e = Y.toString().padStart(3, "0");
|
|
380
384
|
let t = "";
|
|
381
385
|
try {
|
|
382
386
|
if (typeof crypto < "u" && crypto.getRandomValues) {
|
|
383
|
-
const
|
|
384
|
-
|
|
387
|
+
const s = crypto.getRandomValues(new Uint8Array(3));
|
|
388
|
+
s && (t = Array.from(s, (n) => n.toString(16).padStart(2, "0")).join(""));
|
|
385
389
|
}
|
|
386
390
|
} catch {
|
|
387
391
|
}
|
|
388
|
-
return t || (t = Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")), `${
|
|
389
|
-
},
|
|
392
|
+
return t || (t = Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")), `${r}-${e}-${t}`;
|
|
393
|
+
}, ht = (r, e = !1) => {
|
|
390
394
|
try {
|
|
391
|
-
const t = new URL(
|
|
392
|
-
return
|
|
395
|
+
const t = new URL(r), s = t.protocol === "https:", n = t.protocol === "http:";
|
|
396
|
+
return s || e && n;
|
|
393
397
|
} catch {
|
|
394
398
|
return !1;
|
|
395
399
|
}
|
|
396
|
-
},
|
|
400
|
+
}, is = (r) => {
|
|
397
401
|
try {
|
|
398
402
|
const t = new URL(window.location.href).hostname;
|
|
399
403
|
if (!t || typeof t != "string")
|
|
@@ -402,231 +406,233 @@ const nr = () => {
|
|
|
402
406
|
throw new Error(
|
|
403
407
|
"SaaS integration not supported on localhost or IP addresses. Use custom backend integration instead."
|
|
404
408
|
);
|
|
405
|
-
const
|
|
406
|
-
if (!
|
|
409
|
+
const s = t.split(".");
|
|
410
|
+
if (!s || !Array.isArray(s) || s.length === 0 || s.length === 1 && s[0] === "")
|
|
407
411
|
throw new Error("Invalid hostname structure");
|
|
408
|
-
if (
|
|
412
|
+
if (s.length === 1)
|
|
409
413
|
throw new Error("Single-part domain not supported for SaaS integration");
|
|
410
414
|
let n;
|
|
411
|
-
if (
|
|
415
|
+
if (s.length === 2 ? n = s.join(".") : n = s.slice(-2).join("."), !n || n.split(".").length < 2)
|
|
412
416
|
throw new Error("Invalid domain structure for SaaS");
|
|
413
|
-
const i = `https://${
|
|
414
|
-
if (!
|
|
417
|
+
const i = `https://${r}.${n}/collect`;
|
|
418
|
+
if (!ht(i))
|
|
415
419
|
throw new Error("Generated URL failed validation");
|
|
416
420
|
return i;
|
|
417
421
|
} catch (e) {
|
|
418
422
|
throw new Error(`Invalid SaaS URL configuration: ${e instanceof Error ? e.message : String(e)}`);
|
|
419
423
|
}
|
|
420
|
-
},
|
|
424
|
+
}, os = (r) => {
|
|
421
425
|
const e = {};
|
|
422
|
-
|
|
423
|
-
const t =
|
|
426
|
+
r.integrations?.tracelog?.projectId && (e.saas = is(r.integrations.tracelog.projectId));
|
|
427
|
+
const t = r.integrations?.custom?.collectApiUrl;
|
|
424
428
|
if (t) {
|
|
425
|
-
const
|
|
426
|
-
if (!
|
|
429
|
+
const s = r.integrations?.custom?.allowHttp ?? !1;
|
|
430
|
+
if (!ht(t, s))
|
|
427
431
|
throw new Error("Invalid custom API URL");
|
|
428
432
|
e.custom = t;
|
|
429
433
|
}
|
|
430
434
|
return e;
|
|
431
|
-
},
|
|
432
|
-
if (!
|
|
433
|
-
return a("warn", "Invalid URL provided to normalizeUrl", { data: { type: typeof
|
|
435
|
+
}, we = (r, e = []) => {
|
|
436
|
+
if (!r || typeof r != "string")
|
|
437
|
+
return a("warn", "Invalid URL provided to normalizeUrl", { data: { type: typeof r } }), r || "";
|
|
434
438
|
try {
|
|
435
|
-
const t = new URL(
|
|
439
|
+
const t = new URL(r), s = t.searchParams, n = [.../* @__PURE__ */ new Set([...Mt, ...e])];
|
|
436
440
|
let i = !1;
|
|
437
441
|
const o = [];
|
|
438
442
|
return n.forEach((c) => {
|
|
439
|
-
|
|
440
|
-
}), !i &&
|
|
443
|
+
s.has(c) && (s.delete(c), i = !0, o.push(c));
|
|
444
|
+
}), !i && r.includes("?") ? r : (t.search = s.toString(), t.toString());
|
|
441
445
|
} catch (t) {
|
|
442
|
-
return a("warn", "URL normalization failed, returning original", { error: t, data: { urlLength:
|
|
446
|
+
return a("warn", "URL normalization failed, returning original", { error: t, data: { urlLength: r?.length } }), r;
|
|
443
447
|
}
|
|
444
|
-
},
|
|
445
|
-
if (!
|
|
448
|
+
}, Je = (r) => {
|
|
449
|
+
if (!r || typeof r != "string" || r.trim().length === 0)
|
|
446
450
|
return "";
|
|
447
|
-
let e =
|
|
448
|
-
|
|
451
|
+
let e = r;
|
|
452
|
+
r.length > 1e3 && (e = r.slice(0, Math.max(0, 1e3)));
|
|
449
453
|
let t = 0;
|
|
450
|
-
for (const n of
|
|
454
|
+
for (const n of Ct) {
|
|
451
455
|
const i = e;
|
|
452
456
|
e = e.replace(n, ""), i !== e && t++;
|
|
453
457
|
}
|
|
454
458
|
return t > 0 && a("warn", "XSS patterns detected and removed", {
|
|
455
459
|
data: {
|
|
456
460
|
patternMatches: t,
|
|
457
|
-
valueLength:
|
|
461
|
+
valueLength: r.length
|
|
458
462
|
}
|
|
459
463
|
}), e.trim();
|
|
460
|
-
},
|
|
461
|
-
if (
|
|
464
|
+
}, be = (r, e = 0) => {
|
|
465
|
+
if (r == null)
|
|
462
466
|
return null;
|
|
463
|
-
if (typeof
|
|
464
|
-
return
|
|
465
|
-
if (typeof
|
|
466
|
-
return !Number.isFinite(
|
|
467
|
-
if (typeof
|
|
468
|
-
return
|
|
467
|
+
if (typeof r == "string")
|
|
468
|
+
return Je(r);
|
|
469
|
+
if (typeof r == "number")
|
|
470
|
+
return !Number.isFinite(r) || r < -Number.MAX_SAFE_INTEGER || r > Number.MAX_SAFE_INTEGER ? 0 : r;
|
|
471
|
+
if (typeof r == "boolean")
|
|
472
|
+
return r;
|
|
469
473
|
if (e > 10)
|
|
470
474
|
return null;
|
|
471
|
-
if (Array.isArray(
|
|
472
|
-
return
|
|
473
|
-
if (typeof
|
|
474
|
-
const t = {}, n = Object.entries(
|
|
475
|
+
if (Array.isArray(r))
|
|
476
|
+
return r.slice(0, 1e3).map((n) => be(n, e + 1)).filter((n) => n !== null);
|
|
477
|
+
if (typeof r == "object") {
|
|
478
|
+
const t = {}, n = Object.entries(r).slice(0, 200);
|
|
475
479
|
for (const [i, o] of n) {
|
|
476
|
-
const l =
|
|
480
|
+
const l = Je(i);
|
|
477
481
|
if (l) {
|
|
478
|
-
const c =
|
|
482
|
+
const c = be(o, e + 1);
|
|
479
483
|
c !== null && (t[l] = c);
|
|
480
484
|
}
|
|
481
485
|
}
|
|
482
486
|
return t;
|
|
483
487
|
}
|
|
484
488
|
return null;
|
|
485
|
-
},
|
|
486
|
-
if (typeof
|
|
489
|
+
}, as = (r) => {
|
|
490
|
+
if (typeof r != "object" || r === null)
|
|
487
491
|
return {};
|
|
488
492
|
try {
|
|
489
|
-
const e =
|
|
493
|
+
const e = be(r);
|
|
490
494
|
return typeof e == "object" && e !== null ? e : {};
|
|
491
495
|
} catch (e) {
|
|
492
496
|
const t = e instanceof Error ? e.message : String(e);
|
|
493
497
|
throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`);
|
|
494
498
|
}
|
|
495
|
-
},
|
|
496
|
-
if (
|
|
497
|
-
throw new
|
|
498
|
-
if (
|
|
499
|
-
if (
|
|
500
|
-
throw new
|
|
501
|
-
if (
|
|
502
|
-
throw new
|
|
503
|
-
if (
|
|
504
|
-
if (!Array.isArray(
|
|
505
|
-
throw new
|
|
506
|
-
for (const e of
|
|
499
|
+
}, ls = (r) => {
|
|
500
|
+
if (r !== void 0 && (r === null || typeof r != "object"))
|
|
501
|
+
throw new m("Configuration must be an object", "config");
|
|
502
|
+
if (r) {
|
|
503
|
+
if (r.sessionTimeout !== void 0 && (typeof r.sessionTimeout != "number" || r.sessionTimeout < 3e4 || r.sessionTimeout > 864e5))
|
|
504
|
+
throw new Pt(E.INVALID_SESSION_TIMEOUT, "config");
|
|
505
|
+
if (r.globalMetadata !== void 0 && (typeof r.globalMetadata != "object" || r.globalMetadata === null))
|
|
506
|
+
throw new m(E.INVALID_GLOBAL_METADATA, "config");
|
|
507
|
+
if (r.integrations && ds(r.integrations), r.sensitiveQueryParams !== void 0) {
|
|
508
|
+
if (!Array.isArray(r.sensitiveQueryParams))
|
|
509
|
+
throw new m(E.INVALID_SENSITIVE_QUERY_PARAMS, "config");
|
|
510
|
+
for (const e of r.sensitiveQueryParams)
|
|
507
511
|
if (typeof e != "string")
|
|
508
|
-
throw new
|
|
512
|
+
throw new m("All sensitive query params must be strings", "config");
|
|
509
513
|
}
|
|
510
|
-
if (
|
|
511
|
-
throw new
|
|
512
|
-
if (
|
|
513
|
-
throw new
|
|
514
|
-
if (
|
|
515
|
-
if (typeof
|
|
516
|
-
throw new
|
|
517
|
-
if (
|
|
514
|
+
if (r.errorSampling !== void 0 && (typeof r.errorSampling != "number" || r.errorSampling < 0 || r.errorSampling > 1))
|
|
515
|
+
throw new Xe(E.INVALID_ERROR_SAMPLING_RATE, "config");
|
|
516
|
+
if (r.samplingRate !== void 0 && (typeof r.samplingRate != "number" || r.samplingRate < 0 || r.samplingRate > 1))
|
|
517
|
+
throw new Xe(E.INVALID_SAMPLING_RATE, "config");
|
|
518
|
+
if (r.primaryScrollSelector !== void 0) {
|
|
519
|
+
if (typeof r.primaryScrollSelector != "string" || !r.primaryScrollSelector.trim())
|
|
520
|
+
throw new m(E.INVALID_PRIMARY_SCROLL_SELECTOR, "config");
|
|
521
|
+
if (r.primaryScrollSelector !== "window")
|
|
518
522
|
try {
|
|
519
|
-
document.querySelector(
|
|
523
|
+
document.querySelector(r.primaryScrollSelector);
|
|
520
524
|
} catch {
|
|
521
|
-
throw new
|
|
522
|
-
`${
|
|
525
|
+
throw new m(
|
|
526
|
+
`${E.INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX}: "${r.primaryScrollSelector}"`,
|
|
523
527
|
"config"
|
|
524
528
|
);
|
|
525
529
|
}
|
|
526
530
|
}
|
|
527
|
-
if (
|
|
528
|
-
throw new
|
|
529
|
-
if (
|
|
530
|
-
throw new
|
|
531
|
-
if (
|
|
532
|
-
throw new
|
|
533
|
-
if (
|
|
534
|
-
throw new
|
|
535
|
-
if (
|
|
536
|
-
if (typeof
|
|
537
|
-
throw new
|
|
538
|
-
`Invalid webVitalsMode type: ${typeof
|
|
531
|
+
if (r.pageViewThrottleMs !== void 0 && (typeof r.pageViewThrottleMs != "number" || r.pageViewThrottleMs < 0))
|
|
532
|
+
throw new m(E.INVALID_PAGE_VIEW_THROTTLE, "config");
|
|
533
|
+
if (r.clickThrottleMs !== void 0 && (typeof r.clickThrottleMs != "number" || r.clickThrottleMs < 0))
|
|
534
|
+
throw new m(E.INVALID_CLICK_THROTTLE, "config");
|
|
535
|
+
if (r.maxSameEventPerMinute !== void 0 && (typeof r.maxSameEventPerMinute != "number" || r.maxSameEventPerMinute <= 0))
|
|
536
|
+
throw new m(E.INVALID_MAX_SAME_EVENT_PER_MINUTE, "config");
|
|
537
|
+
if (r.sendIntervalMs !== void 0 && (!Number.isFinite(r.sendIntervalMs) || r.sendIntervalMs < 1e3 || r.sendIntervalMs > 6e4))
|
|
538
|
+
throw new m(E.INVALID_SEND_INTERVAL, "config");
|
|
539
|
+
if (r.viewport !== void 0 && cs(r.viewport), r.webVitalsMode !== void 0) {
|
|
540
|
+
if (typeof r.webVitalsMode != "string")
|
|
541
|
+
throw new m(
|
|
542
|
+
`Invalid webVitalsMode type: ${typeof r.webVitalsMode}. Must be a string`,
|
|
539
543
|
"config"
|
|
540
544
|
);
|
|
541
545
|
const e = ["all", "needs-improvement", "poor"];
|
|
542
|
-
if (!e.includes(
|
|
543
|
-
throw new
|
|
544
|
-
`Invalid webVitalsMode: "${
|
|
546
|
+
if (!e.includes(r.webVitalsMode))
|
|
547
|
+
throw new m(
|
|
548
|
+
`Invalid webVitalsMode: "${r.webVitalsMode}". Must be one of: ${e.join(", ")}`,
|
|
545
549
|
"config"
|
|
546
550
|
);
|
|
547
551
|
}
|
|
548
|
-
if (
|
|
549
|
-
if (typeof
|
|
550
|
-
throw new
|
|
552
|
+
if (r.webVitalsThresholds !== void 0) {
|
|
553
|
+
if (typeof r.webVitalsThresholds != "object" || r.webVitalsThresholds === null || Array.isArray(r.webVitalsThresholds))
|
|
554
|
+
throw new m("webVitalsThresholds must be an object", "config");
|
|
551
555
|
const e = ["LCP", "FCP", "CLS", "INP", "TTFB", "LONG_TASK"];
|
|
552
|
-
for (const [t,
|
|
556
|
+
for (const [t, s] of Object.entries(r.webVitalsThresholds)) {
|
|
553
557
|
if (!e.includes(t))
|
|
554
|
-
throw new
|
|
558
|
+
throw new m(
|
|
555
559
|
`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,
|
|
556
560
|
"config"
|
|
557
561
|
);
|
|
558
|
-
if (typeof
|
|
559
|
-
throw new
|
|
560
|
-
`Invalid Web Vitals threshold value for ${t}: ${
|
|
562
|
+
if (typeof s != "number" || !Number.isFinite(s) || s < 0)
|
|
563
|
+
throw new m(
|
|
564
|
+
`Invalid Web Vitals threshold value for ${t}: ${s}. Must be a non-negative finite number`,
|
|
561
565
|
"config"
|
|
562
566
|
);
|
|
563
567
|
}
|
|
564
568
|
}
|
|
565
569
|
}
|
|
566
|
-
},
|
|
567
|
-
if (typeof
|
|
568
|
-
throw new
|
|
569
|
-
if (!
|
|
570
|
-
throw new
|
|
571
|
-
if (
|
|
572
|
-
throw new
|
|
570
|
+
}, cs = (r) => {
|
|
571
|
+
if (typeof r != "object" || r === null)
|
|
572
|
+
throw new m(E.INVALID_VIEWPORT_CONFIG, "config");
|
|
573
|
+
if (!r.elements || !Array.isArray(r.elements))
|
|
574
|
+
throw new m(E.INVALID_VIEWPORT_ELEMENTS, "config");
|
|
575
|
+
if (r.elements.length === 0)
|
|
576
|
+
throw new m(E.INVALID_VIEWPORT_ELEMENTS, "config");
|
|
573
577
|
const e = /* @__PURE__ */ new Set();
|
|
574
|
-
for (const t of
|
|
578
|
+
for (const t of r.elements) {
|
|
575
579
|
if (!t.selector || typeof t.selector != "string" || !t.selector.trim())
|
|
576
|
-
throw new
|
|
577
|
-
const
|
|
578
|
-
if (e.has(
|
|
579
|
-
throw new
|
|
580
|
-
`Duplicate viewport selector found: "${
|
|
580
|
+
throw new m(E.INVALID_VIEWPORT_ELEMENT, "config");
|
|
581
|
+
const s = t.selector.trim();
|
|
582
|
+
if (e.has(s))
|
|
583
|
+
throw new m(
|
|
584
|
+
`Duplicate viewport selector found: "${s}". Each selector should appear only once.`,
|
|
581
585
|
"config"
|
|
582
586
|
);
|
|
583
|
-
if (e.add(
|
|
584
|
-
throw new
|
|
587
|
+
if (e.add(s), t.id !== void 0 && (typeof t.id != "string" || !t.id.trim()))
|
|
588
|
+
throw new m(E.INVALID_VIEWPORT_ELEMENT_ID, "config");
|
|
585
589
|
if (t.name !== void 0 && (typeof t.name != "string" || !t.name.trim()))
|
|
586
|
-
throw new
|
|
587
|
-
}
|
|
588
|
-
if (
|
|
589
|
-
throw new
|
|
590
|
-
if (
|
|
591
|
-
throw new
|
|
592
|
-
if (
|
|
593
|
-
throw new
|
|
594
|
-
if (
|
|
595
|
-
throw new
|
|
596
|
-
},
|
|
597
|
-
if (
|
|
598
|
-
if (
|
|
599
|
-
throw new
|
|
600
|
-
if (
|
|
601
|
-
if (!
|
|
602
|
-
throw new
|
|
603
|
-
if (
|
|
604
|
-
throw new
|
|
605
|
-
const e =
|
|
590
|
+
throw new m(E.INVALID_VIEWPORT_ELEMENT_NAME, "config");
|
|
591
|
+
}
|
|
592
|
+
if (r.threshold !== void 0 && (typeof r.threshold != "number" || r.threshold < 0 || r.threshold > 1))
|
|
593
|
+
throw new m(E.INVALID_VIEWPORT_THRESHOLD, "config");
|
|
594
|
+
if (r.minDwellTime !== void 0 && (typeof r.minDwellTime != "number" || r.minDwellTime < 0))
|
|
595
|
+
throw new m(E.INVALID_VIEWPORT_MIN_DWELL_TIME, "config");
|
|
596
|
+
if (r.cooldownPeriod !== void 0 && (typeof r.cooldownPeriod != "number" || r.cooldownPeriod < 0))
|
|
597
|
+
throw new m(E.INVALID_VIEWPORT_COOLDOWN_PERIOD, "config");
|
|
598
|
+
if (r.maxTrackedElements !== void 0 && (typeof r.maxTrackedElements != "number" || r.maxTrackedElements <= 0))
|
|
599
|
+
throw new m(E.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS, "config");
|
|
600
|
+
}, ds = (r) => {
|
|
601
|
+
if (r) {
|
|
602
|
+
if (r.tracelog && (!r.tracelog.projectId || typeof r.tracelog.projectId != "string" || r.tracelog.projectId.trim() === ""))
|
|
603
|
+
throw new N(E.INVALID_TRACELOG_PROJECT_ID, "config");
|
|
604
|
+
if (r.custom) {
|
|
605
|
+
if (!r.custom.collectApiUrl || typeof r.custom.collectApiUrl != "string" || r.custom.collectApiUrl.trim() === "")
|
|
606
|
+
throw new N(E.INVALID_CUSTOM_API_URL, "config");
|
|
607
|
+
if (r.custom.allowHttp !== void 0 && typeof r.custom.allowHttp != "boolean")
|
|
608
|
+
throw new N("allowHttp must be a boolean", "config");
|
|
609
|
+
const e = r.custom.collectApiUrl.trim();
|
|
606
610
|
if (!e.startsWith("http://") && !e.startsWith("https://"))
|
|
607
|
-
throw new
|
|
608
|
-
if (!(
|
|
609
|
-
throw new
|
|
611
|
+
throw new N('Custom API URL must start with "http://" or "https://"', "config");
|
|
612
|
+
if (!(r.custom.allowHttp ?? !1) && e.startsWith("http://"))
|
|
613
|
+
throw new N(
|
|
610
614
|
"Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)",
|
|
611
615
|
"config"
|
|
612
616
|
);
|
|
613
|
-
if (
|
|
614
|
-
throw new
|
|
617
|
+
if (r.custom.fetchCredentials !== void 0 && !["include", "same-origin", "omit"].includes(r.custom.fetchCredentials))
|
|
618
|
+
throw new N('fetchCredentials must be "include", "same-origin", or "omit"', "config");
|
|
615
619
|
}
|
|
620
|
+
if (r.tracelog?.shopify !== void 0 && typeof r.tracelog.shopify != "boolean")
|
|
621
|
+
throw new N("tracelog.shopify must be a boolean", "config");
|
|
616
622
|
}
|
|
617
|
-
},
|
|
618
|
-
|
|
623
|
+
}, us = (r) => {
|
|
624
|
+
ls(r);
|
|
619
625
|
const e = {
|
|
620
|
-
...
|
|
621
|
-
sessionTimeout:
|
|
622
|
-
globalMetadata:
|
|
623
|
-
sensitiveQueryParams:
|
|
624
|
-
errorSampling:
|
|
625
|
-
samplingRate:
|
|
626
|
-
pageViewThrottleMs:
|
|
627
|
-
clickThrottleMs:
|
|
628
|
-
maxSameEventPerMinute:
|
|
629
|
-
sendIntervalMs:
|
|
626
|
+
...r ?? {},
|
|
627
|
+
sessionTimeout: r?.sessionTimeout ?? 9e5,
|
|
628
|
+
globalMetadata: r?.globalMetadata ?? {},
|
|
629
|
+
sensitiveQueryParams: r?.sensitiveQueryParams ?? [],
|
|
630
|
+
errorSampling: r?.errorSampling ?? ct,
|
|
631
|
+
samplingRate: r?.samplingRate ?? 1,
|
|
632
|
+
pageViewThrottleMs: r?.pageViewThrottleMs ?? 1e3,
|
|
633
|
+
clickThrottleMs: r?.clickThrottleMs ?? 300,
|
|
634
|
+
maxSameEventPerMinute: r?.maxSameEventPerMinute ?? 60,
|
|
635
|
+
sendIntervalMs: r?.sendIntervalMs ?? 1e4
|
|
630
636
|
};
|
|
631
637
|
return e.integrations?.custom && (e.integrations.custom = {
|
|
632
638
|
...e.integrations.custom,
|
|
@@ -638,42 +644,42 @@ const nr = () => {
|
|
|
638
644
|
cooldownPeriod: e.viewport.cooldownPeriod ?? 6e4,
|
|
639
645
|
maxTrackedElements: e.viewport.maxTrackedElements ?? 100
|
|
640
646
|
}), e;
|
|
641
|
-
},
|
|
642
|
-
if (
|
|
647
|
+
}, Ae = (r, e = /* @__PURE__ */ new Set()) => {
|
|
648
|
+
if (r == null)
|
|
643
649
|
return !0;
|
|
644
|
-
const t = typeof
|
|
645
|
-
return t === "string" || t === "number" || t === "boolean" ? !0 : t === "function" || t === "symbol" || t === "bigint" || e.has(
|
|
646
|
-
},
|
|
647
|
-
if (typeof
|
|
650
|
+
const t = typeof r;
|
|
651
|
+
return t === "string" || t === "number" || t === "boolean" ? !0 : t === "function" || t === "symbol" || t === "bigint" || e.has(r) ? !1 : (e.add(r), Array.isArray(r) ? r.every((s) => Ae(s, e)) : t === "object" ? Object.values(r).every((s) => Ae(s, e)) : !1);
|
|
652
|
+
}, hs = (r) => typeof r != "object" || r === null ? !1 : Ae(r), ft = (r) => {
|
|
653
|
+
if (typeof r != "object" || r === null || Array.isArray(r)) return;
|
|
648
654
|
const e = {};
|
|
649
|
-
for (const [t,
|
|
650
|
-
typeof
|
|
655
|
+
for (const [t, s] of Object.entries(r))
|
|
656
|
+
typeof s == "string" && (e[t] = s);
|
|
651
657
|
return Object.keys(e).length > 0 ? e : void 0;
|
|
652
|
-
},
|
|
658
|
+
}, fs = (r) => typeof r != "string" ? {
|
|
653
659
|
valid: !1,
|
|
654
660
|
error: "Event name must be a string"
|
|
655
|
-
} :
|
|
661
|
+
} : r.length === 0 ? {
|
|
656
662
|
valid: !1,
|
|
657
663
|
error: "Event name cannot be empty"
|
|
658
|
-
} :
|
|
664
|
+
} : r.length > 120 ? {
|
|
659
665
|
valid: !1,
|
|
660
666
|
error: "Event name is too long (max 120 characters)"
|
|
661
|
-
} :
|
|
667
|
+
} : r.includes("<") || r.includes(">") || r.includes("&") ? {
|
|
662
668
|
valid: !1,
|
|
663
669
|
error: "Event name contains invalid characters"
|
|
664
|
-
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(
|
|
670
|
+
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(r.toLowerCase()) ? {
|
|
665
671
|
valid: !1,
|
|
666
672
|
error: "Event name cannot be a reserved word"
|
|
667
|
-
} : { valid: !0 },
|
|
668
|
-
const
|
|
669
|
-
if (!
|
|
673
|
+
} : { valid: !0 }, Ze = (r, e, t) => {
|
|
674
|
+
const s = as(e), n = t && t === "customEvent" ? `${t} "${r}" metadata error` : `${r} metadata error`;
|
|
675
|
+
if (!hs(s))
|
|
670
676
|
return {
|
|
671
677
|
valid: !1,
|
|
672
678
|
error: `${n}: object has invalid types. Valid types are string, number, boolean or string arrays.`
|
|
673
679
|
};
|
|
674
680
|
let i;
|
|
675
681
|
try {
|
|
676
|
-
i = JSON.stringify(
|
|
682
|
+
i = JSON.stringify(s);
|
|
677
683
|
} catch {
|
|
678
684
|
return {
|
|
679
685
|
valid: !1,
|
|
@@ -685,26 +691,26 @@ const nr = () => {
|
|
|
685
691
|
valid: !1,
|
|
686
692
|
error: `${n}: object is too large (max ${49152 / 1024} KB).`
|
|
687
693
|
};
|
|
688
|
-
if (Object.keys(
|
|
694
|
+
if (Object.keys(s).length > 100)
|
|
689
695
|
return {
|
|
690
696
|
valid: !1,
|
|
691
697
|
error: `${n}: object has too many keys (max 100 keys).`
|
|
692
698
|
};
|
|
693
|
-
for (const [c,
|
|
694
|
-
if (Array.isArray(
|
|
695
|
-
if (
|
|
699
|
+
for (const [c, d] of Object.entries(s)) {
|
|
700
|
+
if (Array.isArray(d)) {
|
|
701
|
+
if (d.length > 500)
|
|
696
702
|
return {
|
|
697
703
|
valid: !1,
|
|
698
704
|
error: `${n}: array property "${c}" is too large (max 500 items).`
|
|
699
705
|
};
|
|
700
|
-
for (const
|
|
701
|
-
if (typeof
|
|
706
|
+
for (const f of d)
|
|
707
|
+
if (typeof f == "string" && f.length > 500)
|
|
702
708
|
return {
|
|
703
709
|
valid: !1,
|
|
704
710
|
error: `${n}: array property "${c}" contains strings that are too long (max 500 characters).`
|
|
705
711
|
};
|
|
706
712
|
}
|
|
707
|
-
if (typeof
|
|
713
|
+
if (typeof d == "string" && d.length > 1e3)
|
|
708
714
|
return {
|
|
709
715
|
valid: !1,
|
|
710
716
|
error: `${n}: property "${c}" is too long (max 1000 characters).`
|
|
@@ -712,11 +718,11 @@ const nr = () => {
|
|
|
712
718
|
}
|
|
713
719
|
return {
|
|
714
720
|
valid: !0,
|
|
715
|
-
sanitizedMetadata:
|
|
721
|
+
sanitizedMetadata: s
|
|
716
722
|
};
|
|
717
|
-
},
|
|
723
|
+
}, mt = (r, e, t) => {
|
|
718
724
|
if (Array.isArray(e)) {
|
|
719
|
-
const
|
|
725
|
+
const s = [], n = t && t === "customEvent" ? `${t} "${r}" metadata error` : `${r} metadata error`;
|
|
720
726
|
for (let i = 0; i < e.length; i++) {
|
|
721
727
|
const o = e[i];
|
|
722
728
|
if (typeof o != "object" || o === null || Array.isArray(o))
|
|
@@ -724,37 +730,37 @@ const nr = () => {
|
|
|
724
730
|
valid: !1,
|
|
725
731
|
error: `${n}: array item at index ${i} must be an object.`
|
|
726
732
|
};
|
|
727
|
-
const l =
|
|
733
|
+
const l = Ze(r, o, t);
|
|
728
734
|
if (!l.valid)
|
|
729
735
|
return {
|
|
730
736
|
valid: !1,
|
|
731
737
|
error: `${n}: array item at index ${i} is invalid: ${l.error}`
|
|
732
738
|
};
|
|
733
|
-
l.sanitizedMetadata &&
|
|
739
|
+
l.sanitizedMetadata && s.push(l.sanitizedMetadata);
|
|
734
740
|
}
|
|
735
741
|
return {
|
|
736
742
|
valid: !0,
|
|
737
|
-
sanitizedMetadata:
|
|
743
|
+
sanitizedMetadata: s
|
|
738
744
|
};
|
|
739
745
|
}
|
|
740
|
-
return
|
|
741
|
-
},
|
|
742
|
-
const t =
|
|
746
|
+
return Ze(r, e, t);
|
|
747
|
+
}, ms = (r, e) => {
|
|
748
|
+
const t = fs(r);
|
|
743
749
|
if (!t.valid)
|
|
744
750
|
return a("error", "Event name validation failed", {
|
|
745
|
-
data: { eventName:
|
|
751
|
+
data: { eventName: r, error: t.error }
|
|
746
752
|
}), t;
|
|
747
753
|
if (!e)
|
|
748
754
|
return { valid: !0 };
|
|
749
|
-
const
|
|
750
|
-
return
|
|
755
|
+
const s = mt(r, e, "customEvent");
|
|
756
|
+
return s.valid || a("error", "Event metadata validation failed", {
|
|
751
757
|
data: {
|
|
752
|
-
eventName:
|
|
753
|
-
error:
|
|
758
|
+
eventName: r,
|
|
759
|
+
error: s.error
|
|
754
760
|
}
|
|
755
|
-
}),
|
|
761
|
+
}), s;
|
|
756
762
|
};
|
|
757
|
-
class
|
|
763
|
+
class gs {
|
|
758
764
|
listeners = /* @__PURE__ */ new Map();
|
|
759
765
|
/**
|
|
760
766
|
* Subscribes to an event channel
|
|
@@ -805,10 +811,10 @@ class gr {
|
|
|
805
811
|
* ```
|
|
806
812
|
*/
|
|
807
813
|
off(e, t) {
|
|
808
|
-
const
|
|
809
|
-
if (
|
|
810
|
-
const n =
|
|
811
|
-
n > -1 &&
|
|
814
|
+
const s = this.listeners.get(e);
|
|
815
|
+
if (s) {
|
|
816
|
+
const n = s.indexOf(t);
|
|
817
|
+
n > -1 && s.splice(n, 1);
|
|
812
818
|
}
|
|
813
819
|
}
|
|
814
820
|
/**
|
|
@@ -840,8 +846,8 @@ class gr {
|
|
|
840
846
|
* ```
|
|
841
847
|
*/
|
|
842
848
|
emit(e, t) {
|
|
843
|
-
const
|
|
844
|
-
|
|
849
|
+
const s = this.listeners.get(e);
|
|
850
|
+
s && s.forEach((n) => {
|
|
845
851
|
n(t);
|
|
846
852
|
});
|
|
847
853
|
}
|
|
@@ -871,38 +877,38 @@ class gr {
|
|
|
871
877
|
this.listeners.clear();
|
|
872
878
|
}
|
|
873
879
|
}
|
|
874
|
-
function
|
|
880
|
+
function gt(r, e, t) {
|
|
875
881
|
try {
|
|
876
|
-
const
|
|
877
|
-
return
|
|
878
|
-
} catch (
|
|
882
|
+
const s = e(r);
|
|
883
|
+
return s === null ? null : typeof s == "object" && s !== null && "type" in s ? s : (a("warn", `beforeSend transformer returned invalid data, using original [${t}]`), r);
|
|
884
|
+
} catch (s) {
|
|
879
885
|
return a("error", `beforeSend transformer threw error, using original event [${t}]`, {
|
|
880
|
-
error:
|
|
886
|
+
error: s,
|
|
881
887
|
visibility: "critical"
|
|
882
|
-
}),
|
|
888
|
+
}), r;
|
|
883
889
|
}
|
|
884
890
|
}
|
|
885
|
-
function
|
|
886
|
-
return
|
|
891
|
+
function Es(r, e, t) {
|
|
892
|
+
return r.map((s) => gt(s, e, t)).filter((s) => s !== null);
|
|
887
893
|
}
|
|
888
|
-
function
|
|
894
|
+
function Et(r, e, t) {
|
|
889
895
|
try {
|
|
890
|
-
const
|
|
891
|
-
return
|
|
892
|
-
data: { eventCount:
|
|
893
|
-
}), null) : typeof
|
|
894
|
-
data: { eventCount:
|
|
895
|
-
}),
|
|
896
|
-
} catch (
|
|
896
|
+
const s = e(r);
|
|
897
|
+
return s === null ? (a("debug", `Batch filtered by beforeBatch transformer [${t}]`, {
|
|
898
|
+
data: { eventCount: r.events.length }
|
|
899
|
+
}), null) : typeof s == "object" && s !== null && Array.isArray(s.events) ? s : (a("warn", `beforeBatch transformer returned invalid data, using original [${t}]`, {
|
|
900
|
+
data: { eventCount: r.events.length }
|
|
901
|
+
}), r);
|
|
902
|
+
} catch (s) {
|
|
897
903
|
return a("error", `beforeBatch transformer threw error, using original batch [${t}]`, {
|
|
898
|
-
error:
|
|
899
|
-
data: { eventCount:
|
|
904
|
+
error: s,
|
|
905
|
+
data: { eventCount: r.events.length },
|
|
900
906
|
visibility: "critical"
|
|
901
|
-
}),
|
|
907
|
+
}), r;
|
|
902
908
|
}
|
|
903
909
|
}
|
|
904
|
-
const
|
|
905
|
-
class
|
|
910
|
+
const Ee = { config: {} };
|
|
911
|
+
class _ {
|
|
906
912
|
/**
|
|
907
913
|
* Retrieves a value from global state.
|
|
908
914
|
*
|
|
@@ -920,7 +926,7 @@ class w {
|
|
|
920
926
|
* ```
|
|
921
927
|
*/
|
|
922
928
|
get(e) {
|
|
923
|
-
return
|
|
929
|
+
return Ee[e];
|
|
924
930
|
}
|
|
925
931
|
/**
|
|
926
932
|
* Sets a value in global state.
|
|
@@ -940,7 +946,7 @@ class w {
|
|
|
940
946
|
* ```
|
|
941
947
|
*/
|
|
942
948
|
set(e, t) {
|
|
943
|
-
|
|
949
|
+
Ee[e] = t;
|
|
944
950
|
}
|
|
945
951
|
/**
|
|
946
952
|
* Returns an immutable snapshot of the entire global state.
|
|
@@ -957,10 +963,10 @@ class w {
|
|
|
957
963
|
* ```
|
|
958
964
|
*/
|
|
959
965
|
getState() {
|
|
960
|
-
return { ...
|
|
966
|
+
return { ...Ee };
|
|
961
967
|
}
|
|
962
968
|
}
|
|
963
|
-
class
|
|
969
|
+
class et extends _ {
|
|
964
970
|
storeManager;
|
|
965
971
|
integrationId;
|
|
966
972
|
apiUrl;
|
|
@@ -995,10 +1001,10 @@ class Ze extends w {
|
|
|
995
1001
|
* @param customHeadersProvider - Optional callback for dynamic headers
|
|
996
1002
|
* @throws Error if integrationId and apiUrl are not both provided or both undefined
|
|
997
1003
|
*/
|
|
998
|
-
constructor(e, t,
|
|
999
|
-
if (super(), t && !
|
|
1004
|
+
constructor(e, t, s, n = {}, i = {}, o, l = "include") {
|
|
1005
|
+
if (super(), t && !s || !t && s)
|
|
1000
1006
|
throw new Error("SenderManager: integrationId and apiUrl must either both be provided or both be undefined");
|
|
1001
|
-
this.storeManager = e, this.integrationId = t, this.apiUrl =
|
|
1007
|
+
this.storeManager = e, this.integrationId = t, this.apiUrl = s, this.transformers = n, this.staticHeaders = i, this.customHeadersProvider = o, this.fetchCredentials = l;
|
|
1002
1008
|
}
|
|
1003
1009
|
/**
|
|
1004
1010
|
* Get the integration ID for this sender
|
|
@@ -1045,7 +1051,7 @@ class Ze extends w {
|
|
|
1045
1051
|
return { ...this.staticHeaders, ...e };
|
|
1046
1052
|
}
|
|
1047
1053
|
getQueueStorageKey() {
|
|
1048
|
-
const e = this.get("userId") || "anonymous", t =
|
|
1054
|
+
const e = this.get("userId") || "anonymous", t = Rt(e);
|
|
1049
1055
|
return this.integrationId ? `${t}:${this.integrationId}` : t;
|
|
1050
1056
|
}
|
|
1051
1057
|
/**
|
|
@@ -1062,7 +1068,7 @@ class Ze extends w {
|
|
|
1062
1068
|
* - Uses `navigator.sendBeacon()` (browser-queued, synchronous API)
|
|
1063
1069
|
* - Payload size limited to 64KB (enforced by browser)
|
|
1064
1070
|
* - Browser guarantees delivery attempt (survives page close)
|
|
1065
|
-
* -
|
|
1071
|
+
* - Persists to localStorage on beacon failure/size overflow for later recovery
|
|
1066
1072
|
*
|
|
1067
1073
|
* **Return Values**:
|
|
1068
1074
|
* - `true`: Send succeeded OR skipped (standalone mode)
|
|
@@ -1087,13 +1093,13 @@ class Ze extends w {
|
|
|
1087
1093
|
* @see src/managers/README.md (lines 82-139) for send details
|
|
1088
1094
|
*/
|
|
1089
1095
|
sendEventsQueueSync(e) {
|
|
1090
|
-
return this.shouldSkipSend() ? !0 : this.apiUrl?.includes(
|
|
1096
|
+
return this.shouldSkipSend() ? !0 : this.apiUrl?.includes($.Fail) ? (a(
|
|
1091
1097
|
"warn",
|
|
1092
1098
|
`Fail mode: simulating network failure (sync)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1093
1099
|
{
|
|
1094
1100
|
data: { events: e.events.length }
|
|
1095
1101
|
}
|
|
1096
|
-
), !1) : this.apiUrl?.includes(
|
|
1102
|
+
), !1) : this.apiUrl?.includes($.Localhost) ? (a(
|
|
1097
1103
|
"debug",
|
|
1098
1104
|
`Success mode: simulating successful send (sync)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1099
1105
|
{
|
|
@@ -1118,7 +1124,7 @@ class Ze extends w {
|
|
|
1118
1124
|
*
|
|
1119
1125
|
* **Error Handling**:
|
|
1120
1126
|
* - **Permanent errors** (4xx except 408, 429): Events discarded, not persisted
|
|
1121
|
-
* - **Timeout errors
|
|
1127
|
+
* - **Timeout errors**: Events persisted for retry with the same batch idempotency token
|
|
1122
1128
|
* - **Transient errors** (5xx, network, mixed): Events persisted for recovery
|
|
1123
1129
|
*
|
|
1124
1130
|
* **Important**: Events are NOT retried in-session. Persistence is for
|
|
@@ -1132,14 +1138,12 @@ class Ze extends w {
|
|
|
1132
1138
|
* @see src/managers/README.md (lines 82-139) for send details
|
|
1133
1139
|
*/
|
|
1134
1140
|
async sendEventsQueue(e, t) {
|
|
1141
|
+
const s = this.ensureBatchMetadata(e);
|
|
1135
1142
|
try {
|
|
1136
|
-
const
|
|
1137
|
-
return
|
|
1138
|
-
} catch (
|
|
1139
|
-
return
|
|
1140
|
-
"debug",
|
|
1141
|
-
`All attempts timed out, skipping persistence (server likely received events)${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1142
|
-
), this.clearPersistedEvents(), t?.onFailure?.(), !1) : (this.persistEvents(e), t?.onFailure?.(), !1);
|
|
1143
|
+
const n = await this.send(s);
|
|
1144
|
+
return n ? (this.clearPersistedEvents(), t?.onSuccess?.(s.events.length, s.events, s)) : (this.persistEvents(s), t?.onFailure?.()), n;
|
|
1145
|
+
} catch (n) {
|
|
1146
|
+
return n instanceof O ? (this.logPermanentError("Permanent error, not retrying", n), this.clearPersistedEvents(), t?.onFailure?.(), !1) : (this.persistEvents(s), t?.onFailure?.(), !1);
|
|
1143
1147
|
}
|
|
1144
1148
|
}
|
|
1145
1149
|
/**
|
|
@@ -1197,35 +1201,28 @@ class Ze extends w {
|
|
|
1197
1201
|
return;
|
|
1198
1202
|
}
|
|
1199
1203
|
this.recoveryInProgress = !0;
|
|
1204
|
+
let t = null, s = 0;
|
|
1200
1205
|
try {
|
|
1201
|
-
const
|
|
1202
|
-
if (!
|
|
1206
|
+
const n = this.getPersistedData();
|
|
1207
|
+
if (!n || !this.isDataRecent(n) || n.events.length === 0) {
|
|
1203
1208
|
this.clearPersistedEvents();
|
|
1204
1209
|
return;
|
|
1205
1210
|
}
|
|
1206
|
-
const
|
|
1207
|
-
if (
|
|
1211
|
+
const i = n.recoveryFailures;
|
|
1212
|
+
if (s = typeof i == "number" && Number.isFinite(i) && i >= 0 ? i : 0, s >= 3) {
|
|
1208
1213
|
a(
|
|
1209
1214
|
"debug",
|
|
1210
|
-
`Discarding persisted events after ${
|
|
1215
|
+
`Discarding persisted events after ${s} failed recovery attempts${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1211
1216
|
), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1212
1217
|
return;
|
|
1213
1218
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
this.logPermanentError("Permanent error during recovery, clearing persisted events", t), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1219
|
-
return;
|
|
1220
|
-
}
|
|
1221
|
-
if (t instanceof O) {
|
|
1222
|
-
a(
|
|
1223
|
-
"debug",
|
|
1224
|
-
`Recovery timed out, clearing persisted events (server likely received them)${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1225
|
-
), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1219
|
+
t = this.ensureBatchMetadata(this.createRecoveryBody(n)), await this.send(t) ? (this.clearPersistedEvents(), e?.onSuccess?.(n.events.length, n.events, t)) : (this.persistEventsWithFailureCount(t, s + 1, !0), e?.onFailure?.());
|
|
1220
|
+
} catch (n) {
|
|
1221
|
+
if (n instanceof O) {
|
|
1222
|
+
this.logPermanentError("Permanent error during recovery, clearing persisted events", n), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1226
1223
|
return;
|
|
1227
1224
|
}
|
|
1228
|
-
a("error", "Failed to recover persisted events", { error:
|
|
1225
|
+
a("error", "Failed to recover persisted events", { error: n }), t && this.persistEventsWithFailureCount(t, s + 1, !0), e?.onFailure?.();
|
|
1229
1226
|
} finally {
|
|
1230
1227
|
this.recoveryInProgress = !1;
|
|
1231
1228
|
}
|
|
@@ -1275,14 +1272,14 @@ class Ze extends w {
|
|
|
1275
1272
|
const t = this.transformers.beforeSend;
|
|
1276
1273
|
if (!t)
|
|
1277
1274
|
return e;
|
|
1278
|
-
const
|
|
1275
|
+
const s = Es(
|
|
1279
1276
|
e.events,
|
|
1280
1277
|
t,
|
|
1281
1278
|
this.integrationId || "SenderManager"
|
|
1282
1279
|
);
|
|
1283
|
-
return
|
|
1280
|
+
return s.length === 0 ? null : {
|
|
1284
1281
|
...e,
|
|
1285
|
-
events:
|
|
1282
|
+
events: s
|
|
1286
1283
|
};
|
|
1287
1284
|
}
|
|
1288
1285
|
/**
|
|
@@ -1320,7 +1317,7 @@ class Ze extends w {
|
|
|
1320
1317
|
if (this.integrationId === "saas")
|
|
1321
1318
|
return e;
|
|
1322
1319
|
const t = this.transformers.beforeBatch;
|
|
1323
|
-
return t ?
|
|
1320
|
+
return t ? Et(e, t, this.integrationId || "SenderManager") : e;
|
|
1324
1321
|
}
|
|
1325
1322
|
/**
|
|
1326
1323
|
* Calculates exponential backoff delay with jitter for retry attempts.
|
|
@@ -1342,7 +1339,7 @@ class Ze extends w {
|
|
|
1342
1339
|
* @returns Promise that resolves after calculated delay
|
|
1343
1340
|
*/
|
|
1344
1341
|
async backoffDelay(e) {
|
|
1345
|
-
const t = 100 * Math.pow(2, e),
|
|
1342
|
+
const t = 100 * Math.pow(2, e), s = Math.random() * 100, n = t + s;
|
|
1346
1343
|
return new Promise((i) => setTimeout(i, n));
|
|
1347
1344
|
}
|
|
1348
1345
|
/**
|
|
@@ -1378,7 +1375,6 @@ class Ze extends w {
|
|
|
1378
1375
|
* @param body - Event queue to send
|
|
1379
1376
|
* @returns Promise resolving to true if send succeeded, false if all retries exhausted
|
|
1380
1377
|
* @throws PermanentError for 4xx errors (caller should not retry)
|
|
1381
|
-
* @throws TimeoutError when all retry attempts timed out (caller should not persist)
|
|
1382
1378
|
*/
|
|
1383
1379
|
async send(e) {
|
|
1384
1380
|
if (this.shouldSkipSend())
|
|
@@ -1386,70 +1382,75 @@ class Ze extends w {
|
|
|
1386
1382
|
const t = this.applyBeforeSendTransformer(e);
|
|
1387
1383
|
if (!t)
|
|
1388
1384
|
return !0;
|
|
1389
|
-
const
|
|
1390
|
-
if (!
|
|
1385
|
+
const s = this.applyBeforeBatchTransformer(t);
|
|
1386
|
+
if (!s)
|
|
1391
1387
|
return !0;
|
|
1392
|
-
|
|
1388
|
+
const n = this.ensureBatchMetadata(s, e._metadata?.idempotency_token);
|
|
1389
|
+
if (this.apiUrl?.includes($.Fail))
|
|
1393
1390
|
return a("debug", `Fail mode: simulating network failure${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1394
|
-
data: { events:
|
|
1391
|
+
data: { events: n.events.length }
|
|
1395
1392
|
}), !1;
|
|
1396
|
-
if (this.apiUrl?.includes(
|
|
1393
|
+
if (this.apiUrl?.includes($.Localhost))
|
|
1397
1394
|
return a("debug", `Success mode: simulating successful send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1398
|
-
data: { events:
|
|
1395
|
+
data: { events: n.events.length }
|
|
1399
1396
|
}), !0;
|
|
1400
1397
|
if (this.consecutiveNetworkFailures >= 3) {
|
|
1401
|
-
const
|
|
1402
|
-
if (
|
|
1398
|
+
const d = Date.now() - this.circuitOpenedAt;
|
|
1399
|
+
if (d < 12e4)
|
|
1403
1400
|
return a("debug", `Network circuit open, skipping send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1404
1401
|
data: {
|
|
1405
1402
|
consecutiveNetworkFailures: this.consecutiveNetworkFailures,
|
|
1406
|
-
cooldownRemainingMs: 12e4 -
|
|
1403
|
+
cooldownRemainingMs: 12e4 - d
|
|
1407
1404
|
}
|
|
1408
1405
|
}), !1;
|
|
1409
1406
|
}
|
|
1410
|
-
const { url:
|
|
1411
|
-
let
|
|
1412
|
-
for (let
|
|
1407
|
+
const { url: i, payload: o } = this.prepareRequest(n);
|
|
1408
|
+
let l = !0, c = !1;
|
|
1409
|
+
for (let d = 1; d <= 3; d++)
|
|
1413
1410
|
try {
|
|
1414
|
-
return (await this.sendWithTimeout(
|
|
1411
|
+
return (await this.sendWithTimeout(i, o)).ok ? (d > 1 && a(
|
|
1415
1412
|
"info",
|
|
1416
|
-
`Send succeeded after ${
|
|
1413
|
+
`Send succeeded after ${d - 1} retry attempt(s)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1417
1414
|
{
|
|
1418
|
-
data: { events:
|
|
1415
|
+
data: { events: n.events.length, attempt: d }
|
|
1419
1416
|
}
|
|
1420
1417
|
), this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, !0) : !1;
|
|
1421
|
-
} catch (
|
|
1422
|
-
const g =
|
|
1423
|
-
if (
|
|
1424
|
-
throw this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0,
|
|
1425
|
-
if (
|
|
1426
|
-
this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0,
|
|
1427
|
-
data: { events: e.events.length, attempt:
|
|
1418
|
+
} catch (f) {
|
|
1419
|
+
const g = d === 3;
|
|
1420
|
+
if (f instanceof O)
|
|
1421
|
+
throw this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, f;
|
|
1422
|
+
if (f instanceof re) {
|
|
1423
|
+
this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, l = !1, c = !0, a("warn", `Rate limited, skipping retries${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1424
|
+
data: { events: e.events.length, attempt: d }
|
|
1428
1425
|
});
|
|
1429
1426
|
break;
|
|
1430
1427
|
}
|
|
1431
|
-
if (
|
|
1428
|
+
if (f instanceof ne || (l = !1), f instanceof TypeError || (c = !0), a(
|
|
1432
1429
|
g ? "error" : "warn",
|
|
1433
|
-
`Send attempt ${
|
|
1430
|
+
`Send attempt ${d} failed${this.integrationId ? ` [${this.integrationId}]` : ""}${g ? " (all retries exhausted)" : ", will retry"}`,
|
|
1434
1431
|
{
|
|
1435
|
-
error:
|
|
1432
|
+
error: f,
|
|
1436
1433
|
data: {
|
|
1437
1434
|
events: e.events.length,
|
|
1438
|
-
url:
|
|
1439
|
-
attempt:
|
|
1435
|
+
url: i.replace(/\/\/[^/]+/, "//[DOMAIN]"),
|
|
1436
|
+
attempt: d,
|
|
1440
1437
|
maxAttempts: 3
|
|
1441
1438
|
}
|
|
1442
1439
|
}
|
|
1443
1440
|
), !g) {
|
|
1444
|
-
await this.backoffDelay(
|
|
1441
|
+
await this.backoffDelay(d);
|
|
1445
1442
|
continue;
|
|
1446
1443
|
}
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1444
|
+
return l ? (a(
|
|
1445
|
+
"debug",
|
|
1446
|
+
`All retry attempts timed out, preserving batch for retry${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1447
|
+
{
|
|
1448
|
+
data: { events: n.events.length }
|
|
1449
|
+
}
|
|
1450
|
+
), !1) : (c ? (this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0) : (this.consecutiveNetworkFailures = Math.min(
|
|
1450
1451
|
this.consecutiveNetworkFailures + 1,
|
|
1451
1452
|
3
|
|
1452
|
-
), this.consecutiveNetworkFailures >= 3 && (this.circuitOpenedAt = Date.now())), !1;
|
|
1453
|
+
), this.consecutiveNetworkFailures >= 3 && (this.circuitOpenedAt = Date.now())), !1);
|
|
1453
1454
|
}
|
|
1454
1455
|
return !1;
|
|
1455
1456
|
}
|
|
@@ -1461,27 +1462,27 @@ class Ze extends w {
|
|
|
1461
1462
|
*
|
|
1462
1463
|
* **Timeout Behavior**:
|
|
1463
1464
|
* - 10-second timeout via AbortController (REQUEST_TIMEOUT_MS constant)
|
|
1464
|
-
* - Aborted requests throw TimeoutError
|
|
1465
|
+
* - Aborted requests throw TimeoutError
|
|
1465
1466
|
*
|
|
1466
1467
|
* **Error Classification**:
|
|
1467
1468
|
* - 4xx (except 408, 429): PermanentError thrown → no retries
|
|
1468
|
-
* - Timeout: TimeoutError thrown → caller
|
|
1469
|
+
* - Timeout: TimeoutError thrown → caller treats it as a retryable failure
|
|
1469
1470
|
* - 408, 429, 5xx, network: Standard Error thrown → triggers retry
|
|
1470
1471
|
*
|
|
1471
1472
|
* @param url - API endpoint URL
|
|
1472
1473
|
* @param payload - JSON-stringified EventsQueue body
|
|
1473
1474
|
* @returns Response object if successful
|
|
1474
1475
|
* @throws PermanentError for unrecoverable 4xx errors
|
|
1475
|
-
* @throws TimeoutError when request times out
|
|
1476
|
+
* @throws TimeoutError when request times out
|
|
1476
1477
|
* @throws Error for transient errors (5xx, network)
|
|
1477
1478
|
* @private
|
|
1478
1479
|
*/
|
|
1479
1480
|
async sendWithTimeout(e, t) {
|
|
1480
|
-
const
|
|
1481
|
-
this.pendingControllers.add(
|
|
1481
|
+
const s = new AbortController();
|
|
1482
|
+
this.pendingControllers.add(s);
|
|
1482
1483
|
let n = !1;
|
|
1483
1484
|
const i = setTimeout(() => {
|
|
1484
|
-
n = !0,
|
|
1485
|
+
n = !0, s.abort();
|
|
1485
1486
|
}, 15e3);
|
|
1486
1487
|
try {
|
|
1487
1488
|
const o = this.getCustomHeaders(), l = await fetch(e, {
|
|
@@ -1489,19 +1490,19 @@ class Ze extends w {
|
|
|
1489
1490
|
body: t,
|
|
1490
1491
|
keepalive: !0,
|
|
1491
1492
|
credentials: this.fetchCredentials,
|
|
1492
|
-
signal:
|
|
1493
|
+
signal: s.signal,
|
|
1493
1494
|
headers: {
|
|
1494
1495
|
...o,
|
|
1495
1496
|
"Content-Type": "application/json"
|
|
1496
1497
|
}
|
|
1497
1498
|
});
|
|
1498
1499
|
if (!l.ok)
|
|
1499
|
-
throw l.status >= 400 && l.status < 500 && l.status !== 408 && l.status !== 429 ? new
|
|
1500
|
+
throw l.status >= 400 && l.status < 500 && l.status !== 408 && l.status !== 429 ? new O(`HTTP ${l.status}: ${l.statusText}`, l.status) : l.status === 429 ? new re(`HTTP 429: ${l.statusText}`) : new Error(`HTTP ${l.status}: ${l.statusText}`);
|
|
1500
1501
|
return l;
|
|
1501
1502
|
} catch (o) {
|
|
1502
|
-
throw o instanceof
|
|
1503
|
+
throw o instanceof O ? o : n ? new ne("Request timed out") : o;
|
|
1503
1504
|
} finally {
|
|
1504
|
-
clearTimeout(i), this.pendingControllers.delete(
|
|
1505
|
+
clearTimeout(i), this.pendingControllers.delete(s);
|
|
1505
1506
|
}
|
|
1506
1507
|
}
|
|
1507
1508
|
/**
|
|
@@ -1525,36 +1526,36 @@ class Ze extends w {
|
|
|
1525
1526
|
* @private
|
|
1526
1527
|
*/
|
|
1527
1528
|
sendQueueSyncInternal(e) {
|
|
1528
|
-
const t = this.
|
|
1529
|
-
if (!
|
|
1529
|
+
const t = this.ensureBatchMetadata(e), s = this.applyBeforeSendTransformer(t);
|
|
1530
|
+
if (!s)
|
|
1530
1531
|
return !0;
|
|
1531
|
-
const
|
|
1532
|
-
if (!
|
|
1532
|
+
const n = this.applyBeforeBatchTransformer(s);
|
|
1533
|
+
if (!n)
|
|
1533
1534
|
return !0;
|
|
1534
|
-
const { url:
|
|
1535
|
-
if (
|
|
1535
|
+
const i = this.ensureBatchMetadata(n, t._metadata?.idempotency_token), { url: o, payload: l } = this.prepareRequest(i);
|
|
1536
|
+
if (l.length > 65536)
|
|
1536
1537
|
return a(
|
|
1537
1538
|
"warn",
|
|
1538
1539
|
`Payload exceeds sendBeacon limit, persisting for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1539
1540
|
{
|
|
1540
1541
|
data: {
|
|
1541
|
-
size:
|
|
1542
|
+
size: l.length,
|
|
1542
1543
|
limit: 65536,
|
|
1543
|
-
events:
|
|
1544
|
+
events: i.events.length
|
|
1544
1545
|
}
|
|
1545
1546
|
}
|
|
1546
|
-
), this.persistEvents(
|
|
1547
|
-
const
|
|
1547
|
+
), this.persistEvents(t), !1;
|
|
1548
|
+
const c = new Blob([l], { type: "application/json" });
|
|
1548
1549
|
if (!this.isSendBeaconAvailable())
|
|
1549
1550
|
return a(
|
|
1550
1551
|
"warn",
|
|
1551
1552
|
`sendBeacon not available, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1552
|
-
), this.persistEvents(
|
|
1553
|
-
const
|
|
1554
|
-
return
|
|
1553
|
+
), this.persistEvents(t), !1;
|
|
1554
|
+
const d = navigator.sendBeacon(o, c);
|
|
1555
|
+
return d || (a(
|
|
1555
1556
|
"warn",
|
|
1556
1557
|
`sendBeacon rejected request, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1557
|
-
), this.persistEvents(
|
|
1558
|
+
), this.persistEvents(t)), d;
|
|
1558
1559
|
}
|
|
1559
1560
|
/**
|
|
1560
1561
|
* Prepares request by enriching payload with metadata and serializing to JSON.
|
|
@@ -1566,9 +1567,10 @@ class Ze extends w {
|
|
|
1566
1567
|
* - `timestamp`: Request generation time in milliseconds
|
|
1567
1568
|
*
|
|
1568
1569
|
* **Idempotency Token**:
|
|
1569
|
-
* -
|
|
1570
|
-
* -
|
|
1571
|
-
* -
|
|
1570
|
+
* - Set upstream by ensureBatchMetadata() before this method is called
|
|
1571
|
+
* - Fallback generateEventId() is defensive only (should not trigger in normal flow)
|
|
1572
|
+
* - Same token persists across all retry attempts of the same batch
|
|
1573
|
+
* - Backend uses this to deduplicate retries
|
|
1572
1574
|
*
|
|
1573
1575
|
* @param body - EventsQueue to send
|
|
1574
1576
|
* @returns Object with `url` (API endpoint) and `payload` (JSON string)
|
|
@@ -1577,17 +1579,29 @@ class Ze extends w {
|
|
|
1577
1579
|
prepareRequest(e) {
|
|
1578
1580
|
let t = Date.now();
|
|
1579
1581
|
t < this.lastMetadataTimestamp && (t = this.lastMetadataTimestamp), this.lastMetadataTimestamp = t;
|
|
1580
|
-
const
|
|
1582
|
+
const s = {
|
|
1581
1583
|
...e,
|
|
1582
1584
|
_metadata: {
|
|
1585
|
+
...e._metadata,
|
|
1586
|
+
idempotency_token: e._metadata?.idempotency_token ?? ye(),
|
|
1583
1587
|
referer: typeof window < "u" ? window.location.href : void 0,
|
|
1584
1588
|
timestamp: t,
|
|
1585
|
-
client_version:
|
|
1589
|
+
client_version: Zt
|
|
1586
1590
|
}
|
|
1587
1591
|
};
|
|
1588
1592
|
return {
|
|
1589
1593
|
url: this.apiUrl || "",
|
|
1590
|
-
payload: JSON.stringify(
|
|
1594
|
+
payload: JSON.stringify(s)
|
|
1595
|
+
};
|
|
1596
|
+
}
|
|
1597
|
+
ensureBatchMetadata(e, t) {
|
|
1598
|
+
const s = e._metadata?.idempotency_token ?? t ?? ye();
|
|
1599
|
+
return e._metadata?.idempotency_token === s ? e : {
|
|
1600
|
+
...e,
|
|
1601
|
+
_metadata: {
|
|
1602
|
+
...e._metadata,
|
|
1603
|
+
idempotency_token: s
|
|
1604
|
+
}
|
|
1591
1605
|
};
|
|
1592
1606
|
}
|
|
1593
1607
|
/**
|
|
@@ -1638,7 +1652,7 @@ class Ze extends w {
|
|
|
1638
1652
|
* @private
|
|
1639
1653
|
*/
|
|
1640
1654
|
createRecoveryBody(e) {
|
|
1641
|
-
const { timestamp: t, recoveryFailures:
|
|
1655
|
+
const { timestamp: t, recoveryFailures: s, ...n } = e;
|
|
1642
1656
|
return n;
|
|
1643
1657
|
}
|
|
1644
1658
|
/**
|
|
@@ -1675,10 +1689,10 @@ class Ze extends w {
|
|
|
1675
1689
|
* @returns `true` on successful persistence or throttled write, `false` on error
|
|
1676
1690
|
* @private
|
|
1677
1691
|
*/
|
|
1678
|
-
persistEventsWithFailureCount(e, t,
|
|
1692
|
+
persistEventsWithFailureCount(e, t, s = !1) {
|
|
1679
1693
|
try {
|
|
1680
1694
|
const n = this.getPersistedData();
|
|
1681
|
-
if (!
|
|
1695
|
+
if (!s && n && n.timestamp) {
|
|
1682
1696
|
const l = Date.now() - n.timestamp;
|
|
1683
1697
|
if (l < 1e3)
|
|
1684
1698
|
return a(
|
|
@@ -1720,13 +1734,13 @@ class Ze extends w {
|
|
|
1720
1734
|
return typeof navigator < "u" && typeof navigator.sendBeacon == "function";
|
|
1721
1735
|
}
|
|
1722
1736
|
logPermanentError(e, t) {
|
|
1723
|
-
const
|
|
1724
|
-
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode ||
|
|
1737
|
+
const s = Date.now();
|
|
1738
|
+
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode || s - this.lastPermanentErrorLog.timestamp >= Qt) && (a("error", `${e}${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1725
1739
|
data: { status: t.statusCode, message: t.message }
|
|
1726
|
-
}), this.lastPermanentErrorLog = { statusCode: t.statusCode, timestamp:
|
|
1740
|
+
}), this.lastPermanentErrorLog = { statusCode: t.statusCode, timestamp: s });
|
|
1727
1741
|
}
|
|
1728
1742
|
}
|
|
1729
|
-
class
|
|
1743
|
+
class Ss extends _ {
|
|
1730
1744
|
bootTime;
|
|
1731
1745
|
bootTimestamp;
|
|
1732
1746
|
hasPerformanceNow;
|
|
@@ -1818,13 +1832,13 @@ class Sr extends w {
|
|
|
1818
1832
|
if (e - this.lastClockSkewCheck < 5e3)
|
|
1819
1833
|
return this.detectedSkew;
|
|
1820
1834
|
this.lastClockSkewCheck = e;
|
|
1821
|
-
const t = this.now(),
|
|
1822
|
-
return this.detectedSkew =
|
|
1835
|
+
const t = this.now(), s = Date.now();
|
|
1836
|
+
return this.detectedSkew = s - t, Math.abs(this.detectedSkew) > 3e4 && a("warn", "Significant clock skew detected", {
|
|
1823
1837
|
data: {
|
|
1824
1838
|
skewMs: this.detectedSkew,
|
|
1825
1839
|
skewMinutes: (this.detectedSkew / 1e3 / 60).toFixed(2),
|
|
1826
1840
|
monotonicTime: new Date(t).toISOString(),
|
|
1827
|
-
systemTime: new Date(
|
|
1841
|
+
systemTime: new Date(s).toISOString()
|
|
1828
1842
|
}
|
|
1829
1843
|
}), this.detectedSkew;
|
|
1830
1844
|
}
|
|
@@ -1853,7 +1867,7 @@ class Sr extends w {
|
|
|
1853
1867
|
* ```
|
|
1854
1868
|
*/
|
|
1855
1869
|
validateTimestamp(e) {
|
|
1856
|
-
const
|
|
1870
|
+
const s = this.now(), n = e - s;
|
|
1857
1871
|
return n > 12e4 ? {
|
|
1858
1872
|
valid: !1,
|
|
1859
1873
|
error: `Timestamp is ${(n / 1e3 / 60).toFixed(2)} minutes in the future (max allowed: 2 minutes)`
|
|
@@ -1875,8 +1889,8 @@ class Sr extends w {
|
|
|
1875
1889
|
};
|
|
1876
1890
|
}
|
|
1877
1891
|
}
|
|
1878
|
-
const
|
|
1879
|
-
class
|
|
1892
|
+
const ps = new Set(Object.values(u));
|
|
1893
|
+
class Ts extends _ {
|
|
1880
1894
|
dataSenders;
|
|
1881
1895
|
emitter;
|
|
1882
1896
|
transformers;
|
|
@@ -1893,11 +1907,11 @@ class Tr extends w {
|
|
|
1893
1907
|
lastSessionId = null;
|
|
1894
1908
|
sessionEventCounts = {
|
|
1895
1909
|
total: 0,
|
|
1896
|
-
[
|
|
1897
|
-
[
|
|
1898
|
-
[
|
|
1899
|
-
[
|
|
1900
|
-
[
|
|
1910
|
+
[u.CLICK]: 0,
|
|
1911
|
+
[u.PAGE_VIEW]: 0,
|
|
1912
|
+
[u.CUSTOM]: 0,
|
|
1913
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
1914
|
+
[u.SCROLL]: 0
|
|
1901
1915
|
};
|
|
1902
1916
|
saveSessionCountsDebounced = null;
|
|
1903
1917
|
/**
|
|
@@ -1914,15 +1928,15 @@ class Tr extends w {
|
|
|
1914
1928
|
* @param customHeadersProvider - Optional callback for dynamic headers
|
|
1915
1929
|
* @param fetchCredentials - Fetch credentials mode for custom backend. @default 'include'
|
|
1916
1930
|
*/
|
|
1917
|
-
constructor(e, t = null,
|
|
1918
|
-
super(), this.emitter = t, this.transformers =
|
|
1931
|
+
constructor(e, t = null, s = {}, n = {}, i, o = "include") {
|
|
1932
|
+
super(), this.emitter = t, this.transformers = s, this.timeManager = new Ss(), this.dataSenders = [];
|
|
1919
1933
|
const l = this.get("collectApiUrls");
|
|
1920
|
-
l?.saas && this.dataSenders.push(new
|
|
1921
|
-
new
|
|
1934
|
+
l?.saas && this.dataSenders.push(new et(e, "saas", l.saas, s)), l?.custom && this.dataSenders.push(
|
|
1935
|
+
new et(
|
|
1922
1936
|
e,
|
|
1923
1937
|
"custom",
|
|
1924
1938
|
l.custom,
|
|
1925
|
-
|
|
1939
|
+
s,
|
|
1926
1940
|
n,
|
|
1927
1941
|
i,
|
|
1928
1942
|
o
|
|
@@ -1958,7 +1972,7 @@ class Tr extends w {
|
|
|
1958
1972
|
async recoverPersistedEvents() {
|
|
1959
1973
|
const e = this.dataSenders.map(
|
|
1960
1974
|
async (t) => t.recoverPersistedEvents({
|
|
1961
|
-
onSuccess: (
|
|
1975
|
+
onSuccess: (s, n, i) => {
|
|
1962
1976
|
if (n && n.length > 0) {
|
|
1963
1977
|
const o = n.map((l) => l.id);
|
|
1964
1978
|
this.removeProcessedEvents(o), i && this.emitEventsQueue(i);
|
|
@@ -2033,47 +2047,47 @@ class Tr extends w {
|
|
|
2033
2047
|
track({
|
|
2034
2048
|
type: e,
|
|
2035
2049
|
page_url: t,
|
|
2036
|
-
from_page_url:
|
|
2050
|
+
from_page_url: s,
|
|
2037
2051
|
scroll_data: n,
|
|
2038
2052
|
click_data: i,
|
|
2039
2053
|
custom_event: o,
|
|
2040
2054
|
web_vitals: l,
|
|
2041
2055
|
error_data: c,
|
|
2042
|
-
viewport_data:
|
|
2043
|
-
page_view:
|
|
2056
|
+
viewport_data: d,
|
|
2057
|
+
page_view: f
|
|
2044
2058
|
}) {
|
|
2045
2059
|
if (!e) {
|
|
2046
2060
|
a("error", "Event type is required - event will be ignored");
|
|
2047
2061
|
return;
|
|
2048
2062
|
}
|
|
2049
|
-
if (!
|
|
2063
|
+
if (!ps.has(e)) {
|
|
2050
2064
|
a("error", "Invalid event type - event will be ignored", {
|
|
2051
2065
|
data: { type: e }
|
|
2052
2066
|
});
|
|
2053
2067
|
return;
|
|
2054
2068
|
}
|
|
2055
|
-
const
|
|
2056
|
-
if (!
|
|
2069
|
+
const g = this.get("sessionId");
|
|
2070
|
+
if (!g) {
|
|
2057
2071
|
this.pendingEventsBuffer.length >= 100 && (this.pendingEventsBuffer.shift(), a("debug", "Pending events buffer full - dropping oldest event", {
|
|
2058
2072
|
data: { maxBufferSize: 100 }
|
|
2059
2073
|
})), this.pendingEventsBuffer.push({
|
|
2060
2074
|
type: e,
|
|
2061
2075
|
page_url: t,
|
|
2062
|
-
from_page_url:
|
|
2076
|
+
from_page_url: s,
|
|
2063
2077
|
scroll_data: n,
|
|
2064
2078
|
click_data: i,
|
|
2065
2079
|
custom_event: o,
|
|
2066
2080
|
web_vitals: l,
|
|
2067
2081
|
error_data: c,
|
|
2068
|
-
viewport_data:
|
|
2069
|
-
page_view:
|
|
2082
|
+
viewport_data: d,
|
|
2083
|
+
page_view: f
|
|
2070
2084
|
});
|
|
2071
2085
|
return;
|
|
2072
2086
|
}
|
|
2073
|
-
this.lastSessionId !==
|
|
2074
|
-
const T = e ===
|
|
2087
|
+
this.lastSessionId !== g && (this.lastSessionId = g, this.sessionEventCounts = this.loadSessionCounts(g));
|
|
2088
|
+
const T = e === u.SESSION_START;
|
|
2075
2089
|
if (T && a("debug", "Processing SESSION_START event", {
|
|
2076
|
-
data: { sessionId:
|
|
2090
|
+
data: { sessionId: g }
|
|
2077
2091
|
}), !T && !this.checkRateLimit())
|
|
2078
2092
|
return;
|
|
2079
2093
|
const S = e;
|
|
@@ -2090,12 +2104,12 @@ class Tr extends w {
|
|
|
2090
2104
|
}
|
|
2091
2105
|
const v = this.getTypeLimitForEvent(S);
|
|
2092
2106
|
if (v) {
|
|
2093
|
-
const
|
|
2094
|
-
if (
|
|
2107
|
+
const he = this.sessionEventCounts[S];
|
|
2108
|
+
if (he !== void 0 && he >= v) {
|
|
2095
2109
|
a("warn", "Session event type limit reached", {
|
|
2096
2110
|
data: {
|
|
2097
2111
|
type: S,
|
|
2098
|
-
count:
|
|
2112
|
+
count: he,
|
|
2099
2113
|
limit: v
|
|
2100
2114
|
}
|
|
2101
2115
|
});
|
|
@@ -2103,25 +2117,25 @@ class Tr extends w {
|
|
|
2103
2117
|
}
|
|
2104
2118
|
}
|
|
2105
2119
|
}
|
|
2106
|
-
if (S ===
|
|
2120
|
+
if (S === u.CUSTOM && o?.name) {
|
|
2107
2121
|
const v = this.get("config")?.maxSameEventPerMinute ?? 60;
|
|
2108
2122
|
if (!this.checkPerEventRateLimit(o.name, v))
|
|
2109
2123
|
return;
|
|
2110
2124
|
}
|
|
2111
|
-
const
|
|
2125
|
+
const Ue = S === u.SESSION_START, K = t || this.get("pageUrl"), x = this.buildEventPayload({
|
|
2112
2126
|
type: S,
|
|
2113
|
-
page_url:
|
|
2114
|
-
from_page_url:
|
|
2127
|
+
page_url: K,
|
|
2128
|
+
from_page_url: s,
|
|
2115
2129
|
scroll_data: n,
|
|
2116
2130
|
click_data: i,
|
|
2117
2131
|
custom_event: o,
|
|
2118
2132
|
web_vitals: l,
|
|
2119
2133
|
error_data: c,
|
|
2120
|
-
viewport_data:
|
|
2121
|
-
page_view:
|
|
2134
|
+
viewport_data: d,
|
|
2135
|
+
page_view: f
|
|
2122
2136
|
});
|
|
2123
|
-
if (
|
|
2124
|
-
if (
|
|
2137
|
+
if (x && !(!T && !this.shouldSample())) {
|
|
2138
|
+
if (Ue) {
|
|
2125
2139
|
const v = this.get("sessionId");
|
|
2126
2140
|
if (!v) {
|
|
2127
2141
|
a("error", "Session start event requires sessionId - event will be ignored");
|
|
@@ -2135,34 +2149,34 @@ class Tr extends w {
|
|
|
2135
2149
|
}
|
|
2136
2150
|
this.set("hasStartSession", !0);
|
|
2137
2151
|
}
|
|
2138
|
-
if (!this.isDuplicateEvent(
|
|
2139
|
-
if (this.get("mode") ===
|
|
2140
|
-
if (S ===
|
|
2152
|
+
if (!this.isDuplicateEvent(x)) {
|
|
2153
|
+
if (this.get("mode") === ie.QA) {
|
|
2154
|
+
if (S === u.CUSTOM && o) {
|
|
2141
2155
|
a("info", `Custom Event: ${o.name}`, {
|
|
2142
2156
|
visibility: "qa",
|
|
2143
2157
|
data: {
|
|
2144
2158
|
name: o.name,
|
|
2145
2159
|
...o.metadata && { metadata: o.metadata }
|
|
2146
2160
|
}
|
|
2147
|
-
}), this.emitEvent(
|
|
2161
|
+
}), this.emitEvent(x);
|
|
2148
2162
|
return;
|
|
2149
2163
|
}
|
|
2150
|
-
if (S ===
|
|
2151
|
-
const v =
|
|
2164
|
+
if (S === u.VIEWPORT_VISIBLE && d) {
|
|
2165
|
+
const v = d.name || d.id || d.selector;
|
|
2152
2166
|
a("info", `Viewport Visible: ${v}`, {
|
|
2153
2167
|
visibility: "qa",
|
|
2154
2168
|
data: {
|
|
2155
|
-
selector:
|
|
2156
|
-
...
|
|
2157
|
-
...
|
|
2158
|
-
visibilityRatio:
|
|
2159
|
-
dwellTime:
|
|
2169
|
+
selector: d.selector,
|
|
2170
|
+
...d.name && { name: d.name },
|
|
2171
|
+
...d.id && { id: d.id },
|
|
2172
|
+
visibilityRatio: d.visibilityRatio,
|
|
2173
|
+
dwellTime: d.dwellTime
|
|
2160
2174
|
}
|
|
2161
|
-
}), this.emitEvent(
|
|
2175
|
+
}), this.emitEvent(x);
|
|
2162
2176
|
return;
|
|
2163
2177
|
}
|
|
2164
2178
|
}
|
|
2165
|
-
if (this.addToQueue(
|
|
2179
|
+
if (this.addToQueue(x), !T) {
|
|
2166
2180
|
this.sessionEventCounts.total++, this.sessionEventCounts[S] !== void 0 && this.sessionEventCounts[S]++;
|
|
2167
2181
|
const v = this.get("sessionId");
|
|
2168
2182
|
v && this.saveSessionCountsDebounced && this.saveSessionCountsDebounced(v);
|
|
@@ -2209,11 +2223,11 @@ class Tr extends w {
|
|
|
2209
2223
|
const e = this.get("sessionId");
|
|
2210
2224
|
e && this.saveSessionCounts(e), this.eventsQueue = [], this.pendingEventsBuffer = [], this.recentEventFingerprints.clear(), this.rateLimitCounter = 0, this.rateLimitWindowStart = 0, this.perEventRateLimits.clear(), this.sessionEventCounts = {
|
|
2211
2225
|
total: 0,
|
|
2212
|
-
[
|
|
2213
|
-
[
|
|
2214
|
-
[
|
|
2215
|
-
[
|
|
2216
|
-
[
|
|
2226
|
+
[u.CLICK]: 0,
|
|
2227
|
+
[u.PAGE_VIEW]: 0,
|
|
2228
|
+
[u.CUSTOM]: 0,
|
|
2229
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
2230
|
+
[u.SCROLL]: 0
|
|
2217
2231
|
}, this.lastSessionId = null, this.set("hasStartSession", !1), this.dataSenders.forEach((t) => {
|
|
2218
2232
|
t.stop();
|
|
2219
2233
|
});
|
|
@@ -2414,8 +2428,8 @@ class Tr extends w {
|
|
|
2414
2428
|
return;
|
|
2415
2429
|
}
|
|
2416
2430
|
const t = [...this.pendingEventsBuffer];
|
|
2417
|
-
this.pendingEventsBuffer = [], t.forEach((
|
|
2418
|
-
this.track(
|
|
2431
|
+
this.pendingEventsBuffer = [], t.forEach((s) => {
|
|
2432
|
+
this.track(s);
|
|
2419
2433
|
});
|
|
2420
2434
|
}
|
|
2421
2435
|
clearSendTimeout() {
|
|
@@ -2429,7 +2443,7 @@ class Tr extends w {
|
|
|
2429
2443
|
return e ? !0 : Promise.resolve(!0);
|
|
2430
2444
|
if (!e && this.sendInProgress)
|
|
2431
2445
|
return a("debug", "Async flush skipped: send already in progress"), Promise.resolve(!1);
|
|
2432
|
-
const t = this.buildEventsPayload(),
|
|
2446
|
+
const t = this.buildEventsPayload(), s = [...this.eventsQueue], n = s.map((i) => i.id);
|
|
2433
2447
|
if (this.dataSenders.length === 0)
|
|
2434
2448
|
return this.removeProcessedEvents(n), this.clearSendTimeout(), this.emitEventsQueue(t), e ? !0 : Promise.resolve(!0);
|
|
2435
2449
|
if (e) {
|
|
@@ -2449,7 +2463,7 @@ class Tr extends w {
|
|
|
2449
2463
|
return Promise.allSettled(i).then((o) => {
|
|
2450
2464
|
const l = o.some((c) => this.isSuccessfulResult(c));
|
|
2451
2465
|
return l ? (this.removeProcessedEvents(n), this.clearSendTimeout(), this.emitEventsQueue(t)) : a("debug", "Async flush complete failure, events kept in queue for retry", {
|
|
2452
|
-
data: { eventCount:
|
|
2466
|
+
data: { eventCount: s.length }
|
|
2453
2467
|
}), l;
|
|
2454
2468
|
});
|
|
2455
2469
|
}
|
|
@@ -2463,7 +2477,7 @@ class Tr extends w {
|
|
|
2463
2477
|
this.emitEventsQueue(e);
|
|
2464
2478
|
return;
|
|
2465
2479
|
}
|
|
2466
|
-
const t = [...this.eventsQueue],
|
|
2480
|
+
const t = [...this.eventsQueue], s = t.map((l) => l.id), n = this.dataSenders.map(
|
|
2467
2481
|
async (l) => l.sendEventsQueue(e, {
|
|
2468
2482
|
onSuccess: () => {
|
|
2469
2483
|
},
|
|
@@ -2472,7 +2486,7 @@ class Tr extends w {
|
|
|
2472
2486
|
})
|
|
2473
2487
|
), i = await Promise.allSettled(n);
|
|
2474
2488
|
if (i.some((l) => this.isSuccessfulResult(l))) {
|
|
2475
|
-
this.consecutiveSendFailures = 0, this.removeProcessedEvents(
|
|
2489
|
+
this.consecutiveSendFailures = 0, this.removeProcessedEvents(s), this.emitEventsQueue(e);
|
|
2476
2490
|
const l = i.filter((c) => !this.isSuccessfulResult(c)).length;
|
|
2477
2491
|
l > 0 && a("debug", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
|
|
2478
2492
|
data: { eventCount: t.length, failedCount: l }
|
|
@@ -2490,36 +2504,36 @@ class Tr extends w {
|
|
|
2490
2504
|
buildEventsPayload() {
|
|
2491
2505
|
const e = /* @__PURE__ */ new Map(), t = [];
|
|
2492
2506
|
for (const c of this.eventsQueue) {
|
|
2493
|
-
const
|
|
2494
|
-
e.has(
|
|
2507
|
+
const d = this.createEventSignature(c);
|
|
2508
|
+
e.has(d) || t.push(d), e.set(d, c);
|
|
2495
2509
|
}
|
|
2496
|
-
const
|
|
2510
|
+
const s = t.map((c) => e.get(c)).filter((c) => !!c).sort((c, d) => c.type === u.SESSION_START && d.type !== u.SESSION_START ? -1 : d.type === u.SESSION_START && c.type !== u.SESSION_START ? 1 : c.timestamp - d.timestamp);
|
|
2497
2511
|
let n = {
|
|
2498
2512
|
user_id: this.get("userId"),
|
|
2499
2513
|
session_id: this.get("sessionId"),
|
|
2500
2514
|
device: this.get("device"),
|
|
2501
|
-
events:
|
|
2515
|
+
events: s,
|
|
2502
2516
|
...this.get("config")?.globalMetadata && { global_metadata: this.get("config")?.globalMetadata },
|
|
2503
2517
|
...this.get("identity") && { identify: this.get("identity") }
|
|
2504
2518
|
};
|
|
2505
2519
|
const i = this.get("collectApiUrls"), o = !!(i?.custom || i?.saas), l = this.transformers.beforeBatch;
|
|
2506
2520
|
if (!o && l) {
|
|
2507
|
-
const c =
|
|
2521
|
+
const c = Et(n, l, "EventManager");
|
|
2508
2522
|
c !== null && (n = c);
|
|
2509
2523
|
}
|
|
2510
2524
|
return n;
|
|
2511
2525
|
}
|
|
2512
2526
|
buildEventPayload(e) {
|
|
2513
|
-
const t = e.page_url ?? this.get("pageUrl"),
|
|
2527
|
+
const t = e.page_url ?? this.get("pageUrl"), s = this.timeManager.now(), n = this.timeManager.validateTimestamp(s);
|
|
2514
2528
|
n.valid || a("warn", "Event timestamp validation failed", {
|
|
2515
2529
|
data: { type: e.type, error: n.error }
|
|
2516
2530
|
});
|
|
2517
2531
|
const i = this.get("sessionReferrer"), o = this.get("sessionUtm");
|
|
2518
2532
|
let l = {
|
|
2519
|
-
id:
|
|
2533
|
+
id: ye(),
|
|
2520
2534
|
type: e.type,
|
|
2521
2535
|
page_url: t,
|
|
2522
|
-
timestamp:
|
|
2536
|
+
timestamp: s,
|
|
2523
2537
|
...i && { referrer: i },
|
|
2524
2538
|
...e.from_page_url && { from_page_url: e.from_page_url },
|
|
2525
2539
|
...e.scroll_data && { scroll_data: e.scroll_data },
|
|
@@ -2531,25 +2545,25 @@ class Tr extends w {
|
|
|
2531
2545
|
...e.page_view && { page_view: e.page_view },
|
|
2532
2546
|
...o && { utm: o }
|
|
2533
2547
|
};
|
|
2534
|
-
const c = this.get("collectApiUrls"),
|
|
2535
|
-
if (S && (!
|
|
2536
|
-
const
|
|
2537
|
-
if (
|
|
2548
|
+
const c = this.get("collectApiUrls"), d = !!c?.custom, f = !!c?.saas, g = d || f, T = d && f, S = this.transformers.beforeSend;
|
|
2549
|
+
if (S && (!g || d && !T)) {
|
|
2550
|
+
const K = gt(l, S, "EventManager");
|
|
2551
|
+
if (K === null)
|
|
2538
2552
|
return null;
|
|
2539
|
-
l =
|
|
2553
|
+
l = K;
|
|
2540
2554
|
}
|
|
2541
2555
|
return l;
|
|
2542
2556
|
}
|
|
2543
2557
|
isDuplicateEvent(e) {
|
|
2544
|
-
const t = Date.now(),
|
|
2545
|
-
return n && t - n < 1e3 ? (this.recentEventFingerprints.set(
|
|
2558
|
+
const t = Date.now(), s = this.createEventFingerprint(e), n = this.recentEventFingerprints.get(s);
|
|
2559
|
+
return n && t - n < 1e3 ? (this.recentEventFingerprints.set(s, t), !0) : (this.recentEventFingerprints.set(s, t), this.recentEventFingerprints.size > 1500 && this.pruneOldFingerprints(), this.recentEventFingerprints.size > 3e3 && (this.recentEventFingerprints.clear(), this.recentEventFingerprints.set(s, t), a("debug", "Event fingerprint cache exceeded hard limit, cleared", {
|
|
2546
2560
|
data: { hardLimit: 3e3 }
|
|
2547
2561
|
})), !1);
|
|
2548
2562
|
}
|
|
2549
2563
|
pruneOldFingerprints() {
|
|
2550
2564
|
const e = Date.now(), t = 1e3 * 10;
|
|
2551
|
-
for (const [
|
|
2552
|
-
e - n > t && this.recentEventFingerprints.delete(
|
|
2565
|
+
for (const [s, n] of this.recentEventFingerprints.entries())
|
|
2566
|
+
e - n > t && this.recentEventFingerprints.delete(s);
|
|
2553
2567
|
a("debug", "Pruned old event fingerprints", {
|
|
2554
2568
|
data: {
|
|
2555
2569
|
remaining: this.recentEventFingerprints.size,
|
|
@@ -2560,8 +2574,8 @@ class Tr extends w {
|
|
|
2560
2574
|
createEventFingerprint(e) {
|
|
2561
2575
|
let t = `${e.type}_${e.page_url}`;
|
|
2562
2576
|
if (e.click_data) {
|
|
2563
|
-
const
|
|
2564
|
-
t += `_click_${
|
|
2577
|
+
const s = Math.round((e.click_data.x || 0) / 10) * 10, n = Math.round((e.click_data.y || 0) / 10) * 10;
|
|
2578
|
+
t += `_click_${s}_${n}`;
|
|
2565
2579
|
}
|
|
2566
2580
|
return e.scroll_data && (t += `_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`), e.custom_event && (t += `_custom_${e.custom_event.name}`, e.custom_event.metadata && (t += `_${this.stableStringify(e.custom_event.metadata)}`)), e.web_vitals && (t += `_vitals_${e.web_vitals.type}`), e.error_data && (t += `_error_${e.error_data.type}_${e.error_data.message}`), t;
|
|
2567
2581
|
}
|
|
@@ -2570,17 +2584,17 @@ class Tr extends w {
|
|
|
2570
2584
|
}
|
|
2571
2585
|
/** Deterministic JSON string with sorted keys to ensure consistent fingerprints regardless of property insertion order */
|
|
2572
2586
|
stableStringify(e) {
|
|
2573
|
-
return JSON.stringify(e, (t,
|
|
2587
|
+
return JSON.stringify(e, (t, s) => s && typeof s == "object" && !Array.isArray(s) ? Object.keys(s).sort().reduce((n, i) => (n[i] = s[i], n), {}) : s);
|
|
2574
2588
|
}
|
|
2575
2589
|
addToQueue(e) {
|
|
2576
2590
|
if (this.emitEvent(e), this.eventsQueue.push(e), this.eventsQueue.length > 100) {
|
|
2577
|
-
const t = this.eventsQueue.findIndex((n) => n.type !==
|
|
2591
|
+
const t = this.eventsQueue.findIndex((n) => n.type !== u.SESSION_START), s = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
|
|
2578
2592
|
a("warn", "Event queue overflow, oldest non-critical event removed", {
|
|
2579
2593
|
data: {
|
|
2580
2594
|
maxLength: 100,
|
|
2581
2595
|
currentLength: this.eventsQueue.length,
|
|
2582
|
-
removedEventType:
|
|
2583
|
-
wasCritical:
|
|
2596
|
+
removedEventType: s?.type,
|
|
2597
|
+
wasCritical: s?.type === u.SESSION_START
|
|
2584
2598
|
}
|
|
2585
2599
|
});
|
|
2586
2600
|
}
|
|
@@ -2608,33 +2622,33 @@ class Tr extends w {
|
|
|
2608
2622
|
return e - this.rateLimitWindowStart > 1e3 && (this.rateLimitCounter = 0, this.rateLimitWindowStart = e), this.rateLimitCounter >= 50 ? !1 : (this.rateLimitCounter++, !0);
|
|
2609
2623
|
}
|
|
2610
2624
|
checkPerEventRateLimit(e, t) {
|
|
2611
|
-
const
|
|
2625
|
+
const s = Date.now(), i = (this.perEventRateLimits.get(e) ?? []).filter((o) => s - o < 6e4);
|
|
2612
2626
|
return i.length >= t ? (a("warn", "Per-event rate limit exceeded for custom event", {
|
|
2613
2627
|
data: {
|
|
2614
2628
|
eventName: e,
|
|
2615
2629
|
limit: t,
|
|
2616
2630
|
window: `${6e4 / 1e3}s`
|
|
2617
2631
|
}
|
|
2618
|
-
}), !1) : (i.push(
|
|
2632
|
+
}), !1) : (i.push(s), this.perEventRateLimits.set(e, i), !0);
|
|
2619
2633
|
}
|
|
2620
2634
|
getTypeLimitForEvent(e) {
|
|
2621
2635
|
return {
|
|
2622
|
-
[
|
|
2623
|
-
[
|
|
2624
|
-
[
|
|
2625
|
-
[
|
|
2626
|
-
[
|
|
2636
|
+
[u.CLICK]: 500,
|
|
2637
|
+
[u.PAGE_VIEW]: 100,
|
|
2638
|
+
[u.CUSTOM]: 500,
|
|
2639
|
+
[u.VIEWPORT_VISIBLE]: 200,
|
|
2640
|
+
[u.SCROLL]: 120
|
|
2627
2641
|
}[e] ?? null;
|
|
2628
2642
|
}
|
|
2629
2643
|
removeProcessedEvents(e) {
|
|
2630
2644
|
const t = new Set(e);
|
|
2631
|
-
this.eventsQueue = this.eventsQueue.filter((
|
|
2645
|
+
this.eventsQueue = this.eventsQueue.filter((s) => !t.has(s.id));
|
|
2632
2646
|
}
|
|
2633
2647
|
emitEvent(e) {
|
|
2634
|
-
this.emitter && this.emitter.emit(
|
|
2648
|
+
this.emitter && this.emitter.emit(se.EVENT, e);
|
|
2635
2649
|
}
|
|
2636
2650
|
emitEventsQueue(e) {
|
|
2637
|
-
this.emitter && this.emitter.emit(
|
|
2651
|
+
this.emitter && this.emitter.emit(se.QUEUE, e);
|
|
2638
2652
|
}
|
|
2639
2653
|
/**
|
|
2640
2654
|
* Creates a debounced version of a function that delays execution until after
|
|
@@ -2657,10 +2671,10 @@ class Tr extends w {
|
|
|
2657
2671
|
* @internal
|
|
2658
2672
|
*/
|
|
2659
2673
|
debounce(e, t) {
|
|
2660
|
-
let
|
|
2674
|
+
let s = null;
|
|
2661
2675
|
return ((...n) => {
|
|
2662
|
-
|
|
2663
|
-
e(...n),
|
|
2676
|
+
s !== null && clearTimeout(s), s = setTimeout(() => {
|
|
2677
|
+
e(...n), s = null;
|
|
2664
2678
|
}, t);
|
|
2665
2679
|
});
|
|
2666
2680
|
}
|
|
@@ -2677,11 +2691,11 @@ class Tr extends w {
|
|
|
2677
2691
|
getInitialCounts() {
|
|
2678
2692
|
return {
|
|
2679
2693
|
total: 0,
|
|
2680
|
-
[
|
|
2681
|
-
[
|
|
2682
|
-
[
|
|
2683
|
-
[
|
|
2684
|
-
[
|
|
2694
|
+
[u.CLICK]: 0,
|
|
2695
|
+
[u.PAGE_VIEW]: 0,
|
|
2696
|
+
[u.CUSTOM]: 0,
|
|
2697
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
2698
|
+
[u.SCROLL]: 0
|
|
2685
2699
|
};
|
|
2686
2700
|
}
|
|
2687
2701
|
/**
|
|
@@ -2710,24 +2724,24 @@ class Tr extends w {
|
|
|
2710
2724
|
loadSessionCounts(e) {
|
|
2711
2725
|
if (typeof window > "u" || typeof localStorage > "u")
|
|
2712
2726
|
return this.getInitialCounts();
|
|
2713
|
-
const t = this.get("userId") || "anonymous",
|
|
2727
|
+
const t = this.get("userId") || "anonymous", s = xe(t, e);
|
|
2714
2728
|
try {
|
|
2715
|
-
const n = localStorage.getItem(
|
|
2729
|
+
const n = localStorage.getItem(s);
|
|
2716
2730
|
if (!n)
|
|
2717
2731
|
return this.getInitialCounts();
|
|
2718
2732
|
const i = JSON.parse(n);
|
|
2719
|
-
return i._timestamp && Date.now() - i._timestamp >
|
|
2733
|
+
return i._timestamp && Date.now() - i._timestamp > $e ? (a("debug", "Session counts expired, clearing", {
|
|
2720
2734
|
data: { sessionId: e, age: Date.now() - i._timestamp }
|
|
2721
|
-
}), localStorage.removeItem(
|
|
2735
|
+
}), localStorage.removeItem(s), this.getInitialCounts()) : typeof i.total == "number" && typeof i[u.CLICK] == "number" && typeof i[u.PAGE_VIEW] == "number" && typeof i[u.CUSTOM] == "number" && typeof i[u.VIEWPORT_VISIBLE] == "number" && typeof i[u.SCROLL] == "number" ? {
|
|
2722
2736
|
total: i.total,
|
|
2723
|
-
[
|
|
2724
|
-
[
|
|
2725
|
-
[
|
|
2726
|
-
[
|
|
2727
|
-
[
|
|
2737
|
+
[u.CLICK]: i[u.CLICK],
|
|
2738
|
+
[u.PAGE_VIEW]: i[u.PAGE_VIEW],
|
|
2739
|
+
[u.CUSTOM]: i[u.CUSTOM],
|
|
2740
|
+
[u.VIEWPORT_VISIBLE]: i[u.VIEWPORT_VISIBLE],
|
|
2741
|
+
[u.SCROLL]: i[u.SCROLL]
|
|
2728
2742
|
} : (a("warn", "Invalid session counts structure in localStorage, resetting", {
|
|
2729
2743
|
data: { sessionId: e, parsed: i }
|
|
2730
|
-
}), localStorage.removeItem(
|
|
2744
|
+
}), localStorage.removeItem(s), a("debug", "Session counts removed due to invalid/corrupted data", {
|
|
2731
2745
|
data: { sessionId: e, parsed: i }
|
|
2732
2746
|
}), this.getInitialCounts());
|
|
2733
2747
|
} catch (n) {
|
|
@@ -2761,32 +2775,32 @@ class Tr extends w {
|
|
|
2761
2775
|
cleanupExpiredSessionCounts() {
|
|
2762
2776
|
if (!(typeof window > "u" || typeof localStorage > "u"))
|
|
2763
2777
|
try {
|
|
2764
|
-
const e = localStorage.getItem(
|
|
2778
|
+
const e = localStorage.getItem(Be);
|
|
2765
2779
|
if (e) {
|
|
2766
2780
|
const i = Date.now() - parseInt(e, 10);
|
|
2767
|
-
if (i <
|
|
2781
|
+
if (i < We) {
|
|
2768
2782
|
a("debug", "Skipping session counts cleanup (throttled)", {
|
|
2769
|
-
data: { timeSinceLastCleanup: i, throttleMs:
|
|
2783
|
+
data: { timeSinceLastCleanup: i, throttleMs: We }
|
|
2770
2784
|
});
|
|
2771
2785
|
return;
|
|
2772
2786
|
}
|
|
2773
2787
|
}
|
|
2774
|
-
const t = this.get("userId") || "anonymous",
|
|
2788
|
+
const t = this.get("userId") || "anonymous", s = `${I}:${t}:session_counts:`, n = [];
|
|
2775
2789
|
for (let i = 0; i < localStorage.length; i++) {
|
|
2776
2790
|
const o = localStorage.key(i);
|
|
2777
|
-
if (o?.startsWith(
|
|
2791
|
+
if (o?.startsWith(s))
|
|
2778
2792
|
try {
|
|
2779
2793
|
const l = localStorage.getItem(o);
|
|
2780
2794
|
if (l) {
|
|
2781
2795
|
const c = JSON.parse(l);
|
|
2782
|
-
c._timestamp && Date.now() - c._timestamp >
|
|
2796
|
+
c._timestamp && Date.now() - c._timestamp > $e && n.push(o);
|
|
2783
2797
|
}
|
|
2784
2798
|
} catch {
|
|
2785
2799
|
}
|
|
2786
2800
|
}
|
|
2787
2801
|
n.forEach((i) => {
|
|
2788
2802
|
localStorage.removeItem(i), a("debug", "Cleaned up expired session counts", { data: { key: i } });
|
|
2789
|
-
}), n.length > 0 && a("info", `Cleaned up ${n.length} expired session counts entries`), localStorage.setItem(
|
|
2803
|
+
}), n.length > 0 && a("info", `Cleaned up ${n.length} expired session counts entries`), localStorage.setItem(Be, Date.now().toString());
|
|
2790
2804
|
} catch (e) {
|
|
2791
2805
|
a("warn", "Failed to cleanup expired session counts", { error: e });
|
|
2792
2806
|
}
|
|
@@ -2820,14 +2834,14 @@ class Tr extends w {
|
|
|
2820
2834
|
* @internal
|
|
2821
2835
|
*/
|
|
2822
2836
|
saveSessionCounts(e) {
|
|
2823
|
-
const t = this.get("userId") || "anonymous",
|
|
2837
|
+
const t = this.get("userId") || "anonymous", s = xe(t, e);
|
|
2824
2838
|
try {
|
|
2825
2839
|
const n = {
|
|
2826
2840
|
...this.sessionEventCounts,
|
|
2827
2841
|
_timestamp: Date.now(),
|
|
2828
2842
|
_version: 1
|
|
2829
2843
|
};
|
|
2830
|
-
localStorage.setItem(
|
|
2844
|
+
localStorage.setItem(s, JSON.stringify(n));
|
|
2831
2845
|
} catch (n) {
|
|
2832
2846
|
a("warn", "Failed to persist session counts to localStorage", {
|
|
2833
2847
|
error: n,
|
|
@@ -2836,7 +2850,7 @@ class Tr extends w {
|
|
|
2836
2850
|
}
|
|
2837
2851
|
}
|
|
2838
2852
|
}
|
|
2839
|
-
class
|
|
2853
|
+
class Is {
|
|
2840
2854
|
/**
|
|
2841
2855
|
* Gets or creates a unique user ID.
|
|
2842
2856
|
*
|
|
@@ -2854,15 +2868,15 @@ class Ir {
|
|
|
2854
2868
|
* @returns Persistent unique user ID (UUID v4 format)
|
|
2855
2869
|
*/
|
|
2856
2870
|
static getId(e) {
|
|
2857
|
-
const t = e.getItem(
|
|
2871
|
+
const t = e.getItem(Te);
|
|
2858
2872
|
if (t)
|
|
2859
2873
|
return t;
|
|
2860
|
-
const
|
|
2861
|
-
return e.setItem(
|
|
2874
|
+
const s = ut();
|
|
2875
|
+
return e.setItem(Te, s), s;
|
|
2862
2876
|
}
|
|
2863
2877
|
}
|
|
2864
|
-
const
|
|
2865
|
-
class
|
|
2878
|
+
const vs = /^\d{13}-[a-z0-9]{9}$/;
|
|
2879
|
+
class _s extends _ {
|
|
2866
2880
|
storageManager;
|
|
2867
2881
|
eventManager;
|
|
2868
2882
|
projectId;
|
|
@@ -2879,8 +2893,8 @@ class _r extends w {
|
|
|
2879
2893
|
* @param eventManager - Event manager for SESSION_START events
|
|
2880
2894
|
* @param projectId - Project identifier for namespacing session storage
|
|
2881
2895
|
*/
|
|
2882
|
-
constructor(e, t,
|
|
2883
|
-
super(), this.storageManager = e, this.eventManager = t, this.projectId =
|
|
2896
|
+
constructor(e, t, s) {
|
|
2897
|
+
super(), this.storageManager = e, this.eventManager = t, this.projectId = s;
|
|
2884
2898
|
}
|
|
2885
2899
|
initCrossTabSync() {
|
|
2886
2900
|
if (typeof BroadcastChannel > "u") {
|
|
@@ -2888,9 +2902,9 @@ class _r extends w {
|
|
|
2888
2902
|
return;
|
|
2889
2903
|
}
|
|
2890
2904
|
const e = this.getProjectId();
|
|
2891
|
-
this.broadcastChannel = new BroadcastChannel(
|
|
2892
|
-
const { action:
|
|
2893
|
-
o === e && (
|
|
2905
|
+
this.broadcastChannel = new BroadcastChannel(Ot(e)), this.broadcastChannel.onmessage = (t) => {
|
|
2906
|
+
const { action: s, sessionId: n, timestamp: i, projectId: o } = t.data ?? {};
|
|
2907
|
+
o === e && (s === "session_start" && n && typeof i == "number" && i > Date.now() - 5e3 ? (this.set("sessionId", n), this.persistSession(n, i), this.isTracking && this.setupSessionTimeout()) : s && s !== "session_start" && a("debug", "Ignored BroadcastChannel message with unknown action", { data: { action: s } }));
|
|
2894
2908
|
};
|
|
2895
2909
|
}
|
|
2896
2910
|
shareSession(e) {
|
|
@@ -2908,18 +2922,18 @@ class _r extends w {
|
|
|
2908
2922
|
const e = this.loadStoredSession();
|
|
2909
2923
|
if (!e)
|
|
2910
2924
|
return null;
|
|
2911
|
-
if (!
|
|
2925
|
+
if (!vs.test(e.id))
|
|
2912
2926
|
return a("warn", "Invalid session ID format recovered from storage, clearing", {
|
|
2913
2927
|
data: { sessionId: e.id }
|
|
2914
2928
|
}), this.clearStoredSession(), null;
|
|
2915
2929
|
const t = this.get("config")?.sessionTimeout ?? 9e5;
|
|
2916
2930
|
return Date.now() - e.lastActivity > t ? (this.clearStoredSession(), null) : e.id;
|
|
2917
2931
|
}
|
|
2918
|
-
persistSession(e, t = Date.now(),
|
|
2932
|
+
persistSession(e, t = Date.now(), s, n) {
|
|
2919
2933
|
this.saveStoredSession({
|
|
2920
2934
|
id: e,
|
|
2921
2935
|
lastActivity: t,
|
|
2922
|
-
...
|
|
2936
|
+
...s && { referrer: s },
|
|
2923
2937
|
...n && { utm: n }
|
|
2924
2938
|
});
|
|
2925
2939
|
}
|
|
@@ -2937,10 +2951,10 @@ class _r extends w {
|
|
|
2937
2951
|
} catch {
|
|
2938
2952
|
this.storageManager.removeItem(e);
|
|
2939
2953
|
}
|
|
2940
|
-
const
|
|
2941
|
-
if (
|
|
2954
|
+
const s = this.storageManager.getSessionItem(e);
|
|
2955
|
+
if (s !== null)
|
|
2942
2956
|
try {
|
|
2943
|
-
const n = JSON.parse(
|
|
2957
|
+
const n = JSON.parse(s);
|
|
2944
2958
|
if (n.id && typeof n.lastActivity == "number")
|
|
2945
2959
|
return n;
|
|
2946
2960
|
} catch {
|
|
@@ -2949,11 +2963,11 @@ class _r extends w {
|
|
|
2949
2963
|
return null;
|
|
2950
2964
|
}
|
|
2951
2965
|
saveStoredSession(e) {
|
|
2952
|
-
const t = this.getSessionStorageKey(),
|
|
2953
|
-
this.storageManager.setItem(t,
|
|
2966
|
+
const t = this.getSessionStorageKey(), s = JSON.stringify(e);
|
|
2967
|
+
this.storageManager.setItem(t, s), this.storageManager.setSessionItem(t, s);
|
|
2954
2968
|
}
|
|
2955
2969
|
getSessionStorageKey() {
|
|
2956
|
-
return
|
|
2970
|
+
return Nt(this.getProjectId());
|
|
2957
2971
|
}
|
|
2958
2972
|
getProjectId() {
|
|
2959
2973
|
return this.projectId;
|
|
@@ -3016,28 +3030,28 @@ class _r extends w {
|
|
|
3016
3030
|
return;
|
|
3017
3031
|
}
|
|
3018
3032
|
const e = this.recoverSession(), t = e ?? this.generateSessionId();
|
|
3019
|
-
let
|
|
3033
|
+
let s, n;
|
|
3020
3034
|
if (e) {
|
|
3021
3035
|
const i = this.loadStoredSession();
|
|
3022
|
-
|
|
3036
|
+
s = i?.referrer ?? me(), n = i?.utm ?? ge();
|
|
3023
3037
|
} else
|
|
3024
|
-
|
|
3038
|
+
s = me(), n = ge();
|
|
3025
3039
|
a("debug", "Session tracking initialized", {
|
|
3026
3040
|
data: {
|
|
3027
3041
|
sessionId: t,
|
|
3028
3042
|
wasRecovered: !!e,
|
|
3029
3043
|
willEmitSessionStart: !e,
|
|
3030
|
-
sessionReferrer:
|
|
3044
|
+
sessionReferrer: s,
|
|
3031
3045
|
hasUtm: !!n
|
|
3032
3046
|
}
|
|
3033
3047
|
}), this.isTracking = !0;
|
|
3034
3048
|
try {
|
|
3035
|
-
this.set("sessionId", t), this.set("sessionReferrer",
|
|
3049
|
+
this.set("sessionId", t), this.set("sessionReferrer", s), this.set("sessionUtm", n), this.persistSession(t, Date.now(), s, n), this.initCrossTabSync(), this.shareSession(t), e ? a("debug", "Session recovered, skipping SESSION_START", {
|
|
3036
3050
|
data: { sessionId: t }
|
|
3037
3051
|
}) : (a("debug", "Emitting SESSION_START event", {
|
|
3038
3052
|
data: { sessionId: t }
|
|
3039
3053
|
}), this.eventManager.track({
|
|
3040
|
-
type:
|
|
3054
|
+
type: u.SESSION_START
|
|
3041
3055
|
})), this.setupSessionTimeout(), this.setupActivityListeners(), this.setupLifecycleListeners();
|
|
3042
3056
|
} catch (i) {
|
|
3043
3057
|
throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null), i;
|
|
@@ -3072,11 +3086,11 @@ class _r extends w {
|
|
|
3072
3086
|
*/
|
|
3073
3087
|
renewSession() {
|
|
3074
3088
|
this.needsRenewal = !1;
|
|
3075
|
-
const e = this.generateSessionId(), t =
|
|
3089
|
+
const e = this.generateSessionId(), t = me(), s = ge();
|
|
3076
3090
|
a("debug", "Renewing session after timeout", {
|
|
3077
3091
|
data: { newSessionId: e }
|
|
3078
|
-
}), this.set("sessionId", e), this.set("sessionReferrer", t), this.set("sessionUtm",
|
|
3079
|
-
type:
|
|
3092
|
+
}), this.set("sessionId", e), this.set("sessionReferrer", t), this.set("sessionUtm", s), this.persistSession(e, Date.now(), t, s), this.cleanupCrossTabSync(), this.initCrossTabSync(), this.shareSession(e), this.eventManager.track({
|
|
3093
|
+
type: u.SESSION_START
|
|
3080
3094
|
}), this.eventManager.flushPendingEvents(), this.setupSessionTimeout();
|
|
3081
3095
|
}
|
|
3082
3096
|
cleanupActivityListeners() {
|
|
@@ -3105,8 +3119,8 @@ class _r extends w {
|
|
|
3105
3119
|
const t = this.loadStoredSession();
|
|
3106
3120
|
if (!t)
|
|
3107
3121
|
return !1;
|
|
3108
|
-
const
|
|
3109
|
-
return Date.now() - t.lastActivity >
|
|
3122
|
+
const s = this.get("config")?.sessionTimeout ?? 9e5;
|
|
3123
|
+
return Date.now() - t.lastActivity > s;
|
|
3110
3124
|
}
|
|
3111
3125
|
cleanupLifecycleListeners() {
|
|
3112
3126
|
this.visibilityChangeHandler && (document.removeEventListener("visibilitychange", this.visibilityChangeHandler), this.visibilityChangeHandler = null);
|
|
@@ -3193,7 +3207,7 @@ class _r extends w {
|
|
|
3193
3207
|
this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupCrossTabSync(), this.cleanupLifecycleListeners(), this.isTracking = !1, this.needsRenewal = !1, this.set("hasStartSession", !1);
|
|
3194
3208
|
}
|
|
3195
3209
|
}
|
|
3196
|
-
class
|
|
3210
|
+
class ys extends _ {
|
|
3197
3211
|
eventManager;
|
|
3198
3212
|
storageManager;
|
|
3199
3213
|
sessionManager = null;
|
|
@@ -3228,8 +3242,8 @@ class yr extends w {
|
|
|
3228
3242
|
}
|
|
3229
3243
|
const t = this.get("config")?.integrations?.tracelog?.projectId ?? "custom";
|
|
3230
3244
|
try {
|
|
3231
|
-
this.sessionManager = new
|
|
3232
|
-
} catch (
|
|
3245
|
+
this.sessionManager = new _s(this.storageManager, this.eventManager, t), this.sessionManager.startTracking(), this.eventManager.flushPendingEvents();
|
|
3246
|
+
} catch (s) {
|
|
3233
3247
|
if (this.sessionManager) {
|
|
3234
3248
|
try {
|
|
3235
3249
|
this.sessionManager.destroy();
|
|
@@ -3237,7 +3251,7 @@ class yr extends w {
|
|
|
3237
3251
|
}
|
|
3238
3252
|
this.sessionManager = null;
|
|
3239
3253
|
}
|
|
3240
|
-
throw a("error", "Failed to start session tracking", { error:
|
|
3254
|
+
throw a("error", "Failed to start session tracking", { error: s }), s;
|
|
3241
3255
|
}
|
|
3242
3256
|
}
|
|
3243
3257
|
isActive() {
|
|
@@ -3281,7 +3295,7 @@ class yr extends w {
|
|
|
3281
3295
|
this.destroyed || (this.sessionManager && (this.sessionManager.destroy(), this.sessionManager = null), this.destroyed = !0);
|
|
3282
3296
|
}
|
|
3283
3297
|
}
|
|
3284
|
-
class
|
|
3298
|
+
class ws extends _ {
|
|
3285
3299
|
eventManager;
|
|
3286
3300
|
onTrack;
|
|
3287
3301
|
originalPushState;
|
|
@@ -3316,48 +3330,48 @@ class wr extends w {
|
|
|
3316
3330
|
}
|
|
3317
3331
|
patchHistory(e) {
|
|
3318
3332
|
const t = window.history[e];
|
|
3319
|
-
e === "pushState" && !this.originalPushState ? this.originalPushState = t : e === "replaceState" && !this.originalReplaceState && (this.originalReplaceState = t), window.history[e] = (...
|
|
3320
|
-
t.apply(window.history,
|
|
3333
|
+
e === "pushState" && !this.originalPushState ? this.originalPushState = t : e === "replaceState" && !this.originalReplaceState && (this.originalReplaceState = t), window.history[e] = (...s) => {
|
|
3334
|
+
t.apply(window.history, s), this.trackCurrentPage();
|
|
3321
3335
|
};
|
|
3322
3336
|
}
|
|
3323
3337
|
trackCurrentPage = () => {
|
|
3324
|
-
const e = window.location.href, t =
|
|
3338
|
+
const e = window.location.href, t = we(e, this.get("config").sensitiveQueryParams);
|
|
3325
3339
|
if (this.get("pageUrl") === t)
|
|
3326
3340
|
return;
|
|
3327
|
-
const
|
|
3328
|
-
if (
|
|
3341
|
+
const s = Date.now(), n = this.get("config").pageViewThrottleMs ?? 1e3;
|
|
3342
|
+
if (s - this.lastPageViewTime < n)
|
|
3329
3343
|
return;
|
|
3330
|
-
this.lastPageViewTime =
|
|
3344
|
+
this.lastPageViewTime = s, this.onTrack();
|
|
3331
3345
|
const i = this.get("pageUrl");
|
|
3332
3346
|
this.set("pageUrl", t);
|
|
3333
3347
|
const o = this.extractPageViewData();
|
|
3334
3348
|
this.eventManager.track({
|
|
3335
|
-
type:
|
|
3349
|
+
type: u.PAGE_VIEW,
|
|
3336
3350
|
page_url: this.get("pageUrl"),
|
|
3337
3351
|
from_page_url: i,
|
|
3338
3352
|
...o && { page_view: o }
|
|
3339
3353
|
});
|
|
3340
3354
|
};
|
|
3341
3355
|
trackInitialPageView() {
|
|
3342
|
-
const e =
|
|
3356
|
+
const e = we(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
|
|
3343
3357
|
this.lastPageViewTime = Date.now(), this.eventManager.track({
|
|
3344
|
-
type:
|
|
3358
|
+
type: u.PAGE_VIEW,
|
|
3345
3359
|
page_url: e,
|
|
3346
3360
|
...t && { page_view: t }
|
|
3347
3361
|
}), this.onTrack();
|
|
3348
3362
|
}
|
|
3349
3363
|
extractPageViewData() {
|
|
3350
|
-
const { pathname: e, search: t, hash:
|
|
3351
|
-
return !n && !i && !e && !t && !
|
|
3364
|
+
const { pathname: e, search: t, hash: s } = window.location, { referrer: n } = document, { title: i } = document;
|
|
3365
|
+
return !n && !i && !e && !t && !s ? void 0 : {
|
|
3352
3366
|
...n && { referrer: n },
|
|
3353
3367
|
...i && { title: i },
|
|
3354
3368
|
...e && { pathname: e },
|
|
3355
3369
|
...t && { search: t },
|
|
3356
|
-
...
|
|
3370
|
+
...s && { hash: s }
|
|
3357
3371
|
};
|
|
3358
3372
|
}
|
|
3359
3373
|
}
|
|
3360
|
-
class
|
|
3374
|
+
class bs extends _ {
|
|
3361
3375
|
eventManager;
|
|
3362
3376
|
lastClickTimes = /* @__PURE__ */ new Map();
|
|
3363
3377
|
clickHandler;
|
|
@@ -3380,7 +3394,7 @@ class br extends w {
|
|
|
3380
3394
|
*/
|
|
3381
3395
|
startTracking() {
|
|
3382
3396
|
this.clickHandler || (this.clickHandler = (e) => {
|
|
3383
|
-
const t = e,
|
|
3397
|
+
const t = e, s = t.target, n = typeof HTMLElement < "u" && s instanceof HTMLElement ? s : typeof HTMLElement < "u" && s instanceof Node && s.parentElement instanceof HTMLElement ? s.parentElement : null;
|
|
3384
3398
|
if (!n) {
|
|
3385
3399
|
a("debug", "Click target not found or not an element");
|
|
3386
3400
|
return;
|
|
@@ -3392,22 +3406,22 @@ class br extends w {
|
|
|
3392
3406
|
return;
|
|
3393
3407
|
const o = this.findTrackingElement(n), l = this.getRelevantClickElement(n), c = this.calculateClickCoordinates(t, n);
|
|
3394
3408
|
if (o) {
|
|
3395
|
-
const
|
|
3396
|
-
if (
|
|
3397
|
-
const
|
|
3409
|
+
const f = this.extractTrackingData(o);
|
|
3410
|
+
if (f) {
|
|
3411
|
+
const g = this.createCustomEventData(f);
|
|
3398
3412
|
this.eventManager.track({
|
|
3399
|
-
type:
|
|
3413
|
+
type: u.CUSTOM,
|
|
3400
3414
|
custom_event: {
|
|
3401
|
-
name:
|
|
3402
|
-
...
|
|
3415
|
+
name: g.name,
|
|
3416
|
+
...g.value && { metadata: { value: g.value } }
|
|
3403
3417
|
}
|
|
3404
3418
|
});
|
|
3405
3419
|
}
|
|
3406
3420
|
}
|
|
3407
|
-
const
|
|
3421
|
+
const d = this.generateClickData(n, l, c);
|
|
3408
3422
|
this.eventManager.track({
|
|
3409
|
-
type:
|
|
3410
|
-
click_data:
|
|
3423
|
+
type: u.CLICK,
|
|
3424
|
+
click_data: d
|
|
3411
3425
|
});
|
|
3412
3426
|
}, window.addEventListener("click", this.clickHandler, !0));
|
|
3413
3427
|
}
|
|
@@ -3428,15 +3442,15 @@ class br extends w {
|
|
|
3428
3442
|
* Returns true if the click should be tracked, false if throttled
|
|
3429
3443
|
*/
|
|
3430
3444
|
checkClickThrottle(e, t) {
|
|
3431
|
-
const
|
|
3445
|
+
const s = this.getElementSignature(e), n = Date.now();
|
|
3432
3446
|
this.pruneThrottleCache(n);
|
|
3433
|
-
const i = this.lastClickTimes.get(
|
|
3447
|
+
const i = this.lastClickTimes.get(s);
|
|
3434
3448
|
return i !== void 0 && n - i < t ? (a("debug", "ClickHandler: Click suppressed by throttle", {
|
|
3435
3449
|
data: {
|
|
3436
|
-
signature:
|
|
3450
|
+
signature: s,
|
|
3437
3451
|
throttleRemaining: t - (n - i)
|
|
3438
3452
|
}
|
|
3439
|
-
}), !1) : (this.lastClickTimes.set(
|
|
3453
|
+
}), !1) : (this.lastClickTimes.set(s, n), !0);
|
|
3440
3454
|
}
|
|
3441
3455
|
/**
|
|
3442
3456
|
* Prunes stale entries from the throttle cache to prevent memory leaks
|
|
@@ -3448,10 +3462,10 @@ class br extends w {
|
|
|
3448
3462
|
return;
|
|
3449
3463
|
this.lastPruneTime = e;
|
|
3450
3464
|
const t = e - 3e5;
|
|
3451
|
-
for (const [
|
|
3452
|
-
n < t && this.lastClickTimes.delete(
|
|
3465
|
+
for (const [s, n] of this.lastClickTimes.entries())
|
|
3466
|
+
n < t && this.lastClickTimes.delete(s);
|
|
3453
3467
|
if (this.lastClickTimes.size > 1e3) {
|
|
3454
|
-
const
|
|
3468
|
+
const s = Array.from(this.lastClickTimes.entries()).sort((o, l) => o[1] - l[1]), n = this.lastClickTimes.size - 1e3, i = s.slice(0, n);
|
|
3455
3469
|
for (const [o] of i)
|
|
3456
3470
|
this.lastClickTimes.delete(o);
|
|
3457
3471
|
a("debug", "ClickHandler: Pruned throttle cache", {
|
|
@@ -3472,22 +3486,22 @@ class br extends w {
|
|
|
3472
3486
|
const t = e.getAttribute("data-testid");
|
|
3473
3487
|
if (t)
|
|
3474
3488
|
return `[data-testid="${t}"]`;
|
|
3475
|
-
const
|
|
3476
|
-
return
|
|
3489
|
+
const s = e.getAttribute(`${b}-name`);
|
|
3490
|
+
return s ? `[${b}-name="${s}"]` : this.getElementPath(e);
|
|
3477
3491
|
}
|
|
3478
3492
|
/**
|
|
3479
3493
|
* Generates a DOM path for an element (e.g., "body>div>button")
|
|
3480
3494
|
*/
|
|
3481
3495
|
getElementPath(e) {
|
|
3482
3496
|
const t = [];
|
|
3483
|
-
let
|
|
3484
|
-
for (;
|
|
3485
|
-
let n =
|
|
3486
|
-
if (
|
|
3487
|
-
const i =
|
|
3497
|
+
let s = e;
|
|
3498
|
+
for (; s && s !== document.body; ) {
|
|
3499
|
+
let n = s.tagName.toLowerCase();
|
|
3500
|
+
if (s.className) {
|
|
3501
|
+
const i = s.className.split(" ")[0];
|
|
3488
3502
|
i && (n += `.${i}`);
|
|
3489
3503
|
}
|
|
3490
|
-
t.unshift(n),
|
|
3504
|
+
t.unshift(n), s = s.parentElement;
|
|
3491
3505
|
}
|
|
3492
3506
|
return t.join(">") || "unknown";
|
|
3493
3507
|
}
|
|
@@ -3495,15 +3509,15 @@ class br extends w {
|
|
|
3495
3509
|
return e.hasAttribute(`${b}-name`) ? e : e.closest(`[${b}-name]`);
|
|
3496
3510
|
}
|
|
3497
3511
|
getRelevantClickElement(e) {
|
|
3498
|
-
for (const t of
|
|
3512
|
+
for (const t of At)
|
|
3499
3513
|
try {
|
|
3500
3514
|
if (e.matches(t))
|
|
3501
3515
|
return e;
|
|
3502
|
-
const
|
|
3503
|
-
if (
|
|
3504
|
-
return
|
|
3505
|
-
} catch (
|
|
3506
|
-
a("debug", "Invalid selector in element search", { error:
|
|
3516
|
+
const s = e.closest(t);
|
|
3517
|
+
if (s)
|
|
3518
|
+
return s;
|
|
3519
|
+
} catch (s) {
|
|
3520
|
+
a("debug", "Invalid selector in element search", { error: s, data: { selector: t } });
|
|
3507
3521
|
continue;
|
|
3508
3522
|
}
|
|
3509
3523
|
return e;
|
|
@@ -3523,20 +3537,20 @@ class br extends w {
|
|
|
3523
3537
|
return Math.max(0, Math.min(1, Number(e.toFixed(3))));
|
|
3524
3538
|
}
|
|
3525
3539
|
calculateClickCoordinates(e, t) {
|
|
3526
|
-
const
|
|
3540
|
+
const s = t.getBoundingClientRect(), n = e.clientX, i = e.clientY, o = s.width > 0 ? this.clamp((n - s.left) / s.width) : 0, l = s.height > 0 ? this.clamp((i - s.top) / s.height) : 0;
|
|
3527
3541
|
return { x: n, y: i, relativeX: o, relativeY: l };
|
|
3528
3542
|
}
|
|
3529
3543
|
extractTrackingData(e) {
|
|
3530
|
-
const t = e.getAttribute(`${b}-name`),
|
|
3544
|
+
const t = e.getAttribute(`${b}-name`), s = e.getAttribute(`${b}-value`);
|
|
3531
3545
|
if (t)
|
|
3532
3546
|
return {
|
|
3533
3547
|
element: e,
|
|
3534
3548
|
name: t,
|
|
3535
|
-
...
|
|
3549
|
+
...s && { value: s }
|
|
3536
3550
|
};
|
|
3537
3551
|
}
|
|
3538
|
-
generateClickData(e, t,
|
|
3539
|
-
const { x: n, y: i, relativeX: o, relativeY: l } =
|
|
3552
|
+
generateClickData(e, t, s) {
|
|
3553
|
+
const { x: n, y: i, relativeX: o, relativeY: l } = s, c = this.getRelevantText(e, t), d = this.extractElementAttributes(t);
|
|
3540
3554
|
return {
|
|
3541
3555
|
x: n,
|
|
3542
3556
|
y: i,
|
|
@@ -3546,12 +3560,12 @@ class br extends w {
|
|
|
3546
3560
|
...t.id && { id: t.id },
|
|
3547
3561
|
...t.className && { class: t.className },
|
|
3548
3562
|
...c && { text: c },
|
|
3549
|
-
...
|
|
3550
|
-
...
|
|
3551
|
-
...
|
|
3552
|
-
...
|
|
3553
|
-
...
|
|
3554
|
-
...Object.keys(
|
|
3563
|
+
...d.href && { href: d.href },
|
|
3564
|
+
...d.title && { title: d.title },
|
|
3565
|
+
...d.alt && { alt: d.alt },
|
|
3566
|
+
...d.role && { role: d.role },
|
|
3567
|
+
...d["aria-label"] && { ariaLabel: d["aria-label"] },
|
|
3568
|
+
...Object.keys(d).length > 0 && { dataAttributes: d }
|
|
3555
3569
|
};
|
|
3556
3570
|
}
|
|
3557
3571
|
/**
|
|
@@ -3575,18 +3589,18 @@ class br extends w {
|
|
|
3575
3589
|
*/
|
|
3576
3590
|
sanitizeText(e) {
|
|
3577
3591
|
let t = e;
|
|
3578
|
-
for (const
|
|
3579
|
-
const n = new RegExp(
|
|
3592
|
+
for (const s of lt) {
|
|
3593
|
+
const n = new RegExp(s.source, s.flags);
|
|
3580
3594
|
t = t.replace(n, "[REDACTED]");
|
|
3581
3595
|
}
|
|
3582
3596
|
return t;
|
|
3583
3597
|
}
|
|
3584
3598
|
getRelevantText(e, t) {
|
|
3585
|
-
const
|
|
3586
|
-
if (!
|
|
3599
|
+
const s = e.textContent?.trim() ?? "", n = t.textContent?.trim() ?? "";
|
|
3600
|
+
if (!s && !n)
|
|
3587
3601
|
return "";
|
|
3588
3602
|
let i = "";
|
|
3589
|
-
return
|
|
3603
|
+
return s && s.length <= 255 ? i = s : n.length <= 255 ? i = n : i = n.slice(0, 252) + "...", this.sanitizeText(i);
|
|
3590
3604
|
}
|
|
3591
3605
|
extractElementAttributes(e) {
|
|
3592
3606
|
const t = [
|
|
@@ -3600,12 +3614,12 @@ class br extends w {
|
|
|
3600
3614
|
"name",
|
|
3601
3615
|
"alt",
|
|
3602
3616
|
"role"
|
|
3603
|
-
],
|
|
3617
|
+
], s = {};
|
|
3604
3618
|
for (const n of t) {
|
|
3605
3619
|
const i = e.getAttribute(n);
|
|
3606
|
-
i && (
|
|
3620
|
+
i && (s[n] = i);
|
|
3607
3621
|
}
|
|
3608
|
-
return
|
|
3622
|
+
return s;
|
|
3609
3623
|
}
|
|
3610
3624
|
createCustomEventData(e) {
|
|
3611
3625
|
return {
|
|
@@ -3614,7 +3628,7 @@ class br extends w {
|
|
|
3614
3628
|
};
|
|
3615
3629
|
}
|
|
3616
3630
|
}
|
|
3617
|
-
class
|
|
3631
|
+
class As extends _ {
|
|
3618
3632
|
eventManager;
|
|
3619
3633
|
containers = [];
|
|
3620
3634
|
limitWarningLogged = !1;
|
|
@@ -3660,9 +3674,9 @@ class Ar extends w {
|
|
|
3660
3674
|
tryDetectScrollContainers(e) {
|
|
3661
3675
|
const t = this.findScrollableElements();
|
|
3662
3676
|
if (this.isWindowScrollable() && this.setupScrollContainer(window, "window"), t.length > 0) {
|
|
3663
|
-
for (const
|
|
3664
|
-
const n = this.getElementSelector(
|
|
3665
|
-
this.setupScrollContainer(
|
|
3677
|
+
for (const s of t) {
|
|
3678
|
+
const n = this.getElementSelector(s);
|
|
3679
|
+
this.setupScrollContainer(s, n);
|
|
3666
3680
|
}
|
|
3667
3681
|
this.applyPrimaryScrollSelectorIfConfigured();
|
|
3668
3682
|
return;
|
|
@@ -3691,9 +3705,9 @@ class Ar extends w {
|
|
|
3691
3705
|
return o.overflowY === "auto" || o.overflowY === "scroll" || o.overflow === "auto" || o.overflow === "scroll" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
3692
3706
|
}
|
|
3693
3707
|
});
|
|
3694
|
-
let
|
|
3695
|
-
for (; (
|
|
3696
|
-
const n =
|
|
3708
|
+
let s;
|
|
3709
|
+
for (; (s = t.nextNode()) && e.length < 10; ) {
|
|
3710
|
+
const n = s;
|
|
3697
3711
|
this.isElementScrollable(n) && e.push(n);
|
|
3698
3712
|
}
|
|
3699
3713
|
return e;
|
|
@@ -3705,9 +3719,9 @@ class Ar extends w {
|
|
|
3705
3719
|
if (t.id)
|
|
3706
3720
|
return `#${t.id}`;
|
|
3707
3721
|
if (t.className && typeof t.className == "string") {
|
|
3708
|
-
const
|
|
3709
|
-
if (
|
|
3710
|
-
return `.${
|
|
3722
|
+
const s = t.className.split(" ").filter((n) => n.trim())[0];
|
|
3723
|
+
if (s)
|
|
3724
|
+
return `.${s}`;
|
|
3711
3725
|
}
|
|
3712
3726
|
return t.tagName.toLowerCase();
|
|
3713
3727
|
}
|
|
@@ -3715,7 +3729,7 @@ class Ar extends w {
|
|
|
3715
3729
|
return this.isWindowScrollable() ? e === window : this.containers.length === 0;
|
|
3716
3730
|
}
|
|
3717
3731
|
setupScrollContainer(e, t) {
|
|
3718
|
-
if (this.containers.some((
|
|
3732
|
+
if (this.containers.some((d) => d.element === e) || e !== window && !this.isElementScrollable(e))
|
|
3719
3733
|
return;
|
|
3720
3734
|
const n = this.getScrollTop(e), i = this.calculateScrollDepth(
|
|
3721
3735
|
n,
|
|
@@ -3727,7 +3741,7 @@ class Ar extends w {
|
|
|
3727
3741
|
isPrimary: o,
|
|
3728
3742
|
lastScrollPos: n,
|
|
3729
3743
|
lastDepth: i,
|
|
3730
|
-
lastDirection:
|
|
3744
|
+
lastDirection: Z.DOWN,
|
|
3731
3745
|
lastEventTime: 0,
|
|
3732
3746
|
firstScrollEventTime: null,
|
|
3733
3747
|
maxDepthReached: i,
|
|
@@ -3735,23 +3749,23 @@ class Ar extends w {
|
|
|
3735
3749
|
listener: null
|
|
3736
3750
|
}, c = () => {
|
|
3737
3751
|
this.get("suppressNextScroll") || (l.firstScrollEventTime === null && (l.firstScrollEventTime = Date.now()), this.clearContainerTimer(l), l.debounceTimer = window.setTimeout(() => {
|
|
3738
|
-
const
|
|
3739
|
-
if (
|
|
3740
|
-
const
|
|
3741
|
-
this.processScrollEvent(l,
|
|
3752
|
+
const d = this.calculateScrollData(l);
|
|
3753
|
+
if (d) {
|
|
3754
|
+
const f = Date.now();
|
|
3755
|
+
this.processScrollEvent(l, d, f);
|
|
3742
3756
|
}
|
|
3743
3757
|
l.debounceTimer = null;
|
|
3744
3758
|
}, 250));
|
|
3745
3759
|
};
|
|
3746
3760
|
l.listener = c, this.containers.push(l), e === window ? window.addEventListener("scroll", c, { passive: !0 }) : e.addEventListener("scroll", c, { passive: !0 });
|
|
3747
3761
|
}
|
|
3748
|
-
processScrollEvent(e, t,
|
|
3749
|
-
if (!this.shouldEmitScrollEvent(e, t,
|
|
3762
|
+
processScrollEvent(e, t, s) {
|
|
3763
|
+
if (!this.shouldEmitScrollEvent(e, t, s))
|
|
3750
3764
|
return;
|
|
3751
|
-
e.lastEventTime =
|
|
3765
|
+
e.lastEventTime = s, e.lastDepth = t.depth, e.lastDirection = t.direction;
|
|
3752
3766
|
const n = this.get("scrollEventCount") ?? 0;
|
|
3753
3767
|
this.set("scrollEventCount", n + 1), this.eventManager.track({
|
|
3754
|
-
type:
|
|
3768
|
+
type: u.SCROLL,
|
|
3755
3769
|
scroll_data: {
|
|
3756
3770
|
...t,
|
|
3757
3771
|
container_selector: e.selector,
|
|
@@ -3759,8 +3773,8 @@ class Ar extends w {
|
|
|
3759
3773
|
}
|
|
3760
3774
|
});
|
|
3761
3775
|
}
|
|
3762
|
-
shouldEmitScrollEvent(e, t,
|
|
3763
|
-
return this.hasReachedSessionLimit() ? (this.logLimitOnce(), !1) : !(!this.hasElapsedMinimumInterval(e,
|
|
3776
|
+
shouldEmitScrollEvent(e, t, s) {
|
|
3777
|
+
return this.hasReachedSessionLimit() ? (this.logLimitOnce(), !1) : !(!this.hasElapsedMinimumInterval(e, s) || !this.hasSignificantDepthChange(e, t.depth));
|
|
3764
3778
|
}
|
|
3765
3779
|
hasReachedSessionLimit() {
|
|
3766
3780
|
return (this.get("scrollEventCount") ?? 0) >= this.maxEventsPerSession;
|
|
@@ -3786,25 +3800,25 @@ class Ar extends w {
|
|
|
3786
3800
|
e.debounceTimer !== null && (clearTimeout(e.debounceTimer), e.debounceTimer = null);
|
|
3787
3801
|
}
|
|
3788
3802
|
getScrollDirection(e, t) {
|
|
3789
|
-
return e > t ?
|
|
3803
|
+
return e > t ? Z.DOWN : Z.UP;
|
|
3790
3804
|
}
|
|
3791
|
-
calculateScrollDepth(e, t,
|
|
3792
|
-
if (t <=
|
|
3805
|
+
calculateScrollDepth(e, t, s) {
|
|
3806
|
+
if (t <= s)
|
|
3793
3807
|
return 0;
|
|
3794
|
-
const n = t -
|
|
3808
|
+
const n = t - s;
|
|
3795
3809
|
return Math.min(100, Math.max(0, Math.floor(e / n * 100)));
|
|
3796
3810
|
}
|
|
3797
3811
|
calculateScrollData(e) {
|
|
3798
|
-
const { element: t, lastScrollPos:
|
|
3812
|
+
const { element: t, lastScrollPos: s, lastEventTime: n } = e, i = this.getScrollTop(t), o = Date.now(), l = Math.abs(i - s);
|
|
3799
3813
|
if (l < 10 || t === window && !this.isWindowScrollable())
|
|
3800
3814
|
return null;
|
|
3801
|
-
const c = this.getViewportHeight(t),
|
|
3815
|
+
const c = this.getViewportHeight(t), d = this.getScrollHeight(t), f = this.getScrollDirection(i, s), g = this.calculateScrollDepth(i, d, c);
|
|
3802
3816
|
let T;
|
|
3803
3817
|
n > 0 ? T = o - n : e.firstScrollEventTime !== null ? T = o - e.firstScrollEventTime : T = 250;
|
|
3804
3818
|
const S = Math.round(l / T * 1e3);
|
|
3805
|
-
return
|
|
3806
|
-
depth:
|
|
3807
|
-
direction:
|
|
3819
|
+
return g > e.maxDepthReached && (e.maxDepthReached = g), e.lastScrollPos = i, {
|
|
3820
|
+
depth: g,
|
|
3821
|
+
direction: f,
|
|
3808
3822
|
velocity: S,
|
|
3809
3823
|
max_depth_reached: e.maxDepthReached
|
|
3810
3824
|
};
|
|
@@ -3819,8 +3833,8 @@ class Ar extends w {
|
|
|
3819
3833
|
return e === window ? document.documentElement.scrollHeight : e.scrollHeight;
|
|
3820
3834
|
}
|
|
3821
3835
|
isElementScrollable(e) {
|
|
3822
|
-
const t = getComputedStyle(e),
|
|
3823
|
-
return
|
|
3836
|
+
const t = getComputedStyle(e), s = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflow === "auto" || t.overflow === "scroll", n = e.scrollHeight > e.clientHeight;
|
|
3837
|
+
return s && n;
|
|
3824
3838
|
}
|
|
3825
3839
|
applyPrimaryScrollSelector(e) {
|
|
3826
3840
|
let t;
|
|
@@ -3842,7 +3856,7 @@ class Ar extends w {
|
|
|
3842
3856
|
e.isPrimary = t;
|
|
3843
3857
|
}
|
|
3844
3858
|
}
|
|
3845
|
-
class
|
|
3859
|
+
class Ls extends _ {
|
|
3846
3860
|
eventManager;
|
|
3847
3861
|
trackedElements = /* @__PURE__ */ new Map();
|
|
3848
3862
|
observer = null;
|
|
@@ -3859,12 +3873,12 @@ class Lr extends w {
|
|
|
3859
3873
|
const e = this.get("config");
|
|
3860
3874
|
if (this.config = e.viewport ?? null, !this.config?.elements || this.config.elements.length === 0)
|
|
3861
3875
|
return;
|
|
3862
|
-
const t = this.config.threshold ?? 0.5,
|
|
3876
|
+
const t = this.config.threshold ?? 0.5, s = this.config.minDwellTime ?? 1e3;
|
|
3863
3877
|
if (t < 0 || t > 1) {
|
|
3864
3878
|
a("debug", "ViewportHandler: Invalid threshold, must be between 0 and 1");
|
|
3865
3879
|
return;
|
|
3866
3880
|
}
|
|
3867
|
-
if (
|
|
3881
|
+
if (s < 0) {
|
|
3868
3882
|
a("debug", "ViewportHandler: Invalid minDwellTime, must be non-negative");
|
|
3869
3883
|
return;
|
|
3870
3884
|
}
|
|
@@ -3892,15 +3906,15 @@ class Lr extends w {
|
|
|
3892
3906
|
if (!this.config || !this.observer) return;
|
|
3893
3907
|
const e = this.config.maxTrackedElements ?? 100;
|
|
3894
3908
|
let t = this.trackedElements.size;
|
|
3895
|
-
for (const
|
|
3909
|
+
for (const s of this.config.elements)
|
|
3896
3910
|
try {
|
|
3897
|
-
const n = document.querySelectorAll(
|
|
3911
|
+
const n = document.querySelectorAll(s.selector);
|
|
3898
3912
|
for (const i of Array.from(n)) {
|
|
3899
3913
|
if (t >= e) {
|
|
3900
3914
|
a("debug", "ViewportHandler: Maximum tracked elements reached", {
|
|
3901
3915
|
data: {
|
|
3902
3916
|
limit: e,
|
|
3903
|
-
selector:
|
|
3917
|
+
selector: s.selector,
|
|
3904
3918
|
message: "Some elements will not be tracked. Consider more specific selectors."
|
|
3905
3919
|
}
|
|
3906
3920
|
});
|
|
@@ -3908,16 +3922,16 @@ class Lr extends w {
|
|
|
3908
3922
|
}
|
|
3909
3923
|
i.hasAttribute(`${b}-ignore`) || this.trackedElements.has(i) || (this.trackedElements.set(i, {
|
|
3910
3924
|
element: i,
|
|
3911
|
-
selector:
|
|
3912
|
-
id:
|
|
3913
|
-
name:
|
|
3925
|
+
selector: s.selector,
|
|
3926
|
+
id: s.id,
|
|
3927
|
+
name: s.name,
|
|
3914
3928
|
startTime: null,
|
|
3915
3929
|
timeoutId: null,
|
|
3916
3930
|
lastFiredTime: null
|
|
3917
3931
|
}), this.observer?.observe(i), t++);
|
|
3918
3932
|
}
|
|
3919
3933
|
} catch (n) {
|
|
3920
|
-
a("debug", `ViewportHandler: Invalid selector "${
|
|
3934
|
+
a("debug", `ViewportHandler: Invalid selector "${s.selector}"`, { error: n });
|
|
3921
3935
|
}
|
|
3922
3936
|
a("debug", "ViewportHandler: Elements tracked", {
|
|
3923
3937
|
data: { count: t, limit: e }
|
|
@@ -3929,10 +3943,10 @@ class Lr extends w {
|
|
|
3929
3943
|
handleIntersection = (e) => {
|
|
3930
3944
|
if (!this.config) return;
|
|
3931
3945
|
const t = this.config.minDwellTime ?? 1e3;
|
|
3932
|
-
for (const
|
|
3933
|
-
const n = this.trackedElements.get(
|
|
3934
|
-
n && (
|
|
3935
|
-
const i = Math.round(
|
|
3946
|
+
for (const s of e) {
|
|
3947
|
+
const n = this.trackedElements.get(s.target);
|
|
3948
|
+
n && (s.isIntersecting ? n.startTime === null && (n.startTime = performance.now(), n.timeoutId = window.setTimeout(() => {
|
|
3949
|
+
const i = Math.round(s.intersectionRatio * 100) / 100;
|
|
3936
3950
|
this.fireViewportEvent(n, i);
|
|
3937
3951
|
}, t)) : n.startTime !== null && (n.timeoutId !== null && (window.clearTimeout(n.timeoutId), n.timeoutId = null), n.startTime = null));
|
|
3938
3952
|
}
|
|
@@ -3942,7 +3956,7 @@ class Lr extends w {
|
|
|
3942
3956
|
*/
|
|
3943
3957
|
fireViewportEvent(e, t) {
|
|
3944
3958
|
if (e.startTime === null) return;
|
|
3945
|
-
const
|
|
3959
|
+
const s = Math.round(performance.now() - e.startTime);
|
|
3946
3960
|
if (e.element.hasAttribute(`${b}-ignore`))
|
|
3947
3961
|
return;
|
|
3948
3962
|
const n = this.config?.cooldownPeriod ?? 6e4, i = Date.now();
|
|
@@ -3957,13 +3971,13 @@ class Lr extends w {
|
|
|
3957
3971
|
}
|
|
3958
3972
|
const o = {
|
|
3959
3973
|
selector: e.selector,
|
|
3960
|
-
dwellTime:
|
|
3974
|
+
dwellTime: s,
|
|
3961
3975
|
visibilityRatio: t,
|
|
3962
3976
|
...e.id !== void 0 && { id: e.id },
|
|
3963
3977
|
...e.name !== void 0 && { name: e.name }
|
|
3964
3978
|
};
|
|
3965
3979
|
this.eventManager.track({
|
|
3966
|
-
type:
|
|
3980
|
+
type: u.VIEWPORT_VISIBLE,
|
|
3967
3981
|
viewport_data: o
|
|
3968
3982
|
}), e.startTime = null, e.timeoutId = null, e.lastFiredTime = i;
|
|
3969
3983
|
}
|
|
@@ -3978,8 +3992,8 @@ class Lr extends w {
|
|
|
3978
3992
|
}
|
|
3979
3993
|
this.mutationObserver = new MutationObserver((e) => {
|
|
3980
3994
|
let t = !1;
|
|
3981
|
-
for (const
|
|
3982
|
-
|
|
3995
|
+
for (const s of e)
|
|
3996
|
+
s.type === "childList" && (s.addedNodes.length > 0 && (t = !0), s.removedNodes.length > 0 && this.cleanupRemovedNodes(s.removedNodes));
|
|
3983
3997
|
t && (this.mutationDebounceTimer !== null && window.clearTimeout(this.mutationDebounceTimer), this.mutationDebounceTimer = window.setTimeout(() => {
|
|
3984
3998
|
this.observeElements(), this.mutationDebounceTimer = null;
|
|
3985
3999
|
}, 100));
|
|
@@ -3995,15 +4009,58 @@ class Lr extends w {
|
|
|
3995
4009
|
cleanupRemovedNodes(e) {
|
|
3996
4010
|
e.forEach((t) => {
|
|
3997
4011
|
if (t.nodeType !== 1) return;
|
|
3998
|
-
const
|
|
3999
|
-
n && (n.timeoutId !== null && window.clearTimeout(n.timeoutId), this.observer?.unobserve(
|
|
4012
|
+
const s = t, n = this.trackedElements.get(s);
|
|
4013
|
+
n && (n.timeoutId !== null && window.clearTimeout(n.timeoutId), this.observer?.unobserve(s), this.trackedElements.delete(s)), Array.from(this.trackedElements.keys()).filter((o) => s.contains(o)).forEach((o) => {
|
|
4000
4014
|
const l = this.trackedElements.get(o);
|
|
4001
4015
|
l && l.timeoutId !== null && window.clearTimeout(l.timeoutId), this.observer?.unobserve(o), this.trackedElements.delete(o);
|
|
4002
4016
|
});
|
|
4003
4017
|
});
|
|
4004
4018
|
}
|
|
4005
4019
|
}
|
|
4006
|
-
|
|
4020
|
+
const Ms = "tracelog_session_id";
|
|
4021
|
+
class Cs extends _ {
|
|
4022
|
+
visibilityHandler = null;
|
|
4023
|
+
lastSyncedSessionId = null;
|
|
4024
|
+
activate() {
|
|
4025
|
+
this.cleanupVisibilityListener(), this.syncCartAttribute(), this.setupVisibilityListener();
|
|
4026
|
+
}
|
|
4027
|
+
deactivate() {
|
|
4028
|
+
this.cleanupVisibilityListener(), this.lastSyncedSessionId = null;
|
|
4029
|
+
}
|
|
4030
|
+
/** Re-syncs the cart attribute when session rotates (called by App on SESSION_START). */
|
|
4031
|
+
onSessionChange() {
|
|
4032
|
+
this.syncCartAttribute();
|
|
4033
|
+
}
|
|
4034
|
+
syncCartAttribute() {
|
|
4035
|
+
const e = this.get("sessionId");
|
|
4036
|
+
!e || e === this.lastSyncedSessionId || (this.lastSyncedSessionId = e, this.postCartUpdate(e));
|
|
4037
|
+
}
|
|
4038
|
+
postCartUpdate(e) {
|
|
4039
|
+
try {
|
|
4040
|
+
fetch("/cart/update.js", {
|
|
4041
|
+
method: "POST",
|
|
4042
|
+
headers: { "Content-Type": "application/json" },
|
|
4043
|
+
body: JSON.stringify({ attributes: { [Ms]: e } }),
|
|
4044
|
+
credentials: "same-origin"
|
|
4045
|
+
}).then((t) => {
|
|
4046
|
+
t.ok || (this.lastSyncedSessionId = null, a("debug", "Shopify cart attribute update failed", { data: { status: t.status } }));
|
|
4047
|
+
}).catch(() => {
|
|
4048
|
+
this.lastSyncedSessionId = null, a("debug", "Shopify cart attribute update failed");
|
|
4049
|
+
});
|
|
4050
|
+
} catch {
|
|
4051
|
+
this.lastSyncedSessionId = null, a("debug", "Shopify cart attribute update failed");
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
setupVisibilityListener() {
|
|
4055
|
+
this.visibilityHandler = () => {
|
|
4056
|
+
document.hidden || this.syncCartAttribute();
|
|
4057
|
+
}, document.addEventListener("visibilitychange", this.visibilityHandler);
|
|
4058
|
+
}
|
|
4059
|
+
cleanupVisibilityListener() {
|
|
4060
|
+
this.visibilityHandler && (document.removeEventListener("visibilitychange", this.visibilityHandler), this.visibilityHandler = null);
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
class Rs {
|
|
4007
4064
|
storage;
|
|
4008
4065
|
sessionStorageRef;
|
|
4009
4066
|
fallbackStorage = /* @__PURE__ */ new Map();
|
|
@@ -4051,8 +4108,8 @@ class Mr {
|
|
|
4051
4108
|
this.storage.setItem(e, t);
|
|
4052
4109
|
return;
|
|
4053
4110
|
}
|
|
4054
|
-
} catch (
|
|
4055
|
-
if (
|
|
4111
|
+
} catch (s) {
|
|
4112
|
+
if (s instanceof DOMException && s.name === "QuotaExceededError" || s instanceof Error && s.name === "QuotaExceededError")
|
|
4056
4113
|
if (this.hasQuotaExceededError = !0, a("warn", "localStorage quota exceeded, attempting cleanup", {
|
|
4057
4114
|
data: { key: e, valueSize: t.length }
|
|
4058
4115
|
}), this.cleanupOldData())
|
|
@@ -4069,7 +4126,7 @@ class Mr {
|
|
|
4069
4126
|
}
|
|
4070
4127
|
else
|
|
4071
4128
|
a("error", "localStorage quota exceeded and no data to cleanup - data will not persist", {
|
|
4072
|
-
error:
|
|
4129
|
+
error: s,
|
|
4073
4130
|
data: { key: e, valueSize: t.length }
|
|
4074
4131
|
});
|
|
4075
4132
|
}
|
|
@@ -4107,8 +4164,8 @@ class Mr {
|
|
|
4107
4164
|
try {
|
|
4108
4165
|
const e = [];
|
|
4109
4166
|
for (let t = 0; t < this.storage.length; t++) {
|
|
4110
|
-
const
|
|
4111
|
-
|
|
4167
|
+
const s = this.storage.key(t);
|
|
4168
|
+
s?.startsWith("tracelog_") && e.push(s);
|
|
4112
4169
|
}
|
|
4113
4170
|
e.forEach((t) => {
|
|
4114
4171
|
this.storage.removeItem(t);
|
|
@@ -4183,7 +4240,7 @@ class Mr {
|
|
|
4183
4240
|
} catch {
|
|
4184
4241
|
}
|
|
4185
4242
|
}), !0;
|
|
4186
|
-
const
|
|
4243
|
+
const s = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"], n = e.filter((i) => !s.some((o) => i.startsWith(o)));
|
|
4187
4244
|
return n.length > 0 ? (n.slice(0, 5).forEach((o) => {
|
|
4188
4245
|
try {
|
|
4189
4246
|
this.storage.removeItem(o);
|
|
@@ -4222,8 +4279,8 @@ class Mr {
|
|
|
4222
4279
|
if (typeof window > "u")
|
|
4223
4280
|
return null;
|
|
4224
4281
|
try {
|
|
4225
|
-
const t = e === "localStorage" ? window.localStorage : window.sessionStorage,
|
|
4226
|
-
return t.setItem(
|
|
4282
|
+
const t = e === "localStorage" ? window.localStorage : window.sessionStorage, s = "__tracelog_test__";
|
|
4283
|
+
return t.setItem(s, "test"), t.removeItem(s), t;
|
|
4227
4284
|
} catch {
|
|
4228
4285
|
return null;
|
|
4229
4286
|
}
|
|
@@ -4264,9 +4321,9 @@ class Mr {
|
|
|
4264
4321
|
this.sessionStorageRef.setItem(e, t);
|
|
4265
4322
|
return;
|
|
4266
4323
|
}
|
|
4267
|
-
} catch (
|
|
4268
|
-
(
|
|
4269
|
-
error:
|
|
4324
|
+
} catch (s) {
|
|
4325
|
+
(s instanceof DOMException && s.name === "QuotaExceededError" || s instanceof Error && s.name === "QuotaExceededError") && a("error", "sessionStorage quota exceeded - data will not persist", {
|
|
4326
|
+
error: s,
|
|
4270
4327
|
data: { key: e, valueSize: t.length }
|
|
4271
4328
|
});
|
|
4272
4329
|
}
|
|
@@ -4286,7 +4343,7 @@ class Mr {
|
|
|
4286
4343
|
this.fallbackSessionStorage.delete(e);
|
|
4287
4344
|
}
|
|
4288
4345
|
}
|
|
4289
|
-
class
|
|
4346
|
+
class Ns extends _ {
|
|
4290
4347
|
eventManager;
|
|
4291
4348
|
reportedByNav = /* @__PURE__ */ new Map();
|
|
4292
4349
|
navigationHistory = [];
|
|
@@ -4297,7 +4354,7 @@ class Cr extends w {
|
|
|
4297
4354
|
navigationCounter = 0;
|
|
4298
4355
|
// Counter for handling simultaneous navigations edge case
|
|
4299
4356
|
constructor(e) {
|
|
4300
|
-
super(), this.eventManager = e, this.vitalThresholds =
|
|
4357
|
+
super(), this.eventManager = e, this.vitalThresholds = Ye(_e);
|
|
4301
4358
|
}
|
|
4302
4359
|
/**
|
|
4303
4360
|
* Starts tracking Web Vitals and performance metrics.
|
|
@@ -4315,7 +4372,7 @@ class Cr extends w {
|
|
|
4315
4372
|
*/
|
|
4316
4373
|
async startTracking() {
|
|
4317
4374
|
const e = this.get("config"), t = e?.webVitalsMode ?? _e;
|
|
4318
|
-
this.vitalThresholds =
|
|
4375
|
+
this.vitalThresholds = Ye(t), e?.webVitalsThresholds && (this.vitalThresholds = { ...this.vitalThresholds, ...e.webVitalsThresholds }), await this.initWebVitals(), this.observeLongTasks();
|
|
4319
4376
|
}
|
|
4320
4377
|
/**
|
|
4321
4378
|
* Stops tracking Web Vitals and cleans up resources.
|
|
@@ -4330,16 +4387,16 @@ class Cr extends w {
|
|
|
4330
4387
|
this.observers.forEach((e, t) => {
|
|
4331
4388
|
try {
|
|
4332
4389
|
e.disconnect();
|
|
4333
|
-
} catch (
|
|
4334
|
-
a("debug", "Failed to disconnect performance observer", { error:
|
|
4390
|
+
} catch (s) {
|
|
4391
|
+
a("debug", "Failed to disconnect performance observer", { error: s, data: { observerIndex: t } });
|
|
4335
4392
|
}
|
|
4336
4393
|
}), this.observers.length = 0, this.reportedByNav.clear(), this.navigationHistory.length = 0;
|
|
4337
4394
|
}
|
|
4338
4395
|
observeWebVitalsFallback() {
|
|
4339
4396
|
this.reportTTFB(), this.safeObserve(
|
|
4340
4397
|
"largest-contentful-paint",
|
|
4341
|
-
(
|
|
4342
|
-
const n =
|
|
4398
|
+
(s) => {
|
|
4399
|
+
const n = s.getEntries(), i = n[n.length - 1];
|
|
4343
4400
|
i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(2)) });
|
|
4344
4401
|
},
|
|
4345
4402
|
{ type: "largest-contentful-paint", buffered: !0 },
|
|
@@ -4348,10 +4405,10 @@ class Cr extends w {
|
|
|
4348
4405
|
let e = 0, t = this.getNavigationId();
|
|
4349
4406
|
this.safeObserve(
|
|
4350
4407
|
"layout-shift",
|
|
4351
|
-
(
|
|
4408
|
+
(s) => {
|
|
4352
4409
|
const n = this.getNavigationId();
|
|
4353
4410
|
n !== t && (e = 0, t = n);
|
|
4354
|
-
const i =
|
|
4411
|
+
const i = s.getEntries();
|
|
4355
4412
|
for (const o of i) {
|
|
4356
4413
|
if (o.hadRecentInput === !0)
|
|
4357
4414
|
continue;
|
|
@@ -4363,17 +4420,17 @@ class Cr extends w {
|
|
|
4363
4420
|
{ type: "layout-shift", buffered: !0 }
|
|
4364
4421
|
), this.safeObserve(
|
|
4365
4422
|
"paint",
|
|
4366
|
-
(
|
|
4367
|
-
for (const n of
|
|
4423
|
+
(s) => {
|
|
4424
|
+
for (const n of s.getEntries())
|
|
4368
4425
|
n.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(n.startTime.toFixed(2)) });
|
|
4369
4426
|
},
|
|
4370
4427
|
{ type: "paint", buffered: !0 },
|
|
4371
4428
|
!0
|
|
4372
4429
|
), this.safeObserve(
|
|
4373
4430
|
"event",
|
|
4374
|
-
(
|
|
4431
|
+
(s) => {
|
|
4375
4432
|
let n = 0;
|
|
4376
|
-
const i =
|
|
4433
|
+
const i = s.getEntries();
|
|
4377
4434
|
for (const o of i) {
|
|
4378
4435
|
const l = (o.processingEnd ?? 0) - (o.startTime ?? 0);
|
|
4379
4436
|
n = Math.max(n, l);
|
|
@@ -4385,11 +4442,11 @@ class Cr extends w {
|
|
|
4385
4442
|
}
|
|
4386
4443
|
async initWebVitals() {
|
|
4387
4444
|
try {
|
|
4388
|
-
const { onLCP: e, onCLS: t, onFCP:
|
|
4389
|
-
const
|
|
4390
|
-
this.sendVital({ type: l, value:
|
|
4445
|
+
const { onLCP: e, onCLS: t, onFCP: s, onTTFB: n, onINP: i } = await Promise.resolve().then(() => cr), o = (l) => (c) => {
|
|
4446
|
+
const d = Number(c.value.toFixed(2));
|
|
4447
|
+
this.sendVital({ type: l, value: d });
|
|
4391
4448
|
};
|
|
4392
|
-
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }),
|
|
4449
|
+
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }), s(o("FCP"), { reportAllChanges: !1 }), n(o("TTFB"), { reportAllChanges: !1 }), i(o("INP"), { reportAllChanges: !1 });
|
|
4393
4450
|
} catch (e) {
|
|
4394
4451
|
a("debug", "Failed to load web-vitals library, using fallback", { error: e }), this.observeWebVitalsFallback();
|
|
4395
4452
|
}
|
|
@@ -4410,9 +4467,9 @@ class Cr extends w {
|
|
|
4410
4467
|
"longtask",
|
|
4411
4468
|
(e) => {
|
|
4412
4469
|
const t = e.getEntries();
|
|
4413
|
-
for (const
|
|
4414
|
-
const n = Number(
|
|
4415
|
-
i - this.lastLongTaskSentAt >=
|
|
4470
|
+
for (const s of t) {
|
|
4471
|
+
const n = Number(s.duration.toFixed(2)), i = Date.now();
|
|
4472
|
+
i - this.lastLongTaskSentAt >= Yt && (this.shouldSendVital("LONG_TASK", n) && this.trackWebVital("LONG_TASK", n), this.lastLongTaskSentAt = i);
|
|
4416
4473
|
}
|
|
4417
4474
|
},
|
|
4418
4475
|
{ type: "longtask", buffered: !0 }
|
|
@@ -4423,12 +4480,12 @@ class Cr extends w {
|
|
|
4423
4480
|
return;
|
|
4424
4481
|
const t = this.getNavigationId();
|
|
4425
4482
|
if (t) {
|
|
4426
|
-
const
|
|
4427
|
-
if (
|
|
4483
|
+
const s = this.reportedByNav.get(t);
|
|
4484
|
+
if (s?.has(e.type))
|
|
4428
4485
|
return;
|
|
4429
|
-
if (
|
|
4430
|
-
|
|
4431
|
-
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length >
|
|
4486
|
+
if (s)
|
|
4487
|
+
s.add(e.type);
|
|
4488
|
+
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length > qt) {
|
|
4432
4489
|
const i = this.navigationHistory.shift();
|
|
4433
4490
|
i && this.reportedByNav.delete(i);
|
|
4434
4491
|
}
|
|
@@ -4441,7 +4498,7 @@ class Cr extends w {
|
|
|
4441
4498
|
return;
|
|
4442
4499
|
}
|
|
4443
4500
|
this.eventManager.track({
|
|
4444
|
-
type:
|
|
4501
|
+
type: u.WEB_VITALS,
|
|
4445
4502
|
web_vitals: {
|
|
4446
4503
|
type: e,
|
|
4447
4504
|
value: t
|
|
@@ -4474,8 +4531,8 @@ class Cr extends w {
|
|
|
4474
4531
|
const e = performance.getEntriesByType("navigation")[0];
|
|
4475
4532
|
if (!e)
|
|
4476
4533
|
return null;
|
|
4477
|
-
const t = e.startTime || performance.now(),
|
|
4478
|
-
return
|
|
4534
|
+
const t = e.startTime || performance.now(), s = ++this.navigationCounter, n = `${t.toFixed(2)}_${window.location.pathname}`;
|
|
4535
|
+
return s > 1 ? `${n}_${s}` : n;
|
|
4479
4536
|
} catch (e) {
|
|
4480
4537
|
return a("debug", "Failed to get navigation ID", { error: e }), null;
|
|
4481
4538
|
}
|
|
@@ -4485,7 +4542,7 @@ class Cr extends w {
|
|
|
4485
4542
|
const t = PerformanceObserver.supportedEntryTypes;
|
|
4486
4543
|
return !t || t.includes(e);
|
|
4487
4544
|
}
|
|
4488
|
-
safeObserve(e, t,
|
|
4545
|
+
safeObserve(e, t, s, n = !1) {
|
|
4489
4546
|
try {
|
|
4490
4547
|
if (!this.isObserverSupported(e))
|
|
4491
4548
|
return !1;
|
|
@@ -4504,7 +4561,7 @@ class Cr extends w {
|
|
|
4504
4561
|
} catch {
|
|
4505
4562
|
}
|
|
4506
4563
|
});
|
|
4507
|
-
return i.observe(
|
|
4564
|
+
return i.observe(s ?? { type: e, buffered: !0 }), n || this.observers.push(i), !0;
|
|
4508
4565
|
} catch (i) {
|
|
4509
4566
|
return a("debug", "Failed to create performance observer", {
|
|
4510
4567
|
error: i,
|
|
@@ -4515,11 +4572,11 @@ class Cr extends w {
|
|
|
4515
4572
|
shouldSendVital(e, t) {
|
|
4516
4573
|
if (typeof t != "number" || !Number.isFinite(t))
|
|
4517
4574
|
return a("debug", "Invalid web vital value", { data: { type: e, value: t } }), !1;
|
|
4518
|
-
const
|
|
4519
|
-
return !(typeof
|
|
4575
|
+
const s = this.vitalThresholds[e];
|
|
4576
|
+
return !(typeof s == "number" && t <= s);
|
|
4520
4577
|
}
|
|
4521
4578
|
}
|
|
4522
|
-
class
|
|
4579
|
+
class ae extends _ {
|
|
4523
4580
|
eventManager;
|
|
4524
4581
|
recentErrors = /* @__PURE__ */ new Map();
|
|
4525
4582
|
errorBurstCounter = 0;
|
|
@@ -4555,47 +4612,47 @@ class oe extends w {
|
|
|
4555
4612
|
const e = Date.now();
|
|
4556
4613
|
if (e < this.burstBackoffUntil)
|
|
4557
4614
|
return !1;
|
|
4558
|
-
if (e - this.burstWindowStart >
|
|
4559
|
-
return this.burstBackoffUntil = e +
|
|
4615
|
+
if (e - this.burstWindowStart > jt && (this.errorBurstCounter = 0, this.burstWindowStart = e), this.errorBurstCounter++, this.errorBurstCounter > zt)
|
|
4616
|
+
return this.burstBackoffUntil = e + Qe, a("debug", "Error burst detected - entering cooldown", {
|
|
4560
4617
|
data: {
|
|
4561
4618
|
errorsInWindow: this.errorBurstCounter,
|
|
4562
|
-
cooldownMs:
|
|
4619
|
+
cooldownMs: Qe
|
|
4563
4620
|
}
|
|
4564
4621
|
}), !1;
|
|
4565
|
-
const
|
|
4566
|
-
return Math.random() <
|
|
4622
|
+
const s = this.get("config").errorSampling ?? ct;
|
|
4623
|
+
return Math.random() < s;
|
|
4567
4624
|
}
|
|
4568
4625
|
handleError = (e) => {
|
|
4569
4626
|
if (!this.shouldSample())
|
|
4570
4627
|
return;
|
|
4571
4628
|
const t = this.sanitize(e.message || "Unknown error");
|
|
4572
|
-
if (this.shouldSuppressError(
|
|
4629
|
+
if (this.shouldSuppressError(B.JS_ERROR, t))
|
|
4573
4630
|
return;
|
|
4574
|
-
const
|
|
4631
|
+
const s = typeof e.error?.stack == "string" ? this.truncateStack(e.error.stack) : void 0;
|
|
4575
4632
|
this.eventManager.track({
|
|
4576
|
-
type:
|
|
4633
|
+
type: u.ERROR,
|
|
4577
4634
|
error_data: {
|
|
4578
|
-
type:
|
|
4635
|
+
type: B.JS_ERROR,
|
|
4579
4636
|
message: t,
|
|
4580
4637
|
...e.filename !== "" && { filename: e.filename },
|
|
4581
4638
|
...e.lineno !== 0 && { line: e.lineno },
|
|
4582
4639
|
...e.colno !== 0 && { column: e.colno },
|
|
4583
|
-
...
|
|
4640
|
+
...s !== void 0 && { stack: s }
|
|
4584
4641
|
}
|
|
4585
4642
|
});
|
|
4586
4643
|
};
|
|
4587
4644
|
handleRejection = (e) => {
|
|
4588
4645
|
if (!this.shouldSample())
|
|
4589
4646
|
return;
|
|
4590
|
-
const t = this.extractRejectionMessage(e.reason),
|
|
4591
|
-
if (this.shouldSuppressError(
|
|
4647
|
+
const t = this.extractRejectionMessage(e.reason), s = this.sanitize(t);
|
|
4648
|
+
if (this.shouldSuppressError(B.PROMISE_REJECTION, s))
|
|
4592
4649
|
return;
|
|
4593
4650
|
const n = e.reason instanceof Error && typeof e.reason.stack == "string" ? this.truncateStack(e.reason.stack) : void 0;
|
|
4594
4651
|
this.eventManager.track({
|
|
4595
|
-
type:
|
|
4652
|
+
type: u.ERROR,
|
|
4596
4653
|
error_data: {
|
|
4597
|
-
type:
|
|
4598
|
-
message:
|
|
4654
|
+
type: B.PROMISE_REJECTION,
|
|
4655
|
+
message: s,
|
|
4599
4656
|
...n !== void 0 && { stack: n }
|
|
4600
4657
|
}
|
|
4601
4658
|
});
|
|
@@ -4614,50 +4671,51 @@ class oe extends w {
|
|
|
4614
4671
|
}
|
|
4615
4672
|
}
|
|
4616
4673
|
sanitize(e) {
|
|
4617
|
-
const t = e.length >
|
|
4674
|
+
const t = e.length > Ge ? e.slice(0, Ge) + "..." : e;
|
|
4618
4675
|
return this.sanitizePii(t);
|
|
4619
4676
|
}
|
|
4620
4677
|
sanitizePii(e) {
|
|
4621
4678
|
let t = e;
|
|
4622
|
-
for (const
|
|
4623
|
-
const n = new RegExp(
|
|
4679
|
+
for (const s of lt) {
|
|
4680
|
+
const n = new RegExp(s.source, s.flags);
|
|
4624
4681
|
t = t.replace(n, "[REDACTED]");
|
|
4625
4682
|
}
|
|
4626
4683
|
return t;
|
|
4627
4684
|
}
|
|
4628
4685
|
shouldSuppressError(e, t) {
|
|
4629
|
-
const
|
|
4630
|
-
return i !== void 0 &&
|
|
4686
|
+
const s = Date.now(), n = `${e}:${t}`, i = this.recentErrors.get(n);
|
|
4687
|
+
return i !== void 0 && s - i < ze ? (this.recentErrors.set(n, s), !0) : (this.recentErrors.set(n, s), this.recentErrors.size > Gt ? (this.recentErrors.clear(), this.recentErrors.set(n, s), !1) : (this.recentErrors.size > ee && this.pruneOldErrors(), !1));
|
|
4631
4688
|
}
|
|
4632
4689
|
static TRUNCATION_SUFFIX = `
|
|
4633
4690
|
...truncated`;
|
|
4634
4691
|
truncateStack(e) {
|
|
4635
|
-
if (e.length <=
|
|
4636
|
-
const t =
|
|
4637
|
-
return this.sanitizePii(
|
|
4692
|
+
if (e.length <= je) return this.sanitizePii(e);
|
|
4693
|
+
const t = je - ae.TRUNCATION_SUFFIX.length, s = e.slice(0, t) + ae.TRUNCATION_SUFFIX;
|
|
4694
|
+
return this.sanitizePii(s);
|
|
4638
4695
|
}
|
|
4639
4696
|
pruneOldErrors() {
|
|
4640
4697
|
const e = Date.now();
|
|
4641
4698
|
for (const [n, i] of this.recentErrors.entries())
|
|
4642
|
-
e - i >
|
|
4643
|
-
if (this.recentErrors.size <=
|
|
4699
|
+
e - i > ze && this.recentErrors.delete(n);
|
|
4700
|
+
if (this.recentErrors.size <= ee)
|
|
4644
4701
|
return;
|
|
4645
|
-
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]),
|
|
4646
|
-
for (let n = 0; n <
|
|
4702
|
+
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]), s = this.recentErrors.size - ee;
|
|
4703
|
+
for (let n = 0; n < s; n += 1) {
|
|
4647
4704
|
const i = t[n];
|
|
4648
4705
|
i && this.recentErrors.delete(i[0]);
|
|
4649
4706
|
}
|
|
4650
4707
|
}
|
|
4651
4708
|
}
|
|
4652
|
-
class
|
|
4709
|
+
class Os extends _ {
|
|
4653
4710
|
isInitialized = !1;
|
|
4654
4711
|
suppressNextScrollTimer = null;
|
|
4655
4712
|
pageUnloadHandler = null;
|
|
4656
|
-
emitter = new
|
|
4713
|
+
emitter = new gs();
|
|
4657
4714
|
transformers = {};
|
|
4658
4715
|
customHeadersProvider;
|
|
4659
4716
|
managers = {};
|
|
4660
4717
|
handlers = {};
|
|
4718
|
+
integrationInstances = {};
|
|
4661
4719
|
get initialized() {
|
|
4662
4720
|
return this.isInitialized;
|
|
4663
4721
|
}
|
|
@@ -4671,24 +4729,24 @@ class Rr extends w {
|
|
|
4671
4729
|
async init(e = {}) {
|
|
4672
4730
|
if (this.isInitialized)
|
|
4673
4731
|
return { sessionId: this.get("sessionId") ?? "" };
|
|
4674
|
-
this.managers.storage = new
|
|
4732
|
+
this.managers.storage = new Rs();
|
|
4675
4733
|
try {
|
|
4676
4734
|
this.setupState(e);
|
|
4677
|
-
const t = e.integrations?.custom?.headers ?? {},
|
|
4678
|
-
return this.managers.event = new
|
|
4735
|
+
const t = e.integrations?.custom?.headers ?? {}, s = e.integrations?.custom?.fetchCredentials ?? "include";
|
|
4736
|
+
return this.managers.event = new Ts(
|
|
4679
4737
|
this.managers.storage,
|
|
4680
4738
|
this.emitter,
|
|
4681
4739
|
this.transformers,
|
|
4682
4740
|
t,
|
|
4683
4741
|
this.customHeadersProvider,
|
|
4684
|
-
|
|
4742
|
+
s
|
|
4685
4743
|
), this.loadPersistedIdentity(), this.initializeHandlers(), this.setupPageLifecycleListeners(), await this.managers.event.recoverPersistedEvents().catch((n) => {
|
|
4686
4744
|
a("warn", "Failed to recover persisted events", { error: n });
|
|
4687
4745
|
}), this.isInitialized = !0, { sessionId: this.get("sessionId") ?? "" };
|
|
4688
4746
|
} catch (t) {
|
|
4689
4747
|
this.destroy(!0);
|
|
4690
|
-
const
|
|
4691
|
-
throw new Error(`[TraceLog] TraceLog initialization failed: ${
|
|
4748
|
+
const s = t instanceof Error ? t.message : String(t);
|
|
4749
|
+
throw new Error(`[TraceLog] TraceLog initialization failed: ${s}`);
|
|
4692
4750
|
}
|
|
4693
4751
|
}
|
|
4694
4752
|
/**
|
|
@@ -4703,17 +4761,17 @@ class Rr extends w {
|
|
|
4703
4761
|
a("warn", "Cannot send custom event: TraceLog not initialized", { data: { name: e } });
|
|
4704
4762
|
return;
|
|
4705
4763
|
}
|
|
4706
|
-
let
|
|
4707
|
-
t && typeof t == "object" && !Array.isArray(t) && Object.getPrototypeOf(t) !== Object.prototype && (
|
|
4708
|
-
const { valid: n, error: i, sanitizedMetadata: o } =
|
|
4764
|
+
let s = t;
|
|
4765
|
+
t && typeof t == "object" && !Array.isArray(t) && Object.getPrototypeOf(t) !== Object.prototype && (s = Object.assign({}, t));
|
|
4766
|
+
const { valid: n, error: i, sanitizedMetadata: o } = ms(e, s);
|
|
4709
4767
|
if (!n) {
|
|
4710
|
-
if (this.get("mode") ===
|
|
4768
|
+
if (this.get("mode") === ie.QA)
|
|
4711
4769
|
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${i}`);
|
|
4712
4770
|
a("warn", `Custom event "${e}" dropped: ${i}`);
|
|
4713
4771
|
return;
|
|
4714
4772
|
}
|
|
4715
4773
|
this.managers.event.track({
|
|
4716
|
-
type:
|
|
4774
|
+
type: u.CUSTOM,
|
|
4717
4775
|
custom_event: {
|
|
4718
4776
|
name: e,
|
|
4719
4777
|
...o && { metadata: o }
|
|
@@ -4768,21 +4826,21 @@ class Rr extends w {
|
|
|
4768
4826
|
!this.isInitialized && !e || (Object.values(this.handlers).filter(Boolean).forEach((t) => {
|
|
4769
4827
|
try {
|
|
4770
4828
|
t.stopTracking();
|
|
4771
|
-
} catch (
|
|
4772
|
-
a("warn", "Failed to stop tracking", { error:
|
|
4829
|
+
} catch (s) {
|
|
4830
|
+
a("warn", "Failed to stop tracking", { error: s });
|
|
4773
4831
|
}
|
|
4774
|
-
}), this.suppressNextScrollTimer && (clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = null), this.pageUnloadHandler && (window.removeEventListener("pagehide", this.pageUnloadHandler), window.removeEventListener("beforeunload", this.pageUnloadHandler), this.pageUnloadHandler = null), this.managers.event?.flushImmediatelySync(), this.managers.event?.stop(), this.emitter.removeAllListeners(), this.transformers.beforeSend = void 0, this.transformers.beforeBatch = void 0, this.customHeadersProvider = void 0, this.set("suppressNextScroll", !1), this.set("sessionId", null), this.set("identity", void 0), this.clearPersistedIdentity(), this.isInitialized = !1, this.handlers = {}, this.managers = {});
|
|
4832
|
+
}), this.suppressNextScrollTimer && (clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = null), this.pageUnloadHandler && (window.removeEventListener("pagehide", this.pageUnloadHandler), window.removeEventListener("beforeunload", this.pageUnloadHandler), this.pageUnloadHandler = null), this.managers.event?.flushImmediatelySync(), this.managers.event?.stop(), this.emitter.removeAllListeners(), this.transformers.beforeSend = void 0, this.transformers.beforeBatch = void 0, this.customHeadersProvider = void 0, this.set("suppressNextScroll", !1), this.set("sessionId", null), this.set("identity", void 0), this.clearPersistedIdentity(), this.integrationInstances.shopifyCartLinker?.deactivate(), this.integrationInstances = {}, this.isInitialized = !1, this.handlers = {}, this.managers = {});
|
|
4775
4833
|
}
|
|
4776
4834
|
setupState(e = {}) {
|
|
4777
4835
|
this.set("config", e);
|
|
4778
|
-
const t =
|
|
4836
|
+
const t = Is.getId(this.managers.storage);
|
|
4779
4837
|
this.set("userId", t);
|
|
4780
|
-
const
|
|
4781
|
-
this.set("collectApiUrls",
|
|
4782
|
-
const n =
|
|
4838
|
+
const s = os(e);
|
|
4839
|
+
this.set("collectApiUrls", s);
|
|
4840
|
+
const n = Xt();
|
|
4783
4841
|
this.set("device", n);
|
|
4784
|
-
const i =
|
|
4785
|
-
this.set("pageUrl", i),
|
|
4842
|
+
const i = we(window.location.href, e.sensitiveQueryParams);
|
|
4843
|
+
this.set("pageUrl", i), ts() && this.set("mode", ie.QA);
|
|
4786
4844
|
}
|
|
4787
4845
|
/**
|
|
4788
4846
|
* Returns the current configuration object.
|
|
@@ -4833,7 +4891,7 @@ class Rr extends w {
|
|
|
4833
4891
|
valid: !1,
|
|
4834
4892
|
error: "Global metadata must be a plain object"
|
|
4835
4893
|
};
|
|
4836
|
-
const t =
|
|
4894
|
+
const t = mt("Global", e, "globalMetadata");
|
|
4837
4895
|
return t.valid ? { valid: !0 } : {
|
|
4838
4896
|
valid: !1,
|
|
4839
4897
|
error: t.error
|
|
@@ -4867,11 +4925,11 @@ class Rr extends w {
|
|
|
4867
4925
|
const t = this.validateGlobalMetadata(e);
|
|
4868
4926
|
if (!t.valid)
|
|
4869
4927
|
throw new Error(`[TraceLog] Invalid global metadata: ${t.error}`);
|
|
4870
|
-
const
|
|
4871
|
-
...
|
|
4928
|
+
const s = this.get("config"), i = {
|
|
4929
|
+
...s.globalMetadata ?? {},
|
|
4872
4930
|
...e
|
|
4873
4931
|
}, o = {
|
|
4874
|
-
...
|
|
4932
|
+
...s,
|
|
4875
4933
|
globalMetadata: i
|
|
4876
4934
|
};
|
|
4877
4935
|
this.set("config", o), a("debug", "Global metadata updated (merged)", { data: { keys: Object.keys(e) } });
|
|
@@ -4900,12 +4958,12 @@ class Rr extends w {
|
|
|
4900
4958
|
a("warn", "identify() userId exceeds 256 characters", { data: { length: e.trim().length } });
|
|
4901
4959
|
return;
|
|
4902
4960
|
}
|
|
4903
|
-
const
|
|
4904
|
-
userId:
|
|
4961
|
+
const s = e.trim(), n = ft(t), i = {
|
|
4962
|
+
userId: s,
|
|
4905
4963
|
...n ? { traits: n } : {}
|
|
4906
4964
|
};
|
|
4907
4965
|
this.set("identity", i), this.persistIdentity(i), a("debug", "Visitor identified", {
|
|
4908
|
-
data: { userIdLength:
|
|
4966
|
+
data: { userIdLength: s.length, traitKeys: n ? Object.keys(n) : [] }
|
|
4909
4967
|
});
|
|
4910
4968
|
}
|
|
4911
4969
|
/**
|
|
@@ -4920,7 +4978,7 @@ class Rr extends w {
|
|
|
4920
4978
|
async resetIdentity() {
|
|
4921
4979
|
await this.managers.event?.flushImmediately(), this.set("identity", void 0), this.clearPersistedIdentity();
|
|
4922
4980
|
const e = ut();
|
|
4923
|
-
this.managers.storage.setItem(
|
|
4981
|
+
this.managers.storage.setItem(Te, e), this.set("userId", e), this.set("hasStartSession", !1), this.set("sessionId", null), this.handlers.session?.stopTracking(), this.handlers.session?.startTracking(), a("debug", "Identity reset, new UUID generated");
|
|
4924
4982
|
}
|
|
4925
4983
|
/**
|
|
4926
4984
|
* Returns the project ID used for identity storage scoping.
|
|
@@ -4934,8 +4992,8 @@ class Rr extends w {
|
|
|
4934
4992
|
*/
|
|
4935
4993
|
persistIdentity(e) {
|
|
4936
4994
|
try {
|
|
4937
|
-
const t = this.getProjectId(),
|
|
4938
|
-
this.managers.storage.setItem(
|
|
4995
|
+
const t = this.getProjectId(), s = fe(t);
|
|
4996
|
+
this.managers.storage.setItem(s, JSON.stringify(e));
|
|
4939
4997
|
} catch {
|
|
4940
4998
|
a("debug", "Failed to persist identity to localStorage");
|
|
4941
4999
|
}
|
|
@@ -4945,28 +5003,28 @@ class Rr extends w {
|
|
|
4945
5003
|
* Also migrates pending identity (set before init) to the project-scoped key.
|
|
4946
5004
|
*/
|
|
4947
5005
|
loadPersistedIdentity() {
|
|
4948
|
-
const e = this.managers.storage, t = this.getProjectId(),
|
|
5006
|
+
const e = this.managers.storage, t = this.getProjectId(), s = fe(t);
|
|
4949
5007
|
try {
|
|
4950
|
-
const n = e.getItem(
|
|
5008
|
+
const n = e.getItem(U);
|
|
4951
5009
|
if (n) {
|
|
4952
5010
|
const i = JSON.parse(n);
|
|
4953
|
-
if (e.removeItem(
|
|
5011
|
+
if (e.removeItem(U), !this.isValidIdentityData(i)) {
|
|
4954
5012
|
a("debug", "Invalid pending identity in localStorage, discarded");
|
|
4955
5013
|
return;
|
|
4956
5014
|
}
|
|
4957
5015
|
const o = { ...i, userId: i.userId.trim() };
|
|
4958
|
-
e.setItem(
|
|
5016
|
+
e.setItem(s, JSON.stringify(o)), this.set("identity", o), a("debug", "Migrated pending identity to project-scoped key");
|
|
4959
5017
|
return;
|
|
4960
5018
|
}
|
|
4961
5019
|
} catch {
|
|
4962
|
-
e.removeItem(
|
|
5020
|
+
e.removeItem(U);
|
|
4963
5021
|
}
|
|
4964
5022
|
try {
|
|
4965
|
-
const n = e.getItem(
|
|
5023
|
+
const n = e.getItem(s);
|
|
4966
5024
|
if (n) {
|
|
4967
5025
|
const i = JSON.parse(n);
|
|
4968
5026
|
if (!this.isValidIdentityData(i)) {
|
|
4969
|
-
e.removeItem(
|
|
5027
|
+
e.removeItem(s), a("debug", "Invalid persisted identity in localStorage, discarded");
|
|
4970
5028
|
return;
|
|
4971
5029
|
}
|
|
4972
5030
|
const o = { ...i, userId: i.userId.trim() };
|
|
@@ -4982,11 +5040,11 @@ class Rr extends w {
|
|
|
4982
5040
|
*/
|
|
4983
5041
|
isValidIdentityData(e) {
|
|
4984
5042
|
if (!e || typeof e != "object") return !1;
|
|
4985
|
-
const { userId: t, traits:
|
|
5043
|
+
const { userId: t, traits: s } = e;
|
|
4986
5044
|
if (typeof t != "string" || t.trim().length === 0 || t.trim().length > 256) return !1;
|
|
4987
|
-
if (
|
|
4988
|
-
if (typeof
|
|
4989
|
-
for (const n of Object.values(
|
|
5045
|
+
if (s !== void 0) {
|
|
5046
|
+
if (typeof s != "object" || s === null || Array.isArray(s)) return !1;
|
|
5047
|
+
for (const n of Object.values(s))
|
|
4990
5048
|
if (typeof n != "string") return !1;
|
|
4991
5049
|
}
|
|
4992
5050
|
return !0;
|
|
@@ -4997,7 +5055,7 @@ class Rr extends w {
|
|
|
4997
5055
|
clearPersistedIdentity() {
|
|
4998
5056
|
try {
|
|
4999
5057
|
const e = this.managers.storage, t = this.getProjectId();
|
|
5000
|
-
e.removeItem(
|
|
5058
|
+
e.removeItem(fe(t)), e.removeItem(U);
|
|
5001
5059
|
} catch {
|
|
5002
5060
|
a("debug", "Failed to clear persisted identity");
|
|
5003
5061
|
}
|
|
@@ -5009,7 +5067,7 @@ class Rr extends w {
|
|
|
5009
5067
|
}
|
|
5010
5068
|
initializeHandlers() {
|
|
5011
5069
|
const e = this.get("config");
|
|
5012
|
-
this.handlers.session = new
|
|
5070
|
+
this.handlers.session = new ys(
|
|
5013
5071
|
this.managers.storage,
|
|
5014
5072
|
this.managers.event
|
|
5015
5073
|
), this.handlers.session.startTracking();
|
|
@@ -5018,105 +5076,110 @@ class Rr extends w {
|
|
|
5018
5076
|
this.set("suppressNextScroll", !1);
|
|
5019
5077
|
}, 500);
|
|
5020
5078
|
};
|
|
5021
|
-
this.handlers.pageView = new
|
|
5022
|
-
a("warn", "Failed to start performance tracking", { error:
|
|
5023
|
-
}), this.handlers.error = new
|
|
5079
|
+
if (this.handlers.pageView = new ws(this.managers.event, t), this.handlers.pageView.startTracking(), this.handlers.click = new bs(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new As(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new Ns(this.managers.event), this.handlers.performance.startTracking().catch((s) => {
|
|
5080
|
+
a("warn", "Failed to start performance tracking", { error: s });
|
|
5081
|
+
}), this.handlers.error = new ae(this.managers.event), this.handlers.error.startTracking(), e.viewport && (this.handlers.viewport = new Ls(this.managers.event), this.handlers.viewport.startTracking()), e.integrations?.tracelog?.shopify) {
|
|
5082
|
+
const s = new Cs();
|
|
5083
|
+
s.activate(), this.integrationInstances.shopifyCartLinker = s, this.emitter.on(se.EVENT, (n) => {
|
|
5084
|
+
n.type === u.SESSION_START && s.onSessionChange();
|
|
5085
|
+
});
|
|
5086
|
+
}
|
|
5024
5087
|
}
|
|
5025
5088
|
}
|
|
5026
5089
|
const k = [], M = [];
|
|
5027
5090
|
let D = null, h = null, R = !1, p = !1, P = null;
|
|
5028
|
-
const
|
|
5091
|
+
const Ps = async (r) => typeof window > "u" || typeof document > "u" ? { sessionId: "" } : (p = !1, window.__traceLogDisabled === !0 ? { sessionId: "" } : h ? { sessionId: h.getSessionId() ?? "" } : (R && P || (R = !0, P = (async () => {
|
|
5029
5092
|
try {
|
|
5030
|
-
const e =
|
|
5093
|
+
const e = us(r ?? {}), t = new Os();
|
|
5031
5094
|
try {
|
|
5032
5095
|
k.forEach(({ event: o, callback: l }) => {
|
|
5033
5096
|
t.on(o, l);
|
|
5034
5097
|
}), k.length = 0, M.forEach(({ hook: o, fn: l }) => {
|
|
5035
5098
|
o === "beforeSend" ? t.setTransformer("beforeSend", l) : t.setTransformer("beforeBatch", l);
|
|
5036
5099
|
}), M.length = 0, D && (t.setCustomHeaders(D), D = null);
|
|
5037
|
-
const
|
|
5100
|
+
const s = t.init(e), n = new Promise((o, l) => {
|
|
5038
5101
|
setTimeout(() => {
|
|
5039
5102
|
l(new Error("[TraceLog] Initialization timeout after 10000ms"));
|
|
5040
5103
|
}, 1e4);
|
|
5041
|
-
}), i = await Promise.race([
|
|
5104
|
+
}), i = await Promise.race([s, n]);
|
|
5042
5105
|
return h = t, i;
|
|
5043
|
-
} catch (
|
|
5106
|
+
} catch (s) {
|
|
5044
5107
|
try {
|
|
5045
5108
|
t.destroy(!0);
|
|
5046
5109
|
} catch (n) {
|
|
5047
5110
|
a("error", "Failed to cleanup partially initialized app", { error: n });
|
|
5048
5111
|
}
|
|
5049
|
-
throw
|
|
5112
|
+
throw s;
|
|
5050
5113
|
}
|
|
5051
5114
|
} catch (e) {
|
|
5052
5115
|
throw h = null, e;
|
|
5053
5116
|
} finally {
|
|
5054
5117
|
R = !1, P = null;
|
|
5055
5118
|
}
|
|
5056
|
-
})()), P)),
|
|
5119
|
+
})()), P)), Ds = (r, e) => {
|
|
5057
5120
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5058
5121
|
if (!h)
|
|
5059
5122
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5060
5123
|
if (p)
|
|
5061
5124
|
throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
|
|
5062
|
-
h.sendCustomEvent(
|
|
5125
|
+
h.sendCustomEvent(r, e);
|
|
5063
5126
|
}
|
|
5064
|
-
},
|
|
5127
|
+
}, ks = (r, e) => {
|
|
5065
5128
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5066
5129
|
if (!h || R) {
|
|
5067
|
-
k.push({ event:
|
|
5130
|
+
k.push({ event: r, callback: e });
|
|
5068
5131
|
return;
|
|
5069
5132
|
}
|
|
5070
|
-
h.on(
|
|
5133
|
+
h.on(r, e);
|
|
5071
5134
|
}
|
|
5072
|
-
},
|
|
5135
|
+
}, Vs = (r, e) => {
|
|
5073
5136
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5074
5137
|
if (!h) {
|
|
5075
|
-
const t = k.findIndex((
|
|
5138
|
+
const t = k.findIndex((s) => s.event === r && s.callback === e);
|
|
5076
5139
|
t !== -1 && k.splice(t, 1);
|
|
5077
5140
|
return;
|
|
5078
5141
|
}
|
|
5079
|
-
h.off(
|
|
5142
|
+
h.off(r, e);
|
|
5080
5143
|
}
|
|
5081
5144
|
};
|
|
5082
|
-
function
|
|
5145
|
+
function Us(r, e) {
|
|
5083
5146
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5084
5147
|
if (typeof e != "function")
|
|
5085
5148
|
throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof e}`);
|
|
5086
5149
|
if (!h || R) {
|
|
5087
|
-
const t = M.findIndex((
|
|
5088
|
-
t !== -1 && M.splice(t, 1), M.push({ hook:
|
|
5150
|
+
const t = M.findIndex((s) => s.hook === r);
|
|
5151
|
+
t !== -1 && M.splice(t, 1), M.push({ hook: r, fn: e });
|
|
5089
5152
|
return;
|
|
5090
5153
|
}
|
|
5091
5154
|
if (p)
|
|
5092
5155
|
throw new Error("[TraceLog] Cannot set transformers while TraceLog is being destroyed");
|
|
5093
|
-
|
|
5156
|
+
r === "beforeSend" ? h.setTransformer("beforeSend", e) : h.setTransformer("beforeBatch", e);
|
|
5094
5157
|
}
|
|
5095
5158
|
}
|
|
5096
|
-
const
|
|
5159
|
+
const Hs = (r) => {
|
|
5097
5160
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5098
5161
|
if (!h) {
|
|
5099
|
-
const e = M.findIndex((t) => t.hook ===
|
|
5162
|
+
const e = M.findIndex((t) => t.hook === r);
|
|
5100
5163
|
e !== -1 && M.splice(e, 1);
|
|
5101
5164
|
return;
|
|
5102
5165
|
}
|
|
5103
5166
|
if (p)
|
|
5104
5167
|
throw new Error("[TraceLog] Cannot remove transformers while TraceLog is being destroyed");
|
|
5105
|
-
h.removeTransformer(
|
|
5168
|
+
h.removeTransformer(r);
|
|
5106
5169
|
}
|
|
5107
|
-
},
|
|
5170
|
+
}, Fs = (r) => {
|
|
5108
5171
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5109
|
-
if (typeof
|
|
5110
|
-
throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof
|
|
5172
|
+
if (typeof r != "function")
|
|
5173
|
+
throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof r}`);
|
|
5111
5174
|
if (!h || R) {
|
|
5112
|
-
D =
|
|
5175
|
+
D = r;
|
|
5113
5176
|
return;
|
|
5114
5177
|
}
|
|
5115
5178
|
if (p)
|
|
5116
5179
|
throw new Error("[TraceLog] Cannot set custom headers while TraceLog is being destroyed");
|
|
5117
|
-
h.setCustomHeaders(
|
|
5180
|
+
h.setCustomHeaders(r);
|
|
5118
5181
|
}
|
|
5119
|
-
},
|
|
5182
|
+
}, xs = () => {
|
|
5120
5183
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5121
5184
|
if (!h) {
|
|
5122
5185
|
D = null;
|
|
@@ -5126,7 +5189,7 @@ const Vr = (s) => {
|
|
|
5126
5189
|
throw new Error("[TraceLog] Cannot remove custom headers while TraceLog is being destroyed");
|
|
5127
5190
|
h.removeCustomHeaders();
|
|
5128
5191
|
}
|
|
5129
|
-
},
|
|
5192
|
+
}, $s = () => typeof window > "u" || typeof document > "u" ? !1 : h !== null, Bs = () => typeof window > "u" || typeof document > "u" || !h ? null : h.getSessionId(), Ws = () => {
|
|
5130
5193
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5131
5194
|
if (p)
|
|
5132
5195
|
throw new Error("[TraceLog] Destroy operation already in progress");
|
|
@@ -5137,35 +5200,35 @@ const Vr = (s) => {
|
|
|
5137
5200
|
p = !0;
|
|
5138
5201
|
try {
|
|
5139
5202
|
h.destroy(), h = null, R = !1, P = null, k.length = 0, M.length = 0, D = null, p = !1;
|
|
5140
|
-
} catch (
|
|
5141
|
-
h = null, R = !1, P = null, k.length = 0, M.length = 0, D = null, p = !1, a("warn", "Error during destroy, forced cleanup completed", { error:
|
|
5203
|
+
} catch (r) {
|
|
5204
|
+
h = null, R = !1, P = null, k.length = 0, M.length = 0, D = null, p = !1, a("warn", "Error during destroy, forced cleanup completed", { error: r });
|
|
5142
5205
|
}
|
|
5143
5206
|
}
|
|
5144
|
-
},
|
|
5145
|
-
typeof window > "u" || typeof document > "u" ||
|
|
5146
|
-
},
|
|
5207
|
+
}, Xs = (r) => {
|
|
5208
|
+
typeof window > "u" || typeof document > "u" || ss(r);
|
|
5209
|
+
}, Gs = (r) => {
|
|
5147
5210
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5148
5211
|
if (!h)
|
|
5149
5212
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5150
5213
|
if (p)
|
|
5151
5214
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
5152
|
-
h.updateGlobalMetadata(
|
|
5215
|
+
h.updateGlobalMetadata(r);
|
|
5153
5216
|
}
|
|
5154
|
-
},
|
|
5217
|
+
}, js = (r) => {
|
|
5155
5218
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5156
5219
|
if (!h)
|
|
5157
5220
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5158
5221
|
if (p)
|
|
5159
5222
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
5160
|
-
h.mergeGlobalMetadata(
|
|
5223
|
+
h.mergeGlobalMetadata(r);
|
|
5161
5224
|
}
|
|
5162
|
-
},
|
|
5225
|
+
}, zs = (r, e) => {
|
|
5163
5226
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5164
|
-
if (!
|
|
5227
|
+
if (!r || typeof r != "string" || r.trim().length === 0) {
|
|
5165
5228
|
a("warn", "identify() called with invalid userId");
|
|
5166
5229
|
return;
|
|
5167
5230
|
}
|
|
5168
|
-
if (
|
|
5231
|
+
if (r.trim().length > 256) {
|
|
5169
5232
|
a("warn", "identify() userId exceeds 256 characters");
|
|
5170
5233
|
return;
|
|
5171
5234
|
}
|
|
@@ -5174,24 +5237,24 @@ const Vr = (s) => {
|
|
|
5174
5237
|
return;
|
|
5175
5238
|
}
|
|
5176
5239
|
if (h) {
|
|
5177
|
-
h.identify(
|
|
5240
|
+
h.identify(r, e);
|
|
5178
5241
|
return;
|
|
5179
5242
|
}
|
|
5180
5243
|
try {
|
|
5181
|
-
const t =
|
|
5182
|
-
userId:
|
|
5244
|
+
const t = ft(e), s = {
|
|
5245
|
+
userId: r.trim(),
|
|
5183
5246
|
...t ? { traits: t } : {}
|
|
5184
5247
|
};
|
|
5185
|
-
localStorage.setItem(
|
|
5248
|
+
localStorage.setItem(U, JSON.stringify(s)), a("debug", "Identity persisted pre-init (will be applied on init)");
|
|
5186
5249
|
} catch {
|
|
5187
5250
|
a("debug", "Failed to persist pre-init identity");
|
|
5188
5251
|
}
|
|
5189
5252
|
}
|
|
5190
|
-
},
|
|
5253
|
+
}, Qs = async () => {
|
|
5191
5254
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5192
5255
|
if (!h) {
|
|
5193
5256
|
try {
|
|
5194
|
-
localStorage.removeItem(
|
|
5257
|
+
localStorage.removeItem(U);
|
|
5195
5258
|
} catch {
|
|
5196
5259
|
}
|
|
5197
5260
|
return;
|
|
@@ -5200,299 +5263,299 @@ const Vr = (s) => {
|
|
|
5200
5263
|
throw new Error("[TraceLog] Cannot reset identity while TraceLog is being destroyed");
|
|
5201
5264
|
await h.resetIdentity();
|
|
5202
5265
|
}
|
|
5203
|
-
},
|
|
5204
|
-
init:
|
|
5205
|
-
event:
|
|
5206
|
-
on:
|
|
5207
|
-
off:
|
|
5208
|
-
setTransformer:
|
|
5209
|
-
removeTransformer:
|
|
5210
|
-
setCustomHeaders:
|
|
5211
|
-
removeCustomHeaders:
|
|
5212
|
-
isInitialized:
|
|
5213
|
-
getSessionId:
|
|
5214
|
-
destroy:
|
|
5215
|
-
setQaMode:
|
|
5216
|
-
updateGlobalMetadata:
|
|
5217
|
-
mergeGlobalMetadata:
|
|
5218
|
-
identify:
|
|
5219
|
-
resetIdentity:
|
|
5266
|
+
}, yr = {
|
|
5267
|
+
init: Ps,
|
|
5268
|
+
event: Ds,
|
|
5269
|
+
on: ks,
|
|
5270
|
+
off: Vs,
|
|
5271
|
+
setTransformer: Us,
|
|
5272
|
+
removeTransformer: Hs,
|
|
5273
|
+
setCustomHeaders: Fs,
|
|
5274
|
+
removeCustomHeaders: xs,
|
|
5275
|
+
isInitialized: $s,
|
|
5276
|
+
getSessionId: Bs,
|
|
5277
|
+
destroy: Ws,
|
|
5278
|
+
setQaMode: Xs,
|
|
5279
|
+
updateGlobalMetadata: Gs,
|
|
5280
|
+
mergeGlobalMetadata: js,
|
|
5281
|
+
identify: zs,
|
|
5282
|
+
resetIdentity: Qs
|
|
5220
5283
|
};
|
|
5221
|
-
var
|
|
5284
|
+
var Le, C, G, St, le, pt = -1, V = function(r) {
|
|
5222
5285
|
addEventListener("pageshow", (function(e) {
|
|
5223
|
-
e.persisted && (
|
|
5286
|
+
e.persisted && (pt = e.timeStamp, r(e));
|
|
5224
5287
|
}), !0);
|
|
5225
|
-
},
|
|
5226
|
-
var
|
|
5227
|
-
if (
|
|
5228
|
-
},
|
|
5229
|
-
var
|
|
5230
|
-
return
|
|
5231
|
-
},
|
|
5232
|
-
var t =
|
|
5233
|
-
return
|
|
5234
|
-
},
|
|
5288
|
+
}, De = function() {
|
|
5289
|
+
var r = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
|
|
5290
|
+
if (r && r.responseStart > 0 && r.responseStart < performance.now()) return r;
|
|
5291
|
+
}, de = function() {
|
|
5292
|
+
var r = De();
|
|
5293
|
+
return r && r.activationStart || 0;
|
|
5294
|
+
}, y = function(r, e) {
|
|
5295
|
+
var t = De(), s = "navigate";
|
|
5296
|
+
return pt >= 0 ? s = "back-forward-cache" : t && (document.prerendering || de() > 0 ? s = "prerender" : document.wasDiscarded ? s = "restore" : t.type && (s = t.type.replace(/_/g, "-"))), { name: r, value: e === void 0 ? -1 : e, rating: "good", delta: 0, entries: [], id: "v4-".concat(Date.now(), "-").concat(Math.floor(8999999999999 * Math.random()) + 1e12), navigationType: s };
|
|
5297
|
+
}, F = function(r, e, t) {
|
|
5235
5298
|
try {
|
|
5236
|
-
if (PerformanceObserver.supportedEntryTypes.includes(
|
|
5237
|
-
var
|
|
5299
|
+
if (PerformanceObserver.supportedEntryTypes.includes(r)) {
|
|
5300
|
+
var s = new PerformanceObserver((function(n) {
|
|
5238
5301
|
Promise.resolve().then((function() {
|
|
5239
5302
|
e(n.getEntries());
|
|
5240
5303
|
}));
|
|
5241
5304
|
}));
|
|
5242
|
-
return
|
|
5305
|
+
return s.observe(Object.assign({ type: r, buffered: !0 }, t || {})), s;
|
|
5243
5306
|
}
|
|
5244
5307
|
} catch {
|
|
5245
5308
|
}
|
|
5246
|
-
},
|
|
5309
|
+
}, w = function(r, e, t, s) {
|
|
5247
5310
|
var n, i;
|
|
5248
5311
|
return function(o) {
|
|
5249
|
-
e.value >= 0 && (o ||
|
|
5312
|
+
e.value >= 0 && (o || s) && ((i = e.value - (n || 0)) || n === void 0) && (n = e.value, e.delta = i, e.rating = (function(l, c) {
|
|
5250
5313
|
return l > c[1] ? "poor" : l > c[0] ? "needs-improvement" : "good";
|
|
5251
|
-
})(e.value, t),
|
|
5314
|
+
})(e.value, t), r(e));
|
|
5252
5315
|
};
|
|
5253
|
-
},
|
|
5316
|
+
}, ke = function(r) {
|
|
5254
5317
|
requestAnimationFrame((function() {
|
|
5255
5318
|
return requestAnimationFrame((function() {
|
|
5256
|
-
return
|
|
5319
|
+
return r();
|
|
5257
5320
|
}));
|
|
5258
5321
|
}));
|
|
5259
|
-
},
|
|
5322
|
+
}, z = function(r) {
|
|
5260
5323
|
document.addEventListener("visibilitychange", (function() {
|
|
5261
|
-
document.visibilityState === "hidden" &&
|
|
5324
|
+
document.visibilityState === "hidden" && r();
|
|
5262
5325
|
}));
|
|
5263
|
-
}, ue = function(
|
|
5326
|
+
}, ue = function(r) {
|
|
5264
5327
|
var e = !1;
|
|
5265
5328
|
return function() {
|
|
5266
|
-
e || (
|
|
5329
|
+
e || (r(), e = !0);
|
|
5267
5330
|
};
|
|
5268
|
-
},
|
|
5331
|
+
}, H = -1, tt = function() {
|
|
5269
5332
|
return document.visibilityState !== "hidden" || document.prerendering ? 1 / 0 : 0;
|
|
5270
|
-
},
|
|
5271
|
-
document.visibilityState === "hidden" &&
|
|
5272
|
-
},
|
|
5273
|
-
addEventListener("visibilitychange",
|
|
5274
|
-
},
|
|
5275
|
-
removeEventListener("visibilitychange",
|
|
5276
|
-
},
|
|
5277
|
-
return
|
|
5333
|
+
}, ce = function(r) {
|
|
5334
|
+
document.visibilityState === "hidden" && H > -1 && (H = r.type === "visibilitychange" ? r.timeStamp : 0, Ks());
|
|
5335
|
+
}, st = function() {
|
|
5336
|
+
addEventListener("visibilitychange", ce, !0), addEventListener("prerenderingchange", ce, !0);
|
|
5337
|
+
}, Ks = function() {
|
|
5338
|
+
removeEventListener("visibilitychange", ce, !0), removeEventListener("prerenderingchange", ce, !0);
|
|
5339
|
+
}, Ve = function() {
|
|
5340
|
+
return H < 0 && (H = tt(), st(), V((function() {
|
|
5278
5341
|
setTimeout((function() {
|
|
5279
|
-
|
|
5342
|
+
H = tt(), st();
|
|
5280
5343
|
}), 0);
|
|
5281
5344
|
}))), { get firstHiddenTime() {
|
|
5282
|
-
return
|
|
5345
|
+
return H;
|
|
5283
5346
|
} };
|
|
5284
|
-
},
|
|
5347
|
+
}, Q = function(r) {
|
|
5285
5348
|
document.prerendering ? addEventListener("prerenderingchange", (function() {
|
|
5286
|
-
return
|
|
5287
|
-
}), !0) :
|
|
5288
|
-
},
|
|
5289
|
-
e = e || {},
|
|
5290
|
-
var t,
|
|
5349
|
+
return r();
|
|
5350
|
+
}), !0) : r();
|
|
5351
|
+
}, Me = [1800, 3e3], Tt = function(r, e) {
|
|
5352
|
+
e = e || {}, Q((function() {
|
|
5353
|
+
var t, s = Ve(), n = y("FCP"), i = F("paint", (function(o) {
|
|
5291
5354
|
o.forEach((function(l) {
|
|
5292
|
-
l.name === "first-contentful-paint" && (i.disconnect(), l.startTime <
|
|
5355
|
+
l.name === "first-contentful-paint" && (i.disconnect(), l.startTime < s.firstHiddenTime && (n.value = Math.max(l.startTime - de(), 0), n.entries.push(l), t(!0)));
|
|
5293
5356
|
}));
|
|
5294
5357
|
}));
|
|
5295
|
-
i && (t =
|
|
5296
|
-
n =
|
|
5358
|
+
i && (t = w(r, n, Me, e.reportAllChanges), V((function(o) {
|
|
5359
|
+
n = y("FCP"), t = w(r, n, Me, e.reportAllChanges), ke((function() {
|
|
5297
5360
|
n.value = performance.now() - o.timeStamp, t(!0);
|
|
5298
5361
|
}));
|
|
5299
5362
|
})));
|
|
5300
5363
|
}));
|
|
5301
|
-
},
|
|
5302
|
-
e = e || {},
|
|
5303
|
-
var t,
|
|
5304
|
-
c.forEach((function(
|
|
5305
|
-
if (!
|
|
5306
|
-
var
|
|
5307
|
-
n &&
|
|
5364
|
+
}, Ce = [0.1, 0.25], Ys = function(r, e) {
|
|
5365
|
+
e = e || {}, Tt(ue((function() {
|
|
5366
|
+
var t, s = y("CLS", 0), n = 0, i = [], o = function(c) {
|
|
5367
|
+
c.forEach((function(d) {
|
|
5368
|
+
if (!d.hadRecentInput) {
|
|
5369
|
+
var f = i[0], g = i[i.length - 1];
|
|
5370
|
+
n && d.startTime - g.startTime < 1e3 && d.startTime - f.startTime < 5e3 ? (n += d.value, i.push(d)) : (n = d.value, i = [d]);
|
|
5308
5371
|
}
|
|
5309
|
-
})), n >
|
|
5310
|
-
}, l =
|
|
5311
|
-
l && (t =
|
|
5372
|
+
})), n > s.value && (s.value = n, s.entries = i, t());
|
|
5373
|
+
}, l = F("layout-shift", o);
|
|
5374
|
+
l && (t = w(r, s, Ce, e.reportAllChanges), z((function() {
|
|
5312
5375
|
o(l.takeRecords()), t(!0);
|
|
5313
5376
|
})), V((function() {
|
|
5314
|
-
n = 0,
|
|
5377
|
+
n = 0, s = y("CLS", 0), t = w(r, s, Ce, e.reportAllChanges), ke((function() {
|
|
5315
5378
|
return t();
|
|
5316
5379
|
}));
|
|
5317
5380
|
})), setTimeout(t, 0));
|
|
5318
5381
|
})));
|
|
5319
|
-
},
|
|
5320
|
-
|
|
5321
|
-
e.interactionId && (
|
|
5382
|
+
}, It = 0, Se = 1 / 0, J = 0, qs = function(r) {
|
|
5383
|
+
r.forEach((function(e) {
|
|
5384
|
+
e.interactionId && (Se = Math.min(Se, e.interactionId), J = Math.max(J, e.interactionId), It = J ? (J - Se) / 7 + 1 : 0);
|
|
5322
5385
|
}));
|
|
5323
|
-
},
|
|
5324
|
-
return
|
|
5325
|
-
},
|
|
5326
|
-
"interactionCount" in performance ||
|
|
5327
|
-
}, A = [],
|
|
5328
|
-
var
|
|
5329
|
-
return A[
|
|
5330
|
-
},
|
|
5331
|
-
if (
|
|
5332
|
-
return n(
|
|
5333
|
-
})),
|
|
5334
|
-
var e = A[A.length - 1], t =
|
|
5335
|
-
if (t || A.length < 10 ||
|
|
5336
|
-
if (t)
|
|
5386
|
+
}, vt = function() {
|
|
5387
|
+
return Le ? It : performance.interactionCount || 0;
|
|
5388
|
+
}, Js = function() {
|
|
5389
|
+
"interactionCount" in performance || Le || (Le = F("event", qs, { type: "event", buffered: !0, durationThreshold: 0 }));
|
|
5390
|
+
}, A = [], te = /* @__PURE__ */ new Map(), _t = 0, Zs = function() {
|
|
5391
|
+
var r = Math.min(A.length - 1, Math.floor((vt() - _t) / 50));
|
|
5392
|
+
return A[r];
|
|
5393
|
+
}, er = [], tr = function(r) {
|
|
5394
|
+
if (er.forEach((function(n) {
|
|
5395
|
+
return n(r);
|
|
5396
|
+
})), r.interactionId || r.entryType === "first-input") {
|
|
5397
|
+
var e = A[A.length - 1], t = te.get(r.interactionId);
|
|
5398
|
+
if (t || A.length < 10 || r.duration > e.latency) {
|
|
5399
|
+
if (t) r.duration > t.latency ? (t.entries = [r], t.latency = r.duration) : r.duration === t.latency && r.startTime === t.entries[0].startTime && t.entries.push(r);
|
|
5337
5400
|
else {
|
|
5338
|
-
var
|
|
5339
|
-
|
|
5401
|
+
var s = { id: r.interactionId, latency: r.duration, entries: [r] };
|
|
5402
|
+
te.set(s.id, s), A.push(s);
|
|
5340
5403
|
}
|
|
5341
5404
|
A.sort((function(n, i) {
|
|
5342
5405
|
return i.latency - n.latency;
|
|
5343
5406
|
})), A.length > 10 && A.splice(10).forEach((function(n) {
|
|
5344
|
-
return
|
|
5407
|
+
return te.delete(n.id);
|
|
5345
5408
|
}));
|
|
5346
5409
|
}
|
|
5347
5410
|
}
|
|
5348
|
-
},
|
|
5411
|
+
}, yt = function(r) {
|
|
5349
5412
|
var e = self.requestIdleCallback || self.setTimeout, t = -1;
|
|
5350
|
-
return
|
|
5351
|
-
},
|
|
5352
|
-
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {},
|
|
5413
|
+
return r = ue(r), document.visibilityState === "hidden" ? r() : (t = e(r), z(r)), t;
|
|
5414
|
+
}, Re = [200, 500], sr = function(r, e) {
|
|
5415
|
+
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, Q((function() {
|
|
5353
5416
|
var t;
|
|
5354
|
-
|
|
5355
|
-
var
|
|
5356
|
-
|
|
5357
|
-
l.forEach(
|
|
5358
|
-
var c =
|
|
5359
|
-
c && c.latency !== n.value && (n.value = c.latency, n.entries = c.entries,
|
|
5417
|
+
Js();
|
|
5418
|
+
var s, n = y("INP"), i = function(l) {
|
|
5419
|
+
yt((function() {
|
|
5420
|
+
l.forEach(tr);
|
|
5421
|
+
var c = Zs();
|
|
5422
|
+
c && c.latency !== n.value && (n.value = c.latency, n.entries = c.entries, s());
|
|
5360
5423
|
}));
|
|
5361
|
-
}, o =
|
|
5362
|
-
|
|
5363
|
-
i(o.takeRecords()),
|
|
5424
|
+
}, o = F("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
|
|
5425
|
+
s = w(r, n, Re, e.reportAllChanges), o && (o.observe({ type: "first-input", buffered: !0 }), z((function() {
|
|
5426
|
+
i(o.takeRecords()), s(!0);
|
|
5364
5427
|
})), V((function() {
|
|
5365
|
-
|
|
5428
|
+
_t = vt(), A.length = 0, te.clear(), n = y("INP"), s = w(r, n, Re, e.reportAllChanges);
|
|
5366
5429
|
})));
|
|
5367
5430
|
})));
|
|
5368
|
-
},
|
|
5369
|
-
e = e || {},
|
|
5370
|
-
var t,
|
|
5371
|
-
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(
|
|
5372
|
-
|
|
5431
|
+
}, Ne = [2500, 4e3], pe = {}, rr = function(r, e) {
|
|
5432
|
+
e = e || {}, Q((function() {
|
|
5433
|
+
var t, s = Ve(), n = y("LCP"), i = function(c) {
|
|
5434
|
+
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(d) {
|
|
5435
|
+
d.startTime < s.firstHiddenTime && (n.value = Math.max(d.startTime - de(), 0), n.entries = [d], t());
|
|
5373
5436
|
}));
|
|
5374
|
-
}, o =
|
|
5437
|
+
}, o = F("largest-contentful-paint", i);
|
|
5375
5438
|
if (o) {
|
|
5376
|
-
t =
|
|
5439
|
+
t = w(r, n, Ne, e.reportAllChanges);
|
|
5377
5440
|
var l = ue((function() {
|
|
5378
|
-
|
|
5441
|
+
pe[n.id] || (i(o.takeRecords()), o.disconnect(), pe[n.id] = !0, t(!0));
|
|
5379
5442
|
}));
|
|
5380
5443
|
["keydown", "click"].forEach((function(c) {
|
|
5381
5444
|
addEventListener(c, (function() {
|
|
5382
|
-
return
|
|
5445
|
+
return yt(l);
|
|
5383
5446
|
}), { once: !0, capture: !0 });
|
|
5384
|
-
})),
|
|
5385
|
-
n =
|
|
5386
|
-
n.value = performance.now() - c.timeStamp,
|
|
5447
|
+
})), z(l), V((function(c) {
|
|
5448
|
+
n = y("LCP"), t = w(r, n, Ne, e.reportAllChanges), ke((function() {
|
|
5449
|
+
n.value = performance.now() - c.timeStamp, pe[n.id] = !0, t(!0);
|
|
5387
5450
|
}));
|
|
5388
5451
|
}));
|
|
5389
5452
|
}
|
|
5390
5453
|
}));
|
|
5391
|
-
},
|
|
5392
|
-
document.prerendering ?
|
|
5393
|
-
return
|
|
5454
|
+
}, Oe = [800, 1800], nr = function r(e) {
|
|
5455
|
+
document.prerendering ? Q((function() {
|
|
5456
|
+
return r(e);
|
|
5394
5457
|
})) : document.readyState !== "complete" ? addEventListener("load", (function() {
|
|
5395
|
-
return
|
|
5458
|
+
return r(e);
|
|
5396
5459
|
}), !0) : setTimeout(e, 0);
|
|
5397
|
-
},
|
|
5460
|
+
}, ir = function(r, e) {
|
|
5398
5461
|
e = e || {};
|
|
5399
|
-
var t =
|
|
5400
|
-
|
|
5401
|
-
var n =
|
|
5402
|
-
n && (t.value = Math.max(n.responseStart -
|
|
5403
|
-
t =
|
|
5462
|
+
var t = y("TTFB"), s = w(r, t, Oe, e.reportAllChanges);
|
|
5463
|
+
nr((function() {
|
|
5464
|
+
var n = De();
|
|
5465
|
+
n && (t.value = Math.max(n.responseStart - de(), 0), t.entries = [n], s(!0), V((function() {
|
|
5466
|
+
t = y("TTFB", 0), (s = w(r, t, Oe, e.reportAllChanges))(!0);
|
|
5404
5467
|
})));
|
|
5405
5468
|
}));
|
|
5406
|
-
},
|
|
5407
|
-
C || (C = e,
|
|
5408
|
-
},
|
|
5409
|
-
if (
|
|
5410
|
-
var
|
|
5411
|
-
|
|
5412
|
-
e(
|
|
5413
|
-
})),
|
|
5414
|
-
}
|
|
5415
|
-
},
|
|
5416
|
-
if (
|
|
5417
|
-
var e = (
|
|
5418
|
-
|
|
5469
|
+
}, W = { passive: !0, capture: !0 }, or = /* @__PURE__ */ new Date(), rt = function(r, e) {
|
|
5470
|
+
C || (C = e, G = r, St = /* @__PURE__ */ new Date(), bt(removeEventListener), wt());
|
|
5471
|
+
}, wt = function() {
|
|
5472
|
+
if (G >= 0 && G < St - or) {
|
|
5473
|
+
var r = { entryType: "first-input", name: C.type, target: C.target, cancelable: C.cancelable, startTime: C.timeStamp, processingStart: C.timeStamp + G };
|
|
5474
|
+
le.forEach((function(e) {
|
|
5475
|
+
e(r);
|
|
5476
|
+
})), le = [];
|
|
5477
|
+
}
|
|
5478
|
+
}, ar = function(r) {
|
|
5479
|
+
if (r.cancelable) {
|
|
5480
|
+
var e = (r.timeStamp > 1e12 ? /* @__PURE__ */ new Date() : performance.now()) - r.timeStamp;
|
|
5481
|
+
r.type == "pointerdown" ? (function(t, s) {
|
|
5419
5482
|
var n = function() {
|
|
5420
|
-
rt(t,
|
|
5483
|
+
rt(t, s), o();
|
|
5421
5484
|
}, i = function() {
|
|
5422
5485
|
o();
|
|
5423
5486
|
}, o = function() {
|
|
5424
|
-
removeEventListener("pointerup", n,
|
|
5487
|
+
removeEventListener("pointerup", n, W), removeEventListener("pointercancel", i, W);
|
|
5425
5488
|
};
|
|
5426
|
-
addEventListener("pointerup", n,
|
|
5427
|
-
})(e,
|
|
5489
|
+
addEventListener("pointerup", n, W), addEventListener("pointercancel", i, W);
|
|
5490
|
+
})(e, r) : rt(e, r);
|
|
5428
5491
|
}
|
|
5429
|
-
},
|
|
5492
|
+
}, bt = function(r) {
|
|
5430
5493
|
["mousedown", "keydown", "touchstart", "pointerdown"].forEach((function(e) {
|
|
5431
|
-
return
|
|
5494
|
+
return r(e, ar, W);
|
|
5432
5495
|
}));
|
|
5433
|
-
},
|
|
5434
|
-
e = e || {},
|
|
5435
|
-
var t,
|
|
5436
|
-
c.startTime <
|
|
5496
|
+
}, Pe = [100, 300], lr = function(r, e) {
|
|
5497
|
+
e = e || {}, Q((function() {
|
|
5498
|
+
var t, s = Ve(), n = y("FID"), i = function(c) {
|
|
5499
|
+
c.startTime < s.firstHiddenTime && (n.value = c.processingStart - c.startTime, n.entries.push(c), t(!0));
|
|
5437
5500
|
}, o = function(c) {
|
|
5438
5501
|
c.forEach(i);
|
|
5439
|
-
}, l =
|
|
5440
|
-
t =
|
|
5502
|
+
}, l = F("first-input", o);
|
|
5503
|
+
t = w(r, n, Pe, e.reportAllChanges), l && (z(ue((function() {
|
|
5441
5504
|
o(l.takeRecords()), l.disconnect();
|
|
5442
5505
|
}))), V((function() {
|
|
5443
5506
|
var c;
|
|
5444
|
-
n =
|
|
5507
|
+
n = y("FID"), t = w(r, n, Pe, e.reportAllChanges), le = [], G = -1, C = null, bt(addEventListener), c = i, le.push(c), wt();
|
|
5445
5508
|
})));
|
|
5446
5509
|
}));
|
|
5447
5510
|
};
|
|
5448
|
-
const
|
|
5511
|
+
const cr = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
5449
5512
|
__proto__: null,
|
|
5450
|
-
CLSThresholds:
|
|
5451
|
-
FCPThresholds:
|
|
5452
|
-
FIDThresholds:
|
|
5453
|
-
INPThresholds:
|
|
5454
|
-
LCPThresholds:
|
|
5455
|
-
TTFBThresholds:
|
|
5456
|
-
onCLS:
|
|
5457
|
-
onFCP:
|
|
5458
|
-
onFID:
|
|
5459
|
-
onINP:
|
|
5460
|
-
onLCP:
|
|
5461
|
-
onTTFB:
|
|
5513
|
+
CLSThresholds: Ce,
|
|
5514
|
+
FCPThresholds: Me,
|
|
5515
|
+
FIDThresholds: Pe,
|
|
5516
|
+
INPThresholds: Re,
|
|
5517
|
+
LCPThresholds: Ne,
|
|
5518
|
+
TTFBThresholds: Oe,
|
|
5519
|
+
onCLS: Ys,
|
|
5520
|
+
onFCP: Tt,
|
|
5521
|
+
onFID: lr,
|
|
5522
|
+
onINP: sr,
|
|
5523
|
+
onLCP: rr,
|
|
5524
|
+
onTTFB: ir
|
|
5462
5525
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
5463
5526
|
export {
|
|
5464
|
-
|
|
5465
|
-
|
|
5527
|
+
m as AppConfigValidationError,
|
|
5528
|
+
dr as DEFAULT_SESSION_TIMEOUT,
|
|
5466
5529
|
_e as DEFAULT_WEB_VITALS_MODE,
|
|
5467
5530
|
L as DeviceType,
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5531
|
+
se as EmitterEvent,
|
|
5532
|
+
B as ErrorType,
|
|
5533
|
+
u as EventType,
|
|
5534
|
+
vr as InitializationTimeoutError,
|
|
5535
|
+
N as IntegrationValidationError,
|
|
5536
|
+
pr as MAX_ARRAY_LENGTH,
|
|
5537
|
+
mr as MAX_CUSTOM_EVENT_ARRAY_SIZE,
|
|
5538
|
+
fr as MAX_CUSTOM_EVENT_KEYS,
|
|
5539
|
+
ur as MAX_CUSTOM_EVENT_NAME_LENGTH,
|
|
5540
|
+
hr as MAX_CUSTOM_EVENT_STRING_SIZE,
|
|
5541
|
+
gr as MAX_NESTED_OBJECT_KEYS,
|
|
5542
|
+
Er as MAX_STRING_LENGTH,
|
|
5543
|
+
Sr as MAX_STRING_LENGTH_IN_ARRAY,
|
|
5544
|
+
ie as Mode,
|
|
5545
|
+
lt as PII_PATTERNS,
|
|
5546
|
+
O as PermanentError,
|
|
5547
|
+
re as RateLimitError,
|
|
5548
|
+
Xe as SamplingRateValidationError,
|
|
5549
|
+
Z as ScrollDirection,
|
|
5550
|
+
Pt as SessionTimeoutValidationError,
|
|
5551
|
+
$ as SpecialApiUrl,
|
|
5552
|
+
ne as TimeoutError,
|
|
5553
|
+
j as TraceLogValidationError,
|
|
5554
|
+
_r as WEB_VITALS_GOOD_THRESHOLDS,
|
|
5555
|
+
Ke as WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS,
|
|
5556
|
+
Kt as WEB_VITALS_POOR_THRESHOLDS,
|
|
5557
|
+
Ye as getWebVitalsThresholds,
|
|
5558
|
+
Tr as isPrimaryScrollEvent,
|
|
5559
|
+
Ir as isSecondaryScrollEvent,
|
|
5560
|
+
yr as tracelog
|
|
5498
5561
|
};
|