@tracelog/lib 2.7.3 → 2.8.0-rc.100.13
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 +1161 -1097
- 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,13 +1068,14 @@ 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)
|
|
1069
1075
|
* - `false`: Send failed (network error, browser rejected beacon)
|
|
1070
1076
|
*
|
|
1071
|
-
* **Important**: No retry mechanism
|
|
1077
|
+
* **Important**: No retry mechanism. Failed events are persisted to localStorage for
|
|
1078
|
+
* recovery on next page load via `recoverPersistedEvents()`.
|
|
1072
1079
|
*
|
|
1073
1080
|
* **Custom Headers Limitation**: Custom headers set via `setCustomHeaders()` are NOT applied
|
|
1074
1081
|
* to sendBeacon requests due to browser API limitations. The sendBeacon API only supports
|
|
@@ -1087,13 +1094,13 @@ class Ze extends w {
|
|
|
1087
1094
|
* @see src/managers/README.md (lines 82-139) for send details
|
|
1088
1095
|
*/
|
|
1089
1096
|
sendEventsQueueSync(e) {
|
|
1090
|
-
return this.shouldSkipSend() ? !0 : this.apiUrl?.includes(
|
|
1097
|
+
return this.shouldSkipSend() ? !0 : this.apiUrl?.includes($.Fail) ? (a(
|
|
1091
1098
|
"warn",
|
|
1092
1099
|
`Fail mode: simulating network failure (sync)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1093
1100
|
{
|
|
1094
1101
|
data: { events: e.events.length }
|
|
1095
1102
|
}
|
|
1096
|
-
), !1) : this.apiUrl?.includes(
|
|
1103
|
+
), !1) : this.apiUrl?.includes($.Localhost) ? (a(
|
|
1097
1104
|
"debug",
|
|
1098
1105
|
`Success mode: simulating successful send (sync)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1099
1106
|
{
|
|
@@ -1118,7 +1125,7 @@ class Ze extends w {
|
|
|
1118
1125
|
*
|
|
1119
1126
|
* **Error Handling**:
|
|
1120
1127
|
* - **Permanent errors** (4xx except 408, 429): Events discarded, not persisted
|
|
1121
|
-
* - **Timeout errors
|
|
1128
|
+
* - **Timeout errors**: Events persisted for retry with the same batch idempotency token
|
|
1122
1129
|
* - **Transient errors** (5xx, network, mixed): Events persisted for recovery
|
|
1123
1130
|
*
|
|
1124
1131
|
* **Important**: Events are NOT retried in-session. Persistence is for
|
|
@@ -1132,14 +1139,12 @@ class Ze extends w {
|
|
|
1132
1139
|
* @see src/managers/README.md (lines 82-139) for send details
|
|
1133
1140
|
*/
|
|
1134
1141
|
async sendEventsQueue(e, t) {
|
|
1142
|
+
const s = this.ensureBatchMetadata(e);
|
|
1135
1143
|
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);
|
|
1144
|
+
const n = await this.send(s);
|
|
1145
|
+
return n ? (this.clearPersistedEvents(), t?.onSuccess?.(s.events.length, s.events, s)) : (this.persistEvents(s), t?.onFailure?.()), n;
|
|
1146
|
+
} catch (n) {
|
|
1147
|
+
return n instanceof O ? (this.logPermanentError("Permanent error, not retrying", n), this.clearPersistedEvents(), t?.onFailure?.(), !1) : (this.persistEvents(s), t?.onFailure?.(), !1);
|
|
1143
1148
|
}
|
|
1144
1149
|
}
|
|
1145
1150
|
/**
|
|
@@ -1197,35 +1202,28 @@ class Ze extends w {
|
|
|
1197
1202
|
return;
|
|
1198
1203
|
}
|
|
1199
1204
|
this.recoveryInProgress = !0;
|
|
1205
|
+
let t = null, s = 0;
|
|
1200
1206
|
try {
|
|
1201
|
-
const
|
|
1202
|
-
if (!
|
|
1207
|
+
const n = this.getPersistedData();
|
|
1208
|
+
if (!n || !this.isDataRecent(n) || n.events.length === 0) {
|
|
1203
1209
|
this.clearPersistedEvents();
|
|
1204
1210
|
return;
|
|
1205
1211
|
}
|
|
1206
|
-
const
|
|
1207
|
-
if (
|
|
1212
|
+
const i = n.recoveryFailures;
|
|
1213
|
+
if (s = typeof i == "number" && Number.isFinite(i) && i >= 0 ? i : 0, s >= 3) {
|
|
1208
1214
|
a(
|
|
1209
1215
|
"debug",
|
|
1210
|
-
`Discarding persisted events after ${
|
|
1216
|
+
`Discarding persisted events after ${s} failed recovery attempts${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1211
1217
|
), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1212
1218
|
return;
|
|
1213
1219
|
}
|
|
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?.();
|
|
1220
|
+
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?.());
|
|
1221
|
+
} catch (n) {
|
|
1222
|
+
if (n instanceof O) {
|
|
1223
|
+
this.logPermanentError("Permanent error during recovery, clearing persisted events", n), this.clearPersistedEvents(), e?.onFailure?.();
|
|
1226
1224
|
return;
|
|
1227
1225
|
}
|
|
1228
|
-
a("error", "Failed to recover persisted events", { error:
|
|
1226
|
+
a("error", "Failed to recover persisted events", { error: n }), t && this.persistEventsWithFailureCount(t, s + 1, !0), e?.onFailure?.();
|
|
1229
1227
|
} finally {
|
|
1230
1228
|
this.recoveryInProgress = !1;
|
|
1231
1229
|
}
|
|
@@ -1275,14 +1273,14 @@ class Ze extends w {
|
|
|
1275
1273
|
const t = this.transformers.beforeSend;
|
|
1276
1274
|
if (!t)
|
|
1277
1275
|
return e;
|
|
1278
|
-
const
|
|
1276
|
+
const s = Es(
|
|
1279
1277
|
e.events,
|
|
1280
1278
|
t,
|
|
1281
1279
|
this.integrationId || "SenderManager"
|
|
1282
1280
|
);
|
|
1283
|
-
return
|
|
1281
|
+
return s.length === 0 ? null : {
|
|
1284
1282
|
...e,
|
|
1285
|
-
events:
|
|
1283
|
+
events: s
|
|
1286
1284
|
};
|
|
1287
1285
|
}
|
|
1288
1286
|
/**
|
|
@@ -1320,7 +1318,7 @@ class Ze extends w {
|
|
|
1320
1318
|
if (this.integrationId === "saas")
|
|
1321
1319
|
return e;
|
|
1322
1320
|
const t = this.transformers.beforeBatch;
|
|
1323
|
-
return t ?
|
|
1321
|
+
return t ? Et(e, t, this.integrationId || "SenderManager") : e;
|
|
1324
1322
|
}
|
|
1325
1323
|
/**
|
|
1326
1324
|
* Calculates exponential backoff delay with jitter for retry attempts.
|
|
@@ -1342,7 +1340,7 @@ class Ze extends w {
|
|
|
1342
1340
|
* @returns Promise that resolves after calculated delay
|
|
1343
1341
|
*/
|
|
1344
1342
|
async backoffDelay(e) {
|
|
1345
|
-
const t = 100 * Math.pow(2, e),
|
|
1343
|
+
const t = 100 * Math.pow(2, e), s = Math.random() * 100, n = t + s;
|
|
1346
1344
|
return new Promise((i) => setTimeout(i, n));
|
|
1347
1345
|
}
|
|
1348
1346
|
/**
|
|
@@ -1378,7 +1376,6 @@ class Ze extends w {
|
|
|
1378
1376
|
* @param body - Event queue to send
|
|
1379
1377
|
* @returns Promise resolving to true if send succeeded, false if all retries exhausted
|
|
1380
1378
|
* @throws PermanentError for 4xx errors (caller should not retry)
|
|
1381
|
-
* @throws TimeoutError when all retry attempts timed out (caller should not persist)
|
|
1382
1379
|
*/
|
|
1383
1380
|
async send(e) {
|
|
1384
1381
|
if (this.shouldSkipSend())
|
|
@@ -1386,70 +1383,75 @@ class Ze extends w {
|
|
|
1386
1383
|
const t = this.applyBeforeSendTransformer(e);
|
|
1387
1384
|
if (!t)
|
|
1388
1385
|
return !0;
|
|
1389
|
-
const
|
|
1390
|
-
if (!
|
|
1386
|
+
const s = this.applyBeforeBatchTransformer(t);
|
|
1387
|
+
if (!s)
|
|
1391
1388
|
return !0;
|
|
1392
|
-
|
|
1389
|
+
const n = this.ensureBatchMetadata(s, e._metadata?.idempotency_token);
|
|
1390
|
+
if (this.apiUrl?.includes($.Fail))
|
|
1393
1391
|
return a("debug", `Fail mode: simulating network failure${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1394
|
-
data: { events:
|
|
1392
|
+
data: { events: n.events.length }
|
|
1395
1393
|
}), !1;
|
|
1396
|
-
if (this.apiUrl?.includes(
|
|
1394
|
+
if (this.apiUrl?.includes($.Localhost))
|
|
1397
1395
|
return a("debug", `Success mode: simulating successful send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1398
|
-
data: { events:
|
|
1396
|
+
data: { events: n.events.length }
|
|
1399
1397
|
}), !0;
|
|
1400
1398
|
if (this.consecutiveNetworkFailures >= 3) {
|
|
1401
|
-
const
|
|
1402
|
-
if (
|
|
1399
|
+
const d = Date.now() - this.circuitOpenedAt;
|
|
1400
|
+
if (d < 12e4)
|
|
1403
1401
|
return a("debug", `Network circuit open, skipping send${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1404
1402
|
data: {
|
|
1405
1403
|
consecutiveNetworkFailures: this.consecutiveNetworkFailures,
|
|
1406
|
-
cooldownRemainingMs: 12e4 -
|
|
1404
|
+
cooldownRemainingMs: 12e4 - d
|
|
1407
1405
|
}
|
|
1408
1406
|
}), !1;
|
|
1409
1407
|
}
|
|
1410
|
-
const { url:
|
|
1411
|
-
let
|
|
1412
|
-
for (let
|
|
1408
|
+
const { url: i, payload: o } = this.prepareRequest(n);
|
|
1409
|
+
let l = !0, c = !1;
|
|
1410
|
+
for (let d = 1; d <= 3; d++)
|
|
1413
1411
|
try {
|
|
1414
|
-
return (await this.sendWithTimeout(
|
|
1412
|
+
return (await this.sendWithTimeout(i, o)).ok ? (d > 1 && a(
|
|
1415
1413
|
"info",
|
|
1416
|
-
`Send succeeded after ${
|
|
1414
|
+
`Send succeeded after ${d - 1} retry attempt(s)${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1417
1415
|
{
|
|
1418
|
-
data: { events:
|
|
1416
|
+
data: { events: n.events.length, attempt: d }
|
|
1419
1417
|
}
|
|
1420
1418
|
), 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:
|
|
1419
|
+
} catch (f) {
|
|
1420
|
+
const g = d === 3;
|
|
1421
|
+
if (f instanceof O)
|
|
1422
|
+
throw this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, f;
|
|
1423
|
+
if (f instanceof re) {
|
|
1424
|
+
this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0, l = !1, c = !0, a("warn", `Rate limited, skipping retries${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1425
|
+
data: { events: e.events.length, attempt: d }
|
|
1428
1426
|
});
|
|
1429
1427
|
break;
|
|
1430
1428
|
}
|
|
1431
|
-
if (
|
|
1429
|
+
if (f instanceof ne || (l = !1), f instanceof TypeError || (c = !0), a(
|
|
1432
1430
|
g ? "error" : "warn",
|
|
1433
|
-
`Send attempt ${
|
|
1431
|
+
`Send attempt ${d} failed${this.integrationId ? ` [${this.integrationId}]` : ""}${g ? " (all retries exhausted)" : ", will retry"}`,
|
|
1434
1432
|
{
|
|
1435
|
-
error:
|
|
1433
|
+
error: f,
|
|
1436
1434
|
data: {
|
|
1437
1435
|
events: e.events.length,
|
|
1438
|
-
url:
|
|
1439
|
-
attempt:
|
|
1436
|
+
url: i.replace(/\/\/[^/]+/, "//[DOMAIN]"),
|
|
1437
|
+
attempt: d,
|
|
1440
1438
|
maxAttempts: 3
|
|
1441
1439
|
}
|
|
1442
1440
|
}
|
|
1443
1441
|
), !g) {
|
|
1444
|
-
await this.backoffDelay(
|
|
1442
|
+
await this.backoffDelay(d);
|
|
1445
1443
|
continue;
|
|
1446
1444
|
}
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1445
|
+
return l ? (a(
|
|
1446
|
+
"debug",
|
|
1447
|
+
`All retry attempts timed out, preserving batch for retry${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1448
|
+
{
|
|
1449
|
+
data: { events: n.events.length }
|
|
1450
|
+
}
|
|
1451
|
+
), !1) : (c ? (this.consecutiveNetworkFailures = 0, this.circuitOpenedAt = 0) : (this.consecutiveNetworkFailures = Math.min(
|
|
1450
1452
|
this.consecutiveNetworkFailures + 1,
|
|
1451
1453
|
3
|
|
1452
|
-
), this.consecutiveNetworkFailures >= 3 && (this.circuitOpenedAt = Date.now())), !1;
|
|
1454
|
+
), this.consecutiveNetworkFailures >= 3 && (this.circuitOpenedAt = Date.now())), !1);
|
|
1453
1455
|
}
|
|
1454
1456
|
return !1;
|
|
1455
1457
|
}
|
|
@@ -1461,27 +1463,27 @@ class Ze extends w {
|
|
|
1461
1463
|
*
|
|
1462
1464
|
* **Timeout Behavior**:
|
|
1463
1465
|
* - 10-second timeout via AbortController (REQUEST_TIMEOUT_MS constant)
|
|
1464
|
-
* - Aborted requests throw TimeoutError
|
|
1466
|
+
* - Aborted requests throw TimeoutError
|
|
1465
1467
|
*
|
|
1466
1468
|
* **Error Classification**:
|
|
1467
1469
|
* - 4xx (except 408, 429): PermanentError thrown → no retries
|
|
1468
|
-
* - Timeout: TimeoutError thrown → caller
|
|
1470
|
+
* - Timeout: TimeoutError thrown → caller treats it as a retryable failure
|
|
1469
1471
|
* - 408, 429, 5xx, network: Standard Error thrown → triggers retry
|
|
1470
1472
|
*
|
|
1471
1473
|
* @param url - API endpoint URL
|
|
1472
1474
|
* @param payload - JSON-stringified EventsQueue body
|
|
1473
1475
|
* @returns Response object if successful
|
|
1474
1476
|
* @throws PermanentError for unrecoverable 4xx errors
|
|
1475
|
-
* @throws TimeoutError when request times out
|
|
1477
|
+
* @throws TimeoutError when request times out
|
|
1476
1478
|
* @throws Error for transient errors (5xx, network)
|
|
1477
1479
|
* @private
|
|
1478
1480
|
*/
|
|
1479
1481
|
async sendWithTimeout(e, t) {
|
|
1480
|
-
const
|
|
1481
|
-
this.pendingControllers.add(
|
|
1482
|
+
const s = new AbortController();
|
|
1483
|
+
this.pendingControllers.add(s);
|
|
1482
1484
|
let n = !1;
|
|
1483
1485
|
const i = setTimeout(() => {
|
|
1484
|
-
n = !0,
|
|
1486
|
+
n = !0, s.abort();
|
|
1485
1487
|
}, 15e3);
|
|
1486
1488
|
try {
|
|
1487
1489
|
const o = this.getCustomHeaders(), l = await fetch(e, {
|
|
@@ -1489,19 +1491,19 @@ class Ze extends w {
|
|
|
1489
1491
|
body: t,
|
|
1490
1492
|
keepalive: !0,
|
|
1491
1493
|
credentials: this.fetchCredentials,
|
|
1492
|
-
signal:
|
|
1494
|
+
signal: s.signal,
|
|
1493
1495
|
headers: {
|
|
1494
1496
|
...o,
|
|
1495
1497
|
"Content-Type": "application/json"
|
|
1496
1498
|
}
|
|
1497
1499
|
});
|
|
1498
1500
|
if (!l.ok)
|
|
1499
|
-
throw l.status >= 400 && l.status < 500 && l.status !== 408 && l.status !== 429 ? new
|
|
1501
|
+
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
1502
|
return l;
|
|
1501
1503
|
} catch (o) {
|
|
1502
|
-
throw o instanceof
|
|
1504
|
+
throw o instanceof O ? o : n ? new ne("Request timed out") : o;
|
|
1503
1505
|
} finally {
|
|
1504
|
-
clearTimeout(i), this.pendingControllers.delete(
|
|
1506
|
+
clearTimeout(i), this.pendingControllers.delete(s);
|
|
1505
1507
|
}
|
|
1506
1508
|
}
|
|
1507
1509
|
/**
|
|
@@ -1521,40 +1523,40 @@ class Ze extends w {
|
|
|
1521
1523
|
* - Oversized payloads persisted instead of silently failing
|
|
1522
1524
|
*
|
|
1523
1525
|
* @param body - EventsQueue to send
|
|
1524
|
-
* @returns `true` on success
|
|
1526
|
+
* @returns `true` on success, `false` on failure (events persisted for recovery)
|
|
1525
1527
|
* @private
|
|
1526
1528
|
*/
|
|
1527
1529
|
sendQueueSyncInternal(e) {
|
|
1528
|
-
const t = this.
|
|
1529
|
-
if (!
|
|
1530
|
+
const t = this.ensureBatchMetadata(e), s = this.applyBeforeSendTransformer(t);
|
|
1531
|
+
if (!s)
|
|
1530
1532
|
return !0;
|
|
1531
|
-
const
|
|
1532
|
-
if (!
|
|
1533
|
+
const n = this.applyBeforeBatchTransformer(s);
|
|
1534
|
+
if (!n)
|
|
1533
1535
|
return !0;
|
|
1534
|
-
const { url:
|
|
1535
|
-
if (
|
|
1536
|
+
const i = this.ensureBatchMetadata(n, t._metadata?.idempotency_token), { url: o, payload: l } = this.prepareRequest(i);
|
|
1537
|
+
if (l.length > 65536)
|
|
1536
1538
|
return a(
|
|
1537
1539
|
"warn",
|
|
1538
1540
|
`Payload exceeds sendBeacon limit, persisting for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`,
|
|
1539
1541
|
{
|
|
1540
1542
|
data: {
|
|
1541
|
-
size:
|
|
1543
|
+
size: l.length,
|
|
1542
1544
|
limit: 65536,
|
|
1543
|
-
events:
|
|
1545
|
+
events: i.events.length
|
|
1544
1546
|
}
|
|
1545
1547
|
}
|
|
1546
|
-
), this.persistEvents(
|
|
1547
|
-
const
|
|
1548
|
+
), this.persistEvents(t), !1;
|
|
1549
|
+
const c = new Blob([l], { type: "application/json" });
|
|
1548
1550
|
if (!this.isSendBeaconAvailable())
|
|
1549
1551
|
return a(
|
|
1550
1552
|
"warn",
|
|
1551
1553
|
`sendBeacon not available, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1552
|
-
), this.persistEvents(
|
|
1553
|
-
const
|
|
1554
|
-
return
|
|
1554
|
+
), this.persistEvents(t), !1;
|
|
1555
|
+
const d = navigator.sendBeacon(o, c);
|
|
1556
|
+
return d || (a(
|
|
1555
1557
|
"warn",
|
|
1556
1558
|
`sendBeacon rejected request, persisting events for recovery${this.integrationId ? ` [${this.integrationId}]` : ""}`
|
|
1557
|
-
), this.persistEvents(
|
|
1559
|
+
), this.persistEvents(t)), d;
|
|
1558
1560
|
}
|
|
1559
1561
|
/**
|
|
1560
1562
|
* Prepares request by enriching payload with metadata and serializing to JSON.
|
|
@@ -1566,9 +1568,10 @@ class Ze extends w {
|
|
|
1566
1568
|
* - `timestamp`: Request generation time in milliseconds
|
|
1567
1569
|
*
|
|
1568
1570
|
* **Idempotency Token**:
|
|
1569
|
-
* -
|
|
1570
|
-
* -
|
|
1571
|
-
* -
|
|
1571
|
+
* - Set upstream by ensureBatchMetadata() before this method is called
|
|
1572
|
+
* - Fallback generateEventId() is defensive only (should not trigger in normal flow)
|
|
1573
|
+
* - Same token persists across all retry attempts of the same batch
|
|
1574
|
+
* - Backend uses this to deduplicate retries
|
|
1572
1575
|
*
|
|
1573
1576
|
* @param body - EventsQueue to send
|
|
1574
1577
|
* @returns Object with `url` (API endpoint) and `payload` (JSON string)
|
|
@@ -1577,17 +1580,29 @@ class Ze extends w {
|
|
|
1577
1580
|
prepareRequest(e) {
|
|
1578
1581
|
let t = Date.now();
|
|
1579
1582
|
t < this.lastMetadataTimestamp && (t = this.lastMetadataTimestamp), this.lastMetadataTimestamp = t;
|
|
1580
|
-
const
|
|
1583
|
+
const s = {
|
|
1581
1584
|
...e,
|
|
1582
1585
|
_metadata: {
|
|
1586
|
+
...e._metadata,
|
|
1587
|
+
idempotency_token: e._metadata?.idempotency_token ?? ye(),
|
|
1583
1588
|
referer: typeof window < "u" ? window.location.href : void 0,
|
|
1584
1589
|
timestamp: t,
|
|
1585
|
-
client_version:
|
|
1590
|
+
client_version: Zt
|
|
1586
1591
|
}
|
|
1587
1592
|
};
|
|
1588
1593
|
return {
|
|
1589
1594
|
url: this.apiUrl || "",
|
|
1590
|
-
payload: JSON.stringify(
|
|
1595
|
+
payload: JSON.stringify(s)
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
ensureBatchMetadata(e, t) {
|
|
1599
|
+
const s = e._metadata?.idempotency_token ?? t ?? ye();
|
|
1600
|
+
return e._metadata?.idempotency_token === s ? e : {
|
|
1601
|
+
...e,
|
|
1602
|
+
_metadata: {
|
|
1603
|
+
...e._metadata,
|
|
1604
|
+
idempotency_token: s
|
|
1605
|
+
}
|
|
1591
1606
|
};
|
|
1592
1607
|
}
|
|
1593
1608
|
/**
|
|
@@ -1638,7 +1653,7 @@ class Ze extends w {
|
|
|
1638
1653
|
* @private
|
|
1639
1654
|
*/
|
|
1640
1655
|
createRecoveryBody(e) {
|
|
1641
|
-
const { timestamp: t, recoveryFailures:
|
|
1656
|
+
const { timestamp: t, recoveryFailures: s, ...n } = e;
|
|
1642
1657
|
return n;
|
|
1643
1658
|
}
|
|
1644
1659
|
/**
|
|
@@ -1675,10 +1690,10 @@ class Ze extends w {
|
|
|
1675
1690
|
* @returns `true` on successful persistence or throttled write, `false` on error
|
|
1676
1691
|
* @private
|
|
1677
1692
|
*/
|
|
1678
|
-
persistEventsWithFailureCount(e, t,
|
|
1693
|
+
persistEventsWithFailureCount(e, t, s = !1) {
|
|
1679
1694
|
try {
|
|
1680
1695
|
const n = this.getPersistedData();
|
|
1681
|
-
if (!
|
|
1696
|
+
if (!s && n && n.timestamp) {
|
|
1682
1697
|
const l = Date.now() - n.timestamp;
|
|
1683
1698
|
if (l < 1e3)
|
|
1684
1699
|
return a(
|
|
@@ -1720,13 +1735,13 @@ class Ze extends w {
|
|
|
1720
1735
|
return typeof navigator < "u" && typeof navigator.sendBeacon == "function";
|
|
1721
1736
|
}
|
|
1722
1737
|
logPermanentError(e, t) {
|
|
1723
|
-
const
|
|
1724
|
-
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode ||
|
|
1738
|
+
const s = Date.now();
|
|
1739
|
+
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode || s - this.lastPermanentErrorLog.timestamp >= Qt) && (a("error", `${e}${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
|
|
1725
1740
|
data: { status: t.statusCode, message: t.message }
|
|
1726
|
-
}), this.lastPermanentErrorLog = { statusCode: t.statusCode, timestamp:
|
|
1741
|
+
}), this.lastPermanentErrorLog = { statusCode: t.statusCode, timestamp: s });
|
|
1727
1742
|
}
|
|
1728
1743
|
}
|
|
1729
|
-
class
|
|
1744
|
+
class Ss extends _ {
|
|
1730
1745
|
bootTime;
|
|
1731
1746
|
bootTimestamp;
|
|
1732
1747
|
hasPerformanceNow;
|
|
@@ -1818,13 +1833,13 @@ class Sr extends w {
|
|
|
1818
1833
|
if (e - this.lastClockSkewCheck < 5e3)
|
|
1819
1834
|
return this.detectedSkew;
|
|
1820
1835
|
this.lastClockSkewCheck = e;
|
|
1821
|
-
const t = this.now(),
|
|
1822
|
-
return this.detectedSkew =
|
|
1836
|
+
const t = this.now(), s = Date.now();
|
|
1837
|
+
return this.detectedSkew = s - t, Math.abs(this.detectedSkew) > 3e4 && a("warn", "Significant clock skew detected", {
|
|
1823
1838
|
data: {
|
|
1824
1839
|
skewMs: this.detectedSkew,
|
|
1825
1840
|
skewMinutes: (this.detectedSkew / 1e3 / 60).toFixed(2),
|
|
1826
1841
|
monotonicTime: new Date(t).toISOString(),
|
|
1827
|
-
systemTime: new Date(
|
|
1842
|
+
systemTime: new Date(s).toISOString()
|
|
1828
1843
|
}
|
|
1829
1844
|
}), this.detectedSkew;
|
|
1830
1845
|
}
|
|
@@ -1853,7 +1868,7 @@ class Sr extends w {
|
|
|
1853
1868
|
* ```
|
|
1854
1869
|
*/
|
|
1855
1870
|
validateTimestamp(e) {
|
|
1856
|
-
const
|
|
1871
|
+
const s = this.now(), n = e - s;
|
|
1857
1872
|
return n > 12e4 ? {
|
|
1858
1873
|
valid: !1,
|
|
1859
1874
|
error: `Timestamp is ${(n / 1e3 / 60).toFixed(2)} minutes in the future (max allowed: 2 minutes)`
|
|
@@ -1875,8 +1890,8 @@ class Sr extends w {
|
|
|
1875
1890
|
};
|
|
1876
1891
|
}
|
|
1877
1892
|
}
|
|
1878
|
-
const
|
|
1879
|
-
class
|
|
1893
|
+
const ps = new Set(Object.values(u));
|
|
1894
|
+
class Ts extends _ {
|
|
1880
1895
|
dataSenders;
|
|
1881
1896
|
emitter;
|
|
1882
1897
|
transformers;
|
|
@@ -1893,11 +1908,11 @@ class Tr extends w {
|
|
|
1893
1908
|
lastSessionId = null;
|
|
1894
1909
|
sessionEventCounts = {
|
|
1895
1910
|
total: 0,
|
|
1896
|
-
[
|
|
1897
|
-
[
|
|
1898
|
-
[
|
|
1899
|
-
[
|
|
1900
|
-
[
|
|
1911
|
+
[u.CLICK]: 0,
|
|
1912
|
+
[u.PAGE_VIEW]: 0,
|
|
1913
|
+
[u.CUSTOM]: 0,
|
|
1914
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
1915
|
+
[u.SCROLL]: 0
|
|
1901
1916
|
};
|
|
1902
1917
|
saveSessionCountsDebounced = null;
|
|
1903
1918
|
/**
|
|
@@ -1914,15 +1929,15 @@ class Tr extends w {
|
|
|
1914
1929
|
* @param customHeadersProvider - Optional callback for dynamic headers
|
|
1915
1930
|
* @param fetchCredentials - Fetch credentials mode for custom backend. @default 'include'
|
|
1916
1931
|
*/
|
|
1917
|
-
constructor(e, t = null,
|
|
1918
|
-
super(), this.emitter = t, this.transformers =
|
|
1932
|
+
constructor(e, t = null, s = {}, n = {}, i, o = "include") {
|
|
1933
|
+
super(), this.emitter = t, this.transformers = s, this.timeManager = new Ss(), this.dataSenders = [];
|
|
1919
1934
|
const l = this.get("collectApiUrls");
|
|
1920
|
-
l?.saas && this.dataSenders.push(new
|
|
1921
|
-
new
|
|
1935
|
+
l?.saas && this.dataSenders.push(new et(e, "saas", l.saas, s)), l?.custom && this.dataSenders.push(
|
|
1936
|
+
new et(
|
|
1922
1937
|
e,
|
|
1923
1938
|
"custom",
|
|
1924
1939
|
l.custom,
|
|
1925
|
-
|
|
1940
|
+
s,
|
|
1926
1941
|
n,
|
|
1927
1942
|
i,
|
|
1928
1943
|
o
|
|
@@ -1958,7 +1973,7 @@ class Tr extends w {
|
|
|
1958
1973
|
async recoverPersistedEvents() {
|
|
1959
1974
|
const e = this.dataSenders.map(
|
|
1960
1975
|
async (t) => t.recoverPersistedEvents({
|
|
1961
|
-
onSuccess: (
|
|
1976
|
+
onSuccess: (s, n, i) => {
|
|
1962
1977
|
if (n && n.length > 0) {
|
|
1963
1978
|
const o = n.map((l) => l.id);
|
|
1964
1979
|
this.removeProcessedEvents(o), i && this.emitEventsQueue(i);
|
|
@@ -2033,47 +2048,47 @@ class Tr extends w {
|
|
|
2033
2048
|
track({
|
|
2034
2049
|
type: e,
|
|
2035
2050
|
page_url: t,
|
|
2036
|
-
from_page_url:
|
|
2051
|
+
from_page_url: s,
|
|
2037
2052
|
scroll_data: n,
|
|
2038
2053
|
click_data: i,
|
|
2039
2054
|
custom_event: o,
|
|
2040
2055
|
web_vitals: l,
|
|
2041
2056
|
error_data: c,
|
|
2042
|
-
viewport_data:
|
|
2043
|
-
page_view:
|
|
2057
|
+
viewport_data: d,
|
|
2058
|
+
page_view: f
|
|
2044
2059
|
}) {
|
|
2045
2060
|
if (!e) {
|
|
2046
2061
|
a("error", "Event type is required - event will be ignored");
|
|
2047
2062
|
return;
|
|
2048
2063
|
}
|
|
2049
|
-
if (!
|
|
2064
|
+
if (!ps.has(e)) {
|
|
2050
2065
|
a("error", "Invalid event type - event will be ignored", {
|
|
2051
2066
|
data: { type: e }
|
|
2052
2067
|
});
|
|
2053
2068
|
return;
|
|
2054
2069
|
}
|
|
2055
|
-
const
|
|
2056
|
-
if (!
|
|
2070
|
+
const g = this.get("sessionId");
|
|
2071
|
+
if (!g) {
|
|
2057
2072
|
this.pendingEventsBuffer.length >= 100 && (this.pendingEventsBuffer.shift(), a("debug", "Pending events buffer full - dropping oldest event", {
|
|
2058
2073
|
data: { maxBufferSize: 100 }
|
|
2059
2074
|
})), this.pendingEventsBuffer.push({
|
|
2060
2075
|
type: e,
|
|
2061
2076
|
page_url: t,
|
|
2062
|
-
from_page_url:
|
|
2077
|
+
from_page_url: s,
|
|
2063
2078
|
scroll_data: n,
|
|
2064
2079
|
click_data: i,
|
|
2065
2080
|
custom_event: o,
|
|
2066
2081
|
web_vitals: l,
|
|
2067
2082
|
error_data: c,
|
|
2068
|
-
viewport_data:
|
|
2069
|
-
page_view:
|
|
2083
|
+
viewport_data: d,
|
|
2084
|
+
page_view: f
|
|
2070
2085
|
});
|
|
2071
2086
|
return;
|
|
2072
2087
|
}
|
|
2073
|
-
this.lastSessionId !==
|
|
2074
|
-
const T = e ===
|
|
2088
|
+
this.lastSessionId !== g && (this.lastSessionId = g, this.sessionEventCounts = this.loadSessionCounts(g));
|
|
2089
|
+
const T = e === u.SESSION_START;
|
|
2075
2090
|
if (T && a("debug", "Processing SESSION_START event", {
|
|
2076
|
-
data: { sessionId:
|
|
2091
|
+
data: { sessionId: g }
|
|
2077
2092
|
}), !T && !this.checkRateLimit())
|
|
2078
2093
|
return;
|
|
2079
2094
|
const S = e;
|
|
@@ -2090,12 +2105,12 @@ class Tr extends w {
|
|
|
2090
2105
|
}
|
|
2091
2106
|
const v = this.getTypeLimitForEvent(S);
|
|
2092
2107
|
if (v) {
|
|
2093
|
-
const
|
|
2094
|
-
if (
|
|
2108
|
+
const he = this.sessionEventCounts[S];
|
|
2109
|
+
if (he !== void 0 && he >= v) {
|
|
2095
2110
|
a("warn", "Session event type limit reached", {
|
|
2096
2111
|
data: {
|
|
2097
2112
|
type: S,
|
|
2098
|
-
count:
|
|
2113
|
+
count: he,
|
|
2099
2114
|
limit: v
|
|
2100
2115
|
}
|
|
2101
2116
|
});
|
|
@@ -2103,25 +2118,25 @@ class Tr extends w {
|
|
|
2103
2118
|
}
|
|
2104
2119
|
}
|
|
2105
2120
|
}
|
|
2106
|
-
if (S ===
|
|
2121
|
+
if (S === u.CUSTOM && o?.name) {
|
|
2107
2122
|
const v = this.get("config")?.maxSameEventPerMinute ?? 60;
|
|
2108
2123
|
if (!this.checkPerEventRateLimit(o.name, v))
|
|
2109
2124
|
return;
|
|
2110
2125
|
}
|
|
2111
|
-
const
|
|
2126
|
+
const Ue = S === u.SESSION_START, K = t || this.get("pageUrl"), x = this.buildEventPayload({
|
|
2112
2127
|
type: S,
|
|
2113
|
-
page_url:
|
|
2114
|
-
from_page_url:
|
|
2128
|
+
page_url: K,
|
|
2129
|
+
from_page_url: s,
|
|
2115
2130
|
scroll_data: n,
|
|
2116
2131
|
click_data: i,
|
|
2117
2132
|
custom_event: o,
|
|
2118
2133
|
web_vitals: l,
|
|
2119
2134
|
error_data: c,
|
|
2120
|
-
viewport_data:
|
|
2121
|
-
page_view:
|
|
2135
|
+
viewport_data: d,
|
|
2136
|
+
page_view: f
|
|
2122
2137
|
});
|
|
2123
|
-
if (
|
|
2124
|
-
if (
|
|
2138
|
+
if (x && !(!T && !this.shouldSample())) {
|
|
2139
|
+
if (Ue) {
|
|
2125
2140
|
const v = this.get("sessionId");
|
|
2126
2141
|
if (!v) {
|
|
2127
2142
|
a("error", "Session start event requires sessionId - event will be ignored");
|
|
@@ -2135,34 +2150,34 @@ class Tr extends w {
|
|
|
2135
2150
|
}
|
|
2136
2151
|
this.set("hasStartSession", !0);
|
|
2137
2152
|
}
|
|
2138
|
-
if (!this.isDuplicateEvent(
|
|
2139
|
-
if (this.get("mode") ===
|
|
2140
|
-
if (S ===
|
|
2153
|
+
if (!this.isDuplicateEvent(x)) {
|
|
2154
|
+
if (this.get("mode") === ie.QA) {
|
|
2155
|
+
if (S === u.CUSTOM && o) {
|
|
2141
2156
|
a("info", `Custom Event: ${o.name}`, {
|
|
2142
2157
|
visibility: "qa",
|
|
2143
2158
|
data: {
|
|
2144
2159
|
name: o.name,
|
|
2145
2160
|
...o.metadata && { metadata: o.metadata }
|
|
2146
2161
|
}
|
|
2147
|
-
}), this.emitEvent(
|
|
2162
|
+
}), this.emitEvent(x);
|
|
2148
2163
|
return;
|
|
2149
2164
|
}
|
|
2150
|
-
if (S ===
|
|
2151
|
-
const v =
|
|
2165
|
+
if (S === u.VIEWPORT_VISIBLE && d) {
|
|
2166
|
+
const v = d.name || d.id || d.selector;
|
|
2152
2167
|
a("info", `Viewport Visible: ${v}`, {
|
|
2153
2168
|
visibility: "qa",
|
|
2154
2169
|
data: {
|
|
2155
|
-
selector:
|
|
2156
|
-
...
|
|
2157
|
-
...
|
|
2158
|
-
visibilityRatio:
|
|
2159
|
-
dwellTime:
|
|
2170
|
+
selector: d.selector,
|
|
2171
|
+
...d.name && { name: d.name },
|
|
2172
|
+
...d.id && { id: d.id },
|
|
2173
|
+
visibilityRatio: d.visibilityRatio,
|
|
2174
|
+
dwellTime: d.dwellTime
|
|
2160
2175
|
}
|
|
2161
|
-
}), this.emitEvent(
|
|
2176
|
+
}), this.emitEvent(x);
|
|
2162
2177
|
return;
|
|
2163
2178
|
}
|
|
2164
2179
|
}
|
|
2165
|
-
if (this.addToQueue(
|
|
2180
|
+
if (this.addToQueue(x), !T) {
|
|
2166
2181
|
this.sessionEventCounts.total++, this.sessionEventCounts[S] !== void 0 && this.sessionEventCounts[S]++;
|
|
2167
2182
|
const v = this.get("sessionId");
|
|
2168
2183
|
v && this.saveSessionCountsDebounced && this.saveSessionCountsDebounced(v);
|
|
@@ -2209,11 +2224,11 @@ class Tr extends w {
|
|
|
2209
2224
|
const e = this.get("sessionId");
|
|
2210
2225
|
e && this.saveSessionCounts(e), this.eventsQueue = [], this.pendingEventsBuffer = [], this.recentEventFingerprints.clear(), this.rateLimitCounter = 0, this.rateLimitWindowStart = 0, this.perEventRateLimits.clear(), this.sessionEventCounts = {
|
|
2211
2226
|
total: 0,
|
|
2212
|
-
[
|
|
2213
|
-
[
|
|
2214
|
-
[
|
|
2215
|
-
[
|
|
2216
|
-
[
|
|
2227
|
+
[u.CLICK]: 0,
|
|
2228
|
+
[u.PAGE_VIEW]: 0,
|
|
2229
|
+
[u.CUSTOM]: 0,
|
|
2230
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
2231
|
+
[u.SCROLL]: 0
|
|
2217
2232
|
}, this.lastSessionId = null, this.set("hasStartSession", !1), this.dataSenders.forEach((t) => {
|
|
2218
2233
|
t.stop();
|
|
2219
2234
|
});
|
|
@@ -2414,8 +2429,8 @@ class Tr extends w {
|
|
|
2414
2429
|
return;
|
|
2415
2430
|
}
|
|
2416
2431
|
const t = [...this.pendingEventsBuffer];
|
|
2417
|
-
this.pendingEventsBuffer = [], t.forEach((
|
|
2418
|
-
this.track(
|
|
2432
|
+
this.pendingEventsBuffer = [], t.forEach((s) => {
|
|
2433
|
+
this.track(s);
|
|
2419
2434
|
});
|
|
2420
2435
|
}
|
|
2421
2436
|
clearSendTimeout() {
|
|
@@ -2429,7 +2444,7 @@ class Tr extends w {
|
|
|
2429
2444
|
return e ? !0 : Promise.resolve(!0);
|
|
2430
2445
|
if (!e && this.sendInProgress)
|
|
2431
2446
|
return a("debug", "Async flush skipped: send already in progress"), Promise.resolve(!1);
|
|
2432
|
-
const t = this.buildEventsPayload(),
|
|
2447
|
+
const t = this.buildEventsPayload(), s = [...this.eventsQueue], n = s.map((i) => i.id);
|
|
2433
2448
|
if (this.dataSenders.length === 0)
|
|
2434
2449
|
return this.removeProcessedEvents(n), this.clearSendTimeout(), this.emitEventsQueue(t), e ? !0 : Promise.resolve(!0);
|
|
2435
2450
|
if (e) {
|
|
@@ -2449,7 +2464,7 @@ class Tr extends w {
|
|
|
2449
2464
|
return Promise.allSettled(i).then((o) => {
|
|
2450
2465
|
const l = o.some((c) => this.isSuccessfulResult(c));
|
|
2451
2466
|
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:
|
|
2467
|
+
data: { eventCount: s.length }
|
|
2453
2468
|
}), l;
|
|
2454
2469
|
});
|
|
2455
2470
|
}
|
|
@@ -2463,7 +2478,7 @@ class Tr extends w {
|
|
|
2463
2478
|
this.emitEventsQueue(e);
|
|
2464
2479
|
return;
|
|
2465
2480
|
}
|
|
2466
|
-
const t = [...this.eventsQueue],
|
|
2481
|
+
const t = [...this.eventsQueue], s = t.map((l) => l.id), n = this.dataSenders.map(
|
|
2467
2482
|
async (l) => l.sendEventsQueue(e, {
|
|
2468
2483
|
onSuccess: () => {
|
|
2469
2484
|
},
|
|
@@ -2472,7 +2487,7 @@ class Tr extends w {
|
|
|
2472
2487
|
})
|
|
2473
2488
|
), i = await Promise.allSettled(n);
|
|
2474
2489
|
if (i.some((l) => this.isSuccessfulResult(l))) {
|
|
2475
|
-
this.consecutiveSendFailures = 0, this.removeProcessedEvents(
|
|
2490
|
+
this.consecutiveSendFailures = 0, this.removeProcessedEvents(s), this.emitEventsQueue(e);
|
|
2476
2491
|
const l = i.filter((c) => !this.isSuccessfulResult(c)).length;
|
|
2477
2492
|
l > 0 && a("debug", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
|
|
2478
2493
|
data: { eventCount: t.length, failedCount: l }
|
|
@@ -2490,36 +2505,36 @@ class Tr extends w {
|
|
|
2490
2505
|
buildEventsPayload() {
|
|
2491
2506
|
const e = /* @__PURE__ */ new Map(), t = [];
|
|
2492
2507
|
for (const c of this.eventsQueue) {
|
|
2493
|
-
const
|
|
2494
|
-
e.has(
|
|
2508
|
+
const d = this.createEventSignature(c);
|
|
2509
|
+
e.has(d) || t.push(d), e.set(d, c);
|
|
2495
2510
|
}
|
|
2496
|
-
const
|
|
2511
|
+
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
2512
|
let n = {
|
|
2498
2513
|
user_id: this.get("userId"),
|
|
2499
2514
|
session_id: this.get("sessionId"),
|
|
2500
2515
|
device: this.get("device"),
|
|
2501
|
-
events:
|
|
2516
|
+
events: s,
|
|
2502
2517
|
...this.get("config")?.globalMetadata && { global_metadata: this.get("config")?.globalMetadata },
|
|
2503
2518
|
...this.get("identity") && { identify: this.get("identity") }
|
|
2504
2519
|
};
|
|
2505
2520
|
const i = this.get("collectApiUrls"), o = !!(i?.custom || i?.saas), l = this.transformers.beforeBatch;
|
|
2506
2521
|
if (!o && l) {
|
|
2507
|
-
const c =
|
|
2522
|
+
const c = Et(n, l, "EventManager");
|
|
2508
2523
|
c !== null && (n = c);
|
|
2509
2524
|
}
|
|
2510
2525
|
return n;
|
|
2511
2526
|
}
|
|
2512
2527
|
buildEventPayload(e) {
|
|
2513
|
-
const t = e.page_url ?? this.get("pageUrl"),
|
|
2528
|
+
const t = e.page_url ?? this.get("pageUrl"), s = this.timeManager.now(), n = this.timeManager.validateTimestamp(s);
|
|
2514
2529
|
n.valid || a("warn", "Event timestamp validation failed", {
|
|
2515
2530
|
data: { type: e.type, error: n.error }
|
|
2516
2531
|
});
|
|
2517
2532
|
const i = this.get("sessionReferrer"), o = this.get("sessionUtm");
|
|
2518
2533
|
let l = {
|
|
2519
|
-
id:
|
|
2534
|
+
id: ye(),
|
|
2520
2535
|
type: e.type,
|
|
2521
2536
|
page_url: t,
|
|
2522
|
-
timestamp:
|
|
2537
|
+
timestamp: s,
|
|
2523
2538
|
...i && { referrer: i },
|
|
2524
2539
|
...e.from_page_url && { from_page_url: e.from_page_url },
|
|
2525
2540
|
...e.scroll_data && { scroll_data: e.scroll_data },
|
|
@@ -2531,25 +2546,25 @@ class Tr extends w {
|
|
|
2531
2546
|
...e.page_view && { page_view: e.page_view },
|
|
2532
2547
|
...o && { utm: o }
|
|
2533
2548
|
};
|
|
2534
|
-
const c = this.get("collectApiUrls"),
|
|
2535
|
-
if (S && (!
|
|
2536
|
-
const
|
|
2537
|
-
if (
|
|
2549
|
+
const c = this.get("collectApiUrls"), d = !!c?.custom, f = !!c?.saas, g = d || f, T = d && f, S = this.transformers.beforeSend;
|
|
2550
|
+
if (S && (!g || d && !T)) {
|
|
2551
|
+
const K = gt(l, S, "EventManager");
|
|
2552
|
+
if (K === null)
|
|
2538
2553
|
return null;
|
|
2539
|
-
l =
|
|
2554
|
+
l = K;
|
|
2540
2555
|
}
|
|
2541
2556
|
return l;
|
|
2542
2557
|
}
|
|
2543
2558
|
isDuplicateEvent(e) {
|
|
2544
|
-
const t = Date.now(),
|
|
2545
|
-
return n && t - n < 1e3 ? (this.recentEventFingerprints.set(
|
|
2559
|
+
const t = Date.now(), s = this.createEventFingerprint(e), n = this.recentEventFingerprints.get(s);
|
|
2560
|
+
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
2561
|
data: { hardLimit: 3e3 }
|
|
2547
2562
|
})), !1);
|
|
2548
2563
|
}
|
|
2549
2564
|
pruneOldFingerprints() {
|
|
2550
2565
|
const e = Date.now(), t = 1e3 * 10;
|
|
2551
|
-
for (const [
|
|
2552
|
-
e - n > t && this.recentEventFingerprints.delete(
|
|
2566
|
+
for (const [s, n] of this.recentEventFingerprints.entries())
|
|
2567
|
+
e - n > t && this.recentEventFingerprints.delete(s);
|
|
2553
2568
|
a("debug", "Pruned old event fingerprints", {
|
|
2554
2569
|
data: {
|
|
2555
2570
|
remaining: this.recentEventFingerprints.size,
|
|
@@ -2560,8 +2575,8 @@ class Tr extends w {
|
|
|
2560
2575
|
createEventFingerprint(e) {
|
|
2561
2576
|
let t = `${e.type}_${e.page_url}`;
|
|
2562
2577
|
if (e.click_data) {
|
|
2563
|
-
const
|
|
2564
|
-
t += `_click_${
|
|
2578
|
+
const s = Math.round((e.click_data.x || 0) / 10) * 10, n = Math.round((e.click_data.y || 0) / 10) * 10;
|
|
2579
|
+
t += `_click_${s}_${n}`;
|
|
2565
2580
|
}
|
|
2566
2581
|
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
2582
|
}
|
|
@@ -2570,17 +2585,17 @@ class Tr extends w {
|
|
|
2570
2585
|
}
|
|
2571
2586
|
/** Deterministic JSON string with sorted keys to ensure consistent fingerprints regardless of property insertion order */
|
|
2572
2587
|
stableStringify(e) {
|
|
2573
|
-
return JSON.stringify(e, (t,
|
|
2588
|
+
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
2589
|
}
|
|
2575
2590
|
addToQueue(e) {
|
|
2576
2591
|
if (this.emitEvent(e), this.eventsQueue.push(e), this.eventsQueue.length > 100) {
|
|
2577
|
-
const t = this.eventsQueue.findIndex((n) => n.type !==
|
|
2592
|
+
const t = this.eventsQueue.findIndex((n) => n.type !== u.SESSION_START), s = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
|
|
2578
2593
|
a("warn", "Event queue overflow, oldest non-critical event removed", {
|
|
2579
2594
|
data: {
|
|
2580
2595
|
maxLength: 100,
|
|
2581
2596
|
currentLength: this.eventsQueue.length,
|
|
2582
|
-
removedEventType:
|
|
2583
|
-
wasCritical:
|
|
2597
|
+
removedEventType: s?.type,
|
|
2598
|
+
wasCritical: s?.type === u.SESSION_START
|
|
2584
2599
|
}
|
|
2585
2600
|
});
|
|
2586
2601
|
}
|
|
@@ -2608,33 +2623,33 @@ class Tr extends w {
|
|
|
2608
2623
|
return e - this.rateLimitWindowStart > 1e3 && (this.rateLimitCounter = 0, this.rateLimitWindowStart = e), this.rateLimitCounter >= 50 ? !1 : (this.rateLimitCounter++, !0);
|
|
2609
2624
|
}
|
|
2610
2625
|
checkPerEventRateLimit(e, t) {
|
|
2611
|
-
const
|
|
2626
|
+
const s = Date.now(), i = (this.perEventRateLimits.get(e) ?? []).filter((o) => s - o < 6e4);
|
|
2612
2627
|
return i.length >= t ? (a("warn", "Per-event rate limit exceeded for custom event", {
|
|
2613
2628
|
data: {
|
|
2614
2629
|
eventName: e,
|
|
2615
2630
|
limit: t,
|
|
2616
2631
|
window: `${6e4 / 1e3}s`
|
|
2617
2632
|
}
|
|
2618
|
-
}), !1) : (i.push(
|
|
2633
|
+
}), !1) : (i.push(s), this.perEventRateLimits.set(e, i), !0);
|
|
2619
2634
|
}
|
|
2620
2635
|
getTypeLimitForEvent(e) {
|
|
2621
2636
|
return {
|
|
2622
|
-
[
|
|
2623
|
-
[
|
|
2624
|
-
[
|
|
2625
|
-
[
|
|
2626
|
-
[
|
|
2637
|
+
[u.CLICK]: 500,
|
|
2638
|
+
[u.PAGE_VIEW]: 100,
|
|
2639
|
+
[u.CUSTOM]: 500,
|
|
2640
|
+
[u.VIEWPORT_VISIBLE]: 200,
|
|
2641
|
+
[u.SCROLL]: 120
|
|
2627
2642
|
}[e] ?? null;
|
|
2628
2643
|
}
|
|
2629
2644
|
removeProcessedEvents(e) {
|
|
2630
2645
|
const t = new Set(e);
|
|
2631
|
-
this.eventsQueue = this.eventsQueue.filter((
|
|
2646
|
+
this.eventsQueue = this.eventsQueue.filter((s) => !t.has(s.id));
|
|
2632
2647
|
}
|
|
2633
2648
|
emitEvent(e) {
|
|
2634
|
-
this.emitter && this.emitter.emit(
|
|
2649
|
+
this.emitter && this.emitter.emit(se.EVENT, e);
|
|
2635
2650
|
}
|
|
2636
2651
|
emitEventsQueue(e) {
|
|
2637
|
-
this.emitter && this.emitter.emit(
|
|
2652
|
+
this.emitter && this.emitter.emit(se.QUEUE, e);
|
|
2638
2653
|
}
|
|
2639
2654
|
/**
|
|
2640
2655
|
* Creates a debounced version of a function that delays execution until after
|
|
@@ -2657,10 +2672,10 @@ class Tr extends w {
|
|
|
2657
2672
|
* @internal
|
|
2658
2673
|
*/
|
|
2659
2674
|
debounce(e, t) {
|
|
2660
|
-
let
|
|
2675
|
+
let s = null;
|
|
2661
2676
|
return ((...n) => {
|
|
2662
|
-
|
|
2663
|
-
e(...n),
|
|
2677
|
+
s !== null && clearTimeout(s), s = setTimeout(() => {
|
|
2678
|
+
e(...n), s = null;
|
|
2664
2679
|
}, t);
|
|
2665
2680
|
});
|
|
2666
2681
|
}
|
|
@@ -2677,11 +2692,11 @@ class Tr extends w {
|
|
|
2677
2692
|
getInitialCounts() {
|
|
2678
2693
|
return {
|
|
2679
2694
|
total: 0,
|
|
2680
|
-
[
|
|
2681
|
-
[
|
|
2682
|
-
[
|
|
2683
|
-
[
|
|
2684
|
-
[
|
|
2695
|
+
[u.CLICK]: 0,
|
|
2696
|
+
[u.PAGE_VIEW]: 0,
|
|
2697
|
+
[u.CUSTOM]: 0,
|
|
2698
|
+
[u.VIEWPORT_VISIBLE]: 0,
|
|
2699
|
+
[u.SCROLL]: 0
|
|
2685
2700
|
};
|
|
2686
2701
|
}
|
|
2687
2702
|
/**
|
|
@@ -2710,24 +2725,24 @@ class Tr extends w {
|
|
|
2710
2725
|
loadSessionCounts(e) {
|
|
2711
2726
|
if (typeof window > "u" || typeof localStorage > "u")
|
|
2712
2727
|
return this.getInitialCounts();
|
|
2713
|
-
const t = this.get("userId") || "anonymous",
|
|
2728
|
+
const t = this.get("userId") || "anonymous", s = xe(t, e);
|
|
2714
2729
|
try {
|
|
2715
|
-
const n = localStorage.getItem(
|
|
2730
|
+
const n = localStorage.getItem(s);
|
|
2716
2731
|
if (!n)
|
|
2717
2732
|
return this.getInitialCounts();
|
|
2718
2733
|
const i = JSON.parse(n);
|
|
2719
|
-
return i._timestamp && Date.now() - i._timestamp >
|
|
2734
|
+
return i._timestamp && Date.now() - i._timestamp > $e ? (a("debug", "Session counts expired, clearing", {
|
|
2720
2735
|
data: { sessionId: e, age: Date.now() - i._timestamp }
|
|
2721
|
-
}), localStorage.removeItem(
|
|
2736
|
+
}), 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
2737
|
total: i.total,
|
|
2723
|
-
[
|
|
2724
|
-
[
|
|
2725
|
-
[
|
|
2726
|
-
[
|
|
2727
|
-
[
|
|
2738
|
+
[u.CLICK]: i[u.CLICK],
|
|
2739
|
+
[u.PAGE_VIEW]: i[u.PAGE_VIEW],
|
|
2740
|
+
[u.CUSTOM]: i[u.CUSTOM],
|
|
2741
|
+
[u.VIEWPORT_VISIBLE]: i[u.VIEWPORT_VISIBLE],
|
|
2742
|
+
[u.SCROLL]: i[u.SCROLL]
|
|
2728
2743
|
} : (a("warn", "Invalid session counts structure in localStorage, resetting", {
|
|
2729
2744
|
data: { sessionId: e, parsed: i }
|
|
2730
|
-
}), localStorage.removeItem(
|
|
2745
|
+
}), localStorage.removeItem(s), a("debug", "Session counts removed due to invalid/corrupted data", {
|
|
2731
2746
|
data: { sessionId: e, parsed: i }
|
|
2732
2747
|
}), this.getInitialCounts());
|
|
2733
2748
|
} catch (n) {
|
|
@@ -2761,32 +2776,32 @@ class Tr extends w {
|
|
|
2761
2776
|
cleanupExpiredSessionCounts() {
|
|
2762
2777
|
if (!(typeof window > "u" || typeof localStorage > "u"))
|
|
2763
2778
|
try {
|
|
2764
|
-
const e = localStorage.getItem(
|
|
2779
|
+
const e = localStorage.getItem(Be);
|
|
2765
2780
|
if (e) {
|
|
2766
2781
|
const i = Date.now() - parseInt(e, 10);
|
|
2767
|
-
if (i <
|
|
2782
|
+
if (i < We) {
|
|
2768
2783
|
a("debug", "Skipping session counts cleanup (throttled)", {
|
|
2769
|
-
data: { timeSinceLastCleanup: i, throttleMs:
|
|
2784
|
+
data: { timeSinceLastCleanup: i, throttleMs: We }
|
|
2770
2785
|
});
|
|
2771
2786
|
return;
|
|
2772
2787
|
}
|
|
2773
2788
|
}
|
|
2774
|
-
const t = this.get("userId") || "anonymous",
|
|
2789
|
+
const t = this.get("userId") || "anonymous", s = `${I}:${t}:session_counts:`, n = [];
|
|
2775
2790
|
for (let i = 0; i < localStorage.length; i++) {
|
|
2776
2791
|
const o = localStorage.key(i);
|
|
2777
|
-
if (o?.startsWith(
|
|
2792
|
+
if (o?.startsWith(s))
|
|
2778
2793
|
try {
|
|
2779
2794
|
const l = localStorage.getItem(o);
|
|
2780
2795
|
if (l) {
|
|
2781
2796
|
const c = JSON.parse(l);
|
|
2782
|
-
c._timestamp && Date.now() - c._timestamp >
|
|
2797
|
+
c._timestamp && Date.now() - c._timestamp > $e && n.push(o);
|
|
2783
2798
|
}
|
|
2784
2799
|
} catch {
|
|
2785
2800
|
}
|
|
2786
2801
|
}
|
|
2787
2802
|
n.forEach((i) => {
|
|
2788
2803
|
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(
|
|
2804
|
+
}), n.length > 0 && a("info", `Cleaned up ${n.length} expired session counts entries`), localStorage.setItem(Be, Date.now().toString());
|
|
2790
2805
|
} catch (e) {
|
|
2791
2806
|
a("warn", "Failed to cleanup expired session counts", { error: e });
|
|
2792
2807
|
}
|
|
@@ -2820,14 +2835,14 @@ class Tr extends w {
|
|
|
2820
2835
|
* @internal
|
|
2821
2836
|
*/
|
|
2822
2837
|
saveSessionCounts(e) {
|
|
2823
|
-
const t = this.get("userId") || "anonymous",
|
|
2838
|
+
const t = this.get("userId") || "anonymous", s = xe(t, e);
|
|
2824
2839
|
try {
|
|
2825
2840
|
const n = {
|
|
2826
2841
|
...this.sessionEventCounts,
|
|
2827
2842
|
_timestamp: Date.now(),
|
|
2828
2843
|
_version: 1
|
|
2829
2844
|
};
|
|
2830
|
-
localStorage.setItem(
|
|
2845
|
+
localStorage.setItem(s, JSON.stringify(n));
|
|
2831
2846
|
} catch (n) {
|
|
2832
2847
|
a("warn", "Failed to persist session counts to localStorage", {
|
|
2833
2848
|
error: n,
|
|
@@ -2836,7 +2851,7 @@ class Tr extends w {
|
|
|
2836
2851
|
}
|
|
2837
2852
|
}
|
|
2838
2853
|
}
|
|
2839
|
-
class
|
|
2854
|
+
class Is {
|
|
2840
2855
|
/**
|
|
2841
2856
|
* Gets or creates a unique user ID.
|
|
2842
2857
|
*
|
|
@@ -2854,15 +2869,15 @@ class Ir {
|
|
|
2854
2869
|
* @returns Persistent unique user ID (UUID v4 format)
|
|
2855
2870
|
*/
|
|
2856
2871
|
static getId(e) {
|
|
2857
|
-
const t = e.getItem(
|
|
2872
|
+
const t = e.getItem(Te);
|
|
2858
2873
|
if (t)
|
|
2859
2874
|
return t;
|
|
2860
|
-
const
|
|
2861
|
-
return e.setItem(
|
|
2875
|
+
const s = ut();
|
|
2876
|
+
return e.setItem(Te, s), s;
|
|
2862
2877
|
}
|
|
2863
2878
|
}
|
|
2864
|
-
const
|
|
2865
|
-
class
|
|
2879
|
+
const vs = /^\d{13}-[a-z0-9]{9}$/;
|
|
2880
|
+
class _s extends _ {
|
|
2866
2881
|
storageManager;
|
|
2867
2882
|
eventManager;
|
|
2868
2883
|
projectId;
|
|
@@ -2879,8 +2894,8 @@ class _r extends w {
|
|
|
2879
2894
|
* @param eventManager - Event manager for SESSION_START events
|
|
2880
2895
|
* @param projectId - Project identifier for namespacing session storage
|
|
2881
2896
|
*/
|
|
2882
|
-
constructor(e, t,
|
|
2883
|
-
super(), this.storageManager = e, this.eventManager = t, this.projectId =
|
|
2897
|
+
constructor(e, t, s) {
|
|
2898
|
+
super(), this.storageManager = e, this.eventManager = t, this.projectId = s;
|
|
2884
2899
|
}
|
|
2885
2900
|
initCrossTabSync() {
|
|
2886
2901
|
if (typeof BroadcastChannel > "u") {
|
|
@@ -2888,9 +2903,9 @@ class _r extends w {
|
|
|
2888
2903
|
return;
|
|
2889
2904
|
}
|
|
2890
2905
|
const e = this.getProjectId();
|
|
2891
|
-
this.broadcastChannel = new BroadcastChannel(
|
|
2892
|
-
const { action:
|
|
2893
|
-
o === e && (
|
|
2906
|
+
this.broadcastChannel = new BroadcastChannel(Ot(e)), this.broadcastChannel.onmessage = (t) => {
|
|
2907
|
+
const { action: s, sessionId: n, timestamp: i, projectId: o } = t.data ?? {};
|
|
2908
|
+
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
2909
|
};
|
|
2895
2910
|
}
|
|
2896
2911
|
shareSession(e) {
|
|
@@ -2908,18 +2923,18 @@ class _r extends w {
|
|
|
2908
2923
|
const e = this.loadStoredSession();
|
|
2909
2924
|
if (!e)
|
|
2910
2925
|
return null;
|
|
2911
|
-
if (!
|
|
2926
|
+
if (!vs.test(e.id))
|
|
2912
2927
|
return a("warn", "Invalid session ID format recovered from storage, clearing", {
|
|
2913
2928
|
data: { sessionId: e.id }
|
|
2914
2929
|
}), this.clearStoredSession(), null;
|
|
2915
2930
|
const t = this.get("config")?.sessionTimeout ?? 9e5;
|
|
2916
2931
|
return Date.now() - e.lastActivity > t ? (this.clearStoredSession(), null) : e.id;
|
|
2917
2932
|
}
|
|
2918
|
-
persistSession(e, t = Date.now(),
|
|
2933
|
+
persistSession(e, t = Date.now(), s, n) {
|
|
2919
2934
|
this.saveStoredSession({
|
|
2920
2935
|
id: e,
|
|
2921
2936
|
lastActivity: t,
|
|
2922
|
-
...
|
|
2937
|
+
...s && { referrer: s },
|
|
2923
2938
|
...n && { utm: n }
|
|
2924
2939
|
});
|
|
2925
2940
|
}
|
|
@@ -2937,10 +2952,10 @@ class _r extends w {
|
|
|
2937
2952
|
} catch {
|
|
2938
2953
|
this.storageManager.removeItem(e);
|
|
2939
2954
|
}
|
|
2940
|
-
const
|
|
2941
|
-
if (
|
|
2955
|
+
const s = this.storageManager.getSessionItem(e);
|
|
2956
|
+
if (s !== null)
|
|
2942
2957
|
try {
|
|
2943
|
-
const n = JSON.parse(
|
|
2958
|
+
const n = JSON.parse(s);
|
|
2944
2959
|
if (n.id && typeof n.lastActivity == "number")
|
|
2945
2960
|
return n;
|
|
2946
2961
|
} catch {
|
|
@@ -2949,11 +2964,11 @@ class _r extends w {
|
|
|
2949
2964
|
return null;
|
|
2950
2965
|
}
|
|
2951
2966
|
saveStoredSession(e) {
|
|
2952
|
-
const t = this.getSessionStorageKey(),
|
|
2953
|
-
this.storageManager.setItem(t,
|
|
2967
|
+
const t = this.getSessionStorageKey(), s = JSON.stringify(e);
|
|
2968
|
+
this.storageManager.setItem(t, s), this.storageManager.setSessionItem(t, s);
|
|
2954
2969
|
}
|
|
2955
2970
|
getSessionStorageKey() {
|
|
2956
|
-
return
|
|
2971
|
+
return Nt(this.getProjectId());
|
|
2957
2972
|
}
|
|
2958
2973
|
getProjectId() {
|
|
2959
2974
|
return this.projectId;
|
|
@@ -3016,28 +3031,28 @@ class _r extends w {
|
|
|
3016
3031
|
return;
|
|
3017
3032
|
}
|
|
3018
3033
|
const e = this.recoverSession(), t = e ?? this.generateSessionId();
|
|
3019
|
-
let
|
|
3034
|
+
let s, n;
|
|
3020
3035
|
if (e) {
|
|
3021
3036
|
const i = this.loadStoredSession();
|
|
3022
|
-
|
|
3037
|
+
s = i?.referrer ?? me(), n = i?.utm ?? ge();
|
|
3023
3038
|
} else
|
|
3024
|
-
|
|
3039
|
+
s = me(), n = ge();
|
|
3025
3040
|
a("debug", "Session tracking initialized", {
|
|
3026
3041
|
data: {
|
|
3027
3042
|
sessionId: t,
|
|
3028
3043
|
wasRecovered: !!e,
|
|
3029
3044
|
willEmitSessionStart: !e,
|
|
3030
|
-
sessionReferrer:
|
|
3045
|
+
sessionReferrer: s,
|
|
3031
3046
|
hasUtm: !!n
|
|
3032
3047
|
}
|
|
3033
3048
|
}), this.isTracking = !0;
|
|
3034
3049
|
try {
|
|
3035
|
-
this.set("sessionId", t), this.set("sessionReferrer",
|
|
3050
|
+
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
3051
|
data: { sessionId: t }
|
|
3037
3052
|
}) : (a("debug", "Emitting SESSION_START event", {
|
|
3038
3053
|
data: { sessionId: t }
|
|
3039
3054
|
}), this.eventManager.track({
|
|
3040
|
-
type:
|
|
3055
|
+
type: u.SESSION_START
|
|
3041
3056
|
})), this.setupSessionTimeout(), this.setupActivityListeners(), this.setupLifecycleListeners();
|
|
3042
3057
|
} catch (i) {
|
|
3043
3058
|
throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null), i;
|
|
@@ -3072,11 +3087,11 @@ class _r extends w {
|
|
|
3072
3087
|
*/
|
|
3073
3088
|
renewSession() {
|
|
3074
3089
|
this.needsRenewal = !1;
|
|
3075
|
-
const e = this.generateSessionId(), t =
|
|
3090
|
+
const e = this.generateSessionId(), t = me(), s = ge();
|
|
3076
3091
|
a("debug", "Renewing session after timeout", {
|
|
3077
3092
|
data: { newSessionId: e }
|
|
3078
|
-
}), this.set("sessionId", e), this.set("sessionReferrer", t), this.set("sessionUtm",
|
|
3079
|
-
type:
|
|
3093
|
+
}), 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({
|
|
3094
|
+
type: u.SESSION_START
|
|
3080
3095
|
}), this.eventManager.flushPendingEvents(), this.setupSessionTimeout();
|
|
3081
3096
|
}
|
|
3082
3097
|
cleanupActivityListeners() {
|
|
@@ -3105,8 +3120,8 @@ class _r extends w {
|
|
|
3105
3120
|
const t = this.loadStoredSession();
|
|
3106
3121
|
if (!t)
|
|
3107
3122
|
return !1;
|
|
3108
|
-
const
|
|
3109
|
-
return Date.now() - t.lastActivity >
|
|
3123
|
+
const s = this.get("config")?.sessionTimeout ?? 9e5;
|
|
3124
|
+
return Date.now() - t.lastActivity > s;
|
|
3110
3125
|
}
|
|
3111
3126
|
cleanupLifecycleListeners() {
|
|
3112
3127
|
this.visibilityChangeHandler && (document.removeEventListener("visibilitychange", this.visibilityChangeHandler), this.visibilityChangeHandler = null);
|
|
@@ -3193,7 +3208,7 @@ class _r extends w {
|
|
|
3193
3208
|
this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupCrossTabSync(), this.cleanupLifecycleListeners(), this.isTracking = !1, this.needsRenewal = !1, this.set("hasStartSession", !1);
|
|
3194
3209
|
}
|
|
3195
3210
|
}
|
|
3196
|
-
class
|
|
3211
|
+
class ys extends _ {
|
|
3197
3212
|
eventManager;
|
|
3198
3213
|
storageManager;
|
|
3199
3214
|
sessionManager = null;
|
|
@@ -3228,8 +3243,8 @@ class yr extends w {
|
|
|
3228
3243
|
}
|
|
3229
3244
|
const t = this.get("config")?.integrations?.tracelog?.projectId ?? "custom";
|
|
3230
3245
|
try {
|
|
3231
|
-
this.sessionManager = new
|
|
3232
|
-
} catch (
|
|
3246
|
+
this.sessionManager = new _s(this.storageManager, this.eventManager, t), this.sessionManager.startTracking(), this.eventManager.flushPendingEvents();
|
|
3247
|
+
} catch (s) {
|
|
3233
3248
|
if (this.sessionManager) {
|
|
3234
3249
|
try {
|
|
3235
3250
|
this.sessionManager.destroy();
|
|
@@ -3237,7 +3252,7 @@ class yr extends w {
|
|
|
3237
3252
|
}
|
|
3238
3253
|
this.sessionManager = null;
|
|
3239
3254
|
}
|
|
3240
|
-
throw a("error", "Failed to start session tracking", { error:
|
|
3255
|
+
throw a("error", "Failed to start session tracking", { error: s }), s;
|
|
3241
3256
|
}
|
|
3242
3257
|
}
|
|
3243
3258
|
isActive() {
|
|
@@ -3281,7 +3296,7 @@ class yr extends w {
|
|
|
3281
3296
|
this.destroyed || (this.sessionManager && (this.sessionManager.destroy(), this.sessionManager = null), this.destroyed = !0);
|
|
3282
3297
|
}
|
|
3283
3298
|
}
|
|
3284
|
-
class
|
|
3299
|
+
class ws extends _ {
|
|
3285
3300
|
eventManager;
|
|
3286
3301
|
onTrack;
|
|
3287
3302
|
originalPushState;
|
|
@@ -3316,48 +3331,48 @@ class wr extends w {
|
|
|
3316
3331
|
}
|
|
3317
3332
|
patchHistory(e) {
|
|
3318
3333
|
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,
|
|
3334
|
+
e === "pushState" && !this.originalPushState ? this.originalPushState = t : e === "replaceState" && !this.originalReplaceState && (this.originalReplaceState = t), window.history[e] = (...s) => {
|
|
3335
|
+
t.apply(window.history, s), this.trackCurrentPage();
|
|
3321
3336
|
};
|
|
3322
3337
|
}
|
|
3323
3338
|
trackCurrentPage = () => {
|
|
3324
|
-
const e = window.location.href, t =
|
|
3339
|
+
const e = window.location.href, t = we(e, this.get("config").sensitiveQueryParams);
|
|
3325
3340
|
if (this.get("pageUrl") === t)
|
|
3326
3341
|
return;
|
|
3327
|
-
const
|
|
3328
|
-
if (
|
|
3342
|
+
const s = Date.now(), n = this.get("config").pageViewThrottleMs ?? 1e3;
|
|
3343
|
+
if (s - this.lastPageViewTime < n)
|
|
3329
3344
|
return;
|
|
3330
|
-
this.lastPageViewTime =
|
|
3345
|
+
this.lastPageViewTime = s, this.onTrack();
|
|
3331
3346
|
const i = this.get("pageUrl");
|
|
3332
3347
|
this.set("pageUrl", t);
|
|
3333
3348
|
const o = this.extractPageViewData();
|
|
3334
3349
|
this.eventManager.track({
|
|
3335
|
-
type:
|
|
3350
|
+
type: u.PAGE_VIEW,
|
|
3336
3351
|
page_url: this.get("pageUrl"),
|
|
3337
3352
|
from_page_url: i,
|
|
3338
3353
|
...o && { page_view: o }
|
|
3339
3354
|
});
|
|
3340
3355
|
};
|
|
3341
3356
|
trackInitialPageView() {
|
|
3342
|
-
const e =
|
|
3357
|
+
const e = we(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
|
|
3343
3358
|
this.lastPageViewTime = Date.now(), this.eventManager.track({
|
|
3344
|
-
type:
|
|
3359
|
+
type: u.PAGE_VIEW,
|
|
3345
3360
|
page_url: e,
|
|
3346
3361
|
...t && { page_view: t }
|
|
3347
3362
|
}), this.onTrack();
|
|
3348
3363
|
}
|
|
3349
3364
|
extractPageViewData() {
|
|
3350
|
-
const { pathname: e, search: t, hash:
|
|
3351
|
-
return !n && !i && !e && !t && !
|
|
3365
|
+
const { pathname: e, search: t, hash: s } = window.location, { referrer: n } = document, { title: i } = document;
|
|
3366
|
+
return !n && !i && !e && !t && !s ? void 0 : {
|
|
3352
3367
|
...n && { referrer: n },
|
|
3353
3368
|
...i && { title: i },
|
|
3354
3369
|
...e && { pathname: e },
|
|
3355
3370
|
...t && { search: t },
|
|
3356
|
-
...
|
|
3371
|
+
...s && { hash: s }
|
|
3357
3372
|
};
|
|
3358
3373
|
}
|
|
3359
3374
|
}
|
|
3360
|
-
class
|
|
3375
|
+
class bs extends _ {
|
|
3361
3376
|
eventManager;
|
|
3362
3377
|
lastClickTimes = /* @__PURE__ */ new Map();
|
|
3363
3378
|
clickHandler;
|
|
@@ -3380,7 +3395,7 @@ class br extends w {
|
|
|
3380
3395
|
*/
|
|
3381
3396
|
startTracking() {
|
|
3382
3397
|
this.clickHandler || (this.clickHandler = (e) => {
|
|
3383
|
-
const t = e,
|
|
3398
|
+
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
3399
|
if (!n) {
|
|
3385
3400
|
a("debug", "Click target not found or not an element");
|
|
3386
3401
|
return;
|
|
@@ -3392,22 +3407,22 @@ class br extends w {
|
|
|
3392
3407
|
return;
|
|
3393
3408
|
const o = this.findTrackingElement(n), l = this.getRelevantClickElement(n), c = this.calculateClickCoordinates(t, n);
|
|
3394
3409
|
if (o) {
|
|
3395
|
-
const
|
|
3396
|
-
if (
|
|
3397
|
-
const
|
|
3410
|
+
const f = this.extractTrackingData(o);
|
|
3411
|
+
if (f) {
|
|
3412
|
+
const g = this.createCustomEventData(f);
|
|
3398
3413
|
this.eventManager.track({
|
|
3399
|
-
type:
|
|
3414
|
+
type: u.CUSTOM,
|
|
3400
3415
|
custom_event: {
|
|
3401
|
-
name:
|
|
3402
|
-
...
|
|
3416
|
+
name: g.name,
|
|
3417
|
+
...g.value && { metadata: { value: g.value } }
|
|
3403
3418
|
}
|
|
3404
3419
|
});
|
|
3405
3420
|
}
|
|
3406
3421
|
}
|
|
3407
|
-
const
|
|
3422
|
+
const d = this.generateClickData(n, l, c);
|
|
3408
3423
|
this.eventManager.track({
|
|
3409
|
-
type:
|
|
3410
|
-
click_data:
|
|
3424
|
+
type: u.CLICK,
|
|
3425
|
+
click_data: d
|
|
3411
3426
|
});
|
|
3412
3427
|
}, window.addEventListener("click", this.clickHandler, !0));
|
|
3413
3428
|
}
|
|
@@ -3428,15 +3443,15 @@ class br extends w {
|
|
|
3428
3443
|
* Returns true if the click should be tracked, false if throttled
|
|
3429
3444
|
*/
|
|
3430
3445
|
checkClickThrottle(e, t) {
|
|
3431
|
-
const
|
|
3446
|
+
const s = this.getElementSignature(e), n = Date.now();
|
|
3432
3447
|
this.pruneThrottleCache(n);
|
|
3433
|
-
const i = this.lastClickTimes.get(
|
|
3448
|
+
const i = this.lastClickTimes.get(s);
|
|
3434
3449
|
return i !== void 0 && n - i < t ? (a("debug", "ClickHandler: Click suppressed by throttle", {
|
|
3435
3450
|
data: {
|
|
3436
|
-
signature:
|
|
3451
|
+
signature: s,
|
|
3437
3452
|
throttleRemaining: t - (n - i)
|
|
3438
3453
|
}
|
|
3439
|
-
}), !1) : (this.lastClickTimes.set(
|
|
3454
|
+
}), !1) : (this.lastClickTimes.set(s, n), !0);
|
|
3440
3455
|
}
|
|
3441
3456
|
/**
|
|
3442
3457
|
* Prunes stale entries from the throttle cache to prevent memory leaks
|
|
@@ -3448,10 +3463,10 @@ class br extends w {
|
|
|
3448
3463
|
return;
|
|
3449
3464
|
this.lastPruneTime = e;
|
|
3450
3465
|
const t = e - 3e5;
|
|
3451
|
-
for (const [
|
|
3452
|
-
n < t && this.lastClickTimes.delete(
|
|
3466
|
+
for (const [s, n] of this.lastClickTimes.entries())
|
|
3467
|
+
n < t && this.lastClickTimes.delete(s);
|
|
3453
3468
|
if (this.lastClickTimes.size > 1e3) {
|
|
3454
|
-
const
|
|
3469
|
+
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
3470
|
for (const [o] of i)
|
|
3456
3471
|
this.lastClickTimes.delete(o);
|
|
3457
3472
|
a("debug", "ClickHandler: Pruned throttle cache", {
|
|
@@ -3472,22 +3487,22 @@ class br extends w {
|
|
|
3472
3487
|
const t = e.getAttribute("data-testid");
|
|
3473
3488
|
if (t)
|
|
3474
3489
|
return `[data-testid="${t}"]`;
|
|
3475
|
-
const
|
|
3476
|
-
return
|
|
3490
|
+
const s = e.getAttribute(`${b}-name`);
|
|
3491
|
+
return s ? `[${b}-name="${s}"]` : this.getElementPath(e);
|
|
3477
3492
|
}
|
|
3478
3493
|
/**
|
|
3479
3494
|
* Generates a DOM path for an element (e.g., "body>div>button")
|
|
3480
3495
|
*/
|
|
3481
3496
|
getElementPath(e) {
|
|
3482
3497
|
const t = [];
|
|
3483
|
-
let
|
|
3484
|
-
for (;
|
|
3485
|
-
let n =
|
|
3486
|
-
if (
|
|
3487
|
-
const i =
|
|
3498
|
+
let s = e;
|
|
3499
|
+
for (; s && s !== document.body; ) {
|
|
3500
|
+
let n = s.tagName.toLowerCase();
|
|
3501
|
+
if (s.className) {
|
|
3502
|
+
const i = s.className.split(" ")[0];
|
|
3488
3503
|
i && (n += `.${i}`);
|
|
3489
3504
|
}
|
|
3490
|
-
t.unshift(n),
|
|
3505
|
+
t.unshift(n), s = s.parentElement;
|
|
3491
3506
|
}
|
|
3492
3507
|
return t.join(">") || "unknown";
|
|
3493
3508
|
}
|
|
@@ -3495,15 +3510,15 @@ class br extends w {
|
|
|
3495
3510
|
return e.hasAttribute(`${b}-name`) ? e : e.closest(`[${b}-name]`);
|
|
3496
3511
|
}
|
|
3497
3512
|
getRelevantClickElement(e) {
|
|
3498
|
-
for (const t of
|
|
3513
|
+
for (const t of At)
|
|
3499
3514
|
try {
|
|
3500
3515
|
if (e.matches(t))
|
|
3501
3516
|
return e;
|
|
3502
|
-
const
|
|
3503
|
-
if (
|
|
3504
|
-
return
|
|
3505
|
-
} catch (
|
|
3506
|
-
a("debug", "Invalid selector in element search", { error:
|
|
3517
|
+
const s = e.closest(t);
|
|
3518
|
+
if (s)
|
|
3519
|
+
return s;
|
|
3520
|
+
} catch (s) {
|
|
3521
|
+
a("debug", "Invalid selector in element search", { error: s, data: { selector: t } });
|
|
3507
3522
|
continue;
|
|
3508
3523
|
}
|
|
3509
3524
|
return e;
|
|
@@ -3523,20 +3538,20 @@ class br extends w {
|
|
|
3523
3538
|
return Math.max(0, Math.min(1, Number(e.toFixed(3))));
|
|
3524
3539
|
}
|
|
3525
3540
|
calculateClickCoordinates(e, t) {
|
|
3526
|
-
const
|
|
3541
|
+
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
3542
|
return { x: n, y: i, relativeX: o, relativeY: l };
|
|
3528
3543
|
}
|
|
3529
3544
|
extractTrackingData(e) {
|
|
3530
|
-
const t = e.getAttribute(`${b}-name`),
|
|
3545
|
+
const t = e.getAttribute(`${b}-name`), s = e.getAttribute(`${b}-value`);
|
|
3531
3546
|
if (t)
|
|
3532
3547
|
return {
|
|
3533
3548
|
element: e,
|
|
3534
3549
|
name: t,
|
|
3535
|
-
...
|
|
3550
|
+
...s && { value: s }
|
|
3536
3551
|
};
|
|
3537
3552
|
}
|
|
3538
|
-
generateClickData(e, t,
|
|
3539
|
-
const { x: n, y: i, relativeX: o, relativeY: l } =
|
|
3553
|
+
generateClickData(e, t, s) {
|
|
3554
|
+
const { x: n, y: i, relativeX: o, relativeY: l } = s, c = this.getRelevantText(e, t), d = this.extractElementAttributes(t);
|
|
3540
3555
|
return {
|
|
3541
3556
|
x: n,
|
|
3542
3557
|
y: i,
|
|
@@ -3546,12 +3561,12 @@ class br extends w {
|
|
|
3546
3561
|
...t.id && { id: t.id },
|
|
3547
3562
|
...t.className && { class: t.className },
|
|
3548
3563
|
...c && { text: c },
|
|
3549
|
-
...
|
|
3550
|
-
...
|
|
3551
|
-
...
|
|
3552
|
-
...
|
|
3553
|
-
...
|
|
3554
|
-
...Object.keys(
|
|
3564
|
+
...d.href && { href: d.href },
|
|
3565
|
+
...d.title && { title: d.title },
|
|
3566
|
+
...d.alt && { alt: d.alt },
|
|
3567
|
+
...d.role && { role: d.role },
|
|
3568
|
+
...d["aria-label"] && { ariaLabel: d["aria-label"] },
|
|
3569
|
+
...Object.keys(d).length > 0 && { dataAttributes: d }
|
|
3555
3570
|
};
|
|
3556
3571
|
}
|
|
3557
3572
|
/**
|
|
@@ -3575,18 +3590,18 @@ class br extends w {
|
|
|
3575
3590
|
*/
|
|
3576
3591
|
sanitizeText(e) {
|
|
3577
3592
|
let t = e;
|
|
3578
|
-
for (const
|
|
3579
|
-
const n = new RegExp(
|
|
3593
|
+
for (const s of lt) {
|
|
3594
|
+
const n = new RegExp(s.source, s.flags);
|
|
3580
3595
|
t = t.replace(n, "[REDACTED]");
|
|
3581
3596
|
}
|
|
3582
3597
|
return t;
|
|
3583
3598
|
}
|
|
3584
3599
|
getRelevantText(e, t) {
|
|
3585
|
-
const
|
|
3586
|
-
if (!
|
|
3600
|
+
const s = e.textContent?.trim() ?? "", n = t.textContent?.trim() ?? "";
|
|
3601
|
+
if (!s && !n)
|
|
3587
3602
|
return "";
|
|
3588
3603
|
let i = "";
|
|
3589
|
-
return
|
|
3604
|
+
return s && s.length <= 255 ? i = s : n.length <= 255 ? i = n : i = n.slice(0, 252) + "...", this.sanitizeText(i);
|
|
3590
3605
|
}
|
|
3591
3606
|
extractElementAttributes(e) {
|
|
3592
3607
|
const t = [
|
|
@@ -3600,12 +3615,12 @@ class br extends w {
|
|
|
3600
3615
|
"name",
|
|
3601
3616
|
"alt",
|
|
3602
3617
|
"role"
|
|
3603
|
-
],
|
|
3618
|
+
], s = {};
|
|
3604
3619
|
for (const n of t) {
|
|
3605
3620
|
const i = e.getAttribute(n);
|
|
3606
|
-
i && (
|
|
3621
|
+
i && (s[n] = i);
|
|
3607
3622
|
}
|
|
3608
|
-
return
|
|
3623
|
+
return s;
|
|
3609
3624
|
}
|
|
3610
3625
|
createCustomEventData(e) {
|
|
3611
3626
|
return {
|
|
@@ -3614,7 +3629,7 @@ class br extends w {
|
|
|
3614
3629
|
};
|
|
3615
3630
|
}
|
|
3616
3631
|
}
|
|
3617
|
-
class
|
|
3632
|
+
class As extends _ {
|
|
3618
3633
|
eventManager;
|
|
3619
3634
|
containers = [];
|
|
3620
3635
|
limitWarningLogged = !1;
|
|
@@ -3660,9 +3675,9 @@ class Ar extends w {
|
|
|
3660
3675
|
tryDetectScrollContainers(e) {
|
|
3661
3676
|
const t = this.findScrollableElements();
|
|
3662
3677
|
if (this.isWindowScrollable() && this.setupScrollContainer(window, "window"), t.length > 0) {
|
|
3663
|
-
for (const
|
|
3664
|
-
const n = this.getElementSelector(
|
|
3665
|
-
this.setupScrollContainer(
|
|
3678
|
+
for (const s of t) {
|
|
3679
|
+
const n = this.getElementSelector(s);
|
|
3680
|
+
this.setupScrollContainer(s, n);
|
|
3666
3681
|
}
|
|
3667
3682
|
this.applyPrimaryScrollSelectorIfConfigured();
|
|
3668
3683
|
return;
|
|
@@ -3691,9 +3706,9 @@ class Ar extends w {
|
|
|
3691
3706
|
return o.overflowY === "auto" || o.overflowY === "scroll" || o.overflow === "auto" || o.overflow === "scroll" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
3692
3707
|
}
|
|
3693
3708
|
});
|
|
3694
|
-
let
|
|
3695
|
-
for (; (
|
|
3696
|
-
const n =
|
|
3709
|
+
let s;
|
|
3710
|
+
for (; (s = t.nextNode()) && e.length < 10; ) {
|
|
3711
|
+
const n = s;
|
|
3697
3712
|
this.isElementScrollable(n) && e.push(n);
|
|
3698
3713
|
}
|
|
3699
3714
|
return e;
|
|
@@ -3705,9 +3720,9 @@ class Ar extends w {
|
|
|
3705
3720
|
if (t.id)
|
|
3706
3721
|
return `#${t.id}`;
|
|
3707
3722
|
if (t.className && typeof t.className == "string") {
|
|
3708
|
-
const
|
|
3709
|
-
if (
|
|
3710
|
-
return `.${
|
|
3723
|
+
const s = t.className.split(" ").filter((n) => n.trim())[0];
|
|
3724
|
+
if (s)
|
|
3725
|
+
return `.${s}`;
|
|
3711
3726
|
}
|
|
3712
3727
|
return t.tagName.toLowerCase();
|
|
3713
3728
|
}
|
|
@@ -3715,7 +3730,7 @@ class Ar extends w {
|
|
|
3715
3730
|
return this.isWindowScrollable() ? e === window : this.containers.length === 0;
|
|
3716
3731
|
}
|
|
3717
3732
|
setupScrollContainer(e, t) {
|
|
3718
|
-
if (this.containers.some((
|
|
3733
|
+
if (this.containers.some((d) => d.element === e) || e !== window && !this.isElementScrollable(e))
|
|
3719
3734
|
return;
|
|
3720
3735
|
const n = this.getScrollTop(e), i = this.calculateScrollDepth(
|
|
3721
3736
|
n,
|
|
@@ -3727,7 +3742,7 @@ class Ar extends w {
|
|
|
3727
3742
|
isPrimary: o,
|
|
3728
3743
|
lastScrollPos: n,
|
|
3729
3744
|
lastDepth: i,
|
|
3730
|
-
lastDirection:
|
|
3745
|
+
lastDirection: Z.DOWN,
|
|
3731
3746
|
lastEventTime: 0,
|
|
3732
3747
|
firstScrollEventTime: null,
|
|
3733
3748
|
maxDepthReached: i,
|
|
@@ -3735,23 +3750,23 @@ class Ar extends w {
|
|
|
3735
3750
|
listener: null
|
|
3736
3751
|
}, c = () => {
|
|
3737
3752
|
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,
|
|
3753
|
+
const d = this.calculateScrollData(l);
|
|
3754
|
+
if (d) {
|
|
3755
|
+
const f = Date.now();
|
|
3756
|
+
this.processScrollEvent(l, d, f);
|
|
3742
3757
|
}
|
|
3743
3758
|
l.debounceTimer = null;
|
|
3744
3759
|
}, 250));
|
|
3745
3760
|
};
|
|
3746
3761
|
l.listener = c, this.containers.push(l), e === window ? window.addEventListener("scroll", c, { passive: !0 }) : e.addEventListener("scroll", c, { passive: !0 });
|
|
3747
3762
|
}
|
|
3748
|
-
processScrollEvent(e, t,
|
|
3749
|
-
if (!this.shouldEmitScrollEvent(e, t,
|
|
3763
|
+
processScrollEvent(e, t, s) {
|
|
3764
|
+
if (!this.shouldEmitScrollEvent(e, t, s))
|
|
3750
3765
|
return;
|
|
3751
|
-
e.lastEventTime =
|
|
3766
|
+
e.lastEventTime = s, e.lastDepth = t.depth, e.lastDirection = t.direction;
|
|
3752
3767
|
const n = this.get("scrollEventCount") ?? 0;
|
|
3753
3768
|
this.set("scrollEventCount", n + 1), this.eventManager.track({
|
|
3754
|
-
type:
|
|
3769
|
+
type: u.SCROLL,
|
|
3755
3770
|
scroll_data: {
|
|
3756
3771
|
...t,
|
|
3757
3772
|
container_selector: e.selector,
|
|
@@ -3759,8 +3774,8 @@ class Ar extends w {
|
|
|
3759
3774
|
}
|
|
3760
3775
|
});
|
|
3761
3776
|
}
|
|
3762
|
-
shouldEmitScrollEvent(e, t,
|
|
3763
|
-
return this.hasReachedSessionLimit() ? (this.logLimitOnce(), !1) : !(!this.hasElapsedMinimumInterval(e,
|
|
3777
|
+
shouldEmitScrollEvent(e, t, s) {
|
|
3778
|
+
return this.hasReachedSessionLimit() ? (this.logLimitOnce(), !1) : !(!this.hasElapsedMinimumInterval(e, s) || !this.hasSignificantDepthChange(e, t.depth));
|
|
3764
3779
|
}
|
|
3765
3780
|
hasReachedSessionLimit() {
|
|
3766
3781
|
return (this.get("scrollEventCount") ?? 0) >= this.maxEventsPerSession;
|
|
@@ -3786,25 +3801,25 @@ class Ar extends w {
|
|
|
3786
3801
|
e.debounceTimer !== null && (clearTimeout(e.debounceTimer), e.debounceTimer = null);
|
|
3787
3802
|
}
|
|
3788
3803
|
getScrollDirection(e, t) {
|
|
3789
|
-
return e > t ?
|
|
3804
|
+
return e > t ? Z.DOWN : Z.UP;
|
|
3790
3805
|
}
|
|
3791
|
-
calculateScrollDepth(e, t,
|
|
3792
|
-
if (t <=
|
|
3806
|
+
calculateScrollDepth(e, t, s) {
|
|
3807
|
+
if (t <= s)
|
|
3793
3808
|
return 0;
|
|
3794
|
-
const n = t -
|
|
3809
|
+
const n = t - s;
|
|
3795
3810
|
return Math.min(100, Math.max(0, Math.floor(e / n * 100)));
|
|
3796
3811
|
}
|
|
3797
3812
|
calculateScrollData(e) {
|
|
3798
|
-
const { element: t, lastScrollPos:
|
|
3813
|
+
const { element: t, lastScrollPos: s, lastEventTime: n } = e, i = this.getScrollTop(t), o = Date.now(), l = Math.abs(i - s);
|
|
3799
3814
|
if (l < 10 || t === window && !this.isWindowScrollable())
|
|
3800
3815
|
return null;
|
|
3801
|
-
const c = this.getViewportHeight(t),
|
|
3816
|
+
const c = this.getViewportHeight(t), d = this.getScrollHeight(t), f = this.getScrollDirection(i, s), g = this.calculateScrollDepth(i, d, c);
|
|
3802
3817
|
let T;
|
|
3803
3818
|
n > 0 ? T = o - n : e.firstScrollEventTime !== null ? T = o - e.firstScrollEventTime : T = 250;
|
|
3804
3819
|
const S = Math.round(l / T * 1e3);
|
|
3805
|
-
return
|
|
3806
|
-
depth:
|
|
3807
|
-
direction:
|
|
3820
|
+
return g > e.maxDepthReached && (e.maxDepthReached = g), e.lastScrollPos = i, {
|
|
3821
|
+
depth: g,
|
|
3822
|
+
direction: f,
|
|
3808
3823
|
velocity: S,
|
|
3809
3824
|
max_depth_reached: e.maxDepthReached
|
|
3810
3825
|
};
|
|
@@ -3819,8 +3834,8 @@ class Ar extends w {
|
|
|
3819
3834
|
return e === window ? document.documentElement.scrollHeight : e.scrollHeight;
|
|
3820
3835
|
}
|
|
3821
3836
|
isElementScrollable(e) {
|
|
3822
|
-
const t = getComputedStyle(e),
|
|
3823
|
-
return
|
|
3837
|
+
const t = getComputedStyle(e), s = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflow === "auto" || t.overflow === "scroll", n = e.scrollHeight > e.clientHeight;
|
|
3838
|
+
return s && n;
|
|
3824
3839
|
}
|
|
3825
3840
|
applyPrimaryScrollSelector(e) {
|
|
3826
3841
|
let t;
|
|
@@ -3842,7 +3857,7 @@ class Ar extends w {
|
|
|
3842
3857
|
e.isPrimary = t;
|
|
3843
3858
|
}
|
|
3844
3859
|
}
|
|
3845
|
-
class
|
|
3860
|
+
class Ls extends _ {
|
|
3846
3861
|
eventManager;
|
|
3847
3862
|
trackedElements = /* @__PURE__ */ new Map();
|
|
3848
3863
|
observer = null;
|
|
@@ -3859,12 +3874,12 @@ class Lr extends w {
|
|
|
3859
3874
|
const e = this.get("config");
|
|
3860
3875
|
if (this.config = e.viewport ?? null, !this.config?.elements || this.config.elements.length === 0)
|
|
3861
3876
|
return;
|
|
3862
|
-
const t = this.config.threshold ?? 0.5,
|
|
3877
|
+
const t = this.config.threshold ?? 0.5, s = this.config.minDwellTime ?? 1e3;
|
|
3863
3878
|
if (t < 0 || t > 1) {
|
|
3864
3879
|
a("debug", "ViewportHandler: Invalid threshold, must be between 0 and 1");
|
|
3865
3880
|
return;
|
|
3866
3881
|
}
|
|
3867
|
-
if (
|
|
3882
|
+
if (s < 0) {
|
|
3868
3883
|
a("debug", "ViewportHandler: Invalid minDwellTime, must be non-negative");
|
|
3869
3884
|
return;
|
|
3870
3885
|
}
|
|
@@ -3892,15 +3907,15 @@ class Lr extends w {
|
|
|
3892
3907
|
if (!this.config || !this.observer) return;
|
|
3893
3908
|
const e = this.config.maxTrackedElements ?? 100;
|
|
3894
3909
|
let t = this.trackedElements.size;
|
|
3895
|
-
for (const
|
|
3910
|
+
for (const s of this.config.elements)
|
|
3896
3911
|
try {
|
|
3897
|
-
const n = document.querySelectorAll(
|
|
3912
|
+
const n = document.querySelectorAll(s.selector);
|
|
3898
3913
|
for (const i of Array.from(n)) {
|
|
3899
3914
|
if (t >= e) {
|
|
3900
3915
|
a("debug", "ViewportHandler: Maximum tracked elements reached", {
|
|
3901
3916
|
data: {
|
|
3902
3917
|
limit: e,
|
|
3903
|
-
selector:
|
|
3918
|
+
selector: s.selector,
|
|
3904
3919
|
message: "Some elements will not be tracked. Consider more specific selectors."
|
|
3905
3920
|
}
|
|
3906
3921
|
});
|
|
@@ -3908,16 +3923,16 @@ class Lr extends w {
|
|
|
3908
3923
|
}
|
|
3909
3924
|
i.hasAttribute(`${b}-ignore`) || this.trackedElements.has(i) || (this.trackedElements.set(i, {
|
|
3910
3925
|
element: i,
|
|
3911
|
-
selector:
|
|
3912
|
-
id:
|
|
3913
|
-
name:
|
|
3926
|
+
selector: s.selector,
|
|
3927
|
+
id: s.id,
|
|
3928
|
+
name: s.name,
|
|
3914
3929
|
startTime: null,
|
|
3915
3930
|
timeoutId: null,
|
|
3916
3931
|
lastFiredTime: null
|
|
3917
3932
|
}), this.observer?.observe(i), t++);
|
|
3918
3933
|
}
|
|
3919
3934
|
} catch (n) {
|
|
3920
|
-
a("debug", `ViewportHandler: Invalid selector "${
|
|
3935
|
+
a("debug", `ViewportHandler: Invalid selector "${s.selector}"`, { error: n });
|
|
3921
3936
|
}
|
|
3922
3937
|
a("debug", "ViewportHandler: Elements tracked", {
|
|
3923
3938
|
data: { count: t, limit: e }
|
|
@@ -3929,10 +3944,10 @@ class Lr extends w {
|
|
|
3929
3944
|
handleIntersection = (e) => {
|
|
3930
3945
|
if (!this.config) return;
|
|
3931
3946
|
const t = this.config.minDwellTime ?? 1e3;
|
|
3932
|
-
for (const
|
|
3933
|
-
const n = this.trackedElements.get(
|
|
3934
|
-
n && (
|
|
3935
|
-
const i = Math.round(
|
|
3947
|
+
for (const s of e) {
|
|
3948
|
+
const n = this.trackedElements.get(s.target);
|
|
3949
|
+
n && (s.isIntersecting ? n.startTime === null && (n.startTime = performance.now(), n.timeoutId = window.setTimeout(() => {
|
|
3950
|
+
const i = Math.round(s.intersectionRatio * 100) / 100;
|
|
3936
3951
|
this.fireViewportEvent(n, i);
|
|
3937
3952
|
}, t)) : n.startTime !== null && (n.timeoutId !== null && (window.clearTimeout(n.timeoutId), n.timeoutId = null), n.startTime = null));
|
|
3938
3953
|
}
|
|
@@ -3942,7 +3957,7 @@ class Lr extends w {
|
|
|
3942
3957
|
*/
|
|
3943
3958
|
fireViewportEvent(e, t) {
|
|
3944
3959
|
if (e.startTime === null) return;
|
|
3945
|
-
const
|
|
3960
|
+
const s = Math.round(performance.now() - e.startTime);
|
|
3946
3961
|
if (e.element.hasAttribute(`${b}-ignore`))
|
|
3947
3962
|
return;
|
|
3948
3963
|
const n = this.config?.cooldownPeriod ?? 6e4, i = Date.now();
|
|
@@ -3957,13 +3972,13 @@ class Lr extends w {
|
|
|
3957
3972
|
}
|
|
3958
3973
|
const o = {
|
|
3959
3974
|
selector: e.selector,
|
|
3960
|
-
dwellTime:
|
|
3975
|
+
dwellTime: s,
|
|
3961
3976
|
visibilityRatio: t,
|
|
3962
3977
|
...e.id !== void 0 && { id: e.id },
|
|
3963
3978
|
...e.name !== void 0 && { name: e.name }
|
|
3964
3979
|
};
|
|
3965
3980
|
this.eventManager.track({
|
|
3966
|
-
type:
|
|
3981
|
+
type: u.VIEWPORT_VISIBLE,
|
|
3967
3982
|
viewport_data: o
|
|
3968
3983
|
}), e.startTime = null, e.timeoutId = null, e.lastFiredTime = i;
|
|
3969
3984
|
}
|
|
@@ -3978,8 +3993,8 @@ class Lr extends w {
|
|
|
3978
3993
|
}
|
|
3979
3994
|
this.mutationObserver = new MutationObserver((e) => {
|
|
3980
3995
|
let t = !1;
|
|
3981
|
-
for (const
|
|
3982
|
-
|
|
3996
|
+
for (const s of e)
|
|
3997
|
+
s.type === "childList" && (s.addedNodes.length > 0 && (t = !0), s.removedNodes.length > 0 && this.cleanupRemovedNodes(s.removedNodes));
|
|
3983
3998
|
t && (this.mutationDebounceTimer !== null && window.clearTimeout(this.mutationDebounceTimer), this.mutationDebounceTimer = window.setTimeout(() => {
|
|
3984
3999
|
this.observeElements(), this.mutationDebounceTimer = null;
|
|
3985
4000
|
}, 100));
|
|
@@ -3995,15 +4010,58 @@ class Lr extends w {
|
|
|
3995
4010
|
cleanupRemovedNodes(e) {
|
|
3996
4011
|
e.forEach((t) => {
|
|
3997
4012
|
if (t.nodeType !== 1) return;
|
|
3998
|
-
const
|
|
3999
|
-
n && (n.timeoutId !== null && window.clearTimeout(n.timeoutId), this.observer?.unobserve(
|
|
4013
|
+
const s = t, n = this.trackedElements.get(s);
|
|
4014
|
+
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
4015
|
const l = this.trackedElements.get(o);
|
|
4001
4016
|
l && l.timeoutId !== null && window.clearTimeout(l.timeoutId), this.observer?.unobserve(o), this.trackedElements.delete(o);
|
|
4002
4017
|
});
|
|
4003
4018
|
});
|
|
4004
4019
|
}
|
|
4005
4020
|
}
|
|
4006
|
-
|
|
4021
|
+
const Ms = "tracelog_session_id";
|
|
4022
|
+
class Cs extends _ {
|
|
4023
|
+
visibilityHandler = null;
|
|
4024
|
+
lastSyncedSessionId = null;
|
|
4025
|
+
activate() {
|
|
4026
|
+
this.cleanupVisibilityListener(), this.syncCartAttribute(), this.setupVisibilityListener();
|
|
4027
|
+
}
|
|
4028
|
+
deactivate() {
|
|
4029
|
+
this.cleanupVisibilityListener(), this.lastSyncedSessionId = null;
|
|
4030
|
+
}
|
|
4031
|
+
/** Re-syncs the cart attribute when session rotates (called by App on SESSION_START). */
|
|
4032
|
+
onSessionChange() {
|
|
4033
|
+
this.syncCartAttribute();
|
|
4034
|
+
}
|
|
4035
|
+
syncCartAttribute() {
|
|
4036
|
+
const e = this.get("sessionId");
|
|
4037
|
+
!e || e === this.lastSyncedSessionId || (this.lastSyncedSessionId = e, this.postCartUpdate(e));
|
|
4038
|
+
}
|
|
4039
|
+
postCartUpdate(e) {
|
|
4040
|
+
try {
|
|
4041
|
+
fetch("/cart/update.js", {
|
|
4042
|
+
method: "POST",
|
|
4043
|
+
headers: { "Content-Type": "application/json" },
|
|
4044
|
+
body: JSON.stringify({ attributes: { [Ms]: e } }),
|
|
4045
|
+
credentials: "same-origin"
|
|
4046
|
+
}).then((t) => {
|
|
4047
|
+
t.ok || (this.lastSyncedSessionId = null, a("debug", "Shopify cart attribute update failed", { data: { status: t.status } }));
|
|
4048
|
+
}).catch(() => {
|
|
4049
|
+
this.lastSyncedSessionId = null, a("debug", "Shopify cart attribute update failed");
|
|
4050
|
+
});
|
|
4051
|
+
} catch {
|
|
4052
|
+
this.lastSyncedSessionId = null, a("debug", "Shopify cart attribute update failed");
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
4055
|
+
setupVisibilityListener() {
|
|
4056
|
+
this.visibilityHandler = () => {
|
|
4057
|
+
document.hidden || this.syncCartAttribute();
|
|
4058
|
+
}, document.addEventListener("visibilitychange", this.visibilityHandler);
|
|
4059
|
+
}
|
|
4060
|
+
cleanupVisibilityListener() {
|
|
4061
|
+
this.visibilityHandler && (document.removeEventListener("visibilitychange", this.visibilityHandler), this.visibilityHandler = null);
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
class Rs {
|
|
4007
4065
|
storage;
|
|
4008
4066
|
sessionStorageRef;
|
|
4009
4067
|
fallbackStorage = /* @__PURE__ */ new Map();
|
|
@@ -4051,8 +4109,8 @@ class Mr {
|
|
|
4051
4109
|
this.storage.setItem(e, t);
|
|
4052
4110
|
return;
|
|
4053
4111
|
}
|
|
4054
|
-
} catch (
|
|
4055
|
-
if (
|
|
4112
|
+
} catch (s) {
|
|
4113
|
+
if (s instanceof DOMException && s.name === "QuotaExceededError" || s instanceof Error && s.name === "QuotaExceededError")
|
|
4056
4114
|
if (this.hasQuotaExceededError = !0, a("warn", "localStorage quota exceeded, attempting cleanup", {
|
|
4057
4115
|
data: { key: e, valueSize: t.length }
|
|
4058
4116
|
}), this.cleanupOldData())
|
|
@@ -4069,7 +4127,7 @@ class Mr {
|
|
|
4069
4127
|
}
|
|
4070
4128
|
else
|
|
4071
4129
|
a("error", "localStorage quota exceeded and no data to cleanup - data will not persist", {
|
|
4072
|
-
error:
|
|
4130
|
+
error: s,
|
|
4073
4131
|
data: { key: e, valueSize: t.length }
|
|
4074
4132
|
});
|
|
4075
4133
|
}
|
|
@@ -4107,8 +4165,8 @@ class Mr {
|
|
|
4107
4165
|
try {
|
|
4108
4166
|
const e = [];
|
|
4109
4167
|
for (let t = 0; t < this.storage.length; t++) {
|
|
4110
|
-
const
|
|
4111
|
-
|
|
4168
|
+
const s = this.storage.key(t);
|
|
4169
|
+
s?.startsWith("tracelog_") && e.push(s);
|
|
4112
4170
|
}
|
|
4113
4171
|
e.forEach((t) => {
|
|
4114
4172
|
this.storage.removeItem(t);
|
|
@@ -4183,7 +4241,7 @@ class Mr {
|
|
|
4183
4241
|
} catch {
|
|
4184
4242
|
}
|
|
4185
4243
|
}), !0;
|
|
4186
|
-
const
|
|
4244
|
+
const s = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"], n = e.filter((i) => !s.some((o) => i.startsWith(o)));
|
|
4187
4245
|
return n.length > 0 ? (n.slice(0, 5).forEach((o) => {
|
|
4188
4246
|
try {
|
|
4189
4247
|
this.storage.removeItem(o);
|
|
@@ -4222,8 +4280,8 @@ class Mr {
|
|
|
4222
4280
|
if (typeof window > "u")
|
|
4223
4281
|
return null;
|
|
4224
4282
|
try {
|
|
4225
|
-
const t = e === "localStorage" ? window.localStorage : window.sessionStorage,
|
|
4226
|
-
return t.setItem(
|
|
4283
|
+
const t = e === "localStorage" ? window.localStorage : window.sessionStorage, s = "__tracelog_test__";
|
|
4284
|
+
return t.setItem(s, "test"), t.removeItem(s), t;
|
|
4227
4285
|
} catch {
|
|
4228
4286
|
return null;
|
|
4229
4287
|
}
|
|
@@ -4264,9 +4322,9 @@ class Mr {
|
|
|
4264
4322
|
this.sessionStorageRef.setItem(e, t);
|
|
4265
4323
|
return;
|
|
4266
4324
|
}
|
|
4267
|
-
} catch (
|
|
4268
|
-
(
|
|
4269
|
-
error:
|
|
4325
|
+
} catch (s) {
|
|
4326
|
+
(s instanceof DOMException && s.name === "QuotaExceededError" || s instanceof Error && s.name === "QuotaExceededError") && a("error", "sessionStorage quota exceeded - data will not persist", {
|
|
4327
|
+
error: s,
|
|
4270
4328
|
data: { key: e, valueSize: t.length }
|
|
4271
4329
|
});
|
|
4272
4330
|
}
|
|
@@ -4286,7 +4344,7 @@ class Mr {
|
|
|
4286
4344
|
this.fallbackSessionStorage.delete(e);
|
|
4287
4345
|
}
|
|
4288
4346
|
}
|
|
4289
|
-
class
|
|
4347
|
+
class Ns extends _ {
|
|
4290
4348
|
eventManager;
|
|
4291
4349
|
reportedByNav = /* @__PURE__ */ new Map();
|
|
4292
4350
|
navigationHistory = [];
|
|
@@ -4297,7 +4355,7 @@ class Cr extends w {
|
|
|
4297
4355
|
navigationCounter = 0;
|
|
4298
4356
|
// Counter for handling simultaneous navigations edge case
|
|
4299
4357
|
constructor(e) {
|
|
4300
|
-
super(), this.eventManager = e, this.vitalThresholds =
|
|
4358
|
+
super(), this.eventManager = e, this.vitalThresholds = Ye(_e);
|
|
4301
4359
|
}
|
|
4302
4360
|
/**
|
|
4303
4361
|
* Starts tracking Web Vitals and performance metrics.
|
|
@@ -4315,7 +4373,7 @@ class Cr extends w {
|
|
|
4315
4373
|
*/
|
|
4316
4374
|
async startTracking() {
|
|
4317
4375
|
const e = this.get("config"), t = e?.webVitalsMode ?? _e;
|
|
4318
|
-
this.vitalThresholds =
|
|
4376
|
+
this.vitalThresholds = Ye(t), e?.webVitalsThresholds && (this.vitalThresholds = { ...this.vitalThresholds, ...e.webVitalsThresholds }), await this.initWebVitals(), this.observeLongTasks();
|
|
4319
4377
|
}
|
|
4320
4378
|
/**
|
|
4321
4379
|
* Stops tracking Web Vitals and cleans up resources.
|
|
@@ -4330,16 +4388,16 @@ class Cr extends w {
|
|
|
4330
4388
|
this.observers.forEach((e, t) => {
|
|
4331
4389
|
try {
|
|
4332
4390
|
e.disconnect();
|
|
4333
|
-
} catch (
|
|
4334
|
-
a("debug", "Failed to disconnect performance observer", { error:
|
|
4391
|
+
} catch (s) {
|
|
4392
|
+
a("debug", "Failed to disconnect performance observer", { error: s, data: { observerIndex: t } });
|
|
4335
4393
|
}
|
|
4336
4394
|
}), this.observers.length = 0, this.reportedByNav.clear(), this.navigationHistory.length = 0;
|
|
4337
4395
|
}
|
|
4338
4396
|
observeWebVitalsFallback() {
|
|
4339
4397
|
this.reportTTFB(), this.safeObserve(
|
|
4340
4398
|
"largest-contentful-paint",
|
|
4341
|
-
(
|
|
4342
|
-
const n =
|
|
4399
|
+
(s) => {
|
|
4400
|
+
const n = s.getEntries(), i = n[n.length - 1];
|
|
4343
4401
|
i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(2)) });
|
|
4344
4402
|
},
|
|
4345
4403
|
{ type: "largest-contentful-paint", buffered: !0 },
|
|
@@ -4348,10 +4406,10 @@ class Cr extends w {
|
|
|
4348
4406
|
let e = 0, t = this.getNavigationId();
|
|
4349
4407
|
this.safeObserve(
|
|
4350
4408
|
"layout-shift",
|
|
4351
|
-
(
|
|
4409
|
+
(s) => {
|
|
4352
4410
|
const n = this.getNavigationId();
|
|
4353
4411
|
n !== t && (e = 0, t = n);
|
|
4354
|
-
const i =
|
|
4412
|
+
const i = s.getEntries();
|
|
4355
4413
|
for (const o of i) {
|
|
4356
4414
|
if (o.hadRecentInput === !0)
|
|
4357
4415
|
continue;
|
|
@@ -4363,17 +4421,17 @@ class Cr extends w {
|
|
|
4363
4421
|
{ type: "layout-shift", buffered: !0 }
|
|
4364
4422
|
), this.safeObserve(
|
|
4365
4423
|
"paint",
|
|
4366
|
-
(
|
|
4367
|
-
for (const n of
|
|
4424
|
+
(s) => {
|
|
4425
|
+
for (const n of s.getEntries())
|
|
4368
4426
|
n.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(n.startTime.toFixed(2)) });
|
|
4369
4427
|
},
|
|
4370
4428
|
{ type: "paint", buffered: !0 },
|
|
4371
4429
|
!0
|
|
4372
4430
|
), this.safeObserve(
|
|
4373
4431
|
"event",
|
|
4374
|
-
(
|
|
4432
|
+
(s) => {
|
|
4375
4433
|
let n = 0;
|
|
4376
|
-
const i =
|
|
4434
|
+
const i = s.getEntries();
|
|
4377
4435
|
for (const o of i) {
|
|
4378
4436
|
const l = (o.processingEnd ?? 0) - (o.startTime ?? 0);
|
|
4379
4437
|
n = Math.max(n, l);
|
|
@@ -4385,11 +4443,11 @@ class Cr extends w {
|
|
|
4385
4443
|
}
|
|
4386
4444
|
async initWebVitals() {
|
|
4387
4445
|
try {
|
|
4388
|
-
const { onLCP: e, onCLS: t, onFCP:
|
|
4389
|
-
const
|
|
4390
|
-
this.sendVital({ type: l, value:
|
|
4446
|
+
const { onLCP: e, onCLS: t, onFCP: s, onTTFB: n, onINP: i } = await Promise.resolve().then(() => cr), o = (l) => (c) => {
|
|
4447
|
+
const d = Number(c.value.toFixed(2));
|
|
4448
|
+
this.sendVital({ type: l, value: d });
|
|
4391
4449
|
};
|
|
4392
|
-
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }),
|
|
4450
|
+
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
4451
|
} catch (e) {
|
|
4394
4452
|
a("debug", "Failed to load web-vitals library, using fallback", { error: e }), this.observeWebVitalsFallback();
|
|
4395
4453
|
}
|
|
@@ -4410,9 +4468,9 @@ class Cr extends w {
|
|
|
4410
4468
|
"longtask",
|
|
4411
4469
|
(e) => {
|
|
4412
4470
|
const t = e.getEntries();
|
|
4413
|
-
for (const
|
|
4414
|
-
const n = Number(
|
|
4415
|
-
i - this.lastLongTaskSentAt >=
|
|
4471
|
+
for (const s of t) {
|
|
4472
|
+
const n = Number(s.duration.toFixed(2)), i = Date.now();
|
|
4473
|
+
i - this.lastLongTaskSentAt >= Yt && (this.shouldSendVital("LONG_TASK", n) && this.trackWebVital("LONG_TASK", n), this.lastLongTaskSentAt = i);
|
|
4416
4474
|
}
|
|
4417
4475
|
},
|
|
4418
4476
|
{ type: "longtask", buffered: !0 }
|
|
@@ -4423,12 +4481,12 @@ class Cr extends w {
|
|
|
4423
4481
|
return;
|
|
4424
4482
|
const t = this.getNavigationId();
|
|
4425
4483
|
if (t) {
|
|
4426
|
-
const
|
|
4427
|
-
if (
|
|
4484
|
+
const s = this.reportedByNav.get(t);
|
|
4485
|
+
if (s?.has(e.type))
|
|
4428
4486
|
return;
|
|
4429
|
-
if (
|
|
4430
|
-
|
|
4431
|
-
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length >
|
|
4487
|
+
if (s)
|
|
4488
|
+
s.add(e.type);
|
|
4489
|
+
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length > qt) {
|
|
4432
4490
|
const i = this.navigationHistory.shift();
|
|
4433
4491
|
i && this.reportedByNav.delete(i);
|
|
4434
4492
|
}
|
|
@@ -4441,7 +4499,7 @@ class Cr extends w {
|
|
|
4441
4499
|
return;
|
|
4442
4500
|
}
|
|
4443
4501
|
this.eventManager.track({
|
|
4444
|
-
type:
|
|
4502
|
+
type: u.WEB_VITALS,
|
|
4445
4503
|
web_vitals: {
|
|
4446
4504
|
type: e,
|
|
4447
4505
|
value: t
|
|
@@ -4474,8 +4532,8 @@ class Cr extends w {
|
|
|
4474
4532
|
const e = performance.getEntriesByType("navigation")[0];
|
|
4475
4533
|
if (!e)
|
|
4476
4534
|
return null;
|
|
4477
|
-
const t = e.startTime || performance.now(),
|
|
4478
|
-
return
|
|
4535
|
+
const t = e.startTime || performance.now(), s = ++this.navigationCounter, n = `${t.toFixed(2)}_${window.location.pathname}`;
|
|
4536
|
+
return s > 1 ? `${n}_${s}` : n;
|
|
4479
4537
|
} catch (e) {
|
|
4480
4538
|
return a("debug", "Failed to get navigation ID", { error: e }), null;
|
|
4481
4539
|
}
|
|
@@ -4485,7 +4543,7 @@ class Cr extends w {
|
|
|
4485
4543
|
const t = PerformanceObserver.supportedEntryTypes;
|
|
4486
4544
|
return !t || t.includes(e);
|
|
4487
4545
|
}
|
|
4488
|
-
safeObserve(e, t,
|
|
4546
|
+
safeObserve(e, t, s, n = !1) {
|
|
4489
4547
|
try {
|
|
4490
4548
|
if (!this.isObserverSupported(e))
|
|
4491
4549
|
return !1;
|
|
@@ -4504,7 +4562,7 @@ class Cr extends w {
|
|
|
4504
4562
|
} catch {
|
|
4505
4563
|
}
|
|
4506
4564
|
});
|
|
4507
|
-
return i.observe(
|
|
4565
|
+
return i.observe(s ?? { type: e, buffered: !0 }), n || this.observers.push(i), !0;
|
|
4508
4566
|
} catch (i) {
|
|
4509
4567
|
return a("debug", "Failed to create performance observer", {
|
|
4510
4568
|
error: i,
|
|
@@ -4515,11 +4573,11 @@ class Cr extends w {
|
|
|
4515
4573
|
shouldSendVital(e, t) {
|
|
4516
4574
|
if (typeof t != "number" || !Number.isFinite(t))
|
|
4517
4575
|
return a("debug", "Invalid web vital value", { data: { type: e, value: t } }), !1;
|
|
4518
|
-
const
|
|
4519
|
-
return !(typeof
|
|
4576
|
+
const s = this.vitalThresholds[e];
|
|
4577
|
+
return !(typeof s == "number" && t <= s);
|
|
4520
4578
|
}
|
|
4521
4579
|
}
|
|
4522
|
-
class
|
|
4580
|
+
class ae extends _ {
|
|
4523
4581
|
eventManager;
|
|
4524
4582
|
recentErrors = /* @__PURE__ */ new Map();
|
|
4525
4583
|
errorBurstCounter = 0;
|
|
@@ -4555,47 +4613,47 @@ class oe extends w {
|
|
|
4555
4613
|
const e = Date.now();
|
|
4556
4614
|
if (e < this.burstBackoffUntil)
|
|
4557
4615
|
return !1;
|
|
4558
|
-
if (e - this.burstWindowStart >
|
|
4559
|
-
return this.burstBackoffUntil = e +
|
|
4616
|
+
if (e - this.burstWindowStart > jt && (this.errorBurstCounter = 0, this.burstWindowStart = e), this.errorBurstCounter++, this.errorBurstCounter > zt)
|
|
4617
|
+
return this.burstBackoffUntil = e + Qe, a("debug", "Error burst detected - entering cooldown", {
|
|
4560
4618
|
data: {
|
|
4561
4619
|
errorsInWindow: this.errorBurstCounter,
|
|
4562
|
-
cooldownMs:
|
|
4620
|
+
cooldownMs: Qe
|
|
4563
4621
|
}
|
|
4564
4622
|
}), !1;
|
|
4565
|
-
const
|
|
4566
|
-
return Math.random() <
|
|
4623
|
+
const s = this.get("config").errorSampling ?? ct;
|
|
4624
|
+
return Math.random() < s;
|
|
4567
4625
|
}
|
|
4568
4626
|
handleError = (e) => {
|
|
4569
4627
|
if (!this.shouldSample())
|
|
4570
4628
|
return;
|
|
4571
4629
|
const t = this.sanitize(e.message || "Unknown error");
|
|
4572
|
-
if (this.shouldSuppressError(
|
|
4630
|
+
if (this.shouldSuppressError(B.JS_ERROR, t))
|
|
4573
4631
|
return;
|
|
4574
|
-
const
|
|
4632
|
+
const s = typeof e.error?.stack == "string" ? this.truncateStack(e.error.stack) : void 0;
|
|
4575
4633
|
this.eventManager.track({
|
|
4576
|
-
type:
|
|
4634
|
+
type: u.ERROR,
|
|
4577
4635
|
error_data: {
|
|
4578
|
-
type:
|
|
4636
|
+
type: B.JS_ERROR,
|
|
4579
4637
|
message: t,
|
|
4580
4638
|
...e.filename !== "" && { filename: e.filename },
|
|
4581
4639
|
...e.lineno !== 0 && { line: e.lineno },
|
|
4582
4640
|
...e.colno !== 0 && { column: e.colno },
|
|
4583
|
-
...
|
|
4641
|
+
...s !== void 0 && { stack: s }
|
|
4584
4642
|
}
|
|
4585
4643
|
});
|
|
4586
4644
|
};
|
|
4587
4645
|
handleRejection = (e) => {
|
|
4588
4646
|
if (!this.shouldSample())
|
|
4589
4647
|
return;
|
|
4590
|
-
const t = this.extractRejectionMessage(e.reason),
|
|
4591
|
-
if (this.shouldSuppressError(
|
|
4648
|
+
const t = this.extractRejectionMessage(e.reason), s = this.sanitize(t);
|
|
4649
|
+
if (this.shouldSuppressError(B.PROMISE_REJECTION, s))
|
|
4592
4650
|
return;
|
|
4593
4651
|
const n = e.reason instanceof Error && typeof e.reason.stack == "string" ? this.truncateStack(e.reason.stack) : void 0;
|
|
4594
4652
|
this.eventManager.track({
|
|
4595
|
-
type:
|
|
4653
|
+
type: u.ERROR,
|
|
4596
4654
|
error_data: {
|
|
4597
|
-
type:
|
|
4598
|
-
message:
|
|
4655
|
+
type: B.PROMISE_REJECTION,
|
|
4656
|
+
message: s,
|
|
4599
4657
|
...n !== void 0 && { stack: n }
|
|
4600
4658
|
}
|
|
4601
4659
|
});
|
|
@@ -4614,50 +4672,51 @@ class oe extends w {
|
|
|
4614
4672
|
}
|
|
4615
4673
|
}
|
|
4616
4674
|
sanitize(e) {
|
|
4617
|
-
const t = e.length >
|
|
4675
|
+
const t = e.length > Ge ? e.slice(0, Ge) + "..." : e;
|
|
4618
4676
|
return this.sanitizePii(t);
|
|
4619
4677
|
}
|
|
4620
4678
|
sanitizePii(e) {
|
|
4621
4679
|
let t = e;
|
|
4622
|
-
for (const
|
|
4623
|
-
const n = new RegExp(
|
|
4680
|
+
for (const s of lt) {
|
|
4681
|
+
const n = new RegExp(s.source, s.flags);
|
|
4624
4682
|
t = t.replace(n, "[REDACTED]");
|
|
4625
4683
|
}
|
|
4626
4684
|
return t;
|
|
4627
4685
|
}
|
|
4628
4686
|
shouldSuppressError(e, t) {
|
|
4629
|
-
const
|
|
4630
|
-
return i !== void 0 &&
|
|
4687
|
+
const s = Date.now(), n = `${e}:${t}`, i = this.recentErrors.get(n);
|
|
4688
|
+
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
4689
|
}
|
|
4632
4690
|
static TRUNCATION_SUFFIX = `
|
|
4633
4691
|
...truncated`;
|
|
4634
4692
|
truncateStack(e) {
|
|
4635
|
-
if (e.length <=
|
|
4636
|
-
const t =
|
|
4637
|
-
return this.sanitizePii(
|
|
4693
|
+
if (e.length <= je) return this.sanitizePii(e);
|
|
4694
|
+
const t = je - ae.TRUNCATION_SUFFIX.length, s = e.slice(0, t) + ae.TRUNCATION_SUFFIX;
|
|
4695
|
+
return this.sanitizePii(s);
|
|
4638
4696
|
}
|
|
4639
4697
|
pruneOldErrors() {
|
|
4640
4698
|
const e = Date.now();
|
|
4641
4699
|
for (const [n, i] of this.recentErrors.entries())
|
|
4642
|
-
e - i >
|
|
4643
|
-
if (this.recentErrors.size <=
|
|
4700
|
+
e - i > ze && this.recentErrors.delete(n);
|
|
4701
|
+
if (this.recentErrors.size <= ee)
|
|
4644
4702
|
return;
|
|
4645
|
-
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]),
|
|
4646
|
-
for (let n = 0; n <
|
|
4703
|
+
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]), s = this.recentErrors.size - ee;
|
|
4704
|
+
for (let n = 0; n < s; n += 1) {
|
|
4647
4705
|
const i = t[n];
|
|
4648
4706
|
i && this.recentErrors.delete(i[0]);
|
|
4649
4707
|
}
|
|
4650
4708
|
}
|
|
4651
4709
|
}
|
|
4652
|
-
class
|
|
4710
|
+
class Os extends _ {
|
|
4653
4711
|
isInitialized = !1;
|
|
4654
4712
|
suppressNextScrollTimer = null;
|
|
4655
4713
|
pageUnloadHandler = null;
|
|
4656
|
-
emitter = new
|
|
4714
|
+
emitter = new gs();
|
|
4657
4715
|
transformers = {};
|
|
4658
4716
|
customHeadersProvider;
|
|
4659
4717
|
managers = {};
|
|
4660
4718
|
handlers = {};
|
|
4719
|
+
integrationInstances = {};
|
|
4661
4720
|
get initialized() {
|
|
4662
4721
|
return this.isInitialized;
|
|
4663
4722
|
}
|
|
@@ -4671,24 +4730,24 @@ class Rr extends w {
|
|
|
4671
4730
|
async init(e = {}) {
|
|
4672
4731
|
if (this.isInitialized)
|
|
4673
4732
|
return { sessionId: this.get("sessionId") ?? "" };
|
|
4674
|
-
this.managers.storage = new
|
|
4733
|
+
this.managers.storage = new Rs();
|
|
4675
4734
|
try {
|
|
4676
4735
|
this.setupState(e);
|
|
4677
|
-
const t = e.integrations?.custom?.headers ?? {},
|
|
4678
|
-
return this.managers.event = new
|
|
4736
|
+
const t = e.integrations?.custom?.headers ?? {}, s = e.integrations?.custom?.fetchCredentials ?? "include";
|
|
4737
|
+
return this.managers.event = new Ts(
|
|
4679
4738
|
this.managers.storage,
|
|
4680
4739
|
this.emitter,
|
|
4681
4740
|
this.transformers,
|
|
4682
4741
|
t,
|
|
4683
4742
|
this.customHeadersProvider,
|
|
4684
|
-
|
|
4743
|
+
s
|
|
4685
4744
|
), this.loadPersistedIdentity(), this.initializeHandlers(), this.setupPageLifecycleListeners(), await this.managers.event.recoverPersistedEvents().catch((n) => {
|
|
4686
4745
|
a("warn", "Failed to recover persisted events", { error: n });
|
|
4687
4746
|
}), this.isInitialized = !0, { sessionId: this.get("sessionId") ?? "" };
|
|
4688
4747
|
} catch (t) {
|
|
4689
4748
|
this.destroy(!0);
|
|
4690
|
-
const
|
|
4691
|
-
throw new Error(`[TraceLog] TraceLog initialization failed: ${
|
|
4749
|
+
const s = t instanceof Error ? t.message : String(t);
|
|
4750
|
+
throw new Error(`[TraceLog] TraceLog initialization failed: ${s}`);
|
|
4692
4751
|
}
|
|
4693
4752
|
}
|
|
4694
4753
|
/**
|
|
@@ -4703,17 +4762,17 @@ class Rr extends w {
|
|
|
4703
4762
|
a("warn", "Cannot send custom event: TraceLog not initialized", { data: { name: e } });
|
|
4704
4763
|
return;
|
|
4705
4764
|
}
|
|
4706
|
-
let
|
|
4707
|
-
t && typeof t == "object" && !Array.isArray(t) && Object.getPrototypeOf(t) !== Object.prototype && (
|
|
4708
|
-
const { valid: n, error: i, sanitizedMetadata: o } =
|
|
4765
|
+
let s = t;
|
|
4766
|
+
t && typeof t == "object" && !Array.isArray(t) && Object.getPrototypeOf(t) !== Object.prototype && (s = Object.assign({}, t));
|
|
4767
|
+
const { valid: n, error: i, sanitizedMetadata: o } = ms(e, s);
|
|
4709
4768
|
if (!n) {
|
|
4710
|
-
if (this.get("mode") ===
|
|
4769
|
+
if (this.get("mode") === ie.QA)
|
|
4711
4770
|
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${i}`);
|
|
4712
4771
|
a("warn", `Custom event "${e}" dropped: ${i}`);
|
|
4713
4772
|
return;
|
|
4714
4773
|
}
|
|
4715
4774
|
this.managers.event.track({
|
|
4716
|
-
type:
|
|
4775
|
+
type: u.CUSTOM,
|
|
4717
4776
|
custom_event: {
|
|
4718
4777
|
name: e,
|
|
4719
4778
|
...o && { metadata: o }
|
|
@@ -4768,21 +4827,21 @@ class Rr extends w {
|
|
|
4768
4827
|
!this.isInitialized && !e || (Object.values(this.handlers).filter(Boolean).forEach((t) => {
|
|
4769
4828
|
try {
|
|
4770
4829
|
t.stopTracking();
|
|
4771
|
-
} catch (
|
|
4772
|
-
a("warn", "Failed to stop tracking", { error:
|
|
4830
|
+
} catch (s) {
|
|
4831
|
+
a("warn", "Failed to stop tracking", { error: s });
|
|
4773
4832
|
}
|
|
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 = {});
|
|
4833
|
+
}), 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
4834
|
}
|
|
4776
4835
|
setupState(e = {}) {
|
|
4777
4836
|
this.set("config", e);
|
|
4778
|
-
const t =
|
|
4837
|
+
const t = Is.getId(this.managers.storage);
|
|
4779
4838
|
this.set("userId", t);
|
|
4780
|
-
const
|
|
4781
|
-
this.set("collectApiUrls",
|
|
4782
|
-
const n =
|
|
4839
|
+
const s = os(e);
|
|
4840
|
+
this.set("collectApiUrls", s);
|
|
4841
|
+
const n = Xt();
|
|
4783
4842
|
this.set("device", n);
|
|
4784
|
-
const i =
|
|
4785
|
-
this.set("pageUrl", i),
|
|
4843
|
+
const i = we(window.location.href, e.sensitiveQueryParams);
|
|
4844
|
+
this.set("pageUrl", i), ts() && this.set("mode", ie.QA);
|
|
4786
4845
|
}
|
|
4787
4846
|
/**
|
|
4788
4847
|
* Returns the current configuration object.
|
|
@@ -4833,7 +4892,7 @@ class Rr extends w {
|
|
|
4833
4892
|
valid: !1,
|
|
4834
4893
|
error: "Global metadata must be a plain object"
|
|
4835
4894
|
};
|
|
4836
|
-
const t =
|
|
4895
|
+
const t = mt("Global", e, "globalMetadata");
|
|
4837
4896
|
return t.valid ? { valid: !0 } : {
|
|
4838
4897
|
valid: !1,
|
|
4839
4898
|
error: t.error
|
|
@@ -4867,11 +4926,11 @@ class Rr extends w {
|
|
|
4867
4926
|
const t = this.validateGlobalMetadata(e);
|
|
4868
4927
|
if (!t.valid)
|
|
4869
4928
|
throw new Error(`[TraceLog] Invalid global metadata: ${t.error}`);
|
|
4870
|
-
const
|
|
4871
|
-
...
|
|
4929
|
+
const s = this.get("config"), i = {
|
|
4930
|
+
...s.globalMetadata ?? {},
|
|
4872
4931
|
...e
|
|
4873
4932
|
}, o = {
|
|
4874
|
-
...
|
|
4933
|
+
...s,
|
|
4875
4934
|
globalMetadata: i
|
|
4876
4935
|
};
|
|
4877
4936
|
this.set("config", o), a("debug", "Global metadata updated (merged)", { data: { keys: Object.keys(e) } });
|
|
@@ -4900,12 +4959,12 @@ class Rr extends w {
|
|
|
4900
4959
|
a("warn", "identify() userId exceeds 256 characters", { data: { length: e.trim().length } });
|
|
4901
4960
|
return;
|
|
4902
4961
|
}
|
|
4903
|
-
const
|
|
4904
|
-
userId:
|
|
4962
|
+
const s = e.trim(), n = ft(t), i = {
|
|
4963
|
+
userId: s,
|
|
4905
4964
|
...n ? { traits: n } : {}
|
|
4906
4965
|
};
|
|
4907
4966
|
this.set("identity", i), this.persistIdentity(i), a("debug", "Visitor identified", {
|
|
4908
|
-
data: { userIdLength:
|
|
4967
|
+
data: { userIdLength: s.length, traitKeys: n ? Object.keys(n) : [] }
|
|
4909
4968
|
});
|
|
4910
4969
|
}
|
|
4911
4970
|
/**
|
|
@@ -4920,7 +4979,7 @@ class Rr extends w {
|
|
|
4920
4979
|
async resetIdentity() {
|
|
4921
4980
|
await this.managers.event?.flushImmediately(), this.set("identity", void 0), this.clearPersistedIdentity();
|
|
4922
4981
|
const e = ut();
|
|
4923
|
-
this.managers.storage.setItem(
|
|
4982
|
+
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
4983
|
}
|
|
4925
4984
|
/**
|
|
4926
4985
|
* Returns the project ID used for identity storage scoping.
|
|
@@ -4934,8 +4993,8 @@ class Rr extends w {
|
|
|
4934
4993
|
*/
|
|
4935
4994
|
persistIdentity(e) {
|
|
4936
4995
|
try {
|
|
4937
|
-
const t = this.getProjectId(),
|
|
4938
|
-
this.managers.storage.setItem(
|
|
4996
|
+
const t = this.getProjectId(), s = fe(t);
|
|
4997
|
+
this.managers.storage.setItem(s, JSON.stringify(e));
|
|
4939
4998
|
} catch {
|
|
4940
4999
|
a("debug", "Failed to persist identity to localStorage");
|
|
4941
5000
|
}
|
|
@@ -4945,28 +5004,28 @@ class Rr extends w {
|
|
|
4945
5004
|
* Also migrates pending identity (set before init) to the project-scoped key.
|
|
4946
5005
|
*/
|
|
4947
5006
|
loadPersistedIdentity() {
|
|
4948
|
-
const e = this.managers.storage, t = this.getProjectId(),
|
|
5007
|
+
const e = this.managers.storage, t = this.getProjectId(), s = fe(t);
|
|
4949
5008
|
try {
|
|
4950
|
-
const n = e.getItem(
|
|
5009
|
+
const n = e.getItem(U);
|
|
4951
5010
|
if (n) {
|
|
4952
5011
|
const i = JSON.parse(n);
|
|
4953
|
-
if (e.removeItem(
|
|
5012
|
+
if (e.removeItem(U), !this.isValidIdentityData(i)) {
|
|
4954
5013
|
a("debug", "Invalid pending identity in localStorage, discarded");
|
|
4955
5014
|
return;
|
|
4956
5015
|
}
|
|
4957
5016
|
const o = { ...i, userId: i.userId.trim() };
|
|
4958
|
-
e.setItem(
|
|
5017
|
+
e.setItem(s, JSON.stringify(o)), this.set("identity", o), a("debug", "Migrated pending identity to project-scoped key");
|
|
4959
5018
|
return;
|
|
4960
5019
|
}
|
|
4961
5020
|
} catch {
|
|
4962
|
-
e.removeItem(
|
|
5021
|
+
e.removeItem(U);
|
|
4963
5022
|
}
|
|
4964
5023
|
try {
|
|
4965
|
-
const n = e.getItem(
|
|
5024
|
+
const n = e.getItem(s);
|
|
4966
5025
|
if (n) {
|
|
4967
5026
|
const i = JSON.parse(n);
|
|
4968
5027
|
if (!this.isValidIdentityData(i)) {
|
|
4969
|
-
e.removeItem(
|
|
5028
|
+
e.removeItem(s), a("debug", "Invalid persisted identity in localStorage, discarded");
|
|
4970
5029
|
return;
|
|
4971
5030
|
}
|
|
4972
5031
|
const o = { ...i, userId: i.userId.trim() };
|
|
@@ -4982,11 +5041,11 @@ class Rr extends w {
|
|
|
4982
5041
|
*/
|
|
4983
5042
|
isValidIdentityData(e) {
|
|
4984
5043
|
if (!e || typeof e != "object") return !1;
|
|
4985
|
-
const { userId: t, traits:
|
|
5044
|
+
const { userId: t, traits: s } = e;
|
|
4986
5045
|
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(
|
|
5046
|
+
if (s !== void 0) {
|
|
5047
|
+
if (typeof s != "object" || s === null || Array.isArray(s)) return !1;
|
|
5048
|
+
for (const n of Object.values(s))
|
|
4990
5049
|
if (typeof n != "string") return !1;
|
|
4991
5050
|
}
|
|
4992
5051
|
return !0;
|
|
@@ -4997,7 +5056,7 @@ class Rr extends w {
|
|
|
4997
5056
|
clearPersistedIdentity() {
|
|
4998
5057
|
try {
|
|
4999
5058
|
const e = this.managers.storage, t = this.getProjectId();
|
|
5000
|
-
e.removeItem(
|
|
5059
|
+
e.removeItem(fe(t)), e.removeItem(U);
|
|
5001
5060
|
} catch {
|
|
5002
5061
|
a("debug", "Failed to clear persisted identity");
|
|
5003
5062
|
}
|
|
@@ -5009,7 +5068,7 @@ class Rr extends w {
|
|
|
5009
5068
|
}
|
|
5010
5069
|
initializeHandlers() {
|
|
5011
5070
|
const e = this.get("config");
|
|
5012
|
-
this.handlers.session = new
|
|
5071
|
+
this.handlers.session = new ys(
|
|
5013
5072
|
this.managers.storage,
|
|
5014
5073
|
this.managers.event
|
|
5015
5074
|
), this.handlers.session.startTracking();
|
|
@@ -5018,105 +5077,110 @@ class Rr extends w {
|
|
|
5018
5077
|
this.set("suppressNextScroll", !1);
|
|
5019
5078
|
}, 500);
|
|
5020
5079
|
};
|
|
5021
|
-
this.handlers.pageView = new
|
|
5022
|
-
a("warn", "Failed to start performance tracking", { error:
|
|
5023
|
-
}), this.handlers.error = new
|
|
5080
|
+
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) => {
|
|
5081
|
+
a("warn", "Failed to start performance tracking", { error: s });
|
|
5082
|
+
}), 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) {
|
|
5083
|
+
const s = new Cs();
|
|
5084
|
+
s.activate(), this.integrationInstances.shopifyCartLinker = s, this.emitter.on(se.EVENT, (n) => {
|
|
5085
|
+
n.type === u.SESSION_START && s.onSessionChange();
|
|
5086
|
+
});
|
|
5087
|
+
}
|
|
5024
5088
|
}
|
|
5025
5089
|
}
|
|
5026
5090
|
const k = [], M = [];
|
|
5027
5091
|
let D = null, h = null, R = !1, p = !1, P = null;
|
|
5028
|
-
const
|
|
5092
|
+
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
5093
|
try {
|
|
5030
|
-
const e =
|
|
5094
|
+
const e = us(r ?? {}), t = new Os();
|
|
5031
5095
|
try {
|
|
5032
5096
|
k.forEach(({ event: o, callback: l }) => {
|
|
5033
5097
|
t.on(o, l);
|
|
5034
5098
|
}), k.length = 0, M.forEach(({ hook: o, fn: l }) => {
|
|
5035
5099
|
o === "beforeSend" ? t.setTransformer("beforeSend", l) : t.setTransformer("beforeBatch", l);
|
|
5036
5100
|
}), M.length = 0, D && (t.setCustomHeaders(D), D = null);
|
|
5037
|
-
const
|
|
5101
|
+
const s = t.init(e), n = new Promise((o, l) => {
|
|
5038
5102
|
setTimeout(() => {
|
|
5039
5103
|
l(new Error("[TraceLog] Initialization timeout after 10000ms"));
|
|
5040
5104
|
}, 1e4);
|
|
5041
|
-
}), i = await Promise.race([
|
|
5105
|
+
}), i = await Promise.race([s, n]);
|
|
5042
5106
|
return h = t, i;
|
|
5043
|
-
} catch (
|
|
5107
|
+
} catch (s) {
|
|
5044
5108
|
try {
|
|
5045
5109
|
t.destroy(!0);
|
|
5046
5110
|
} catch (n) {
|
|
5047
5111
|
a("error", "Failed to cleanup partially initialized app", { error: n });
|
|
5048
5112
|
}
|
|
5049
|
-
throw
|
|
5113
|
+
throw s;
|
|
5050
5114
|
}
|
|
5051
5115
|
} catch (e) {
|
|
5052
5116
|
throw h = null, e;
|
|
5053
5117
|
} finally {
|
|
5054
5118
|
R = !1, P = null;
|
|
5055
5119
|
}
|
|
5056
|
-
})()), P)),
|
|
5120
|
+
})()), P)), Ds = (r, e) => {
|
|
5057
5121
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5058
5122
|
if (!h)
|
|
5059
5123
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5060
5124
|
if (p)
|
|
5061
5125
|
throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
|
|
5062
|
-
h.sendCustomEvent(
|
|
5126
|
+
h.sendCustomEvent(r, e);
|
|
5063
5127
|
}
|
|
5064
|
-
},
|
|
5128
|
+
}, ks = (r, e) => {
|
|
5065
5129
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5066
5130
|
if (!h || R) {
|
|
5067
|
-
k.push({ event:
|
|
5131
|
+
k.push({ event: r, callback: e });
|
|
5068
5132
|
return;
|
|
5069
5133
|
}
|
|
5070
|
-
h.on(
|
|
5134
|
+
h.on(r, e);
|
|
5071
5135
|
}
|
|
5072
|
-
},
|
|
5136
|
+
}, Vs = (r, e) => {
|
|
5073
5137
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5074
5138
|
if (!h) {
|
|
5075
|
-
const t = k.findIndex((
|
|
5139
|
+
const t = k.findIndex((s) => s.event === r && s.callback === e);
|
|
5076
5140
|
t !== -1 && k.splice(t, 1);
|
|
5077
5141
|
return;
|
|
5078
5142
|
}
|
|
5079
|
-
h.off(
|
|
5143
|
+
h.off(r, e);
|
|
5080
5144
|
}
|
|
5081
5145
|
};
|
|
5082
|
-
function
|
|
5146
|
+
function Us(r, e) {
|
|
5083
5147
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5084
5148
|
if (typeof e != "function")
|
|
5085
5149
|
throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof e}`);
|
|
5086
5150
|
if (!h || R) {
|
|
5087
|
-
const t = M.findIndex((
|
|
5088
|
-
t !== -1 && M.splice(t, 1), M.push({ hook:
|
|
5151
|
+
const t = M.findIndex((s) => s.hook === r);
|
|
5152
|
+
t !== -1 && M.splice(t, 1), M.push({ hook: r, fn: e });
|
|
5089
5153
|
return;
|
|
5090
5154
|
}
|
|
5091
5155
|
if (p)
|
|
5092
5156
|
throw new Error("[TraceLog] Cannot set transformers while TraceLog is being destroyed");
|
|
5093
|
-
|
|
5157
|
+
r === "beforeSend" ? h.setTransformer("beforeSend", e) : h.setTransformer("beforeBatch", e);
|
|
5094
5158
|
}
|
|
5095
5159
|
}
|
|
5096
|
-
const
|
|
5160
|
+
const Hs = (r) => {
|
|
5097
5161
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5098
5162
|
if (!h) {
|
|
5099
|
-
const e = M.findIndex((t) => t.hook ===
|
|
5163
|
+
const e = M.findIndex((t) => t.hook === r);
|
|
5100
5164
|
e !== -1 && M.splice(e, 1);
|
|
5101
5165
|
return;
|
|
5102
5166
|
}
|
|
5103
5167
|
if (p)
|
|
5104
5168
|
throw new Error("[TraceLog] Cannot remove transformers while TraceLog is being destroyed");
|
|
5105
|
-
h.removeTransformer(
|
|
5169
|
+
h.removeTransformer(r);
|
|
5106
5170
|
}
|
|
5107
|
-
},
|
|
5171
|
+
}, Fs = (r) => {
|
|
5108
5172
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5109
|
-
if (typeof
|
|
5110
|
-
throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof
|
|
5173
|
+
if (typeof r != "function")
|
|
5174
|
+
throw new Error(`[TraceLog] Custom headers provider must be a function, received: ${typeof r}`);
|
|
5111
5175
|
if (!h || R) {
|
|
5112
|
-
D =
|
|
5176
|
+
D = r;
|
|
5113
5177
|
return;
|
|
5114
5178
|
}
|
|
5115
5179
|
if (p)
|
|
5116
5180
|
throw new Error("[TraceLog] Cannot set custom headers while TraceLog is being destroyed");
|
|
5117
|
-
h.setCustomHeaders(
|
|
5181
|
+
h.setCustomHeaders(r);
|
|
5118
5182
|
}
|
|
5119
|
-
},
|
|
5183
|
+
}, xs = () => {
|
|
5120
5184
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5121
5185
|
if (!h) {
|
|
5122
5186
|
D = null;
|
|
@@ -5126,7 +5190,7 @@ const Vr = (s) => {
|
|
|
5126
5190
|
throw new Error("[TraceLog] Cannot remove custom headers while TraceLog is being destroyed");
|
|
5127
5191
|
h.removeCustomHeaders();
|
|
5128
5192
|
}
|
|
5129
|
-
},
|
|
5193
|
+
}, $s = () => typeof window > "u" || typeof document > "u" ? !1 : h !== null, Bs = () => typeof window > "u" || typeof document > "u" || !h ? null : h.getSessionId(), Ws = () => {
|
|
5130
5194
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5131
5195
|
if (p)
|
|
5132
5196
|
throw new Error("[TraceLog] Destroy operation already in progress");
|
|
@@ -5137,35 +5201,35 @@ const Vr = (s) => {
|
|
|
5137
5201
|
p = !0;
|
|
5138
5202
|
try {
|
|
5139
5203
|
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:
|
|
5204
|
+
} catch (r) {
|
|
5205
|
+
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
5206
|
}
|
|
5143
5207
|
}
|
|
5144
|
-
},
|
|
5145
|
-
typeof window > "u" || typeof document > "u" ||
|
|
5146
|
-
},
|
|
5208
|
+
}, Xs = (r) => {
|
|
5209
|
+
typeof window > "u" || typeof document > "u" || ss(r);
|
|
5210
|
+
}, Gs = (r) => {
|
|
5147
5211
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5148
5212
|
if (!h)
|
|
5149
5213
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5150
5214
|
if (p)
|
|
5151
5215
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
5152
|
-
h.updateGlobalMetadata(
|
|
5216
|
+
h.updateGlobalMetadata(r);
|
|
5153
5217
|
}
|
|
5154
|
-
},
|
|
5218
|
+
}, js = (r) => {
|
|
5155
5219
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5156
5220
|
if (!h)
|
|
5157
5221
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
5158
5222
|
if (p)
|
|
5159
5223
|
throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");
|
|
5160
|
-
h.mergeGlobalMetadata(
|
|
5224
|
+
h.mergeGlobalMetadata(r);
|
|
5161
5225
|
}
|
|
5162
|
-
},
|
|
5226
|
+
}, zs = (r, e) => {
|
|
5163
5227
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5164
|
-
if (!
|
|
5228
|
+
if (!r || typeof r != "string" || r.trim().length === 0) {
|
|
5165
5229
|
a("warn", "identify() called with invalid userId");
|
|
5166
5230
|
return;
|
|
5167
5231
|
}
|
|
5168
|
-
if (
|
|
5232
|
+
if (r.trim().length > 256) {
|
|
5169
5233
|
a("warn", "identify() userId exceeds 256 characters");
|
|
5170
5234
|
return;
|
|
5171
5235
|
}
|
|
@@ -5174,24 +5238,24 @@ const Vr = (s) => {
|
|
|
5174
5238
|
return;
|
|
5175
5239
|
}
|
|
5176
5240
|
if (h) {
|
|
5177
|
-
h.identify(
|
|
5241
|
+
h.identify(r, e);
|
|
5178
5242
|
return;
|
|
5179
5243
|
}
|
|
5180
5244
|
try {
|
|
5181
|
-
const t =
|
|
5182
|
-
userId:
|
|
5245
|
+
const t = ft(e), s = {
|
|
5246
|
+
userId: r.trim(),
|
|
5183
5247
|
...t ? { traits: t } : {}
|
|
5184
5248
|
};
|
|
5185
|
-
localStorage.setItem(
|
|
5249
|
+
localStorage.setItem(U, JSON.stringify(s)), a("debug", "Identity persisted pre-init (will be applied on init)");
|
|
5186
5250
|
} catch {
|
|
5187
5251
|
a("debug", "Failed to persist pre-init identity");
|
|
5188
5252
|
}
|
|
5189
5253
|
}
|
|
5190
|
-
},
|
|
5254
|
+
}, Qs = async () => {
|
|
5191
5255
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
5192
5256
|
if (!h) {
|
|
5193
5257
|
try {
|
|
5194
|
-
localStorage.removeItem(
|
|
5258
|
+
localStorage.removeItem(U);
|
|
5195
5259
|
} catch {
|
|
5196
5260
|
}
|
|
5197
5261
|
return;
|
|
@@ -5200,299 +5264,299 @@ const Vr = (s) => {
|
|
|
5200
5264
|
throw new Error("[TraceLog] Cannot reset identity while TraceLog is being destroyed");
|
|
5201
5265
|
await h.resetIdentity();
|
|
5202
5266
|
}
|
|
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:
|
|
5267
|
+
}, yr = {
|
|
5268
|
+
init: Ps,
|
|
5269
|
+
event: Ds,
|
|
5270
|
+
on: ks,
|
|
5271
|
+
off: Vs,
|
|
5272
|
+
setTransformer: Us,
|
|
5273
|
+
removeTransformer: Hs,
|
|
5274
|
+
setCustomHeaders: Fs,
|
|
5275
|
+
removeCustomHeaders: xs,
|
|
5276
|
+
isInitialized: $s,
|
|
5277
|
+
getSessionId: Bs,
|
|
5278
|
+
destroy: Ws,
|
|
5279
|
+
setQaMode: Xs,
|
|
5280
|
+
updateGlobalMetadata: Gs,
|
|
5281
|
+
mergeGlobalMetadata: js,
|
|
5282
|
+
identify: zs,
|
|
5283
|
+
resetIdentity: Qs
|
|
5220
5284
|
};
|
|
5221
|
-
var
|
|
5285
|
+
var Le, C, G, St, le, pt = -1, V = function(r) {
|
|
5222
5286
|
addEventListener("pageshow", (function(e) {
|
|
5223
|
-
e.persisted && (
|
|
5287
|
+
e.persisted && (pt = e.timeStamp, r(e));
|
|
5224
5288
|
}), !0);
|
|
5225
|
-
},
|
|
5226
|
-
var
|
|
5227
|
-
if (
|
|
5228
|
-
},
|
|
5229
|
-
var
|
|
5230
|
-
return
|
|
5231
|
-
},
|
|
5232
|
-
var t =
|
|
5233
|
-
return
|
|
5234
|
-
},
|
|
5289
|
+
}, De = function() {
|
|
5290
|
+
var r = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
|
|
5291
|
+
if (r && r.responseStart > 0 && r.responseStart < performance.now()) return r;
|
|
5292
|
+
}, de = function() {
|
|
5293
|
+
var r = De();
|
|
5294
|
+
return r && r.activationStart || 0;
|
|
5295
|
+
}, y = function(r, e) {
|
|
5296
|
+
var t = De(), s = "navigate";
|
|
5297
|
+
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 };
|
|
5298
|
+
}, F = function(r, e, t) {
|
|
5235
5299
|
try {
|
|
5236
|
-
if (PerformanceObserver.supportedEntryTypes.includes(
|
|
5237
|
-
var
|
|
5300
|
+
if (PerformanceObserver.supportedEntryTypes.includes(r)) {
|
|
5301
|
+
var s = new PerformanceObserver((function(n) {
|
|
5238
5302
|
Promise.resolve().then((function() {
|
|
5239
5303
|
e(n.getEntries());
|
|
5240
5304
|
}));
|
|
5241
5305
|
}));
|
|
5242
|
-
return
|
|
5306
|
+
return s.observe(Object.assign({ type: r, buffered: !0 }, t || {})), s;
|
|
5243
5307
|
}
|
|
5244
5308
|
} catch {
|
|
5245
5309
|
}
|
|
5246
|
-
},
|
|
5310
|
+
}, w = function(r, e, t, s) {
|
|
5247
5311
|
var n, i;
|
|
5248
5312
|
return function(o) {
|
|
5249
|
-
e.value >= 0 && (o ||
|
|
5313
|
+
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
5314
|
return l > c[1] ? "poor" : l > c[0] ? "needs-improvement" : "good";
|
|
5251
|
-
})(e.value, t),
|
|
5315
|
+
})(e.value, t), r(e));
|
|
5252
5316
|
};
|
|
5253
|
-
},
|
|
5317
|
+
}, ke = function(r) {
|
|
5254
5318
|
requestAnimationFrame((function() {
|
|
5255
5319
|
return requestAnimationFrame((function() {
|
|
5256
|
-
return
|
|
5320
|
+
return r();
|
|
5257
5321
|
}));
|
|
5258
5322
|
}));
|
|
5259
|
-
},
|
|
5323
|
+
}, z = function(r) {
|
|
5260
5324
|
document.addEventListener("visibilitychange", (function() {
|
|
5261
|
-
document.visibilityState === "hidden" &&
|
|
5325
|
+
document.visibilityState === "hidden" && r();
|
|
5262
5326
|
}));
|
|
5263
|
-
}, ue = function(
|
|
5327
|
+
}, ue = function(r) {
|
|
5264
5328
|
var e = !1;
|
|
5265
5329
|
return function() {
|
|
5266
|
-
e || (
|
|
5330
|
+
e || (r(), e = !0);
|
|
5267
5331
|
};
|
|
5268
|
-
},
|
|
5332
|
+
}, H = -1, tt = function() {
|
|
5269
5333
|
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
|
|
5334
|
+
}, ce = function(r) {
|
|
5335
|
+
document.visibilityState === "hidden" && H > -1 && (H = r.type === "visibilitychange" ? r.timeStamp : 0, Ks());
|
|
5336
|
+
}, st = function() {
|
|
5337
|
+
addEventListener("visibilitychange", ce, !0), addEventListener("prerenderingchange", ce, !0);
|
|
5338
|
+
}, Ks = function() {
|
|
5339
|
+
removeEventListener("visibilitychange", ce, !0), removeEventListener("prerenderingchange", ce, !0);
|
|
5340
|
+
}, Ve = function() {
|
|
5341
|
+
return H < 0 && (H = tt(), st(), V((function() {
|
|
5278
5342
|
setTimeout((function() {
|
|
5279
|
-
|
|
5343
|
+
H = tt(), st();
|
|
5280
5344
|
}), 0);
|
|
5281
5345
|
}))), { get firstHiddenTime() {
|
|
5282
|
-
return
|
|
5346
|
+
return H;
|
|
5283
5347
|
} };
|
|
5284
|
-
},
|
|
5348
|
+
}, Q = function(r) {
|
|
5285
5349
|
document.prerendering ? addEventListener("prerenderingchange", (function() {
|
|
5286
|
-
return
|
|
5287
|
-
}), !0) :
|
|
5288
|
-
},
|
|
5289
|
-
e = e || {},
|
|
5290
|
-
var t,
|
|
5350
|
+
return r();
|
|
5351
|
+
}), !0) : r();
|
|
5352
|
+
}, Me = [1800, 3e3], Tt = function(r, e) {
|
|
5353
|
+
e = e || {}, Q((function() {
|
|
5354
|
+
var t, s = Ve(), n = y("FCP"), i = F("paint", (function(o) {
|
|
5291
5355
|
o.forEach((function(l) {
|
|
5292
|
-
l.name === "first-contentful-paint" && (i.disconnect(), l.startTime <
|
|
5356
|
+
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
5357
|
}));
|
|
5294
5358
|
}));
|
|
5295
|
-
i && (t =
|
|
5296
|
-
n =
|
|
5359
|
+
i && (t = w(r, n, Me, e.reportAllChanges), V((function(o) {
|
|
5360
|
+
n = y("FCP"), t = w(r, n, Me, e.reportAllChanges), ke((function() {
|
|
5297
5361
|
n.value = performance.now() - o.timeStamp, t(!0);
|
|
5298
5362
|
}));
|
|
5299
5363
|
})));
|
|
5300
5364
|
}));
|
|
5301
|
-
},
|
|
5302
|
-
e = e || {},
|
|
5303
|
-
var t,
|
|
5304
|
-
c.forEach((function(
|
|
5305
|
-
if (!
|
|
5306
|
-
var
|
|
5307
|
-
n &&
|
|
5365
|
+
}, Ce = [0.1, 0.25], Ys = function(r, e) {
|
|
5366
|
+
e = e || {}, Tt(ue((function() {
|
|
5367
|
+
var t, s = y("CLS", 0), n = 0, i = [], o = function(c) {
|
|
5368
|
+
c.forEach((function(d) {
|
|
5369
|
+
if (!d.hadRecentInput) {
|
|
5370
|
+
var f = i[0], g = i[i.length - 1];
|
|
5371
|
+
n && d.startTime - g.startTime < 1e3 && d.startTime - f.startTime < 5e3 ? (n += d.value, i.push(d)) : (n = d.value, i = [d]);
|
|
5308
5372
|
}
|
|
5309
|
-
})), n >
|
|
5310
|
-
}, l =
|
|
5311
|
-
l && (t =
|
|
5373
|
+
})), n > s.value && (s.value = n, s.entries = i, t());
|
|
5374
|
+
}, l = F("layout-shift", o);
|
|
5375
|
+
l && (t = w(r, s, Ce, e.reportAllChanges), z((function() {
|
|
5312
5376
|
o(l.takeRecords()), t(!0);
|
|
5313
5377
|
})), V((function() {
|
|
5314
|
-
n = 0,
|
|
5378
|
+
n = 0, s = y("CLS", 0), t = w(r, s, Ce, e.reportAllChanges), ke((function() {
|
|
5315
5379
|
return t();
|
|
5316
5380
|
}));
|
|
5317
5381
|
})), setTimeout(t, 0));
|
|
5318
5382
|
})));
|
|
5319
|
-
},
|
|
5320
|
-
|
|
5321
|
-
e.interactionId && (
|
|
5383
|
+
}, It = 0, Se = 1 / 0, J = 0, qs = function(r) {
|
|
5384
|
+
r.forEach((function(e) {
|
|
5385
|
+
e.interactionId && (Se = Math.min(Se, e.interactionId), J = Math.max(J, e.interactionId), It = J ? (J - Se) / 7 + 1 : 0);
|
|
5322
5386
|
}));
|
|
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)
|
|
5387
|
+
}, vt = function() {
|
|
5388
|
+
return Le ? It : performance.interactionCount || 0;
|
|
5389
|
+
}, Js = function() {
|
|
5390
|
+
"interactionCount" in performance || Le || (Le = F("event", qs, { type: "event", buffered: !0, durationThreshold: 0 }));
|
|
5391
|
+
}, A = [], te = /* @__PURE__ */ new Map(), _t = 0, Zs = function() {
|
|
5392
|
+
var r = Math.min(A.length - 1, Math.floor((vt() - _t) / 50));
|
|
5393
|
+
return A[r];
|
|
5394
|
+
}, er = [], tr = function(r) {
|
|
5395
|
+
if (er.forEach((function(n) {
|
|
5396
|
+
return n(r);
|
|
5397
|
+
})), r.interactionId || r.entryType === "first-input") {
|
|
5398
|
+
var e = A[A.length - 1], t = te.get(r.interactionId);
|
|
5399
|
+
if (t || A.length < 10 || r.duration > e.latency) {
|
|
5400
|
+
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
5401
|
else {
|
|
5338
|
-
var
|
|
5339
|
-
|
|
5402
|
+
var s = { id: r.interactionId, latency: r.duration, entries: [r] };
|
|
5403
|
+
te.set(s.id, s), A.push(s);
|
|
5340
5404
|
}
|
|
5341
5405
|
A.sort((function(n, i) {
|
|
5342
5406
|
return i.latency - n.latency;
|
|
5343
5407
|
})), A.length > 10 && A.splice(10).forEach((function(n) {
|
|
5344
|
-
return
|
|
5408
|
+
return te.delete(n.id);
|
|
5345
5409
|
}));
|
|
5346
5410
|
}
|
|
5347
5411
|
}
|
|
5348
|
-
},
|
|
5412
|
+
}, yt = function(r) {
|
|
5349
5413
|
var e = self.requestIdleCallback || self.setTimeout, t = -1;
|
|
5350
|
-
return
|
|
5351
|
-
},
|
|
5352
|
-
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {},
|
|
5414
|
+
return r = ue(r), document.visibilityState === "hidden" ? r() : (t = e(r), z(r)), t;
|
|
5415
|
+
}, Re = [200, 500], sr = function(r, e) {
|
|
5416
|
+
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, Q((function() {
|
|
5353
5417
|
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,
|
|
5418
|
+
Js();
|
|
5419
|
+
var s, n = y("INP"), i = function(l) {
|
|
5420
|
+
yt((function() {
|
|
5421
|
+
l.forEach(tr);
|
|
5422
|
+
var c = Zs();
|
|
5423
|
+
c && c.latency !== n.value && (n.value = c.latency, n.entries = c.entries, s());
|
|
5360
5424
|
}));
|
|
5361
|
-
}, o =
|
|
5362
|
-
|
|
5363
|
-
i(o.takeRecords()),
|
|
5425
|
+
}, o = F("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
|
|
5426
|
+
s = w(r, n, Re, e.reportAllChanges), o && (o.observe({ type: "first-input", buffered: !0 }), z((function() {
|
|
5427
|
+
i(o.takeRecords()), s(!0);
|
|
5364
5428
|
})), V((function() {
|
|
5365
|
-
|
|
5429
|
+
_t = vt(), A.length = 0, te.clear(), n = y("INP"), s = w(r, n, Re, e.reportAllChanges);
|
|
5366
5430
|
})));
|
|
5367
5431
|
})));
|
|
5368
|
-
},
|
|
5369
|
-
e = e || {},
|
|
5370
|
-
var t,
|
|
5371
|
-
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(
|
|
5372
|
-
|
|
5432
|
+
}, Ne = [2500, 4e3], pe = {}, rr = function(r, e) {
|
|
5433
|
+
e = e || {}, Q((function() {
|
|
5434
|
+
var t, s = Ve(), n = y("LCP"), i = function(c) {
|
|
5435
|
+
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(d) {
|
|
5436
|
+
d.startTime < s.firstHiddenTime && (n.value = Math.max(d.startTime - de(), 0), n.entries = [d], t());
|
|
5373
5437
|
}));
|
|
5374
|
-
}, o =
|
|
5438
|
+
}, o = F("largest-contentful-paint", i);
|
|
5375
5439
|
if (o) {
|
|
5376
|
-
t =
|
|
5440
|
+
t = w(r, n, Ne, e.reportAllChanges);
|
|
5377
5441
|
var l = ue((function() {
|
|
5378
|
-
|
|
5442
|
+
pe[n.id] || (i(o.takeRecords()), o.disconnect(), pe[n.id] = !0, t(!0));
|
|
5379
5443
|
}));
|
|
5380
5444
|
["keydown", "click"].forEach((function(c) {
|
|
5381
5445
|
addEventListener(c, (function() {
|
|
5382
|
-
return
|
|
5446
|
+
return yt(l);
|
|
5383
5447
|
}), { once: !0, capture: !0 });
|
|
5384
|
-
})),
|
|
5385
|
-
n =
|
|
5386
|
-
n.value = performance.now() - c.timeStamp,
|
|
5448
|
+
})), z(l), V((function(c) {
|
|
5449
|
+
n = y("LCP"), t = w(r, n, Ne, e.reportAllChanges), ke((function() {
|
|
5450
|
+
n.value = performance.now() - c.timeStamp, pe[n.id] = !0, t(!0);
|
|
5387
5451
|
}));
|
|
5388
5452
|
}));
|
|
5389
5453
|
}
|
|
5390
5454
|
}));
|
|
5391
|
-
},
|
|
5392
|
-
document.prerendering ?
|
|
5393
|
-
return
|
|
5455
|
+
}, Oe = [800, 1800], nr = function r(e) {
|
|
5456
|
+
document.prerendering ? Q((function() {
|
|
5457
|
+
return r(e);
|
|
5394
5458
|
})) : document.readyState !== "complete" ? addEventListener("load", (function() {
|
|
5395
|
-
return
|
|
5459
|
+
return r(e);
|
|
5396
5460
|
}), !0) : setTimeout(e, 0);
|
|
5397
|
-
},
|
|
5461
|
+
}, ir = function(r, e) {
|
|
5398
5462
|
e = e || {};
|
|
5399
|
-
var t =
|
|
5400
|
-
|
|
5401
|
-
var n =
|
|
5402
|
-
n && (t.value = Math.max(n.responseStart -
|
|
5403
|
-
t =
|
|
5463
|
+
var t = y("TTFB"), s = w(r, t, Oe, e.reportAllChanges);
|
|
5464
|
+
nr((function() {
|
|
5465
|
+
var n = De();
|
|
5466
|
+
n && (t.value = Math.max(n.responseStart - de(), 0), t.entries = [n], s(!0), V((function() {
|
|
5467
|
+
t = y("TTFB", 0), (s = w(r, t, Oe, e.reportAllChanges))(!0);
|
|
5404
5468
|
})));
|
|
5405
5469
|
}));
|
|
5406
|
-
},
|
|
5407
|
-
C || (C = e,
|
|
5408
|
-
},
|
|
5409
|
-
if (
|
|
5410
|
-
var
|
|
5411
|
-
|
|
5412
|
-
e(
|
|
5413
|
-
})),
|
|
5414
|
-
}
|
|
5415
|
-
},
|
|
5416
|
-
if (
|
|
5417
|
-
var e = (
|
|
5418
|
-
|
|
5470
|
+
}, W = { passive: !0, capture: !0 }, or = /* @__PURE__ */ new Date(), rt = function(r, e) {
|
|
5471
|
+
C || (C = e, G = r, St = /* @__PURE__ */ new Date(), bt(removeEventListener), wt());
|
|
5472
|
+
}, wt = function() {
|
|
5473
|
+
if (G >= 0 && G < St - or) {
|
|
5474
|
+
var r = { entryType: "first-input", name: C.type, target: C.target, cancelable: C.cancelable, startTime: C.timeStamp, processingStart: C.timeStamp + G };
|
|
5475
|
+
le.forEach((function(e) {
|
|
5476
|
+
e(r);
|
|
5477
|
+
})), le = [];
|
|
5478
|
+
}
|
|
5479
|
+
}, ar = function(r) {
|
|
5480
|
+
if (r.cancelable) {
|
|
5481
|
+
var e = (r.timeStamp > 1e12 ? /* @__PURE__ */ new Date() : performance.now()) - r.timeStamp;
|
|
5482
|
+
r.type == "pointerdown" ? (function(t, s) {
|
|
5419
5483
|
var n = function() {
|
|
5420
|
-
rt(t,
|
|
5484
|
+
rt(t, s), o();
|
|
5421
5485
|
}, i = function() {
|
|
5422
5486
|
o();
|
|
5423
5487
|
}, o = function() {
|
|
5424
|
-
removeEventListener("pointerup", n,
|
|
5488
|
+
removeEventListener("pointerup", n, W), removeEventListener("pointercancel", i, W);
|
|
5425
5489
|
};
|
|
5426
|
-
addEventListener("pointerup", n,
|
|
5427
|
-
})(e,
|
|
5490
|
+
addEventListener("pointerup", n, W), addEventListener("pointercancel", i, W);
|
|
5491
|
+
})(e, r) : rt(e, r);
|
|
5428
5492
|
}
|
|
5429
|
-
},
|
|
5493
|
+
}, bt = function(r) {
|
|
5430
5494
|
["mousedown", "keydown", "touchstart", "pointerdown"].forEach((function(e) {
|
|
5431
|
-
return
|
|
5495
|
+
return r(e, ar, W);
|
|
5432
5496
|
}));
|
|
5433
|
-
},
|
|
5434
|
-
e = e || {},
|
|
5435
|
-
var t,
|
|
5436
|
-
c.startTime <
|
|
5497
|
+
}, Pe = [100, 300], lr = function(r, e) {
|
|
5498
|
+
e = e || {}, Q((function() {
|
|
5499
|
+
var t, s = Ve(), n = y("FID"), i = function(c) {
|
|
5500
|
+
c.startTime < s.firstHiddenTime && (n.value = c.processingStart - c.startTime, n.entries.push(c), t(!0));
|
|
5437
5501
|
}, o = function(c) {
|
|
5438
5502
|
c.forEach(i);
|
|
5439
|
-
}, l =
|
|
5440
|
-
t =
|
|
5503
|
+
}, l = F("first-input", o);
|
|
5504
|
+
t = w(r, n, Pe, e.reportAllChanges), l && (z(ue((function() {
|
|
5441
5505
|
o(l.takeRecords()), l.disconnect();
|
|
5442
5506
|
}))), V((function() {
|
|
5443
5507
|
var c;
|
|
5444
|
-
n =
|
|
5508
|
+
n = y("FID"), t = w(r, n, Pe, e.reportAllChanges), le = [], G = -1, C = null, bt(addEventListener), c = i, le.push(c), wt();
|
|
5445
5509
|
})));
|
|
5446
5510
|
}));
|
|
5447
5511
|
};
|
|
5448
|
-
const
|
|
5512
|
+
const cr = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
5449
5513
|
__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:
|
|
5514
|
+
CLSThresholds: Ce,
|
|
5515
|
+
FCPThresholds: Me,
|
|
5516
|
+
FIDThresholds: Pe,
|
|
5517
|
+
INPThresholds: Re,
|
|
5518
|
+
LCPThresholds: Ne,
|
|
5519
|
+
TTFBThresholds: Oe,
|
|
5520
|
+
onCLS: Ys,
|
|
5521
|
+
onFCP: Tt,
|
|
5522
|
+
onFID: lr,
|
|
5523
|
+
onINP: sr,
|
|
5524
|
+
onLCP: rr,
|
|
5525
|
+
onTTFB: ir
|
|
5462
5526
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
5463
5527
|
export {
|
|
5464
|
-
|
|
5465
|
-
|
|
5528
|
+
m as AppConfigValidationError,
|
|
5529
|
+
dr as DEFAULT_SESSION_TIMEOUT,
|
|
5466
5530
|
_e as DEFAULT_WEB_VITALS_MODE,
|
|
5467
5531
|
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
|
-
|
|
5532
|
+
se as EmitterEvent,
|
|
5533
|
+
B as ErrorType,
|
|
5534
|
+
u as EventType,
|
|
5535
|
+
vr as InitializationTimeoutError,
|
|
5536
|
+
N as IntegrationValidationError,
|
|
5537
|
+
pr as MAX_ARRAY_LENGTH,
|
|
5538
|
+
mr as MAX_CUSTOM_EVENT_ARRAY_SIZE,
|
|
5539
|
+
fr as MAX_CUSTOM_EVENT_KEYS,
|
|
5540
|
+
ur as MAX_CUSTOM_EVENT_NAME_LENGTH,
|
|
5541
|
+
hr as MAX_CUSTOM_EVENT_STRING_SIZE,
|
|
5542
|
+
gr as MAX_NESTED_OBJECT_KEYS,
|
|
5543
|
+
Er as MAX_STRING_LENGTH,
|
|
5544
|
+
Sr as MAX_STRING_LENGTH_IN_ARRAY,
|
|
5545
|
+
ie as Mode,
|
|
5546
|
+
lt as PII_PATTERNS,
|
|
5547
|
+
O as PermanentError,
|
|
5548
|
+
re as RateLimitError,
|
|
5549
|
+
Xe as SamplingRateValidationError,
|
|
5550
|
+
Z as ScrollDirection,
|
|
5551
|
+
Pt as SessionTimeoutValidationError,
|
|
5552
|
+
$ as SpecialApiUrl,
|
|
5553
|
+
ne as TimeoutError,
|
|
5554
|
+
j as TraceLogValidationError,
|
|
5555
|
+
_r as WEB_VITALS_GOOD_THRESHOLDS,
|
|
5556
|
+
Ke as WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS,
|
|
5557
|
+
Kt as WEB_VITALS_POOR_THRESHOLDS,
|
|
5558
|
+
Ye as getWebVitalsThresholds,
|
|
5559
|
+
Tr as isPrimaryScrollEvent,
|
|
5560
|
+
Ir as isSecondaryScrollEvent,
|
|
5561
|
+
yr as tracelog
|
|
5498
5562
|
};
|