@tracelog/lib 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/browser/tracelog.esm.js +704 -607
- package/dist/browser/tracelog.esm.js.map +1 -0
- package/dist/browser/tracelog.js +2 -2
- package/dist/browser/tracelog.js.map +1 -0
- package/dist/cjs/api.js +12 -3
- package/dist/cjs/constants/config.constants.d.ts +3 -0
- package/dist/cjs/constants/config.constants.js +5 -2
- package/dist/cjs/managers/event.manager.d.ts +3 -0
- package/dist/cjs/managers/event.manager.js +47 -6
- package/dist/cjs/managers/storage.manager.d.ts +5 -0
- package/dist/cjs/managers/storage.manager.js +95 -6
- package/dist/cjs/types/config.types.d.ts +2 -2
- package/dist/cjs/utils/logging.utils.d.ts +16 -1
- package/dist/cjs/utils/logging.utils.js +65 -4
- package/dist/cjs/utils/network/url.utils.js +3 -4
- package/dist/cjs/utils/validations/config-validations.utils.js +17 -8
- package/dist/esm/api.js +12 -3
- package/dist/esm/constants/config.constants.d.ts +3 -0
- package/dist/esm/constants/config.constants.js +3 -0
- package/dist/esm/managers/event.manager.d.ts +3 -0
- package/dist/esm/managers/event.manager.js +48 -7
- package/dist/esm/managers/storage.manager.d.ts +5 -0
- package/dist/esm/managers/storage.manager.js +95 -6
- package/dist/esm/types/config.types.d.ts +2 -2
- package/dist/esm/utils/logging.utils.d.ts +16 -1
- package/dist/esm/utils/logging.utils.js +65 -4
- package/dist/esm/utils/network/url.utils.js +3 -4
- package/dist/esm/utils/validations/config-validations.utils.js +17 -8
- package/package.json +3 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const O = "data-tlog",
|
|
1
|
+
const O = "data-tlog", Ce = [
|
|
2
2
|
"button",
|
|
3
3
|
"a",
|
|
4
4
|
'input[type="button"]',
|
|
@@ -30,7 +30,7 @@ const O = "data-tlog", be = [
|
|
|
30
30
|
".menu-item",
|
|
31
31
|
"[data-testid]",
|
|
32
32
|
'[tabindex="0"]'
|
|
33
|
-
],
|
|
33
|
+
], be = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
|
|
34
34
|
const m = {
|
|
35
35
|
INVALID_SESSION_TIMEOUT: "Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",
|
|
36
36
|
INVALID_SAMPLING_RATE: "Sampling rate must be between 0 and 1",
|
|
@@ -41,7 +41,7 @@ const m = {
|
|
|
41
41
|
INVALID_SCROLL_CONTAINER_SELECTORS: "Scroll container selectors must be valid CSS selectors",
|
|
42
42
|
INVALID_GLOBAL_METADATA: "Global metadata must be an object",
|
|
43
43
|
INVALID_SENSITIVE_QUERY_PARAMS: "Sensitive query params must be an array of strings"
|
|
44
|
-
},
|
|
44
|
+
}, Oe = [
|
|
45
45
|
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
|
46
46
|
/javascript:/gi,
|
|
47
47
|
/on\w+\s*=/gi,
|
|
@@ -49,63 +49,83 @@ const m = {
|
|
|
49
49
|
/<embed\b[^>]*>/gi,
|
|
50
50
|
/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi
|
|
51
51
|
];
|
|
52
|
-
var
|
|
53
|
-
class
|
|
54
|
-
constructor(e, t,
|
|
55
|
-
super(e), this.errorCode = t, this.layer =
|
|
52
|
+
var j = /* @__PURE__ */ ((s) => (s.Localhost = "localhost:8080", s.Fail = "localhost:9999", s))(j || {}), _ = /* @__PURE__ */ ((s) => (s.Mobile = "mobile", s.Tablet = "tablet", s.Desktop = "desktop", s.Unknown = "unknown", s))(_ || {}), X = /* @__PURE__ */ ((s) => (s.EVENT = "event", s.QUEUE = "queue", s))(X || {}), d = /* @__PURE__ */ ((s) => (s.PAGE_VIEW = "page_view", s.CLICK = "click", s.SCROLL = "scroll", s.SESSION_START = "session_start", s.SESSION_END = "session_end", s.CUSTOM = "custom", s.WEB_VITALS = "web_vitals", s.ERROR = "error", s))(d || {}), D = /* @__PURE__ */ ((s) => (s.UP = "up", s.DOWN = "down", s))(D || {}), L = /* @__PURE__ */ ((s) => (s.JS_ERROR = "js_error", s.PROMISE_REJECTION = "promise_rejection", s))(L || {}), R = /* @__PURE__ */ ((s) => (s.QA = "qa", s))(R || {});
|
|
53
|
+
class C extends Error {
|
|
54
|
+
constructor(e, t, r) {
|
|
55
|
+
super(e), this.errorCode = t, this.layer = r, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
-
class
|
|
58
|
+
class y extends C {
|
|
59
59
|
constructor(e, t = "config") {
|
|
60
60
|
super(e, "APP_CONFIG_INVALID", t);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
class
|
|
63
|
+
class Pe extends C {
|
|
64
64
|
constructor(e, t = "config") {
|
|
65
65
|
super(e, "SESSION_TIMEOUT_INVALID", t);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
class oe extends
|
|
68
|
+
class oe extends C {
|
|
69
69
|
constructor(e, t = "config") {
|
|
70
70
|
super(e, "SAMPLING_RATE_INVALID", t);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
class
|
|
73
|
+
class v extends C {
|
|
74
74
|
constructor(e, t = "config") {
|
|
75
75
|
super(e, "INTEGRATION_INVALID", t);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
class xt extends
|
|
79
|
-
constructor(e, t,
|
|
80
|
-
super(e, "INITIALIZATION_TIMEOUT",
|
|
78
|
+
class xt extends C {
|
|
79
|
+
constructor(e, t, r = "runtime") {
|
|
80
|
+
super(e, "INITIALIZATION_TIMEOUT", r), this.timeoutMs = t;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const De = (s, e) => {
|
|
84
|
+
if (e) {
|
|
85
|
+
if (e instanceof Error) {
|
|
86
|
+
const t = e.message.replace(/\s+at\s+.*$/gm, "").replace(/\(.*?:\d+:\d+\)/g, "");
|
|
87
|
+
return `[TraceLog] ${s}: ${t}`;
|
|
88
|
+
}
|
|
89
|
+
return `[TraceLog] ${s}: ${e instanceof Error ? e.message : "Unknown error"}`;
|
|
90
|
+
}
|
|
91
|
+
return `[TraceLog] ${s}`;
|
|
92
|
+
}, o = (s, e, t) => {
|
|
93
|
+
const { error: r, data: n, showToClient: i = !1 } = t ?? {}, a = r ? De(e, r) : `[TraceLog] ${e}`, c = s === "error" ? "error" : s === "warn" ? "warn" : "log";
|
|
94
|
+
if (!(s === "debug" || s === "info" && !i))
|
|
95
|
+
if (n !== void 0) {
|
|
96
|
+
const l = ke(n);
|
|
97
|
+
console[c](a, l);
|
|
98
|
+
} else n !== void 0 ? console[c](a, n) : console[c](a);
|
|
99
|
+
}, ke = (s) => {
|
|
100
|
+
const e = {}, t = ["token", "password", "secret", "key", "apikey", "api_key", "sessionid", "session_id"];
|
|
101
|
+
for (const [r, n] of Object.entries(s)) {
|
|
102
|
+
const i = r.toLowerCase();
|
|
103
|
+
t.some((a) => i.includes(a)) ? e[r] = "[REDACTED]" : e[r] = n;
|
|
104
|
+
}
|
|
105
|
+
return e;
|
|
86
106
|
};
|
|
87
|
-
let
|
|
107
|
+
let W, pe;
|
|
88
108
|
const Ue = () => {
|
|
89
|
-
typeof window < "u" && !
|
|
109
|
+
typeof window < "u" && !W && (W = window.matchMedia("(pointer: coarse)"), pe = window.matchMedia("(hover: none)"));
|
|
90
110
|
}, He = () => {
|
|
91
111
|
try {
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
94
|
-
return
|
|
112
|
+
const s = navigator;
|
|
113
|
+
if (s.userAgentData && typeof s.userAgentData.mobile == "boolean")
|
|
114
|
+
return s.userAgentData.platform && /ipad|tablet/i.test(s.userAgentData.platform) ? _.Tablet : s.userAgentData.mobile ? _.Mobile : _.Desktop;
|
|
95
115
|
Ue();
|
|
96
|
-
const e = window.innerWidth, t =
|
|
97
|
-
return e <= 767 || a && n ? _.Mobile : e >= 768 && e <= 1024 ||
|
|
98
|
-
} catch (
|
|
99
|
-
return
|
|
116
|
+
const e = window.innerWidth, t = W?.matches ?? !1, r = pe?.matches ?? !1, n = "ontouchstart" in window || navigator.maxTouchPoints > 0, i = navigator.userAgent.toLowerCase(), a = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i), c = /tablet|ipad|android(?!.*mobile)/.test(i);
|
|
117
|
+
return e <= 767 || a && n ? _.Mobile : e >= 768 && e <= 1024 || c || t && r && n ? _.Tablet : _.Desktop;
|
|
118
|
+
} catch (s) {
|
|
119
|
+
return o("warn", "Device detection failed, defaulting to desktop", { error: s }), _.Desktop;
|
|
100
120
|
}
|
|
101
|
-
}, T = "tlog",
|
|
121
|
+
}, T = "tlog", ce = `${T}:qa_mode`, xe = `${T}:uid`, Ve = (s) => s ? `${T}:${s}:queue` : `${T}:queue`, Fe = (s) => s ? `${T}:${s}:session` : `${T}:session`, Ge = (s) => s ? `${T}:${s}:broadcast` : `${T}:broadcast`, _e = {
|
|
102
122
|
LCP: 4e3,
|
|
103
123
|
FCP: 1800,
|
|
104
124
|
CLS: 0.25,
|
|
105
125
|
INP: 200,
|
|
106
126
|
TTFB: 800,
|
|
107
127
|
LONG_TASK: 50
|
|
108
|
-
},
|
|
128
|
+
}, ze = 1e3, Te = [
|
|
109
129
|
// Email addresses
|
|
110
130
|
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi,
|
|
111
131
|
// US Phone numbers (various formats)
|
|
@@ -120,230 +140,241 @@ const Ue = () => {
|
|
|
120
140
|
/Bearer\s+[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?(?:\.[A-Za-z0-9_-]+)?/gi,
|
|
121
141
|
// Passwords in connection strings (protocol://user:password@host)
|
|
122
142
|
/:\/\/[^:/]+:([^@]+)@/gi
|
|
123
|
-
],
|
|
124
|
-
if (sessionStorage.getItem(
|
|
143
|
+
], le = 500, ue = 5e3, k = 50, $e = k * 2, de = "tlog_mode", Qe = "qa", Be = () => {
|
|
144
|
+
if (sessionStorage.getItem(ce) === "true")
|
|
125
145
|
return !0;
|
|
126
|
-
const e = new URLSearchParams(window.location.search),
|
|
127
|
-
if (
|
|
128
|
-
sessionStorage.setItem(
|
|
146
|
+
const e = new URLSearchParams(window.location.search), r = e.get(de) === Qe;
|
|
147
|
+
if (r) {
|
|
148
|
+
sessionStorage.setItem(ce, "true"), e.delete(de);
|
|
129
149
|
const n = e.toString(), i = `${window.location.pathname}${n ? "?" + n : ""}${window.location.hash}`;
|
|
130
150
|
try {
|
|
131
151
|
window.history.replaceState({}, "", i);
|
|
132
152
|
} catch (a) {
|
|
133
|
-
|
|
153
|
+
o("warn", "History API not available, cannot replace URL", { error: a });
|
|
134
154
|
}
|
|
135
155
|
console.log(
|
|
136
156
|
"%c[TraceLog] QA Mode ACTIVE",
|
|
137
157
|
"background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;"
|
|
138
158
|
);
|
|
139
159
|
}
|
|
140
|
-
return
|
|
160
|
+
return r;
|
|
141
161
|
}, he = () => {
|
|
142
|
-
const
|
|
143
|
-
return
|
|
144
|
-
const n =
|
|
162
|
+
const s = new URLSearchParams(window.location.search), e = {};
|
|
163
|
+
return be.forEach((r) => {
|
|
164
|
+
const n = s.get(r);
|
|
145
165
|
if (n) {
|
|
146
|
-
const i =
|
|
166
|
+
const i = r.split("utm_")[1];
|
|
147
167
|
e[i] = n;
|
|
148
168
|
}
|
|
149
169
|
}), Object.keys(e).length ? e : void 0;
|
|
150
|
-
},
|
|
170
|
+
}, je = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (s) => {
|
|
151
171
|
const e = Math.random() * 16 | 0;
|
|
152
|
-
return (
|
|
172
|
+
return (s === "x" ? e : e & 3 | 8).toString(16);
|
|
153
173
|
}), Xe = () => {
|
|
154
|
-
const
|
|
174
|
+
const s = Date.now();
|
|
155
175
|
let e = "";
|
|
156
176
|
try {
|
|
157
177
|
if (typeof crypto < "u" && crypto.getRandomValues) {
|
|
158
178
|
const t = crypto.getRandomValues(new Uint8Array(4));
|
|
159
|
-
t && (e = Array.from(t, (
|
|
179
|
+
t && (e = Array.from(t, (r) => r.toString(16).padStart(2, "0")).join(""));
|
|
160
180
|
}
|
|
161
181
|
} catch {
|
|
162
182
|
}
|
|
163
|
-
return e || (e = Math.floor(Math.random() * 4294967295).toString(16).padStart(8, "0")), `${
|
|
164
|
-
}, fe = (
|
|
183
|
+
return e || (e = Math.floor(Math.random() * 4294967295).toString(16).padStart(8, "0")), `${s}-${e}`;
|
|
184
|
+
}, fe = (s, e = !1) => {
|
|
165
185
|
try {
|
|
166
|
-
const t = new URL(
|
|
167
|
-
return
|
|
186
|
+
const t = new URL(s), r = t.protocol === "https:", n = t.protocol === "http:";
|
|
187
|
+
return r || e && n;
|
|
168
188
|
} catch {
|
|
169
189
|
return !1;
|
|
170
190
|
}
|
|
171
|
-
},
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (n.length === 0)
|
|
191
|
+
}, We = (s) => {
|
|
192
|
+
if (s.integrations?.tracelog?.projectId) {
|
|
193
|
+
const r = new URL(window.location.href).hostname.split(".");
|
|
194
|
+
if (r.length === 0)
|
|
176
195
|
throw new Error("Invalid URL");
|
|
177
|
-
const
|
|
178
|
-
if (!fe(
|
|
196
|
+
const n = s.integrations.tracelog.projectId, i = r.slice(-2).join("."), a = `https://${n}.${i}`;
|
|
197
|
+
if (!fe(a))
|
|
179
198
|
throw new Error("Invalid URL");
|
|
180
|
-
return
|
|
199
|
+
return a;
|
|
181
200
|
}
|
|
182
|
-
if (
|
|
183
|
-
const
|
|
184
|
-
if (!fe(
|
|
201
|
+
if (s.integrations?.custom?.apiUrl) {
|
|
202
|
+
const e = s.integrations.custom.apiUrl, t = s.integrations?.custom?.allowHttp ?? !1;
|
|
203
|
+
if (!fe(e, t))
|
|
185
204
|
throw new Error("Invalid URL");
|
|
186
|
-
return
|
|
205
|
+
return e;
|
|
187
206
|
}
|
|
188
207
|
return "";
|
|
189
|
-
},
|
|
208
|
+
}, Y = (s, e = []) => {
|
|
190
209
|
try {
|
|
191
|
-
const t = new URL(
|
|
210
|
+
const t = new URL(s), r = t.searchParams;
|
|
192
211
|
let n = !1;
|
|
193
212
|
const i = [];
|
|
194
|
-
return e.forEach((
|
|
195
|
-
|
|
196
|
-
}), !n &&
|
|
213
|
+
return e.forEach((c) => {
|
|
214
|
+
r.has(c) && (r.delete(c), n = !0, i.push(c));
|
|
215
|
+
}), !n && s.includes("?") ? s : (t.search = r.toString(), t.toString());
|
|
197
216
|
} catch (t) {
|
|
198
|
-
return
|
|
217
|
+
return o("warn", "URL normalization failed, returning original", { error: t, data: { url: s.slice(0, 100) } }), s;
|
|
199
218
|
}
|
|
200
|
-
}, ge = (
|
|
201
|
-
if (!
|
|
219
|
+
}, ge = (s) => {
|
|
220
|
+
if (!s || typeof s != "string" || s.trim().length === 0)
|
|
202
221
|
return "";
|
|
203
|
-
let e =
|
|
204
|
-
|
|
222
|
+
let e = s;
|
|
223
|
+
s.length > 1e3 && (e = s.slice(0, Math.max(0, 1e3)));
|
|
205
224
|
let t = 0;
|
|
206
|
-
for (const n of
|
|
225
|
+
for (const n of Oe) {
|
|
207
226
|
const i = e;
|
|
208
227
|
e = e.replace(n, ""), i !== e && t++;
|
|
209
228
|
}
|
|
210
|
-
return t > 0 &&
|
|
229
|
+
return t > 0 && o("warn", "XSS patterns detected and removed", {
|
|
211
230
|
data: {
|
|
212
231
|
patternMatches: t,
|
|
213
|
-
originalValue:
|
|
232
|
+
originalValue: s.slice(0, 100)
|
|
214
233
|
}
|
|
215
234
|
}), e = e.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'").replaceAll("/", "/"), e.trim();
|
|
216
|
-
}, K = (
|
|
217
|
-
if (e > 3 ||
|
|
235
|
+
}, K = (s, e = 0) => {
|
|
236
|
+
if (e > 3 || s == null)
|
|
218
237
|
return null;
|
|
219
|
-
if (typeof
|
|
220
|
-
return ge(
|
|
221
|
-
if (typeof
|
|
222
|
-
return !Number.isFinite(
|
|
223
|
-
if (typeof
|
|
224
|
-
return
|
|
225
|
-
if (Array.isArray(
|
|
226
|
-
return
|
|
227
|
-
if (typeof
|
|
228
|
-
const t = {}, n = Object.entries(
|
|
238
|
+
if (typeof s == "string")
|
|
239
|
+
return ge(s);
|
|
240
|
+
if (typeof s == "number")
|
|
241
|
+
return !Number.isFinite(s) || s < -Number.MAX_SAFE_INTEGER || s > Number.MAX_SAFE_INTEGER ? 0 : s;
|
|
242
|
+
if (typeof s == "boolean")
|
|
243
|
+
return s;
|
|
244
|
+
if (Array.isArray(s))
|
|
245
|
+
return s.slice(0, 100).map((n) => K(n, e + 1)).filter((n) => n !== null);
|
|
246
|
+
if (typeof s == "object") {
|
|
247
|
+
const t = {}, n = Object.entries(s).slice(0, 20);
|
|
229
248
|
for (const [i, a] of n) {
|
|
230
|
-
const
|
|
231
|
-
if (
|
|
232
|
-
const
|
|
233
|
-
|
|
249
|
+
const c = ge(i);
|
|
250
|
+
if (c) {
|
|
251
|
+
const l = K(a, e + 1);
|
|
252
|
+
l !== null && (t[c] = l);
|
|
234
253
|
}
|
|
235
254
|
}
|
|
236
255
|
return t;
|
|
237
256
|
}
|
|
238
257
|
return null;
|
|
239
|
-
},
|
|
240
|
-
if (typeof
|
|
258
|
+
}, Ye = (s) => {
|
|
259
|
+
if (typeof s != "object" || s === null)
|
|
241
260
|
return {};
|
|
242
261
|
try {
|
|
243
|
-
const e = K(
|
|
262
|
+
const e = K(s);
|
|
244
263
|
return typeof e == "object" && e !== null ? e : {};
|
|
245
264
|
} catch (e) {
|
|
246
265
|
const t = e instanceof Error ? e.message : String(e);
|
|
247
266
|
throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`);
|
|
248
267
|
}
|
|
249
|
-
}, Ke = (
|
|
250
|
-
if (!
|
|
251
|
-
throw new
|
|
252
|
-
if (
|
|
253
|
-
throw new
|
|
254
|
-
if (
|
|
255
|
-
throw new
|
|
256
|
-
if (
|
|
257
|
-
if (!Array.isArray(
|
|
258
|
-
throw new
|
|
259
|
-
for (const e of
|
|
268
|
+
}, Ke = (s) => {
|
|
269
|
+
if (!s || typeof s != "object")
|
|
270
|
+
throw new y("Configuration must be an object", "config");
|
|
271
|
+
if (s.sessionTimeout !== void 0 && (typeof s.sessionTimeout != "number" || s.sessionTimeout < 3e4 || s.sessionTimeout > 864e5))
|
|
272
|
+
throw new Pe(m.INVALID_SESSION_TIMEOUT, "config");
|
|
273
|
+
if (s.globalMetadata !== void 0 && (typeof s.globalMetadata != "object" || s.globalMetadata === null))
|
|
274
|
+
throw new y(m.INVALID_GLOBAL_METADATA, "config");
|
|
275
|
+
if (s.scrollContainerSelectors !== void 0 && Ze(s.scrollContainerSelectors), s.integrations && Je(s.integrations), s.sensitiveQueryParams !== void 0) {
|
|
276
|
+
if (!Array.isArray(s.sensitiveQueryParams))
|
|
277
|
+
throw new y(m.INVALID_SENSITIVE_QUERY_PARAMS, "config");
|
|
278
|
+
for (const e of s.sensitiveQueryParams)
|
|
260
279
|
if (typeof e != "string")
|
|
261
|
-
throw new
|
|
280
|
+
throw new y("All sensitive query params must be strings", "config");
|
|
262
281
|
}
|
|
263
|
-
if (
|
|
282
|
+
if (s.errorSampling !== void 0 && (typeof s.errorSampling != "number" || s.errorSampling < 0 || s.errorSampling > 1))
|
|
264
283
|
throw new oe(m.INVALID_ERROR_SAMPLING_RATE, "config");
|
|
265
|
-
if (
|
|
284
|
+
if (s.samplingRate !== void 0 && (typeof s.samplingRate != "number" || s.samplingRate < 0 || s.samplingRate > 1))
|
|
266
285
|
throw new oe(m.INVALID_SAMPLING_RATE, "config");
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
}, qe = (r) => {
|
|
270
|
-
if (r.includes("<") || r.includes(">") || /on\w+\s*=/i.test(r) || !/^[a-zA-Z0-9\-_#.[\]="':, >+~*()]+$/.test(r))
|
|
286
|
+
}, qe = (s) => {
|
|
287
|
+
if (s.includes("<") || s.includes(">") || /on\w+\s*=/i.test(s) || !/^[a-zA-Z0-9\-_#.[\]="':, >+~*()]+$/.test(s))
|
|
271
288
|
return !1;
|
|
272
289
|
let t = 0;
|
|
273
|
-
for (const n of
|
|
290
|
+
for (const n of s)
|
|
274
291
|
if (n === "(" && t++, n === ")" && t--, t < 0) return !1;
|
|
275
292
|
if (t !== 0) return !1;
|
|
276
|
-
let
|
|
277
|
-
for (const n of
|
|
278
|
-
if (n === "[" &&
|
|
279
|
-
return
|
|
280
|
-
},
|
|
281
|
-
const e = Array.isArray(
|
|
293
|
+
let r = 0;
|
|
294
|
+
for (const n of s)
|
|
295
|
+
if (n === "[" && r++, n === "]" && r--, r < 0) return !1;
|
|
296
|
+
return r === 0;
|
|
297
|
+
}, Ze = (s) => {
|
|
298
|
+
const e = Array.isArray(s) ? s : [s];
|
|
282
299
|
for (const t of e) {
|
|
283
300
|
if (typeof t != "string" || t.trim() === "")
|
|
284
|
-
throw
|
|
301
|
+
throw o("error", "Invalid scroll container selector", {
|
|
285
302
|
showToClient: !0,
|
|
286
303
|
data: {
|
|
287
304
|
selector: t,
|
|
288
305
|
type: typeof t,
|
|
289
306
|
isEmpty: t === "" || typeof t == "string" && t.trim() === ""
|
|
290
307
|
}
|
|
291
|
-
}), new
|
|
308
|
+
}), new y(m.INVALID_SCROLL_CONTAINER_SELECTORS, "config");
|
|
292
309
|
if (!qe(t))
|
|
293
|
-
throw
|
|
310
|
+
throw o("error", "Invalid or potentially unsafe CSS selector", {
|
|
294
311
|
showToClient: !0,
|
|
295
312
|
data: {
|
|
296
313
|
selector: t,
|
|
297
314
|
reason: "Failed security validation"
|
|
298
315
|
}
|
|
299
|
-
}), new
|
|
316
|
+
}), new y("Invalid or potentially unsafe CSS selector", "config");
|
|
300
317
|
}
|
|
301
|
-
},
|
|
302
|
-
if (
|
|
303
|
-
if (
|
|
304
|
-
throw new
|
|
305
|
-
if (
|
|
306
|
-
if (!
|
|
307
|
-
throw new
|
|
308
|
-
if (
|
|
309
|
-
throw new
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
327
|
-
|
|
318
|
+
}, Je = (s) => {
|
|
319
|
+
if (s) {
|
|
320
|
+
if (s.tracelog && (!s.tracelog.projectId || typeof s.tracelog.projectId != "string" || s.tracelog.projectId.trim() === ""))
|
|
321
|
+
throw new v(m.INVALID_TRACELOG_PROJECT_ID, "config");
|
|
322
|
+
if (s.custom) {
|
|
323
|
+
if (!s.custom.apiUrl || typeof s.custom.apiUrl != "string" || s.custom.apiUrl.trim() === "")
|
|
324
|
+
throw new v(m.INVALID_CUSTOM_API_URL, "config");
|
|
325
|
+
if (s.custom.allowHttp !== void 0 && typeof s.custom.allowHttp != "boolean")
|
|
326
|
+
throw new v("allowHttp must be a boolean", "config");
|
|
327
|
+
const e = s.custom.apiUrl.trim();
|
|
328
|
+
if (!e.startsWith("http://") && !e.startsWith("https://"))
|
|
329
|
+
throw new v('Custom API URL must start with "http://" or "https://"', "config");
|
|
330
|
+
if (!(s.custom.allowHttp ?? !1) && e.startsWith("http://"))
|
|
331
|
+
throw new v(
|
|
332
|
+
"Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)",
|
|
333
|
+
"config"
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
if (s.googleAnalytics) {
|
|
337
|
+
if (!s.googleAnalytics.measurementId || typeof s.googleAnalytics.measurementId != "string" || s.googleAnalytics.measurementId.trim() === "")
|
|
338
|
+
throw new v(m.INVALID_GOOGLE_ANALYTICS_ID, "config");
|
|
339
|
+
if (!s.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))
|
|
340
|
+
throw new v('Google Analytics measurement ID must start with "G-" or "UA-"', "config");
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}, et = (s) => {
|
|
344
|
+
Ke(s);
|
|
345
|
+
const e = {
|
|
346
|
+
...s,
|
|
347
|
+
sessionTimeout: s.sessionTimeout ?? 9e5,
|
|
348
|
+
globalMetadata: s.globalMetadata ?? {},
|
|
349
|
+
sensitiveQueryParams: s.sensitiveQueryParams ?? [],
|
|
350
|
+
errorSampling: s.errorSampling ?? 1,
|
|
351
|
+
samplingRate: s.samplingRate ?? 1
|
|
352
|
+
};
|
|
353
|
+
return e.integrations?.custom && (e.integrations.custom = {
|
|
354
|
+
...e.integrations.custom,
|
|
355
|
+
allowHttp: e.integrations.custom.allowHttp ?? !1
|
|
356
|
+
}), e;
|
|
357
|
+
}, tt = (s) => {
|
|
358
|
+
if (typeof s == "string")
|
|
328
359
|
return !0;
|
|
329
|
-
if (typeof
|
|
330
|
-
const e = Object.entries(
|
|
360
|
+
if (typeof s == "object" && s !== null && !Array.isArray(s)) {
|
|
361
|
+
const e = Object.entries(s);
|
|
331
362
|
if (e.length > 20)
|
|
332
363
|
return !1;
|
|
333
364
|
for (const [, t] of e) {
|
|
334
365
|
if (t == null)
|
|
335
366
|
continue;
|
|
336
|
-
const
|
|
337
|
-
if (
|
|
367
|
+
const r = typeof t;
|
|
368
|
+
if (r !== "string" && r !== "number" && r !== "boolean")
|
|
338
369
|
return !1;
|
|
339
370
|
}
|
|
340
371
|
return !0;
|
|
341
372
|
}
|
|
342
373
|
return !1;
|
|
343
|
-
}, rt = (
|
|
344
|
-
if (typeof
|
|
374
|
+
}, rt = (s) => {
|
|
375
|
+
if (typeof s != "object" || s === null)
|
|
345
376
|
return !1;
|
|
346
|
-
for (const e of Object.values(
|
|
377
|
+
for (const e of Object.values(s)) {
|
|
347
378
|
if (e == null)
|
|
348
379
|
continue;
|
|
349
380
|
const t = typeof e;
|
|
@@ -362,31 +393,31 @@ const Ue = () => {
|
|
|
362
393
|
}
|
|
363
394
|
}
|
|
364
395
|
return !0;
|
|
365
|
-
}, st = (
|
|
396
|
+
}, st = (s) => typeof s != "string" ? {
|
|
366
397
|
valid: !1,
|
|
367
398
|
error: "Event name must be a string"
|
|
368
|
-
} :
|
|
399
|
+
} : s.length === 0 ? {
|
|
369
400
|
valid: !1,
|
|
370
401
|
error: "Event name cannot be empty"
|
|
371
|
-
} :
|
|
402
|
+
} : s.length > 120 ? {
|
|
372
403
|
valid: !1,
|
|
373
404
|
error: "Event name is too long (max 120 characters)"
|
|
374
|
-
} :
|
|
405
|
+
} : s.includes("<") || s.includes(">") || s.includes("&") ? {
|
|
375
406
|
valid: !1,
|
|
376
407
|
error: "Event name contains invalid characters"
|
|
377
|
-
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(
|
|
408
|
+
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(s.toLowerCase()) ? {
|
|
378
409
|
valid: !1,
|
|
379
410
|
error: "Event name cannot be a reserved word"
|
|
380
|
-
} : { valid: !0 }, Se = (
|
|
381
|
-
const
|
|
382
|
-
if (!rt(
|
|
411
|
+
} : { valid: !0 }, Se = (s, e, t) => {
|
|
412
|
+
const r = Ye(e), n = `${t} "${s}" metadata error`;
|
|
413
|
+
if (!rt(r))
|
|
383
414
|
return {
|
|
384
415
|
valid: !1,
|
|
385
416
|
error: `${n}: object has invalid types. Valid types are string, number, boolean or string arrays.`
|
|
386
417
|
};
|
|
387
418
|
let i;
|
|
388
419
|
try {
|
|
389
|
-
i = JSON.stringify(
|
|
420
|
+
i = JSON.stringify(r);
|
|
390
421
|
} catch {
|
|
391
422
|
return {
|
|
392
423
|
valid: !1,
|
|
@@ -398,38 +429,38 @@ const Ue = () => {
|
|
|
398
429
|
valid: !1,
|
|
399
430
|
error: `${n}: object is too large (max ${8192 / 1024} KB).`
|
|
400
431
|
};
|
|
401
|
-
if (Object.keys(
|
|
432
|
+
if (Object.keys(r).length > 10)
|
|
402
433
|
return {
|
|
403
434
|
valid: !1,
|
|
404
435
|
error: `${n}: object has too many keys (max 10 keys).`
|
|
405
436
|
};
|
|
406
|
-
for (const [
|
|
407
|
-
if (Array.isArray(
|
|
408
|
-
if (
|
|
437
|
+
for (const [c, l] of Object.entries(r)) {
|
|
438
|
+
if (Array.isArray(l)) {
|
|
439
|
+
if (l.length > 10)
|
|
409
440
|
return {
|
|
410
441
|
valid: !1,
|
|
411
|
-
error: `${n}: array property "${
|
|
442
|
+
error: `${n}: array property "${c}" is too large (max 10 items).`
|
|
412
443
|
};
|
|
413
|
-
for (const u of
|
|
444
|
+
for (const u of l)
|
|
414
445
|
if (typeof u == "string" && u.length > 500)
|
|
415
446
|
return {
|
|
416
447
|
valid: !1,
|
|
417
|
-
error: `${n}: array property "${
|
|
448
|
+
error: `${n}: array property "${c}" contains strings that are too long (max 500 characters).`
|
|
418
449
|
};
|
|
419
450
|
}
|
|
420
|
-
if (typeof
|
|
451
|
+
if (typeof l == "string" && l.length > 1e3)
|
|
421
452
|
return {
|
|
422
453
|
valid: !1,
|
|
423
|
-
error: `${n}: property "${
|
|
454
|
+
error: `${n}: property "${c}" is too long (max 1000 characters).`
|
|
424
455
|
};
|
|
425
456
|
}
|
|
426
457
|
return {
|
|
427
458
|
valid: !0,
|
|
428
|
-
sanitizedMetadata:
|
|
459
|
+
sanitizedMetadata: r
|
|
429
460
|
};
|
|
430
|
-
}, nt = (
|
|
461
|
+
}, nt = (s, e, t) => {
|
|
431
462
|
if (Array.isArray(e)) {
|
|
432
|
-
const
|
|
463
|
+
const r = [], n = `${t} "${s}" metadata error`;
|
|
433
464
|
for (let i = 0; i < e.length; i++) {
|
|
434
465
|
const a = e[i];
|
|
435
466
|
if (typeof a != "object" || a === null || Array.isArray(a))
|
|
@@ -437,37 +468,37 @@ const Ue = () => {
|
|
|
437
468
|
valid: !1,
|
|
438
469
|
error: `${n}: array item at index ${i} must be an object.`
|
|
439
470
|
};
|
|
440
|
-
const
|
|
441
|
-
if (!
|
|
471
|
+
const c = Se(s, a, t);
|
|
472
|
+
if (!c.valid)
|
|
442
473
|
return {
|
|
443
474
|
valid: !1,
|
|
444
|
-
error: `${n}: array item at index ${i} is invalid: ${
|
|
475
|
+
error: `${n}: array item at index ${i} is invalid: ${c.error}`
|
|
445
476
|
};
|
|
446
|
-
|
|
477
|
+
c.sanitizedMetadata && r.push(c.sanitizedMetadata);
|
|
447
478
|
}
|
|
448
479
|
return {
|
|
449
480
|
valid: !0,
|
|
450
|
-
sanitizedMetadata:
|
|
481
|
+
sanitizedMetadata: r
|
|
451
482
|
};
|
|
452
483
|
}
|
|
453
|
-
return Se(
|
|
454
|
-
}, it = (
|
|
455
|
-
const t = st(
|
|
484
|
+
return Se(s, e, t);
|
|
485
|
+
}, it = (s, e) => {
|
|
486
|
+
const t = st(s);
|
|
456
487
|
if (!t.valid)
|
|
457
|
-
return
|
|
488
|
+
return o("error", "Event name validation failed", {
|
|
458
489
|
showToClient: !0,
|
|
459
|
-
data: { eventName:
|
|
490
|
+
data: { eventName: s, error: t.error }
|
|
460
491
|
}), t;
|
|
461
492
|
if (!e)
|
|
462
493
|
return { valid: !0 };
|
|
463
|
-
const
|
|
464
|
-
return
|
|
494
|
+
const r = nt(s, e, "customEvent");
|
|
495
|
+
return r.valid || o("error", "Event metadata validation failed", {
|
|
465
496
|
showToClient: !0,
|
|
466
497
|
data: {
|
|
467
|
-
eventName:
|
|
468
|
-
error:
|
|
498
|
+
eventName: s,
|
|
499
|
+
error: r.error
|
|
469
500
|
}
|
|
470
|
-
}),
|
|
501
|
+
}), r;
|
|
471
502
|
};
|
|
472
503
|
class at {
|
|
473
504
|
listeners = /* @__PURE__ */ new Map();
|
|
@@ -475,15 +506,15 @@ class at {
|
|
|
475
506
|
this.listeners.has(e) || this.listeners.set(e, []), this.listeners.get(e).push(t);
|
|
476
507
|
}
|
|
477
508
|
off(e, t) {
|
|
478
|
-
const
|
|
479
|
-
if (
|
|
480
|
-
const n =
|
|
481
|
-
n > -1 &&
|
|
509
|
+
const r = this.listeners.get(e);
|
|
510
|
+
if (r) {
|
|
511
|
+
const n = r.indexOf(t);
|
|
512
|
+
n > -1 && r.splice(n, 1);
|
|
482
513
|
}
|
|
483
514
|
}
|
|
484
515
|
emit(e, t) {
|
|
485
|
-
const
|
|
486
|
-
|
|
516
|
+
const r = this.listeners.get(e);
|
|
517
|
+
r && r.forEach((n) => n(t));
|
|
487
518
|
}
|
|
488
519
|
removeAllListeners() {
|
|
489
520
|
this.listeners.clear();
|
|
@@ -516,17 +547,17 @@ class ot extends f {
|
|
|
516
547
|
sendEventsQueueSync(e) {
|
|
517
548
|
if (this.shouldSkipSend())
|
|
518
549
|
return this.resetRetryState(), !0;
|
|
519
|
-
if (this.get("config")?.integrations?.custom?.apiUrl ===
|
|
520
|
-
return
|
|
550
|
+
if (this.get("config")?.integrations?.custom?.apiUrl === j.Fail)
|
|
551
|
+
return o("warn", "Fail mode: simulating network failure (sync)", {
|
|
521
552
|
data: { events: e.events.length }
|
|
522
553
|
}), !1;
|
|
523
|
-
const
|
|
524
|
-
return
|
|
554
|
+
const r = this.sendQueueSyncInternal(e);
|
|
555
|
+
return r && this.resetRetryState(), r;
|
|
525
556
|
}
|
|
526
557
|
async sendEventsQueue(e, t) {
|
|
527
|
-
this.shouldSkipSend() || this.persistEvents(e) ||
|
|
528
|
-
const
|
|
529
|
-
return
|
|
558
|
+
this.shouldSkipSend() || this.persistEvents(e) || o("warn", "Failed to persist events, attempting immediate send");
|
|
559
|
+
const r = await this.send(e);
|
|
560
|
+
return r ? (this.clearPersistedEvents(), this.resetRetryState(), t?.onSuccess?.(e.events.length, e.events, e)) : (this.scheduleRetry(e, t), t?.onFailure?.()), r;
|
|
530
561
|
}
|
|
531
562
|
async recoverPersistedEvents(e) {
|
|
532
563
|
try {
|
|
@@ -535,10 +566,10 @@ class ot extends f {
|
|
|
535
566
|
this.clearPersistedEvents();
|
|
536
567
|
return;
|
|
537
568
|
}
|
|
538
|
-
const
|
|
539
|
-
await this.send(
|
|
569
|
+
const r = this.createRecoveryBody(t);
|
|
570
|
+
await this.send(r) ? (this.clearPersistedEvents(), this.resetRetryState(), e?.onSuccess?.(t.events.length, t.events, r)) : (this.scheduleRetry(r, e), e?.onFailure?.());
|
|
540
571
|
} catch (t) {
|
|
541
|
-
|
|
572
|
+
o("error", "Failed to recover persisted events", { error: t }), this.clearPersistedEvents();
|
|
542
573
|
}
|
|
543
574
|
}
|
|
544
575
|
persistEventsForRecovery(e) {
|
|
@@ -553,32 +584,32 @@ class ot extends f {
|
|
|
553
584
|
async send(e) {
|
|
554
585
|
if (this.shouldSkipSend())
|
|
555
586
|
return this.simulateSuccessfulSend();
|
|
556
|
-
if (this.get("config")?.integrations?.custom?.apiUrl ===
|
|
557
|
-
return
|
|
587
|
+
if (this.get("config")?.integrations?.custom?.apiUrl === j.Fail)
|
|
588
|
+
return o("warn", "Fail mode: simulating network failure", {
|
|
558
589
|
data: { events: e.events.length }
|
|
559
590
|
}), !1;
|
|
560
|
-
const { url:
|
|
591
|
+
const { url: r, payload: n } = this.prepareRequest(e);
|
|
561
592
|
try {
|
|
562
|
-
return (await this.sendWithTimeout(
|
|
593
|
+
return (await this.sendWithTimeout(r, n)).ok;
|
|
563
594
|
} catch (i) {
|
|
564
|
-
return
|
|
595
|
+
return o("error", "Send request failed", {
|
|
565
596
|
error: i,
|
|
566
597
|
data: {
|
|
567
598
|
events: e.events.length,
|
|
568
|
-
url:
|
|
599
|
+
url: r.replace(/\/\/[^/]+/, "//[DOMAIN]")
|
|
569
600
|
}
|
|
570
601
|
}), !1;
|
|
571
602
|
}
|
|
572
603
|
}
|
|
573
604
|
async sendWithTimeout(e, t) {
|
|
574
|
-
const
|
|
605
|
+
const r = new AbortController(), n = setTimeout(() => r.abort(), 1e4);
|
|
575
606
|
try {
|
|
576
607
|
const i = await fetch(e, {
|
|
577
608
|
method: "POST",
|
|
578
609
|
body: t,
|
|
579
610
|
keepalive: !0,
|
|
580
611
|
credentials: "include",
|
|
581
|
-
signal:
|
|
612
|
+
signal: r.signal,
|
|
582
613
|
headers: {
|
|
583
614
|
"Content-Type": "application/json"
|
|
584
615
|
}
|
|
@@ -591,17 +622,17 @@ class ot extends f {
|
|
|
591
622
|
}
|
|
592
623
|
}
|
|
593
624
|
sendQueueSyncInternal(e) {
|
|
594
|
-
const { url: t, payload:
|
|
625
|
+
const { url: t, payload: r } = this.prepareRequest(e), n = new Blob([r], { type: "application/json" });
|
|
595
626
|
if (this.isSendBeaconAvailable()) {
|
|
596
627
|
if (navigator.sendBeacon(t, n))
|
|
597
628
|
return !0;
|
|
598
|
-
|
|
629
|
+
o("warn", "sendBeacon failed, persisting events for recovery");
|
|
599
630
|
} else
|
|
600
|
-
|
|
631
|
+
o("warn", "sendBeacon not available, persisting events for recovery");
|
|
601
632
|
return this.persistEventsForRecovery(e), !1;
|
|
602
633
|
}
|
|
603
634
|
prepareRequest(e) {
|
|
604
|
-
const t = `${this.get("apiUrl")}/collect`,
|
|
635
|
+
const t = `${this.get("apiUrl")}/collect`, r = {
|
|
605
636
|
...e,
|
|
606
637
|
_metadata: {
|
|
607
638
|
referer: typeof window < "u" ? window.location.href : void 0,
|
|
@@ -610,7 +641,7 @@ class ot extends f {
|
|
|
610
641
|
};
|
|
611
642
|
return {
|
|
612
643
|
url: t,
|
|
613
|
-
payload: JSON.stringify(
|
|
644
|
+
payload: JSON.stringify(r)
|
|
614
645
|
};
|
|
615
646
|
}
|
|
616
647
|
getPersistedData() {
|
|
@@ -619,7 +650,7 @@ class ot extends f {
|
|
|
619
650
|
if (t)
|
|
620
651
|
return JSON.parse(t);
|
|
621
652
|
} catch (e) {
|
|
622
|
-
|
|
653
|
+
o("warn", "Failed to parse persisted data", { error: e }), this.clearPersistedEvents();
|
|
623
654
|
}
|
|
624
655
|
return null;
|
|
625
656
|
}
|
|
@@ -644,10 +675,10 @@ class ot extends f {
|
|
|
644
675
|
events: e.events,
|
|
645
676
|
timestamp: Date.now(),
|
|
646
677
|
...e.global_metadata && { global_metadata: e.global_metadata }
|
|
647
|
-
},
|
|
648
|
-
return this.storeManager.setItem(
|
|
678
|
+
}, r = this.getQueueStorageKey();
|
|
679
|
+
return this.storeManager.setItem(r, JSON.stringify(t)), !!this.storeManager.getItem(r);
|
|
649
680
|
} catch (t) {
|
|
650
|
-
return
|
|
681
|
+
return o("warn", "Failed to persist events", { error: t }), !1;
|
|
651
682
|
}
|
|
652
683
|
}
|
|
653
684
|
clearPersistedEvents() {
|
|
@@ -655,7 +686,7 @@ class ot extends f {
|
|
|
655
686
|
const e = this.getQueueStorageKey();
|
|
656
687
|
this.storeManager.removeItem(e);
|
|
657
688
|
} catch (e) {
|
|
658
|
-
|
|
689
|
+
o("warn", "Failed to clear persisted events", { error: e });
|
|
659
690
|
}
|
|
660
691
|
}
|
|
661
692
|
resetRetryState() {
|
|
@@ -665,10 +696,10 @@ class ot extends f {
|
|
|
665
696
|
if (this.retryTimeoutId !== null || this.isRetrying)
|
|
666
697
|
return;
|
|
667
698
|
if (this.retryCount >= 3) {
|
|
668
|
-
|
|
699
|
+
o("warn", "Max retries reached, giving up", { data: { retryCount: this.retryCount } }), this.clearPersistedEvents(), this.resetRetryState(), t?.onFailure?.();
|
|
669
700
|
return;
|
|
670
701
|
}
|
|
671
|
-
const
|
|
702
|
+
const r = 5e3 * Math.pow(2, this.retryCount);
|
|
672
703
|
this.isRetrying = !0, this.retryTimeoutId = window.setTimeout(async () => {
|
|
673
704
|
this.retryTimeoutId = null, this.retryCount++;
|
|
674
705
|
try {
|
|
@@ -676,7 +707,7 @@ class ot extends f {
|
|
|
676
707
|
} finally {
|
|
677
708
|
this.isRetrying = !1;
|
|
678
709
|
}
|
|
679
|
-
},
|
|
710
|
+
}, r);
|
|
680
711
|
}
|
|
681
712
|
shouldSkipSend() {
|
|
682
713
|
return !this.get("apiUrl");
|
|
@@ -692,7 +723,7 @@ class ot extends f {
|
|
|
692
723
|
this.retryTimeoutId !== null && (clearTimeout(this.retryTimeoutId), this.retryTimeoutId = null);
|
|
693
724
|
}
|
|
694
725
|
}
|
|
695
|
-
class
|
|
726
|
+
class ct extends f {
|
|
696
727
|
googleAnalytics;
|
|
697
728
|
dataSender;
|
|
698
729
|
emitter;
|
|
@@ -701,91 +732,98 @@ class lt extends f {
|
|
|
701
732
|
lastEventFingerprint = null;
|
|
702
733
|
lastEventTime = 0;
|
|
703
734
|
sendIntervalId = null;
|
|
704
|
-
|
|
705
|
-
|
|
735
|
+
rateLimitCounter = 0;
|
|
736
|
+
rateLimitWindowStart = 0;
|
|
737
|
+
constructor(e, t = null, r = null) {
|
|
738
|
+
super(), this.googleAnalytics = t, this.dataSender = new ot(e), this.emitter = r;
|
|
706
739
|
}
|
|
707
740
|
async recoverPersistedEvents() {
|
|
708
741
|
await this.dataSender.recoverPersistedEvents({
|
|
709
|
-
onSuccess: (e, t,
|
|
742
|
+
onSuccess: (e, t, r) => {
|
|
710
743
|
if (t && t.length > 0) {
|
|
711
744
|
const n = t.map((i) => i.id);
|
|
712
|
-
this.removeProcessedEvents(n),
|
|
745
|
+
this.removeProcessedEvents(n), r && this.emitEventsQueue(r);
|
|
713
746
|
}
|
|
714
747
|
},
|
|
715
748
|
onFailure: async () => {
|
|
716
|
-
|
|
749
|
+
o("warn", "Failed to recover persisted events");
|
|
717
750
|
}
|
|
718
751
|
});
|
|
719
752
|
}
|
|
720
753
|
track({
|
|
721
754
|
type: e,
|
|
722
755
|
page_url: t,
|
|
723
|
-
from_page_url:
|
|
756
|
+
from_page_url: r,
|
|
724
757
|
scroll_data: n,
|
|
725
758
|
click_data: i,
|
|
726
759
|
custom_event: a,
|
|
727
|
-
web_vitals:
|
|
728
|
-
error_data:
|
|
760
|
+
web_vitals: c,
|
|
761
|
+
error_data: l,
|
|
729
762
|
session_end_reason: u
|
|
730
763
|
}) {
|
|
731
764
|
if (!e) {
|
|
732
|
-
|
|
765
|
+
o("error", "Event type is required - event will be ignored");
|
|
733
766
|
return;
|
|
734
767
|
}
|
|
735
768
|
if (!this.get("sessionId")) {
|
|
736
|
-
this.pendingEventsBuffer.
|
|
769
|
+
this.pendingEventsBuffer.length >= 100 && (this.pendingEventsBuffer.shift(), o("warn", "Pending events buffer full - dropping oldest event", {
|
|
770
|
+
data: { maxBufferSize: 100 }
|
|
771
|
+
})), this.pendingEventsBuffer.push({
|
|
737
772
|
type: e,
|
|
738
773
|
page_url: t,
|
|
739
|
-
from_page_url:
|
|
774
|
+
from_page_url: r,
|
|
740
775
|
scroll_data: n,
|
|
741
776
|
click_data: i,
|
|
742
777
|
custom_event: a,
|
|
743
|
-
web_vitals:
|
|
744
|
-
error_data:
|
|
778
|
+
web_vitals: c,
|
|
779
|
+
error_data: l,
|
|
745
780
|
session_end_reason: u
|
|
746
781
|
});
|
|
747
782
|
return;
|
|
748
783
|
}
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
784
|
+
const p = e === d.SESSION_START || e === d.SESSION_END;
|
|
785
|
+
if (!p && !this.checkRateLimit())
|
|
786
|
+
return;
|
|
787
|
+
const N = e, Le = N === d.SESSION_START, Re = t || this.get("pageUrl"), z = this.buildEventPayload({
|
|
788
|
+
type: N,
|
|
789
|
+
page_url: Re,
|
|
790
|
+
from_page_url: r,
|
|
753
791
|
scroll_data: n,
|
|
754
792
|
click_data: i,
|
|
755
793
|
custom_event: a,
|
|
756
|
-
web_vitals:
|
|
757
|
-
error_data:
|
|
794
|
+
web_vitals: c,
|
|
795
|
+
error_data: l,
|
|
758
796
|
session_end_reason: u
|
|
759
797
|
});
|
|
760
|
-
if (!(!
|
|
761
|
-
if (
|
|
798
|
+
if (!(!p && !this.shouldSample())) {
|
|
799
|
+
if (Le) {
|
|
762
800
|
const ae = this.get("sessionId");
|
|
763
801
|
if (!ae) {
|
|
764
|
-
|
|
802
|
+
o("error", "Session start event requires sessionId - event will be ignored");
|
|
765
803
|
return;
|
|
766
804
|
}
|
|
767
805
|
if (this.get("hasStartSession")) {
|
|
768
|
-
|
|
806
|
+
o("warn", "Duplicate session_start detected", {
|
|
769
807
|
data: { sessionId: ae }
|
|
770
808
|
});
|
|
771
809
|
return;
|
|
772
810
|
}
|
|
773
811
|
this.set("hasStartSession", !0);
|
|
774
812
|
}
|
|
775
|
-
if (!this.isDuplicateEvent(
|
|
776
|
-
if (this.get("mode") === R.QA &&
|
|
813
|
+
if (!this.isDuplicateEvent(z)) {
|
|
814
|
+
if (this.get("mode") === R.QA && N === d.CUSTOM && a) {
|
|
777
815
|
console.log("[TraceLog] Event", {
|
|
778
816
|
name: a.name,
|
|
779
817
|
...a.metadata && { metadata: a.metadata }
|
|
780
|
-
}), this.emitEvent(
|
|
818
|
+
}), this.emitEvent(z);
|
|
781
819
|
return;
|
|
782
820
|
}
|
|
783
|
-
this.addToQueue(
|
|
821
|
+
this.addToQueue(z);
|
|
784
822
|
}
|
|
785
823
|
}
|
|
786
824
|
}
|
|
787
825
|
stop() {
|
|
788
|
-
this.sendIntervalId && (clearInterval(this.sendIntervalId), this.sendIntervalId = null), this.eventsQueue = [], this.pendingEventsBuffer = [], this.lastEventFingerprint = null, this.lastEventTime = 0, this.dataSender.stop();
|
|
826
|
+
this.sendIntervalId && (clearInterval(this.sendIntervalId), this.sendIntervalId = null), this.eventsQueue = [], this.pendingEventsBuffer = [], this.lastEventFingerprint = null, this.lastEventTime = 0, this.rateLimitCounter = 0, this.rateLimitWindowStart = 0, this.dataSender.stop();
|
|
789
827
|
}
|
|
790
828
|
async flushImmediately() {
|
|
791
829
|
return this.flushEvents(!1);
|
|
@@ -800,12 +838,14 @@ class lt extends f {
|
|
|
800
838
|
if (this.pendingEventsBuffer.length === 0)
|
|
801
839
|
return;
|
|
802
840
|
if (!this.get("sessionId")) {
|
|
803
|
-
|
|
841
|
+
o("warn", "Cannot flush pending events: session not initialized - keeping in buffer", {
|
|
842
|
+
data: { bufferedEventCount: this.pendingEventsBuffer.length }
|
|
843
|
+
});
|
|
804
844
|
return;
|
|
805
845
|
}
|
|
806
|
-
const
|
|
807
|
-
this.pendingEventsBuffer = [],
|
|
808
|
-
this.track(
|
|
846
|
+
const t = [...this.pendingEventsBuffer];
|
|
847
|
+
this.pendingEventsBuffer = [], t.forEach((r) => {
|
|
848
|
+
this.track(r);
|
|
809
849
|
});
|
|
810
850
|
}
|
|
811
851
|
clearSendInterval() {
|
|
@@ -814,7 +854,7 @@ class lt extends f {
|
|
|
814
854
|
flushEvents(e) {
|
|
815
855
|
if (this.eventsQueue.length === 0)
|
|
816
856
|
return e ? !0 : Promise.resolve(!0);
|
|
817
|
-
const t = this.buildEventsPayload(),
|
|
857
|
+
const t = this.buildEventsPayload(), r = [...this.eventsQueue], n = r.map((i) => i.id);
|
|
818
858
|
if (e) {
|
|
819
859
|
const i = this.dataSender.sendEventsQueueSync(t);
|
|
820
860
|
return i && (this.removeProcessedEvents(n), this.clearSendInterval(), this.emitEventsQueue(t)), i;
|
|
@@ -824,8 +864,8 @@ class lt extends f {
|
|
|
824
864
|
this.removeProcessedEvents(n), this.clearSendInterval(), this.emitEventsQueue(t);
|
|
825
865
|
},
|
|
826
866
|
onFailure: () => {
|
|
827
|
-
|
|
828
|
-
data: { eventCount:
|
|
867
|
+
o("warn", "Async flush failed", {
|
|
868
|
+
data: { eventCount: r.length }
|
|
829
869
|
});
|
|
830
870
|
}
|
|
831
871
|
});
|
|
@@ -833,13 +873,13 @@ class lt extends f {
|
|
|
833
873
|
async sendEventsQueue() {
|
|
834
874
|
if (!this.get("sessionId") || this.eventsQueue.length === 0)
|
|
835
875
|
return;
|
|
836
|
-
const e = this.buildEventsPayload(), t = [...this.eventsQueue],
|
|
876
|
+
const e = this.buildEventsPayload(), t = [...this.eventsQueue], r = t.map((n) => n.id);
|
|
837
877
|
await this.dataSender.sendEventsQueue(e, {
|
|
838
878
|
onSuccess: () => {
|
|
839
|
-
this.removeProcessedEvents(
|
|
879
|
+
this.removeProcessedEvents(r), this.emitEventsQueue(e);
|
|
840
880
|
},
|
|
841
881
|
onFailure: async () => {
|
|
842
|
-
|
|
882
|
+
o("warn", "Events send failed, keeping in queue", {
|
|
843
883
|
data: { eventCount: t.length }
|
|
844
884
|
});
|
|
845
885
|
}
|
|
@@ -851,21 +891,21 @@ class lt extends f {
|
|
|
851
891
|
const i = this.createEventSignature(n);
|
|
852
892
|
e.has(i) || t.push(i), e.set(i, n);
|
|
853
893
|
}
|
|
854
|
-
const
|
|
894
|
+
const r = t.map((n) => e.get(n)).filter((n) => !!n).sort((n, i) => n.timestamp - i.timestamp);
|
|
855
895
|
return {
|
|
856
896
|
user_id: this.get("userId"),
|
|
857
897
|
session_id: this.get("sessionId"),
|
|
858
898
|
device: this.get("device"),
|
|
859
|
-
events:
|
|
899
|
+
events: r,
|
|
860
900
|
...this.get("config")?.globalMetadata && { global_metadata: this.get("config")?.globalMetadata }
|
|
861
901
|
};
|
|
862
902
|
}
|
|
863
903
|
buildEventPayload(e) {
|
|
864
|
-
const t = e.type === d.SESSION_START,
|
|
904
|
+
const t = e.type === d.SESSION_START, r = e.page_url ?? this.get("pageUrl");
|
|
865
905
|
return {
|
|
866
906
|
id: Xe(),
|
|
867
907
|
type: e.type,
|
|
868
|
-
page_url:
|
|
908
|
+
page_url: r,
|
|
869
909
|
timestamp: Date.now(),
|
|
870
910
|
...t && { referrer: document.referrer || "Direct" },
|
|
871
911
|
...e.from_page_url && { from_page_url: e.from_page_url },
|
|
@@ -879,14 +919,14 @@ class lt extends f {
|
|
|
879
919
|
};
|
|
880
920
|
}
|
|
881
921
|
isDuplicateEvent(e) {
|
|
882
|
-
const t = Date.now(),
|
|
883
|
-
return this.lastEventFingerprint ===
|
|
922
|
+
const t = Date.now(), r = this.createEventFingerprint(e);
|
|
923
|
+
return this.lastEventFingerprint === r && t - this.lastEventTime < 500 ? !0 : (this.lastEventFingerprint = r, this.lastEventTime = t, !1);
|
|
884
924
|
}
|
|
885
925
|
createEventFingerprint(e) {
|
|
886
926
|
let t = `${e.type}_${e.page_url}`;
|
|
887
927
|
if (e.click_data) {
|
|
888
|
-
const
|
|
889
|
-
t += `_click_${
|
|
928
|
+
const r = Math.round((e.click_data.x || 0) / 10) * 10, n = Math.round((e.click_data.y || 0) / 10) * 10;
|
|
929
|
+
t += `_click_${r}_${n}`;
|
|
890
930
|
}
|
|
891
931
|
return e.scroll_data && (t += `_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`), e.custom_event && (t += `_custom_${e.custom_event.name}`), e.web_vitals && (t += `_vitals_${e.web_vitals.type}`), e.error_data && (t += `_error_${e.error_data.type}_${e.error_data.message}`), t;
|
|
892
932
|
}
|
|
@@ -897,13 +937,13 @@ class lt extends f {
|
|
|
897
937
|
if (this.eventsQueue.push(e), this.emitEvent(e), this.eventsQueue.length > 100) {
|
|
898
938
|
const t = this.eventsQueue.findIndex(
|
|
899
939
|
(n) => n.type !== d.SESSION_START && n.type !== d.SESSION_END
|
|
900
|
-
),
|
|
901
|
-
|
|
940
|
+
), r = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
|
|
941
|
+
o("warn", "Event queue overflow, oldest non-critical event removed", {
|
|
902
942
|
data: {
|
|
903
943
|
maxLength: 100,
|
|
904
944
|
currentLength: this.eventsQueue.length,
|
|
905
|
-
removedEventType:
|
|
906
|
-
wasCritical:
|
|
945
|
+
removedEventType: r?.type,
|
|
946
|
+
wasCritical: r?.type === d.SESSION_START || r?.type === d.SESSION_END
|
|
907
947
|
}
|
|
908
948
|
});
|
|
909
949
|
}
|
|
@@ -925,9 +965,13 @@ class lt extends f {
|
|
|
925
965
|
const e = this.get("config")?.samplingRate ?? 1;
|
|
926
966
|
return Math.random() < e;
|
|
927
967
|
}
|
|
968
|
+
checkRateLimit() {
|
|
969
|
+
const e = Date.now();
|
|
970
|
+
return e - this.rateLimitWindowStart > 1e3 && (this.rateLimitCounter = 0, this.rateLimitWindowStart = e), this.rateLimitCounter >= 200 ? !1 : (this.rateLimitCounter++, !0);
|
|
971
|
+
}
|
|
928
972
|
removeProcessedEvents(e) {
|
|
929
973
|
const t = new Set(e);
|
|
930
|
-
this.eventsQueue = this.eventsQueue.filter((
|
|
974
|
+
this.eventsQueue = this.eventsQueue.filter((r) => !t.has(r.id));
|
|
931
975
|
}
|
|
932
976
|
emitEvent(e) {
|
|
933
977
|
this.emitter && this.emitter.emit(X.EVENT, e);
|
|
@@ -936,7 +980,7 @@ class lt extends f {
|
|
|
936
980
|
this.emitter && this.emitter.emit(X.QUEUE, e);
|
|
937
981
|
}
|
|
938
982
|
}
|
|
939
|
-
class
|
|
983
|
+
class lt {
|
|
940
984
|
/**
|
|
941
985
|
* Gets or creates a unique user ID for the given project.
|
|
942
986
|
* The user ID is persisted in localStorage and reused across sessions.
|
|
@@ -946,10 +990,10 @@ class ct {
|
|
|
946
990
|
* @returns Persistent unique user ID
|
|
947
991
|
*/
|
|
948
992
|
static getId(e) {
|
|
949
|
-
const t = xe,
|
|
950
|
-
if (
|
|
951
|
-
return
|
|
952
|
-
const n =
|
|
993
|
+
const t = xe, r = e.getItem(t);
|
|
994
|
+
if (r)
|
|
995
|
+
return r;
|
|
996
|
+
const n = je();
|
|
953
997
|
return e.setItem(t, n), n;
|
|
954
998
|
}
|
|
955
999
|
}
|
|
@@ -963,19 +1007,19 @@ class ut extends f {
|
|
|
963
1007
|
visibilityChangeHandler = null;
|
|
964
1008
|
beforeUnloadHandler = null;
|
|
965
1009
|
isTracking = !1;
|
|
966
|
-
constructor(e, t,
|
|
967
|
-
super(), this.storageManager = e, this.eventManager = t, this.projectId =
|
|
1010
|
+
constructor(e, t, r) {
|
|
1011
|
+
super(), this.storageManager = e, this.eventManager = t, this.projectId = r;
|
|
968
1012
|
}
|
|
969
1013
|
initCrossTabSync() {
|
|
970
1014
|
if (typeof BroadcastChannel > "u") {
|
|
971
|
-
|
|
1015
|
+
o("warn", "BroadcastChannel not supported");
|
|
972
1016
|
return;
|
|
973
1017
|
}
|
|
974
1018
|
const e = this.getProjectId();
|
|
975
1019
|
this.broadcastChannel = new BroadcastChannel(Ge(e)), this.broadcastChannel.onmessage = (t) => {
|
|
976
|
-
const { action:
|
|
1020
|
+
const { action: r, sessionId: n, timestamp: i, projectId: a } = t.data ?? {};
|
|
977
1021
|
if (a === e) {
|
|
978
|
-
if (
|
|
1022
|
+
if (r === "session_end") {
|
|
979
1023
|
this.resetSessionState();
|
|
980
1024
|
return;
|
|
981
1025
|
}
|
|
@@ -1025,8 +1069,8 @@ class ut extends f {
|
|
|
1025
1069
|
if (!t)
|
|
1026
1070
|
return null;
|
|
1027
1071
|
try {
|
|
1028
|
-
const
|
|
1029
|
-
return !
|
|
1072
|
+
const r = JSON.parse(t);
|
|
1073
|
+
return !r.id || typeof r.lastActivity != "number" ? null : r;
|
|
1030
1074
|
} catch {
|
|
1031
1075
|
return this.storageManager.removeItem(e), null;
|
|
1032
1076
|
}
|
|
@@ -1043,13 +1087,13 @@ class ut extends f {
|
|
|
1043
1087
|
}
|
|
1044
1088
|
async startTracking() {
|
|
1045
1089
|
if (this.isTracking) {
|
|
1046
|
-
|
|
1090
|
+
o("warn", "Session tracking already active");
|
|
1047
1091
|
return;
|
|
1048
1092
|
}
|
|
1049
|
-
const e = this.recoverSession(), t = e ?? this.generateSessionId(),
|
|
1093
|
+
const e = this.recoverSession(), t = e ?? this.generateSessionId(), r = !!e;
|
|
1050
1094
|
this.isTracking = !0;
|
|
1051
1095
|
try {
|
|
1052
|
-
this.set("sessionId", t), this.persistSession(t),
|
|
1096
|
+
this.set("sessionId", t), this.persistSession(t), r || this.eventManager.track({
|
|
1053
1097
|
type: d.SESSION_START
|
|
1054
1098
|
}), this.initCrossTabSync(), this.shareSession(t), this.setupSessionTimeout(), this.setupActivityListeners(), this.setupLifecycleListeners();
|
|
1055
1099
|
} catch (n) {
|
|
@@ -1093,24 +1137,24 @@ class ut extends f {
|
|
|
1093
1137
|
async endSession(e) {
|
|
1094
1138
|
const t = this.get("sessionId");
|
|
1095
1139
|
if (!t) {
|
|
1096
|
-
|
|
1140
|
+
o("warn", "endSession called without active session", { data: { reason: e } }), this.resetSessionState(e);
|
|
1097
1141
|
return;
|
|
1098
1142
|
}
|
|
1099
1143
|
this.eventManager.track({
|
|
1100
1144
|
type: d.SESSION_END,
|
|
1101
1145
|
session_end_reason: e
|
|
1102
1146
|
});
|
|
1103
|
-
const
|
|
1147
|
+
const r = () => {
|
|
1104
1148
|
this.broadcastSessionEnd(t, e), this.resetSessionState(e);
|
|
1105
1149
|
};
|
|
1106
1150
|
if (this.eventManager.flushImmediatelySync()) {
|
|
1107
|
-
|
|
1151
|
+
r();
|
|
1108
1152
|
return;
|
|
1109
1153
|
}
|
|
1110
1154
|
try {
|
|
1111
|
-
await this.eventManager.flushImmediately(),
|
|
1155
|
+
await this.eventManager.flushImmediately(), r();
|
|
1112
1156
|
} catch (i) {
|
|
1113
|
-
|
|
1157
|
+
o("warn", "Async flush failed during session end", { error: i }), r();
|
|
1114
1158
|
}
|
|
1115
1159
|
}
|
|
1116
1160
|
resetSessionState(e) {
|
|
@@ -1135,7 +1179,7 @@ class dt extends f {
|
|
|
1135
1179
|
if (this.isActive())
|
|
1136
1180
|
return;
|
|
1137
1181
|
if (this.destroyed) {
|
|
1138
|
-
|
|
1182
|
+
o("warn", "Cannot start tracking on destroyed handler");
|
|
1139
1183
|
return;
|
|
1140
1184
|
}
|
|
1141
1185
|
const e = this.get("config"), t = e?.integrations?.tracelog?.projectId ?? e?.integrations?.custom?.apiUrl ?? "default";
|
|
@@ -1143,7 +1187,7 @@ class dt extends f {
|
|
|
1143
1187
|
throw new Error("Cannot start session tracking: config not available");
|
|
1144
1188
|
try {
|
|
1145
1189
|
this.sessionManager = new ut(this.storageManager, this.eventManager, t), await this.sessionManager.startTracking(), this.eventManager.flushPendingEvents();
|
|
1146
|
-
} catch (
|
|
1190
|
+
} catch (r) {
|
|
1147
1191
|
if (this.sessionManager) {
|
|
1148
1192
|
try {
|
|
1149
1193
|
this.sessionManager.destroy();
|
|
@@ -1151,7 +1195,7 @@ class dt extends f {
|
|
|
1151
1195
|
}
|
|
1152
1196
|
this.sessionManager = null;
|
|
1153
1197
|
}
|
|
1154
|
-
throw
|
|
1198
|
+
throw o("error", "Failed to start session tracking", { error: r }), r;
|
|
1155
1199
|
}
|
|
1156
1200
|
}
|
|
1157
1201
|
isActive() {
|
|
@@ -1183,27 +1227,27 @@ class ht extends f {
|
|
|
1183
1227
|
}
|
|
1184
1228
|
patchHistory(e) {
|
|
1185
1229
|
const t = window.history[e];
|
|
1186
|
-
e === "pushState" && !this.originalPushState ? this.originalPushState = t : e === "replaceState" && !this.originalReplaceState && (this.originalReplaceState = t), window.history[e] = (...
|
|
1187
|
-
t.apply(window.history,
|
|
1230
|
+
e === "pushState" && !this.originalPushState ? this.originalPushState = t : e === "replaceState" && !this.originalReplaceState && (this.originalReplaceState = t), window.history[e] = (...r) => {
|
|
1231
|
+
t.apply(window.history, r), this.trackCurrentPage();
|
|
1188
1232
|
};
|
|
1189
1233
|
}
|
|
1190
1234
|
trackCurrentPage = async () => {
|
|
1191
|
-
const e = window.location.href, t =
|
|
1235
|
+
const e = window.location.href, t = Y(e, this.get("config").sensitiveQueryParams);
|
|
1192
1236
|
if (this.get("pageUrl") === t)
|
|
1193
1237
|
return;
|
|
1194
1238
|
this.onTrack();
|
|
1195
|
-
const
|
|
1239
|
+
const r = this.get("pageUrl");
|
|
1196
1240
|
this.set("pageUrl", t);
|
|
1197
1241
|
const n = this.extractPageViewData();
|
|
1198
1242
|
this.eventManager.track({
|
|
1199
1243
|
type: d.PAGE_VIEW,
|
|
1200
1244
|
page_url: this.get("pageUrl"),
|
|
1201
|
-
from_page_url:
|
|
1245
|
+
from_page_url: r,
|
|
1202
1246
|
...n && { page_view: n }
|
|
1203
1247
|
});
|
|
1204
1248
|
};
|
|
1205
1249
|
trackInitialPageView() {
|
|
1206
|
-
const e =
|
|
1250
|
+
const e = Y(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
|
|
1207
1251
|
this.eventManager.track({
|
|
1208
1252
|
type: d.PAGE_VIEW,
|
|
1209
1253
|
page_url: e,
|
|
@@ -1211,13 +1255,13 @@ class ht extends f {
|
|
|
1211
1255
|
}), this.onTrack();
|
|
1212
1256
|
}
|
|
1213
1257
|
extractPageViewData() {
|
|
1214
|
-
const { pathname: e, search: t, hash:
|
|
1215
|
-
return !n && !i && !e && !t && !
|
|
1258
|
+
const { pathname: e, search: t, hash: r } = window.location, { referrer: n } = document, { title: i } = document;
|
|
1259
|
+
return !n && !i && !e && !t && !r ? void 0 : {
|
|
1216
1260
|
...n && { referrer: n },
|
|
1217
1261
|
...i && { title: i },
|
|
1218
1262
|
...e && { pathname: e },
|
|
1219
1263
|
...t && { search: t },
|
|
1220
|
-
...
|
|
1264
|
+
...r && { hash: r }
|
|
1221
1265
|
};
|
|
1222
1266
|
}
|
|
1223
1267
|
}
|
|
@@ -1229,29 +1273,29 @@ class ft extends f {
|
|
|
1229
1273
|
}
|
|
1230
1274
|
startTracking() {
|
|
1231
1275
|
this.clickHandler || (this.clickHandler = (e) => {
|
|
1232
|
-
const t = e,
|
|
1276
|
+
const t = e, r = t.target, n = r instanceof HTMLElement ? r : r instanceof Node && r.parentElement instanceof HTMLElement ? r.parentElement : null;
|
|
1233
1277
|
if (!n) {
|
|
1234
|
-
|
|
1278
|
+
o("warn", "Click target not found or not an element");
|
|
1235
1279
|
return;
|
|
1236
1280
|
}
|
|
1237
|
-
const i = this.findTrackingElement(n), a = this.getRelevantClickElement(n),
|
|
1281
|
+
const i = this.findTrackingElement(n), a = this.getRelevantClickElement(n), c = this.calculateClickCoordinates(t, n);
|
|
1238
1282
|
if (i) {
|
|
1239
1283
|
const u = this.extractTrackingData(i);
|
|
1240
1284
|
if (u) {
|
|
1241
|
-
const
|
|
1285
|
+
const p = this.createCustomEventData(u);
|
|
1242
1286
|
this.eventManager.track({
|
|
1243
1287
|
type: d.CUSTOM,
|
|
1244
1288
|
custom_event: {
|
|
1245
|
-
name:
|
|
1246
|
-
...
|
|
1289
|
+
name: p.name,
|
|
1290
|
+
...p.value && { metadata: { value: p.value } }
|
|
1247
1291
|
}
|
|
1248
1292
|
});
|
|
1249
1293
|
}
|
|
1250
1294
|
}
|
|
1251
|
-
const
|
|
1295
|
+
const l = this.generateClickData(n, a, c);
|
|
1252
1296
|
this.eventManager.track({
|
|
1253
1297
|
type: d.CLICK,
|
|
1254
|
-
click_data:
|
|
1298
|
+
click_data: l
|
|
1255
1299
|
});
|
|
1256
1300
|
}, window.addEventListener("click", this.clickHandler, !0));
|
|
1257
1301
|
}
|
|
@@ -1262,15 +1306,15 @@ class ft extends f {
|
|
|
1262
1306
|
return e.hasAttribute(`${O}-name`) ? e : e.closest(`[${O}-name]`) || void 0;
|
|
1263
1307
|
}
|
|
1264
1308
|
getRelevantClickElement(e) {
|
|
1265
|
-
for (const t of
|
|
1309
|
+
for (const t of Ce)
|
|
1266
1310
|
try {
|
|
1267
1311
|
if (e.matches(t))
|
|
1268
1312
|
return e;
|
|
1269
|
-
const
|
|
1270
|
-
if (
|
|
1271
|
-
return
|
|
1272
|
-
} catch (
|
|
1273
|
-
|
|
1313
|
+
const r = e.closest(t);
|
|
1314
|
+
if (r)
|
|
1315
|
+
return r;
|
|
1316
|
+
} catch (r) {
|
|
1317
|
+
o("warn", "Invalid selector in element search", { error: r, data: { selector: t } });
|
|
1274
1318
|
continue;
|
|
1275
1319
|
}
|
|
1276
1320
|
return e;
|
|
@@ -1279,29 +1323,29 @@ class ft extends f {
|
|
|
1279
1323
|
return Math.max(0, Math.min(1, Number(e.toFixed(3))));
|
|
1280
1324
|
}
|
|
1281
1325
|
calculateClickCoordinates(e, t) {
|
|
1282
|
-
const
|
|
1283
|
-
return { x: n, y: i, relativeX: a, relativeY:
|
|
1326
|
+
const r = t.getBoundingClientRect(), n = e.clientX, i = e.clientY, a = r.width > 0 ? this.clamp((n - r.left) / r.width) : 0, c = r.height > 0 ? this.clamp((i - r.top) / r.height) : 0;
|
|
1327
|
+
return { x: n, y: i, relativeX: a, relativeY: c };
|
|
1284
1328
|
}
|
|
1285
1329
|
extractTrackingData(e) {
|
|
1286
|
-
const t = e.getAttribute(`${O}-name`),
|
|
1330
|
+
const t = e.getAttribute(`${O}-name`), r = e.getAttribute(`${O}-value`);
|
|
1287
1331
|
if (t)
|
|
1288
1332
|
return {
|
|
1289
1333
|
element: e,
|
|
1290
1334
|
name: t,
|
|
1291
|
-
...
|
|
1335
|
+
...r && { value: r }
|
|
1292
1336
|
};
|
|
1293
1337
|
}
|
|
1294
|
-
generateClickData(e, t,
|
|
1295
|
-
const { x: n, y: i, relativeX: a, relativeY:
|
|
1338
|
+
generateClickData(e, t, r) {
|
|
1339
|
+
const { x: n, y: i, relativeX: a, relativeY: c } = r, l = this.getRelevantText(e, t), u = this.extractElementAttributes(t);
|
|
1296
1340
|
return {
|
|
1297
1341
|
x: n,
|
|
1298
1342
|
y: i,
|
|
1299
1343
|
relativeX: a,
|
|
1300
|
-
relativeY:
|
|
1344
|
+
relativeY: c,
|
|
1301
1345
|
tag: t.tagName.toLowerCase(),
|
|
1302
1346
|
...t.id && { id: t.id },
|
|
1303
1347
|
...t.className && { class: t.className },
|
|
1304
|
-
...
|
|
1348
|
+
...l && { text: l },
|
|
1305
1349
|
...u.href && { href: u.href },
|
|
1306
1350
|
...u.title && { title: u.title },
|
|
1307
1351
|
...u.alt && { alt: u.alt },
|
|
@@ -1311,8 +1355,8 @@ class ft extends f {
|
|
|
1311
1355
|
};
|
|
1312
1356
|
}
|
|
1313
1357
|
getRelevantText(e, t) {
|
|
1314
|
-
const
|
|
1315
|
-
return !
|
|
1358
|
+
const r = e.textContent?.trim() ?? "", n = t.textContent?.trim() ?? "";
|
|
1359
|
+
return !r && !n ? "" : r && r.length <= 255 ? r : n.length <= 255 ? n : n.slice(0, 252) + "...";
|
|
1316
1360
|
}
|
|
1317
1361
|
extractElementAttributes(e) {
|
|
1318
1362
|
const t = [
|
|
@@ -1326,12 +1370,12 @@ class ft extends f {
|
|
|
1326
1370
|
"name",
|
|
1327
1371
|
"alt",
|
|
1328
1372
|
"role"
|
|
1329
|
-
],
|
|
1373
|
+
], r = {};
|
|
1330
1374
|
for (const n of t) {
|
|
1331
1375
|
const i = e.getAttribute(n);
|
|
1332
|
-
i && (
|
|
1376
|
+
i && (r[n] = i);
|
|
1333
1377
|
}
|
|
1334
|
-
return
|
|
1378
|
+
return r;
|
|
1335
1379
|
}
|
|
1336
1380
|
createCustomEventData(e) {
|
|
1337
1381
|
return {
|
|
@@ -1361,9 +1405,9 @@ class gt extends f {
|
|
|
1361
1405
|
this.containers.length = 0, this.set("scrollEventCount", 0), this.limitWarningLogged = !1;
|
|
1362
1406
|
}
|
|
1363
1407
|
trySetupContainers(e, t) {
|
|
1364
|
-
const
|
|
1365
|
-
if (
|
|
1366
|
-
for (const n of
|
|
1408
|
+
const r = e.map((n) => this.safeQuerySelector(n)).filter((n) => n instanceof HTMLElement);
|
|
1409
|
+
if (r.length > 0) {
|
|
1410
|
+
for (const n of r)
|
|
1367
1411
|
this.containers.some((a) => a.element === n) || this.setupScrollContainer(n);
|
|
1368
1412
|
return;
|
|
1369
1413
|
}
|
|
@@ -1385,11 +1429,11 @@ class gt extends f {
|
|
|
1385
1429
|
}
|
|
1386
1430
|
n.debounceTimer = null;
|
|
1387
1431
|
}, 250));
|
|
1388
|
-
},
|
|
1432
|
+
}, r = this.getScrollTop(e), n = {
|
|
1389
1433
|
element: e,
|
|
1390
|
-
lastScrollPos:
|
|
1434
|
+
lastScrollPos: r,
|
|
1391
1435
|
lastDepth: this.calculateScrollDepth(
|
|
1392
|
-
|
|
1436
|
+
r,
|
|
1393
1437
|
this.getScrollHeight(e),
|
|
1394
1438
|
this.getViewportHeight(e)
|
|
1395
1439
|
),
|
|
@@ -1400,18 +1444,18 @@ class gt extends f {
|
|
|
1400
1444
|
};
|
|
1401
1445
|
this.containers.push(n), e instanceof Window ? window.addEventListener("scroll", t, { passive: !0 }) : e.addEventListener("scroll", t, { passive: !0 });
|
|
1402
1446
|
}
|
|
1403
|
-
processScrollEvent(e, t,
|
|
1404
|
-
if (!this.shouldEmitScrollEvent(e, t,
|
|
1447
|
+
processScrollEvent(e, t, r) {
|
|
1448
|
+
if (!this.shouldEmitScrollEvent(e, t, r))
|
|
1405
1449
|
return;
|
|
1406
|
-
e.lastEventTime =
|
|
1450
|
+
e.lastEventTime = r, e.lastDepth = t.depth, e.lastDirection = t.direction;
|
|
1407
1451
|
const n = this.get("scrollEventCount") ?? 0;
|
|
1408
1452
|
this.set("scrollEventCount", n + 1), this.eventManager.track({
|
|
1409
1453
|
type: d.SCROLL,
|
|
1410
1454
|
scroll_data: t
|
|
1411
1455
|
});
|
|
1412
1456
|
}
|
|
1413
|
-
shouldEmitScrollEvent(e, t,
|
|
1414
|
-
return this.hasReachedSessionLimit() ? (this.logLimitOnce(), !1) : !(!this.hasElapsedMinimumInterval(e,
|
|
1457
|
+
shouldEmitScrollEvent(e, t, r) {
|
|
1458
|
+
return this.hasReachedSessionLimit() ? (this.logLimitOnce(), !1) : !(!this.hasElapsedMinimumInterval(e, r) || !this.hasSignificantDepthChange(e, t.depth));
|
|
1415
1459
|
}
|
|
1416
1460
|
hasReachedSessionLimit() {
|
|
1417
1461
|
return (this.get("scrollEventCount") ?? 0) >= this.maxEventsPerSession;
|
|
@@ -1423,7 +1467,7 @@ class gt extends f {
|
|
|
1423
1467
|
return Math.abs(t - e.lastDepth) >= this.minDepthChange;
|
|
1424
1468
|
}
|
|
1425
1469
|
logLimitOnce() {
|
|
1426
|
-
this.limitWarningLogged || (this.limitWarningLogged = !0,
|
|
1470
|
+
this.limitWarningLogged || (this.limitWarningLogged = !0, o("warn", "Max scroll events per session reached", {
|
|
1427
1471
|
data: { limit: this.maxEventsPerSession }
|
|
1428
1472
|
}));
|
|
1429
1473
|
}
|
|
@@ -1439,18 +1483,18 @@ class gt extends f {
|
|
|
1439
1483
|
getScrollDirection(e, t) {
|
|
1440
1484
|
return e > t ? D.DOWN : D.UP;
|
|
1441
1485
|
}
|
|
1442
|
-
calculateScrollDepth(e, t,
|
|
1443
|
-
if (t <=
|
|
1486
|
+
calculateScrollDepth(e, t, r) {
|
|
1487
|
+
if (t <= r)
|
|
1444
1488
|
return 0;
|
|
1445
|
-
const n = t -
|
|
1489
|
+
const n = t - r;
|
|
1446
1490
|
return Math.min(100, Math.max(0, Math.floor(e / n * 100)));
|
|
1447
1491
|
}
|
|
1448
1492
|
calculateScrollData(e) {
|
|
1449
|
-
const { element: t, lastScrollPos:
|
|
1450
|
-
if (Math.abs(n -
|
|
1493
|
+
const { element: t, lastScrollPos: r } = e, n = this.getScrollTop(t);
|
|
1494
|
+
if (Math.abs(n - r) < 10 || t === window && !this.isWindowScrollable())
|
|
1451
1495
|
return null;
|
|
1452
|
-
const a = this.getViewportHeight(t),
|
|
1453
|
-
return e.lastScrollPos = n, { depth: u, direction:
|
|
1496
|
+
const a = this.getViewportHeight(t), c = this.getScrollHeight(t), l = this.getScrollDirection(n, r), u = this.calculateScrollDepth(n, c, a);
|
|
1497
|
+
return e.lastScrollPos = n, { depth: u, direction: l };
|
|
1454
1498
|
}
|
|
1455
1499
|
getScrollTop(e) {
|
|
1456
1500
|
return e instanceof Window ? window.scrollY : e.scrollTop;
|
|
@@ -1462,14 +1506,14 @@ class gt extends f {
|
|
|
1462
1506
|
return e instanceof Window ? document.documentElement.scrollHeight : e.scrollHeight;
|
|
1463
1507
|
}
|
|
1464
1508
|
isElementScrollable(e) {
|
|
1465
|
-
const t = getComputedStyle(e),
|
|
1466
|
-
return
|
|
1509
|
+
const t = getComputedStyle(e), r = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflowX === "auto" || t.overflowX === "scroll" || t.overflow === "auto" || t.overflow === "scroll", n = e.scrollHeight > e.clientHeight || e.scrollWidth > e.clientWidth;
|
|
1510
|
+
return r && n;
|
|
1467
1511
|
}
|
|
1468
1512
|
safeQuerySelector(e) {
|
|
1469
1513
|
try {
|
|
1470
1514
|
return document.querySelector(e);
|
|
1471
1515
|
} catch (t) {
|
|
1472
|
-
return
|
|
1516
|
+
return o("warn", "Invalid CSS selector", {
|
|
1473
1517
|
error: t,
|
|
1474
1518
|
data: { selector: e },
|
|
1475
1519
|
showToClient: !0
|
|
@@ -1490,17 +1534,17 @@ class St extends f {
|
|
|
1490
1534
|
return;
|
|
1491
1535
|
}
|
|
1492
1536
|
await this.loadScript(e), this.configureGtag(e, t), this.isInitialized = !0;
|
|
1493
|
-
} catch (
|
|
1494
|
-
|
|
1537
|
+
} catch (r) {
|
|
1538
|
+
o("error", "Google Analytics initialization failed", { error: r });
|
|
1495
1539
|
}
|
|
1496
1540
|
}
|
|
1497
1541
|
trackEvent(e, t) {
|
|
1498
1542
|
if (!(!e?.trim() || !this.isInitialized || typeof window.gtag != "function"))
|
|
1499
1543
|
try {
|
|
1500
|
-
const
|
|
1501
|
-
window.gtag("event", e,
|
|
1502
|
-
} catch (
|
|
1503
|
-
|
|
1544
|
+
const r = Array.isArray(t) ? { items: t } : t;
|
|
1545
|
+
window.gtag("event", e, r);
|
|
1546
|
+
} catch (r) {
|
|
1547
|
+
o("error", "Google Analytics event tracking failed", { error: r });
|
|
1504
1548
|
}
|
|
1505
1549
|
}
|
|
1506
1550
|
cleanup() {
|
|
@@ -1512,21 +1556,21 @@ class St extends f {
|
|
|
1512
1556
|
return document.getElementById("tracelog-ga-script") ? !0 : !!document.querySelector('script[src*="googletagmanager.com/gtag/js"]');
|
|
1513
1557
|
}
|
|
1514
1558
|
async loadScript(e) {
|
|
1515
|
-
return new Promise((t,
|
|
1559
|
+
return new Promise((t, r) => {
|
|
1516
1560
|
const n = document.createElement("script");
|
|
1517
|
-
n.id = "tracelog-ga-script", n.async = !0, n.src = `https://www.googletagmanager.com/gtag/js?id=${e}`, n.onload = () => t(), n.onerror = () =>
|
|
1561
|
+
n.id = "tracelog-ga-script", n.async = !0, n.src = `https://www.googletagmanager.com/gtag/js?id=${e}`, n.onload = () => t(), n.onerror = () => r(new Error("Failed to load Google Analytics script")), document.head.appendChild(n);
|
|
1518
1562
|
});
|
|
1519
1563
|
}
|
|
1520
1564
|
configureGtag(e, t) {
|
|
1521
|
-
const
|
|
1522
|
-
|
|
1565
|
+
const r = document.createElement("script");
|
|
1566
|
+
r.innerHTML = `
|
|
1523
1567
|
window.dataLayer = window.dataLayer || [];
|
|
1524
1568
|
function gtag(){dataLayer.push(arguments);}
|
|
1525
1569
|
gtag('js', new Date());
|
|
1526
1570
|
gtag('config', '${e}', {
|
|
1527
1571
|
'user_id': '${t}'
|
|
1528
1572
|
});
|
|
1529
|
-
`, document.head.appendChild(
|
|
1573
|
+
`, document.head.appendChild(r);
|
|
1530
1574
|
}
|
|
1531
1575
|
}
|
|
1532
1576
|
class Et {
|
|
@@ -1536,7 +1580,7 @@ class Et {
|
|
|
1536
1580
|
fallbackSessionStorage = /* @__PURE__ */ new Map();
|
|
1537
1581
|
hasQuotaExceededError = !1;
|
|
1538
1582
|
constructor() {
|
|
1539
|
-
this.storage = this.initializeStorage("localStorage"), this.sessionStorageRef = this.initializeStorage("sessionStorage"), this.storage ||
|
|
1583
|
+
this.storage = this.initializeStorage("localStorage"), this.sessionStorageRef = this.initializeStorage("sessionStorage"), this.storage || o("warn", "localStorage not available, using memory fallback"), this.sessionStorageRef || o("warn", "sessionStorage not available, using memory fallback");
|
|
1540
1584
|
}
|
|
1541
1585
|
/**
|
|
1542
1586
|
* Retrieves an item from storage
|
|
@@ -1552,18 +1596,34 @@ class Et {
|
|
|
1552
1596
|
* Stores an item in storage
|
|
1553
1597
|
*/
|
|
1554
1598
|
setItem(e, t) {
|
|
1599
|
+
this.fallbackStorage.set(e, t);
|
|
1555
1600
|
try {
|
|
1556
1601
|
if (this.storage) {
|
|
1557
1602
|
this.storage.setItem(e, t);
|
|
1558
1603
|
return;
|
|
1559
1604
|
}
|
|
1560
|
-
} catch (
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1605
|
+
} catch (r) {
|
|
1606
|
+
if (r instanceof DOMException && r.name === "QuotaExceededError")
|
|
1607
|
+
if (this.hasQuotaExceededError = !0, o("warn", "localStorage quota exceeded, attempting cleanup", {
|
|
1608
|
+
data: { key: e, valueSize: t.length }
|
|
1609
|
+
}), this.cleanupOldData())
|
|
1610
|
+
try {
|
|
1611
|
+
if (this.storage) {
|
|
1612
|
+
this.storage.setItem(e, t);
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
} catch (i) {
|
|
1616
|
+
o("error", "localStorage quota exceeded even after cleanup - data will not persist", {
|
|
1617
|
+
error: i,
|
|
1618
|
+
data: { key: e, valueSize: t.length }
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
else
|
|
1622
|
+
o("error", "localStorage quota exceeded and no data to cleanup - data will not persist", {
|
|
1623
|
+
error: r,
|
|
1624
|
+
data: { key: e, valueSize: t.length }
|
|
1625
|
+
});
|
|
1565
1626
|
}
|
|
1566
|
-
this.fallbackStorage.set(e, t);
|
|
1567
1627
|
}
|
|
1568
1628
|
/**
|
|
1569
1629
|
* Removes an item from storage
|
|
@@ -1586,12 +1646,12 @@ class Et {
|
|
|
1586
1646
|
try {
|
|
1587
1647
|
const e = [];
|
|
1588
1648
|
for (let t = 0; t < this.storage.length; t++) {
|
|
1589
|
-
const
|
|
1590
|
-
|
|
1649
|
+
const r = this.storage.key(t);
|
|
1650
|
+
r?.startsWith("tracelog_") && e.push(r);
|
|
1591
1651
|
}
|
|
1592
1652
|
e.forEach((t) => this.storage.removeItem(t)), this.fallbackStorage.clear();
|
|
1593
1653
|
} catch (e) {
|
|
1594
|
-
|
|
1654
|
+
o("error", "Failed to clear storage", { error: e }), this.fallbackStorage.clear();
|
|
1595
1655
|
}
|
|
1596
1656
|
}
|
|
1597
1657
|
/**
|
|
@@ -1607,6 +1667,37 @@ class Et {
|
|
|
1607
1667
|
hasQuotaError() {
|
|
1608
1668
|
return this.hasQuotaExceededError;
|
|
1609
1669
|
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Attempts to cleanup old TraceLog data from storage to free up space
|
|
1672
|
+
* Returns true if any data was removed, false otherwise
|
|
1673
|
+
*/
|
|
1674
|
+
cleanupOldData() {
|
|
1675
|
+
if (!this.storage)
|
|
1676
|
+
return !1;
|
|
1677
|
+
try {
|
|
1678
|
+
const e = [], t = [];
|
|
1679
|
+
for (let i = 0; i < this.storage.length; i++) {
|
|
1680
|
+
const a = this.storage.key(i);
|
|
1681
|
+
a?.startsWith("tracelog_") && (e.push(a), a.startsWith("tracelog_persisted_events_") && t.push(a));
|
|
1682
|
+
}
|
|
1683
|
+
if (t.length > 0)
|
|
1684
|
+
return t.forEach((i) => {
|
|
1685
|
+
try {
|
|
1686
|
+
this.storage.removeItem(i);
|
|
1687
|
+
} catch {
|
|
1688
|
+
}
|
|
1689
|
+
}), !0;
|
|
1690
|
+
const r = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"], n = e.filter((i) => !r.some((a) => i.startsWith(a)));
|
|
1691
|
+
return n.length > 0 ? (n.slice(0, 5).forEach((a) => {
|
|
1692
|
+
try {
|
|
1693
|
+
this.storage.removeItem(a);
|
|
1694
|
+
} catch {
|
|
1695
|
+
}
|
|
1696
|
+
}), !0) : !1;
|
|
1697
|
+
} catch (e) {
|
|
1698
|
+
return o("error", "Failed to cleanup old data", { error: e }), !1;
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1610
1701
|
/**
|
|
1611
1702
|
* Initialize storage (localStorage or sessionStorage) with feature detection
|
|
1612
1703
|
*/
|
|
@@ -1614,8 +1705,8 @@ class Et {
|
|
|
1614
1705
|
if (typeof window > "u")
|
|
1615
1706
|
return null;
|
|
1616
1707
|
try {
|
|
1617
|
-
const t = e === "localStorage" ? window.localStorage : window.sessionStorage,
|
|
1618
|
-
return t.setItem(
|
|
1708
|
+
const t = e === "localStorage" ? window.localStorage : window.sessionStorage, r = "__tracelog_test__";
|
|
1709
|
+
return t.setItem(r, "test"), t.removeItem(r), t;
|
|
1619
1710
|
} catch {
|
|
1620
1711
|
return null;
|
|
1621
1712
|
}
|
|
@@ -1634,18 +1725,18 @@ class Et {
|
|
|
1634
1725
|
* Stores an item in sessionStorage
|
|
1635
1726
|
*/
|
|
1636
1727
|
setSessionItem(e, t) {
|
|
1728
|
+
this.fallbackSessionStorage.set(e, t);
|
|
1637
1729
|
try {
|
|
1638
1730
|
if (this.sessionStorageRef) {
|
|
1639
1731
|
this.sessionStorageRef.setItem(e, t);
|
|
1640
1732
|
return;
|
|
1641
1733
|
}
|
|
1642
|
-
} catch (
|
|
1643
|
-
|
|
1644
|
-
error:
|
|
1734
|
+
} catch (r) {
|
|
1735
|
+
r instanceof DOMException && r.name === "QuotaExceededError" && o("error", "sessionStorage quota exceeded - data will not persist", {
|
|
1736
|
+
error: r,
|
|
1645
1737
|
data: { key: e, valueSize: t.length }
|
|
1646
1738
|
});
|
|
1647
1739
|
}
|
|
1648
|
-
this.fallbackSessionStorage.set(e, t);
|
|
1649
1740
|
}
|
|
1650
1741
|
/**
|
|
1651
1742
|
* Removes an item from sessionStorage
|
|
@@ -1658,7 +1749,7 @@ class Et {
|
|
|
1658
1749
|
this.fallbackSessionStorage.delete(e);
|
|
1659
1750
|
}
|
|
1660
1751
|
}
|
|
1661
|
-
class
|
|
1752
|
+
class mt extends f {
|
|
1662
1753
|
eventManager;
|
|
1663
1754
|
reportedByNav = /* @__PURE__ */ new Map();
|
|
1664
1755
|
observers = [];
|
|
@@ -1674,16 +1765,16 @@ class pt extends f {
|
|
|
1674
1765
|
this.observers.forEach((e, t) => {
|
|
1675
1766
|
try {
|
|
1676
1767
|
e.disconnect();
|
|
1677
|
-
} catch (
|
|
1678
|
-
|
|
1768
|
+
} catch (r) {
|
|
1769
|
+
o("warn", "Failed to disconnect performance observer", { error: r, data: { observerIndex: t } });
|
|
1679
1770
|
}
|
|
1680
1771
|
}), this.observers.length = 0, this.reportedByNav.clear();
|
|
1681
1772
|
}
|
|
1682
1773
|
observeWebVitalsFallback() {
|
|
1683
1774
|
this.reportTTFB(), this.safeObserve(
|
|
1684
1775
|
"largest-contentful-paint",
|
|
1685
|
-
(
|
|
1686
|
-
const n =
|
|
1776
|
+
(r) => {
|
|
1777
|
+
const n = r.getEntries(), i = n[n.length - 1];
|
|
1687
1778
|
i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(2)) });
|
|
1688
1779
|
},
|
|
1689
1780
|
{ type: "largest-contentful-paint", buffered: !0 },
|
|
@@ -1692,35 +1783,35 @@ class pt extends f {
|
|
|
1692
1783
|
let e = 0, t = this.getNavigationId();
|
|
1693
1784
|
this.safeObserve(
|
|
1694
1785
|
"layout-shift",
|
|
1695
|
-
(
|
|
1786
|
+
(r) => {
|
|
1696
1787
|
const n = this.getNavigationId();
|
|
1697
1788
|
n !== t && (e = 0, t = n);
|
|
1698
|
-
const i =
|
|
1789
|
+
const i = r.getEntries();
|
|
1699
1790
|
for (const a of i) {
|
|
1700
1791
|
if (a.hadRecentInput === !0)
|
|
1701
1792
|
continue;
|
|
1702
|
-
const
|
|
1703
|
-
e +=
|
|
1793
|
+
const c = typeof a.value == "number" ? a.value : 0;
|
|
1794
|
+
e += c;
|
|
1704
1795
|
}
|
|
1705
1796
|
this.sendVital({ type: "CLS", value: Number(e.toFixed(2)) });
|
|
1706
1797
|
},
|
|
1707
1798
|
{ type: "layout-shift", buffered: !0 }
|
|
1708
1799
|
), this.safeObserve(
|
|
1709
1800
|
"paint",
|
|
1710
|
-
(
|
|
1711
|
-
for (const n of
|
|
1801
|
+
(r) => {
|
|
1802
|
+
for (const n of r.getEntries())
|
|
1712
1803
|
n.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(n.startTime.toFixed(2)) });
|
|
1713
1804
|
},
|
|
1714
1805
|
{ type: "paint", buffered: !0 },
|
|
1715
1806
|
!0
|
|
1716
1807
|
), this.safeObserve(
|
|
1717
1808
|
"event",
|
|
1718
|
-
(
|
|
1809
|
+
(r) => {
|
|
1719
1810
|
let n = 0;
|
|
1720
|
-
const i =
|
|
1811
|
+
const i = r.getEntries();
|
|
1721
1812
|
for (const a of i) {
|
|
1722
|
-
const
|
|
1723
|
-
n = Math.max(n,
|
|
1813
|
+
const c = (a.processingEnd ?? 0) - (a.startTime ?? 0);
|
|
1814
|
+
n = Math.max(n, c);
|
|
1724
1815
|
}
|
|
1725
1816
|
n > 0 && this.sendVital({ type: "INP", value: Number(n.toFixed(2)) });
|
|
1726
1817
|
},
|
|
@@ -1729,13 +1820,13 @@ class pt extends f {
|
|
|
1729
1820
|
}
|
|
1730
1821
|
async initWebVitals() {
|
|
1731
1822
|
try {
|
|
1732
|
-
const { onLCP: e, onCLS: t, onFCP:
|
|
1733
|
-
const u = Number(
|
|
1734
|
-
this.sendVital({ type:
|
|
1823
|
+
const { onLCP: e, onCLS: t, onFCP: r, onTTFB: n, onINP: i } = await Promise.resolve().then(() => Ht), a = (c) => (l) => {
|
|
1824
|
+
const u = Number(l.value.toFixed(2));
|
|
1825
|
+
this.sendVital({ type: c, value: u });
|
|
1735
1826
|
};
|
|
1736
|
-
e(a("LCP")), t(a("CLS")),
|
|
1827
|
+
e(a("LCP")), t(a("CLS")), r(a("FCP")), n(a("TTFB")), i(a("INP"));
|
|
1737
1828
|
} catch (e) {
|
|
1738
|
-
|
|
1829
|
+
o("warn", "Failed to load web-vitals library, using fallback", { error: e }), this.observeWebVitalsFallback();
|
|
1739
1830
|
}
|
|
1740
1831
|
}
|
|
1741
1832
|
reportTTFB() {
|
|
@@ -1746,7 +1837,7 @@ class pt extends f {
|
|
|
1746
1837
|
const t = e.responseStart;
|
|
1747
1838
|
typeof t == "number" && Number.isFinite(t) && this.sendVital({ type: "TTFB", value: Number(t.toFixed(2)) });
|
|
1748
1839
|
} catch (e) {
|
|
1749
|
-
|
|
1840
|
+
o("warn", "Failed to report TTFB", { error: e });
|
|
1750
1841
|
}
|
|
1751
1842
|
}
|
|
1752
1843
|
observeLongTasks() {
|
|
@@ -1754,9 +1845,9 @@ class pt extends f {
|
|
|
1754
1845
|
"longtask",
|
|
1755
1846
|
(e) => {
|
|
1756
1847
|
const t = e.getEntries();
|
|
1757
|
-
for (const
|
|
1758
|
-
const n = Number(
|
|
1759
|
-
i - this.lastLongTaskSentAt >=
|
|
1848
|
+
for (const r of t) {
|
|
1849
|
+
const n = Number(r.duration.toFixed(2)), i = Date.now();
|
|
1850
|
+
i - this.lastLongTaskSentAt >= ze && (this.shouldSendVital("LONG_TASK", n) && this.trackWebVital("LONG_TASK", n), this.lastLongTaskSentAt = i);
|
|
1760
1851
|
}
|
|
1761
1852
|
},
|
|
1762
1853
|
{ type: "longtask", buffered: !0 }
|
|
@@ -1767,16 +1858,16 @@ class pt extends f {
|
|
|
1767
1858
|
return;
|
|
1768
1859
|
const t = this.getNavigationId();
|
|
1769
1860
|
if (t) {
|
|
1770
|
-
const
|
|
1771
|
-
if (
|
|
1861
|
+
const r = this.reportedByNav.get(t);
|
|
1862
|
+
if (r?.has(e.type))
|
|
1772
1863
|
return;
|
|
1773
|
-
|
|
1864
|
+
r ? r.add(e.type) : this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type]));
|
|
1774
1865
|
}
|
|
1775
1866
|
this.trackWebVital(e.type, e.value);
|
|
1776
1867
|
}
|
|
1777
1868
|
trackWebVital(e, t) {
|
|
1778
1869
|
if (!Number.isFinite(t)) {
|
|
1779
|
-
|
|
1870
|
+
o("warn", "Invalid web vital value", { data: { type: e, value: t } });
|
|
1780
1871
|
return;
|
|
1781
1872
|
}
|
|
1782
1873
|
this.eventManager.track({
|
|
@@ -1792,10 +1883,10 @@ class pt extends f {
|
|
|
1792
1883
|
const e = performance.getEntriesByType("navigation")[0];
|
|
1793
1884
|
if (!e)
|
|
1794
1885
|
return null;
|
|
1795
|
-
const t = e.startTime || performance.now(),
|
|
1796
|
-
return `${t.toFixed(2)}_${window.location.pathname}_${
|
|
1886
|
+
const t = e.startTime || performance.now(), r = Math.random().toString(36).substr(2, 5);
|
|
1887
|
+
return `${t.toFixed(2)}_${window.location.pathname}_${r}`;
|
|
1797
1888
|
} catch (e) {
|
|
1798
|
-
return
|
|
1889
|
+
return o("warn", "Failed to get navigation ID", { error: e }), null;
|
|
1799
1890
|
}
|
|
1800
1891
|
}
|
|
1801
1892
|
isObserverSupported(e) {
|
|
@@ -1803,28 +1894,28 @@ class pt extends f {
|
|
|
1803
1894
|
const t = PerformanceObserver.supportedEntryTypes;
|
|
1804
1895
|
return !t || t.includes(e);
|
|
1805
1896
|
}
|
|
1806
|
-
safeObserve(e, t,
|
|
1897
|
+
safeObserve(e, t, r, n = !1) {
|
|
1807
1898
|
try {
|
|
1808
1899
|
if (!this.isObserverSupported(e))
|
|
1809
1900
|
return !1;
|
|
1810
|
-
const i = new PerformanceObserver((a,
|
|
1901
|
+
const i = new PerformanceObserver((a, c) => {
|
|
1811
1902
|
try {
|
|
1812
|
-
t(a,
|
|
1813
|
-
} catch (
|
|
1814
|
-
|
|
1815
|
-
error:
|
|
1903
|
+
t(a, c);
|
|
1904
|
+
} catch (l) {
|
|
1905
|
+
o("warn", "Observer callback failed", {
|
|
1906
|
+
error: l,
|
|
1816
1907
|
data: { type: e }
|
|
1817
1908
|
});
|
|
1818
1909
|
}
|
|
1819
1910
|
if (n)
|
|
1820
1911
|
try {
|
|
1821
|
-
|
|
1912
|
+
c.disconnect();
|
|
1822
1913
|
} catch {
|
|
1823
1914
|
}
|
|
1824
1915
|
});
|
|
1825
|
-
return i.observe(
|
|
1916
|
+
return i.observe(r ?? { type: e, buffered: !0 }), n || this.observers.push(i), !0;
|
|
1826
1917
|
} catch (i) {
|
|
1827
|
-
return
|
|
1918
|
+
return o("warn", "Failed to create performance observer", {
|
|
1828
1919
|
error: i,
|
|
1829
1920
|
data: { type: e }
|
|
1830
1921
|
}), !1;
|
|
@@ -1832,12 +1923,12 @@ class pt extends f {
|
|
|
1832
1923
|
}
|
|
1833
1924
|
shouldSendVital(e, t) {
|
|
1834
1925
|
if (typeof t != "number" || !Number.isFinite(t))
|
|
1835
|
-
return
|
|
1836
|
-
const
|
|
1837
|
-
return !(typeof
|
|
1926
|
+
return o("warn", "Invalid web vital value", { data: { type: e, value: t } }), !1;
|
|
1927
|
+
const r = this.vitalThresholds[e];
|
|
1928
|
+
return !(typeof r == "number" && t <= r);
|
|
1838
1929
|
}
|
|
1839
1930
|
}
|
|
1840
|
-
class
|
|
1931
|
+
class pt extends f {
|
|
1841
1932
|
eventManager;
|
|
1842
1933
|
recentErrors = /* @__PURE__ */ new Map();
|
|
1843
1934
|
constructor(e) {
|
|
@@ -1857,10 +1948,10 @@ class mt extends f {
|
|
|
1857
1948
|
if (!this.shouldSample())
|
|
1858
1949
|
return;
|
|
1859
1950
|
const t = this.sanitize(e.message || "Unknown error");
|
|
1860
|
-
this.shouldSuppressError(
|
|
1951
|
+
this.shouldSuppressError(L.JS_ERROR, t) || this.eventManager.track({
|
|
1861
1952
|
type: d.ERROR,
|
|
1862
1953
|
error_data: {
|
|
1863
|
-
type:
|
|
1954
|
+
type: L.JS_ERROR,
|
|
1864
1955
|
message: t,
|
|
1865
1956
|
...e.filename && { filename: e.filename },
|
|
1866
1957
|
...e.lineno && { line: e.lineno },
|
|
@@ -1871,12 +1962,12 @@ class mt extends f {
|
|
|
1871
1962
|
handleRejection = (e) => {
|
|
1872
1963
|
if (!this.shouldSample())
|
|
1873
1964
|
return;
|
|
1874
|
-
const t = this.extractRejectionMessage(e.reason),
|
|
1875
|
-
this.shouldSuppressError(
|
|
1965
|
+
const t = this.extractRejectionMessage(e.reason), r = this.sanitize(t);
|
|
1966
|
+
this.shouldSuppressError(L.PROMISE_REJECTION, r) || this.eventManager.track({
|
|
1876
1967
|
type: d.ERROR,
|
|
1877
1968
|
error_data: {
|
|
1878
|
-
type:
|
|
1879
|
-
message:
|
|
1969
|
+
type: L.PROMISE_REJECTION,
|
|
1970
|
+
message: r
|
|
1880
1971
|
}
|
|
1881
1972
|
});
|
|
1882
1973
|
};
|
|
@@ -1894,16 +1985,16 @@ class mt extends f {
|
|
|
1894
1985
|
}
|
|
1895
1986
|
}
|
|
1896
1987
|
sanitize(e) {
|
|
1897
|
-
let t = e.length >
|
|
1898
|
-
for (const
|
|
1899
|
-
const n = new RegExp(
|
|
1988
|
+
let t = e.length > le ? e.slice(0, le) + "..." : e;
|
|
1989
|
+
for (const r of Te) {
|
|
1990
|
+
const n = new RegExp(r.source, r.flags);
|
|
1900
1991
|
t = t.replace(n, "[REDACTED]");
|
|
1901
1992
|
}
|
|
1902
1993
|
return t;
|
|
1903
1994
|
}
|
|
1904
1995
|
shouldSuppressError(e, t) {
|
|
1905
|
-
const
|
|
1906
|
-
return i &&
|
|
1996
|
+
const r = Date.now(), n = `${e}:${t}`, i = this.recentErrors.get(n);
|
|
1997
|
+
return i && r - i < ue ? (this.recentErrors.set(n, r), !0) : (this.recentErrors.set(n, r), this.recentErrors.size > $e ? (this.recentErrors.clear(), this.recentErrors.set(n, r), !1) : (this.recentErrors.size > k && this.pruneOldErrors(), !1));
|
|
1907
1998
|
}
|
|
1908
1999
|
pruneOldErrors() {
|
|
1909
2000
|
const e = Date.now();
|
|
@@ -1911,8 +2002,8 @@ class mt extends f {
|
|
|
1911
2002
|
e - i > ue && this.recentErrors.delete(n);
|
|
1912
2003
|
if (this.recentErrors.size <= k)
|
|
1913
2004
|
return;
|
|
1914
|
-
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]),
|
|
1915
|
-
for (let n = 0; n <
|
|
2005
|
+
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]), r = this.recentErrors.size - k;
|
|
2006
|
+
for (let n = 0; n < r; n += 1) {
|
|
1916
2007
|
const i = t[n];
|
|
1917
2008
|
i && this.recentErrors.delete(i[0]);
|
|
1918
2009
|
}
|
|
@@ -1932,21 +2023,21 @@ class _t extends f {
|
|
|
1932
2023
|
if (!this.isInitialized) {
|
|
1933
2024
|
this.managers.storage = new Et();
|
|
1934
2025
|
try {
|
|
1935
|
-
this.setupState(e), await this.setupIntegrations(), this.managers.event = new
|
|
1936
|
-
|
|
2026
|
+
this.setupState(e), await this.setupIntegrations(), this.managers.event = new ct(this.managers.storage, this.integrations.googleAnalytics, this.emitter), await this.initializeHandlers(), await this.managers.event.recoverPersistedEvents().catch((t) => {
|
|
2027
|
+
o("warn", "Failed to recover persisted events", { error: t });
|
|
1937
2028
|
}), this.isInitialized = !0;
|
|
1938
2029
|
} catch (t) {
|
|
1939
2030
|
await this.destroy(!0);
|
|
1940
|
-
const
|
|
1941
|
-
throw new Error(`[TraceLog] TraceLog initialization failed: ${
|
|
2031
|
+
const r = t instanceof Error ? t.message : String(t);
|
|
2032
|
+
throw new Error(`[TraceLog] TraceLog initialization failed: ${r}`);
|
|
1942
2033
|
}
|
|
1943
2034
|
}
|
|
1944
2035
|
}
|
|
1945
2036
|
sendCustomEvent(e, t) {
|
|
1946
2037
|
if (!this.managers.event)
|
|
1947
2038
|
return;
|
|
1948
|
-
const { valid:
|
|
1949
|
-
if (!
|
|
2039
|
+
const { valid: r, error: n, sanitizedMetadata: i } = it(e, t);
|
|
2040
|
+
if (!r) {
|
|
1950
2041
|
if (this.get("mode") === R.QA)
|
|
1951
2042
|
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${n}`);
|
|
1952
2043
|
return;
|
|
@@ -1969,26 +2060,26 @@ class _t extends f {
|
|
|
1969
2060
|
if (!this.isInitialized && !e)
|
|
1970
2061
|
return;
|
|
1971
2062
|
this.integrations.googleAnalytics?.cleanup();
|
|
1972
|
-
const t = Object.values(this.handlers).filter(Boolean).map(async (
|
|
2063
|
+
const t = Object.values(this.handlers).filter(Boolean).map(async (r) => {
|
|
1973
2064
|
try {
|
|
1974
|
-
await
|
|
2065
|
+
await r.stopTracking();
|
|
1975
2066
|
} catch (n) {
|
|
1976
|
-
|
|
2067
|
+
o("warn", "Failed to stop tracking", { error: n });
|
|
1977
2068
|
}
|
|
1978
2069
|
});
|
|
1979
2070
|
await Promise.allSettled(t), this.suppressNextScrollTimer && (clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = null), this.managers.event?.flushImmediatelySync(), this.managers.event?.stop(), this.emitter.removeAllListeners(), this.set("hasStartSession", !1), this.set("suppressNextScroll", !1), this.set("sessionId", null), this.isInitialized = !1, this.handlers = {};
|
|
1980
2071
|
}
|
|
1981
2072
|
setupState(e) {
|
|
1982
2073
|
this.set("config", e);
|
|
1983
|
-
const t =
|
|
2074
|
+
const t = lt.getId(this.managers.storage);
|
|
1984
2075
|
this.set("userId", t);
|
|
1985
|
-
const
|
|
1986
|
-
this.set("apiUrl",
|
|
2076
|
+
const r = We(e);
|
|
2077
|
+
this.set("apiUrl", r);
|
|
1987
2078
|
const n = He();
|
|
1988
2079
|
this.set("device", n);
|
|
1989
|
-
const i =
|
|
2080
|
+
const i = Y(window.location.href, e.sensitiveQueryParams);
|
|
1990
2081
|
this.set("pageUrl", i);
|
|
1991
|
-
const a =
|
|
2082
|
+
const a = Be() ? R.QA : void 0;
|
|
1992
2083
|
a && this.set("mode", a);
|
|
1993
2084
|
}
|
|
1994
2085
|
async setupIntegrations() {
|
|
@@ -2009,57 +2100,63 @@ class _t extends f {
|
|
|
2009
2100
|
this.set("suppressNextScroll", !1);
|
|
2010
2101
|
}, 250 * 2);
|
|
2011
2102
|
};
|
|
2012
|
-
this.handlers.pageView = new ht(this.managers.event, e), this.handlers.pageView.startTracking(), this.handlers.click = new ft(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new gt(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new
|
|
2013
|
-
|
|
2014
|
-
}), this.handlers.error = new
|
|
2103
|
+
this.handlers.pageView = new ht(this.managers.event, e), this.handlers.pageView.startTracking(), this.handlers.click = new ft(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new gt(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new mt(this.managers.event), this.handlers.performance.startTracking().catch((t) => {
|
|
2104
|
+
o("warn", "Failed to start performance tracking", { error: t });
|
|
2105
|
+
}), this.handlers.error = new pt(this.managers.event), this.handlers.error.startTracking();
|
|
2015
2106
|
}
|
|
2016
2107
|
}
|
|
2017
2108
|
const I = [];
|
|
2018
|
-
let h = null,
|
|
2019
|
-
const Tt = async (
|
|
2109
|
+
let h = null, w = !1, U = !1;
|
|
2110
|
+
const Tt = async (s) => {
|
|
2020
2111
|
if (typeof window > "u" || typeof document > "u")
|
|
2021
2112
|
throw new Error("[TraceLog] This library can only be used in a browser environment");
|
|
2022
|
-
if (!window.__traceLogDisabled && !h && !
|
|
2023
|
-
|
|
2113
|
+
if (!window.__traceLogDisabled && !h && !w) {
|
|
2114
|
+
w = !0;
|
|
2024
2115
|
try {
|
|
2025
|
-
const e = et(
|
|
2116
|
+
const e = et(s), t = new _t();
|
|
2026
2117
|
try {
|
|
2027
|
-
I.forEach(({ event:
|
|
2028
|
-
t.on(
|
|
2029
|
-
}), I.length = 0
|
|
2030
|
-
|
|
2118
|
+
I.forEach(({ event: i, callback: a }) => {
|
|
2119
|
+
t.on(i, a);
|
|
2120
|
+
}), I.length = 0;
|
|
2121
|
+
const r = t.init(e), n = new Promise((i, a) => {
|
|
2122
|
+
setTimeout(() => {
|
|
2123
|
+
a(new Error("[TraceLog] Initialization timeout after 10000ms"));
|
|
2124
|
+
}, 1e4);
|
|
2125
|
+
});
|
|
2126
|
+
await Promise.race([r, n]), h = t;
|
|
2127
|
+
} catch (r) {
|
|
2031
2128
|
try {
|
|
2032
2129
|
await t.destroy(!0);
|
|
2033
2130
|
} catch (n) {
|
|
2034
|
-
|
|
2131
|
+
o("error", "Failed to cleanup partially initialized app", { error: n });
|
|
2035
2132
|
}
|
|
2036
|
-
throw
|
|
2133
|
+
throw r;
|
|
2037
2134
|
}
|
|
2038
2135
|
} catch (e) {
|
|
2039
2136
|
throw h = null, e;
|
|
2040
2137
|
} finally {
|
|
2041
|
-
|
|
2138
|
+
w = !1;
|
|
2042
2139
|
}
|
|
2043
2140
|
}
|
|
2044
|
-
}, vt = (
|
|
2141
|
+
}, vt = (s, e) => {
|
|
2045
2142
|
if (!h)
|
|
2046
2143
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
2047
2144
|
if (U)
|
|
2048
2145
|
throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
|
|
2049
|
-
h.sendCustomEvent(
|
|
2050
|
-
}, It = (
|
|
2051
|
-
if (!h ||
|
|
2052
|
-
I.push({ event:
|
|
2146
|
+
h.sendCustomEvent(s, e);
|
|
2147
|
+
}, It = (s, e) => {
|
|
2148
|
+
if (!h || w) {
|
|
2149
|
+
I.push({ event: s, callback: e });
|
|
2053
2150
|
return;
|
|
2054
2151
|
}
|
|
2055
|
-
h.on(
|
|
2056
|
-
}, yt = (
|
|
2152
|
+
h.on(s, e);
|
|
2153
|
+
}, yt = (s, e) => {
|
|
2057
2154
|
if (!h) {
|
|
2058
|
-
const t = I.findIndex((
|
|
2155
|
+
const t = I.findIndex((r) => r.event === s && r.callback === e);
|
|
2059
2156
|
t !== -1 && I.splice(t, 1);
|
|
2060
2157
|
return;
|
|
2061
2158
|
}
|
|
2062
|
-
h.off(
|
|
2159
|
+
h.off(s, e);
|
|
2063
2160
|
}, At = () => h !== null, wt = async () => {
|
|
2064
2161
|
if (!h)
|
|
2065
2162
|
throw new Error("[TraceLog] App not initialized");
|
|
@@ -2067,9 +2164,9 @@ const Tt = async (r) => {
|
|
|
2067
2164
|
throw new Error("[TraceLog] Destroy operation already in progress");
|
|
2068
2165
|
U = !0;
|
|
2069
2166
|
try {
|
|
2070
|
-
await h.destroy(), h = null,
|
|
2071
|
-
} catch (
|
|
2072
|
-
|
|
2167
|
+
await h.destroy(), h = null, w = !1, I.length = 0;
|
|
2168
|
+
} catch (s) {
|
|
2169
|
+
h = null, w = !1, I.length = 0, o("warn", "Error during destroy, forced cleanup completed", { error: s });
|
|
2073
2170
|
} finally {
|
|
2074
2171
|
U = !1;
|
|
2075
2172
|
}
|
|
@@ -2089,7 +2186,7 @@ const Tt = async (r) => {
|
|
|
2089
2186
|
MIN_ENGAGED_SESSION_DURATION_MS: 30 * 1e3,
|
|
2090
2187
|
MIN_SCROLL_DEPTH_ENGAGEMENT: 25
|
|
2091
2188
|
// 25% scroll depth for engagement
|
|
2092
|
-
},
|
|
2189
|
+
}, zt = {
|
|
2093
2190
|
INACTIVITY_TIMEOUT_MS: 30 * 60 * 1e3,
|
|
2094
2191
|
// 30min for analytics (vs 15min client)
|
|
2095
2192
|
SHORT_SESSION_THRESHOLD_MS: 30 * 1e3,
|
|
@@ -2103,14 +2200,14 @@ const Tt = async (r) => {
|
|
|
2103
2200
|
MOBILE_PERFORMANCE_FACTOR: 1.5,
|
|
2104
2201
|
// Mobile typically 1.5x slower
|
|
2105
2202
|
TABLET_PERFORMANCE_FACTOR: 1.2
|
|
2106
|
-
},
|
|
2203
|
+
}, Qt = {
|
|
2107
2204
|
MIN_TEXT_LENGTH_FOR_ANALYSIS: 10,
|
|
2108
2205
|
MIN_CLICKS_FOR_HOT_ELEMENT: 10,
|
|
2109
2206
|
// Popular element threshold
|
|
2110
2207
|
MIN_SCROLL_COMPLETION_PERCENT: 80,
|
|
2111
2208
|
// Page consumption threshold
|
|
2112
2209
|
MIN_TIME_ON_PAGE_FOR_READ_MS: 15 * 1e3
|
|
2113
|
-
},
|
|
2210
|
+
}, Bt = {
|
|
2114
2211
|
SIGNIFICANT_CHANGE_PERCENT: 20,
|
|
2115
2212
|
MAJOR_CHANGE_PERCENT: 50,
|
|
2116
2213
|
MIN_EVENTS_FOR_INSIGHT: 100,
|
|
@@ -2120,7 +2217,7 @@ const Tt = async (r) => {
|
|
|
2120
2217
|
LOW_ERROR_RATE_PERCENT: 1,
|
|
2121
2218
|
HIGH_ERROR_RATE_PERCENT: 5,
|
|
2122
2219
|
CRITICAL_ERROR_RATE_PERCENT: 10
|
|
2123
|
-
},
|
|
2220
|
+
}, jt = {
|
|
2124
2221
|
SHORT_TERM_TREND_HOURS: 24,
|
|
2125
2222
|
MEDIUM_TERM_TREND_DAYS: 7,
|
|
2126
2223
|
LONG_TERM_TREND_DAYS: 30,
|
|
@@ -2132,7 +2229,7 @@ const Tt = async (r) => {
|
|
|
2132
2229
|
MIN_COHORT_SIZE: 5,
|
|
2133
2230
|
COHORT_ANALYSIS_DAYS: [1, 3, 7, 14, 30],
|
|
2134
2231
|
MIN_FUNNEL_EVENTS: 20
|
|
2135
|
-
},
|
|
2232
|
+
}, Wt = {
|
|
2136
2233
|
DEFAULT_EVENTS_LIMIT: 5,
|
|
2137
2234
|
DEFAULT_SESSIONS_LIMIT: 5,
|
|
2138
2235
|
DEFAULT_PAGES_LIMIT: 5,
|
|
@@ -2140,7 +2237,7 @@ const Tt = async (r) => {
|
|
|
2140
2237
|
MAX_TIME_RANGE_DAYS: 365,
|
|
2141
2238
|
ANALYTICS_BATCH_SIZE: 1e3
|
|
2142
2239
|
// For historical analysis
|
|
2143
|
-
},
|
|
2240
|
+
}, Yt = {
|
|
2144
2241
|
ANOMALY_THRESHOLD_SIGMA: 2.5,
|
|
2145
2242
|
STRONG_ANOMALY_THRESHOLD_SIGMA: 3,
|
|
2146
2243
|
TRAFFIC_DROP_ALERT_PERCENT: -30,
|
|
@@ -2158,196 +2255,196 @@ const Tt = async (r) => {
|
|
|
2158
2255
|
isInitialized: At,
|
|
2159
2256
|
destroy: wt
|
|
2160
2257
|
};
|
|
2161
|
-
var q, ve = -1,
|
|
2258
|
+
var q, ve = -1, M = function(s) {
|
|
2162
2259
|
addEventListener("pageshow", function(e) {
|
|
2163
|
-
e.persisted && (ve = e.timeStamp,
|
|
2260
|
+
e.persisted && (ve = e.timeStamp, s(e));
|
|
2164
2261
|
}, !0);
|
|
2165
2262
|
}, se = function() {
|
|
2166
|
-
var
|
|
2167
|
-
if (
|
|
2263
|
+
var s = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
|
|
2264
|
+
if (s && s.responseStart > 0 && s.responseStart < performance.now()) return s;
|
|
2168
2265
|
}, V = function() {
|
|
2169
|
-
var
|
|
2170
|
-
return
|
|
2171
|
-
},
|
|
2172
|
-
var t = se(),
|
|
2173
|
-
return ve >= 0 ?
|
|
2174
|
-
},
|
|
2266
|
+
var s = se();
|
|
2267
|
+
return s && s.activationStart || 0;
|
|
2268
|
+
}, S = function(s, e) {
|
|
2269
|
+
var t = se(), r = "navigate";
|
|
2270
|
+
return ve >= 0 ? r = "back-forward-cache" : t && (document.prerendering || V() > 0 ? r = "prerender" : document.wasDiscarded ? r = "restore" : t.type && (r = t.type.replace(/_/g, "-"))), { name: s, value: e === void 0 ? -1 : e, rating: "good", delta: 0, entries: [], id: "v4-".concat(Date.now(), "-").concat(Math.floor(8999999999999 * Math.random()) + 1e12), navigationType: r };
|
|
2271
|
+
}, b = function(s, e, t) {
|
|
2175
2272
|
try {
|
|
2176
|
-
if (PerformanceObserver.supportedEntryTypes.includes(
|
|
2177
|
-
var
|
|
2273
|
+
if (PerformanceObserver.supportedEntryTypes.includes(s)) {
|
|
2274
|
+
var r = new PerformanceObserver(function(n) {
|
|
2178
2275
|
Promise.resolve().then(function() {
|
|
2179
2276
|
e(n.getEntries());
|
|
2180
2277
|
});
|
|
2181
2278
|
});
|
|
2182
|
-
return
|
|
2279
|
+
return r.observe(Object.assign({ type: s, buffered: !0 }, t || {})), r;
|
|
2183
2280
|
}
|
|
2184
2281
|
} catch {
|
|
2185
2282
|
}
|
|
2186
|
-
},
|
|
2283
|
+
}, E = function(s, e, t, r) {
|
|
2187
2284
|
var n, i;
|
|
2188
2285
|
return function(a) {
|
|
2189
|
-
e.value >= 0 && (a ||
|
|
2190
|
-
return
|
|
2191
|
-
}(e.value, t),
|
|
2286
|
+
e.value >= 0 && (a || r) && ((i = e.value - (n || 0)) || n === void 0) && (n = e.value, e.delta = i, e.rating = function(c, l) {
|
|
2287
|
+
return c > l[1] ? "poor" : c > l[0] ? "needs-improvement" : "good";
|
|
2288
|
+
}(e.value, t), s(e));
|
|
2192
2289
|
};
|
|
2193
|
-
}, ne = function(
|
|
2290
|
+
}, ne = function(s) {
|
|
2194
2291
|
requestAnimationFrame(function() {
|
|
2195
2292
|
return requestAnimationFrame(function() {
|
|
2196
|
-
return
|
|
2293
|
+
return s();
|
|
2197
2294
|
});
|
|
2198
2295
|
});
|
|
2199
|
-
}, F = function(
|
|
2296
|
+
}, F = function(s) {
|
|
2200
2297
|
document.addEventListener("visibilitychange", function() {
|
|
2201
|
-
document.visibilityState === "hidden" &&
|
|
2298
|
+
document.visibilityState === "hidden" && s();
|
|
2202
2299
|
});
|
|
2203
|
-
}, ie = function(
|
|
2300
|
+
}, ie = function(s) {
|
|
2204
2301
|
var e = !1;
|
|
2205
2302
|
return function() {
|
|
2206
|
-
e || (
|
|
2303
|
+
e || (s(), e = !0);
|
|
2207
2304
|
};
|
|
2208
|
-
},
|
|
2305
|
+
}, A = -1, Ee = function() {
|
|
2209
2306
|
return document.visibilityState !== "hidden" || document.prerendering ? 1 / 0 : 0;
|
|
2210
|
-
}, x = function(
|
|
2211
|
-
document.visibilityState === "hidden" &&
|
|
2212
|
-
},
|
|
2307
|
+
}, x = function(s) {
|
|
2308
|
+
document.visibilityState === "hidden" && A > -1 && (A = s.type === "visibilitychange" ? s.timeStamp : 0, Mt());
|
|
2309
|
+
}, me = function() {
|
|
2213
2310
|
addEventListener("visibilitychange", x, !0), addEventListener("prerenderingchange", x, !0);
|
|
2214
2311
|
}, Mt = function() {
|
|
2215
2312
|
removeEventListener("visibilitychange", x, !0), removeEventListener("prerenderingchange", x, !0);
|
|
2216
2313
|
}, Ie = function() {
|
|
2217
|
-
return
|
|
2314
|
+
return A < 0 && (A = Ee(), me(), M(function() {
|
|
2218
2315
|
setTimeout(function() {
|
|
2219
|
-
|
|
2316
|
+
A = Ee(), me();
|
|
2220
2317
|
}, 0);
|
|
2221
2318
|
})), { get firstHiddenTime() {
|
|
2222
|
-
return
|
|
2319
|
+
return A;
|
|
2223
2320
|
} };
|
|
2224
|
-
}, G = function(
|
|
2321
|
+
}, G = function(s) {
|
|
2225
2322
|
document.prerendering ? addEventListener("prerenderingchange", function() {
|
|
2226
|
-
return
|
|
2227
|
-
}, !0) :
|
|
2228
|
-
},
|
|
2323
|
+
return s();
|
|
2324
|
+
}, !0) : s();
|
|
2325
|
+
}, Z = [1800, 3e3], ye = function(s, e) {
|
|
2229
2326
|
e = e || {}, G(function() {
|
|
2230
|
-
var t,
|
|
2231
|
-
a.forEach(function(
|
|
2232
|
-
|
|
2327
|
+
var t, r = Ie(), n = S("FCP"), i = b("paint", function(a) {
|
|
2328
|
+
a.forEach(function(c) {
|
|
2329
|
+
c.name === "first-contentful-paint" && (i.disconnect(), c.startTime < r.firstHiddenTime && (n.value = Math.max(c.startTime - V(), 0), n.entries.push(c), t(!0)));
|
|
2233
2330
|
});
|
|
2234
2331
|
});
|
|
2235
|
-
i && (t =
|
|
2236
|
-
n =
|
|
2332
|
+
i && (t = E(s, n, Z, e.reportAllChanges), M(function(a) {
|
|
2333
|
+
n = S("FCP"), t = E(s, n, Z, e.reportAllChanges), ne(function() {
|
|
2237
2334
|
n.value = performance.now() - a.timeStamp, t(!0);
|
|
2238
2335
|
});
|
|
2239
2336
|
}));
|
|
2240
2337
|
});
|
|
2241
|
-
},
|
|
2338
|
+
}, J = [0.1, 0.25], Nt = function(s, e) {
|
|
2242
2339
|
e = e || {}, ye(ie(function() {
|
|
2243
|
-
var t,
|
|
2244
|
-
|
|
2340
|
+
var t, r = S("CLS", 0), n = 0, i = [], a = function(l) {
|
|
2341
|
+
l.forEach(function(u) {
|
|
2245
2342
|
if (!u.hadRecentInput) {
|
|
2246
|
-
var
|
|
2247
|
-
n && u.startTime -
|
|
2343
|
+
var p = i[0], N = i[i.length - 1];
|
|
2344
|
+
n && u.startTime - N.startTime < 1e3 && u.startTime - p.startTime < 5e3 ? (n += u.value, i.push(u)) : (n = u.value, i = [u]);
|
|
2248
2345
|
}
|
|
2249
|
-
}), n >
|
|
2250
|
-
},
|
|
2251
|
-
|
|
2252
|
-
a(
|
|
2253
|
-
}),
|
|
2254
|
-
n = 0,
|
|
2346
|
+
}), n > r.value && (r.value = n, r.entries = i, t());
|
|
2347
|
+
}, c = b("layout-shift", a);
|
|
2348
|
+
c && (t = E(s, r, J, e.reportAllChanges), F(function() {
|
|
2349
|
+
a(c.takeRecords()), t(!0);
|
|
2350
|
+
}), M(function() {
|
|
2351
|
+
n = 0, r = S("CLS", 0), t = E(s, r, J, e.reportAllChanges), ne(function() {
|
|
2255
2352
|
return t();
|
|
2256
2353
|
});
|
|
2257
2354
|
}), setTimeout(t, 0));
|
|
2258
2355
|
}));
|
|
2259
|
-
}, Ae = 0,
|
|
2260
|
-
|
|
2261
|
-
e.interactionId && (
|
|
2356
|
+
}, Ae = 0, Q = 1 / 0, P = 0, Lt = function(s) {
|
|
2357
|
+
s.forEach(function(e) {
|
|
2358
|
+
e.interactionId && (Q = Math.min(Q, e.interactionId), P = Math.max(P, e.interactionId), Ae = P ? (P - Q) / 7 + 1 : 0);
|
|
2262
2359
|
});
|
|
2263
2360
|
}, we = function() {
|
|
2264
2361
|
return q ? Ae : performance.interactionCount || 0;
|
|
2265
|
-
},
|
|
2266
|
-
"interactionCount" in performance || q || (q =
|
|
2267
|
-
},
|
|
2268
|
-
var
|
|
2269
|
-
return
|
|
2270
|
-
}, bt = [], Ot = function(
|
|
2362
|
+
}, Rt = function() {
|
|
2363
|
+
"interactionCount" in performance || q || (q = b("event", Lt, { type: "event", buffered: !0, durationThreshold: 0 }));
|
|
2364
|
+
}, g = [], H = /* @__PURE__ */ new Map(), Me = 0, Ct = function() {
|
|
2365
|
+
var s = Math.min(g.length - 1, Math.floor((we() - Me) / 50));
|
|
2366
|
+
return g[s];
|
|
2367
|
+
}, bt = [], Ot = function(s) {
|
|
2271
2368
|
if (bt.forEach(function(n) {
|
|
2272
|
-
return n(
|
|
2273
|
-
}),
|
|
2274
|
-
var e =
|
|
2275
|
-
if (t ||
|
|
2276
|
-
if (t)
|
|
2369
|
+
return n(s);
|
|
2370
|
+
}), s.interactionId || s.entryType === "first-input") {
|
|
2371
|
+
var e = g[g.length - 1], t = H.get(s.interactionId);
|
|
2372
|
+
if (t || g.length < 10 || s.duration > e.latency) {
|
|
2373
|
+
if (t) s.duration > t.latency ? (t.entries = [s], t.latency = s.duration) : s.duration === t.latency && s.startTime === t.entries[0].startTime && t.entries.push(s);
|
|
2277
2374
|
else {
|
|
2278
|
-
var
|
|
2279
|
-
H.set(
|
|
2375
|
+
var r = { id: s.interactionId, latency: s.duration, entries: [s] };
|
|
2376
|
+
H.set(r.id, r), g.push(r);
|
|
2280
2377
|
}
|
|
2281
|
-
|
|
2378
|
+
g.sort(function(n, i) {
|
|
2282
2379
|
return i.latency - n.latency;
|
|
2283
|
-
}),
|
|
2380
|
+
}), g.length > 10 && g.splice(10).forEach(function(n) {
|
|
2284
2381
|
return H.delete(n.id);
|
|
2285
2382
|
});
|
|
2286
2383
|
}
|
|
2287
2384
|
}
|
|
2288
|
-
}, Ne = function(
|
|
2385
|
+
}, Ne = function(s) {
|
|
2289
2386
|
var e = self.requestIdleCallback || self.setTimeout, t = -1;
|
|
2290
|
-
return
|
|
2291
|
-
}, ee = [200, 500], Pt = function(
|
|
2387
|
+
return s = ie(s), document.visibilityState === "hidden" ? s() : (t = e(s), F(s)), t;
|
|
2388
|
+
}, ee = [200, 500], Pt = function(s, e) {
|
|
2292
2389
|
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, G(function() {
|
|
2293
2390
|
var t;
|
|
2294
|
-
|
|
2295
|
-
var
|
|
2391
|
+
Rt();
|
|
2392
|
+
var r, n = S("INP"), i = function(c) {
|
|
2296
2393
|
Ne(function() {
|
|
2297
|
-
|
|
2298
|
-
var
|
|
2299
|
-
|
|
2394
|
+
c.forEach(Ot);
|
|
2395
|
+
var l = Ct();
|
|
2396
|
+
l && l.latency !== n.value && (n.value = l.latency, n.entries = l.entries, r());
|
|
2300
2397
|
});
|
|
2301
|
-
}, a =
|
|
2302
|
-
|
|
2303
|
-
i(a.takeRecords()),
|
|
2304
|
-
}),
|
|
2305
|
-
Me = we(),
|
|
2398
|
+
}, a = b("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
|
|
2399
|
+
r = E(s, n, ee, e.reportAllChanges), a && (a.observe({ type: "first-input", buffered: !0 }), F(function() {
|
|
2400
|
+
i(a.takeRecords()), r(!0);
|
|
2401
|
+
}), M(function() {
|
|
2402
|
+
Me = we(), g.length = 0, H.clear(), n = S("INP"), r = E(s, n, ee, e.reportAllChanges);
|
|
2306
2403
|
}));
|
|
2307
2404
|
}));
|
|
2308
|
-
}, te = [2500, 4e3],
|
|
2405
|
+
}, te = [2500, 4e3], B = {}, Dt = function(s, e) {
|
|
2309
2406
|
e = e || {}, G(function() {
|
|
2310
|
-
var t,
|
|
2311
|
-
e.reportAllChanges || (
|
|
2312
|
-
u.startTime <
|
|
2407
|
+
var t, r = Ie(), n = S("LCP"), i = function(l) {
|
|
2408
|
+
e.reportAllChanges || (l = l.slice(-1)), l.forEach(function(u) {
|
|
2409
|
+
u.startTime < r.firstHiddenTime && (n.value = Math.max(u.startTime - V(), 0), n.entries = [u], t());
|
|
2313
2410
|
});
|
|
2314
|
-
}, a =
|
|
2411
|
+
}, a = b("largest-contentful-paint", i);
|
|
2315
2412
|
if (a) {
|
|
2316
|
-
t =
|
|
2317
|
-
var
|
|
2318
|
-
|
|
2413
|
+
t = E(s, n, te, e.reportAllChanges);
|
|
2414
|
+
var c = ie(function() {
|
|
2415
|
+
B[n.id] || (i(a.takeRecords()), a.disconnect(), B[n.id] = !0, t(!0));
|
|
2319
2416
|
});
|
|
2320
|
-
["keydown", "click"].forEach(function(
|
|
2321
|
-
addEventListener(
|
|
2322
|
-
return Ne(
|
|
2417
|
+
["keydown", "click"].forEach(function(l) {
|
|
2418
|
+
addEventListener(l, function() {
|
|
2419
|
+
return Ne(c);
|
|
2323
2420
|
}, { once: !0, capture: !0 });
|
|
2324
|
-
}), F(
|
|
2325
|
-
n =
|
|
2326
|
-
n.value = performance.now() -
|
|
2421
|
+
}), F(c), M(function(l) {
|
|
2422
|
+
n = S("LCP"), t = E(s, n, te, e.reportAllChanges), ne(function() {
|
|
2423
|
+
n.value = performance.now() - l.timeStamp, B[n.id] = !0, t(!0);
|
|
2327
2424
|
});
|
|
2328
2425
|
});
|
|
2329
2426
|
}
|
|
2330
2427
|
});
|
|
2331
|
-
}, re = [800, 1800], kt = function
|
|
2428
|
+
}, re = [800, 1800], kt = function s(e) {
|
|
2332
2429
|
document.prerendering ? G(function() {
|
|
2333
|
-
return
|
|
2430
|
+
return s(e);
|
|
2334
2431
|
}) : document.readyState !== "complete" ? addEventListener("load", function() {
|
|
2335
|
-
return
|
|
2432
|
+
return s(e);
|
|
2336
2433
|
}, !0) : setTimeout(e, 0);
|
|
2337
|
-
}, Ut = function(
|
|
2434
|
+
}, Ut = function(s, e) {
|
|
2338
2435
|
e = e || {};
|
|
2339
|
-
var t =
|
|
2436
|
+
var t = S("TTFB"), r = E(s, t, re, e.reportAllChanges);
|
|
2340
2437
|
kt(function() {
|
|
2341
2438
|
var n = se();
|
|
2342
|
-
n && (t.value = Math.max(n.responseStart - V(), 0), t.entries = [n],
|
|
2343
|
-
t =
|
|
2439
|
+
n && (t.value = Math.max(n.responseStart - V(), 0), t.entries = [n], r(!0), M(function() {
|
|
2440
|
+
t = S("TTFB", 0), (r = E(s, t, re, e.reportAllChanges))(!0);
|
|
2344
2441
|
}));
|
|
2345
2442
|
});
|
|
2346
2443
|
};
|
|
2347
2444
|
const Ht = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2348
2445
|
__proto__: null,
|
|
2349
|
-
CLSThresholds:
|
|
2350
|
-
FCPThresholds:
|
|
2446
|
+
CLSThresholds: J,
|
|
2447
|
+
FCPThresholds: Z,
|
|
2351
2448
|
INPThresholds: ee,
|
|
2352
2449
|
LCPThresholds: te,
|
|
2353
2450
|
TTFBThresholds: re,
|
|
@@ -2358,30 +2455,30 @@ const Ht = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
2358
2455
|
onTTFB: Ut
|
|
2359
2456
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2360
2457
|
export {
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2458
|
+
Wt as ANALYTICS_QUERY_LIMITS,
|
|
2459
|
+
Yt as ANOMALY_DETECTION,
|
|
2460
|
+
y as AppConfigValidationError,
|
|
2461
|
+
Qt as CONTENT_ANALYTICS,
|
|
2365
2462
|
Ft as DATA_PROTECTION,
|
|
2366
2463
|
$t as DEVICE_ANALYTICS,
|
|
2367
2464
|
_ as DeviceType,
|
|
2368
2465
|
Gt as ENGAGEMENT_THRESHOLDS,
|
|
2369
2466
|
X as EmitterEvent,
|
|
2370
|
-
|
|
2467
|
+
L as ErrorType,
|
|
2371
2468
|
d as EventType,
|
|
2372
|
-
|
|
2469
|
+
Bt as INSIGHT_THRESHOLDS,
|
|
2373
2470
|
xt as InitializationTimeoutError,
|
|
2374
|
-
|
|
2471
|
+
v as IntegrationValidationError,
|
|
2375
2472
|
R as Mode,
|
|
2376
2473
|
Vt as PERFORMANCE_CONFIG,
|
|
2377
2474
|
Xt as SEGMENTATION_ANALYTICS,
|
|
2378
|
-
|
|
2475
|
+
zt as SESSION_ANALYTICS,
|
|
2379
2476
|
Kt as SPECIAL_PAGE_URLS,
|
|
2380
2477
|
oe as SamplingRateValidationError,
|
|
2381
2478
|
D as ScrollDirection,
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2479
|
+
Pe as SessionTimeoutValidationError,
|
|
2480
|
+
j as SpecialApiUrl,
|
|
2481
|
+
jt as TEMPORAL_ANALYSIS,
|
|
2482
|
+
C as TraceLogValidationError,
|
|
2386
2483
|
qt as tracelog
|
|
2387
2484
|
};
|