@tracelog/lib 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/tracelog.js +37 -26
- package/dist/cjs/api.d.ts +7 -7
- package/dist/cjs/api.js +7 -7
- package/dist/cjs/app.types.d.ts +1 -1
- package/dist/cjs/handlers/scroll.handler.d.ts +1 -0
- package/dist/cjs/handlers/scroll.handler.js +25 -7
- package/dist/cjs/managers/session.manager.js +1 -1
- package/dist/cjs/types/event.types.d.ts +5 -0
- package/dist/esm/api.d.ts +7 -7
- package/dist/esm/api.js +7 -7
- package/dist/esm/app.types.d.ts +1 -1
- package/dist/esm/handlers/scroll.handler.d.ts +1 -0
- package/dist/esm/handlers/scroll.handler.js +25 -7
- package/dist/esm/managers/session.manager.js +1 -1
- package/dist/esm/types/event.types.d.ts +5 -0
- package/package.json +1 -1
package/dist/browser/tracelog.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var y = /* @__PURE__ */ ((r) => (r.Mobile = "mobile", r.Tablet = "tablet", r.Desktop = "desktop", r.Unknown = "unknown", r))(y || {});
|
|
2
|
-
const ee = 15 * 60 * 1e3, Ze = 1e3, et = 1e4, Ue = 250, tt = 24, Ee = 500, ve = 3, rt = 5e3, xe = 1e4, nt = 10, ye = 5, Te = 500,
|
|
2
|
+
const ee = 15 * 60 * 1e3, Ze = 1e3, et = 1e4, Ue = 250, tt = 24, Ee = 500, ve = 3, rt = 5e3, xe = 1e4, nt = 10, ye = 5, Te = 500, _e = 120, A = 1, st = 0, it = 1, z = 3e4, G = 864e5, Ie = 120, we = 8 * 1024, Ae = 10, be = 10, Y = 255, T = 1e3, K = 100, Me = 3, I = 2, at = 2e3, k = "data-tl", ot = [
|
|
3
3
|
"button",
|
|
4
4
|
"a",
|
|
5
5
|
'input[type="button"]',
|
|
@@ -75,7 +75,7 @@ const ee = 15 * 60 * 1e3, Ze = 1e3, et = 1e4, Ue = 250, tt = 24, Ee = 500, ve =
|
|
|
75
75
|
excludedUrlPaths: r.excludedUrlPaths ?? [],
|
|
76
76
|
tags: r.tags ?? [],
|
|
77
77
|
ipExcluded: r.ipExcluded ?? !1
|
|
78
|
-
}),
|
|
78
|
+
}), _ = "tl", dt = (r) => r ? `${_}:${r}:uid` : `${_}:uid`, ht = (r) => r ? `${_}:${r}:queue` : `${_}:queue`, gt = (r) => r ? `${_}:${r}:session` : `${_}:session`, ft = (r) => r ? `${_}:${r}:broadcast` : `${_}:broadcast`, Fe = {
|
|
79
79
|
LCP: 4e3,
|
|
80
80
|
FCP: 1800,
|
|
81
81
|
CLS: 0.25,
|
|
@@ -224,7 +224,7 @@ const St = () => {
|
|
|
224
224
|
const e = Math.random() * 16 | 0;
|
|
225
225
|
return (r === "x" ? e : e & 3 | 8).toString(16);
|
|
226
226
|
});
|
|
227
|
-
var w = /* @__PURE__ */ ((r) => (r.Skip = "skip", r.Localhost = "localhost:", r))(w || {}), re = /* @__PURE__ */ ((r) => (r.EVENT = "event", r.QUEUE = "queue", r))(re || {}), d = /* @__PURE__ */ ((r) => (r.PAGE_VIEW = "page_view", r.CLICK = "click", r.SCROLL = "scroll", r.SESSION_START = "session_start", r.SESSION_END = "session_end", r.CUSTOM = "custom", r.WEB_VITALS = "web_vitals", r.ERROR = "error", r))(d || {}), x = /* @__PURE__ */ ((r) => (r.UP = "up", r.DOWN = "down", r))(x || {}), N = /* @__PURE__ */ ((r) => (r.JS_ERROR = "js_error", r.PROMISE_REJECTION = "promise_rejection", r.NETWORK_ERROR = "network_error", r))(N || {}), H = /* @__PURE__ */ ((r) => (r.QA = "qa", r.DEBUG = "debug", r))(H || {}), yt = /* @__PURE__ */ ((r) => (r.AND = "AND", r.OR = "OR", r))(yt || {}), Tt = /* @__PURE__ */ ((r) => (r.URL_MATCHES = "url_matches", r.ELEMENT_MATCHES = "element_matches", r.DEVICE_TYPE = "device_type", r.ELEMENT_TEXT = "element_text", r.ELEMENT_ATTRIBUTE = "element_attribute", r.UTM_SOURCE = "utm_source", r.UTM_MEDIUM = "utm_medium", r.UTM_CAMPAIGN = "utm_campaign", r))(Tt || {}),
|
|
227
|
+
var w = /* @__PURE__ */ ((r) => (r.Skip = "skip", r.Localhost = "localhost:", r))(w || {}), re = /* @__PURE__ */ ((r) => (r.EVENT = "event", r.QUEUE = "queue", r))(re || {}), d = /* @__PURE__ */ ((r) => (r.PAGE_VIEW = "page_view", r.CLICK = "click", r.SCROLL = "scroll", r.SESSION_START = "session_start", r.SESSION_END = "session_end", r.CUSTOM = "custom", r.WEB_VITALS = "web_vitals", r.ERROR = "error", r))(d || {}), x = /* @__PURE__ */ ((r) => (r.UP = "up", r.DOWN = "down", r))(x || {}), N = /* @__PURE__ */ ((r) => (r.JS_ERROR = "js_error", r.PROMISE_REJECTION = "promise_rejection", r.NETWORK_ERROR = "network_error", r))(N || {}), H = /* @__PURE__ */ ((r) => (r.QA = "qa", r.DEBUG = "debug", r))(H || {}), yt = /* @__PURE__ */ ((r) => (r.AND = "AND", r.OR = "OR", r))(yt || {}), Tt = /* @__PURE__ */ ((r) => (r.URL_MATCHES = "url_matches", r.ELEMENT_MATCHES = "element_matches", r.DEVICE_TYPE = "device_type", r.ELEMENT_TEXT = "element_text", r.ELEMENT_ATTRIBUTE = "element_attribute", r.UTM_SOURCE = "utm_source", r.UTM_MEDIUM = "utm_medium", r.UTM_CAMPAIGN = "utm_campaign", r))(Tt || {}), _t = /* @__PURE__ */ ((r) => (r.EQUALS = "equals", r.CONTAINS = "contains", r.STARTS_WITH = "starts_with", r.ENDS_WITH = "ends_with", r.REGEX = "regex", r.GREATER_THAN = "greater_than", r.LESS_THAN = "less_than", r.EXISTS = "exists", r.NOT_EXISTS = "not_exists", r))(_t || {});
|
|
228
228
|
class O extends Error {
|
|
229
229
|
constructor(e, t, n) {
|
|
230
230
|
super(e), this.errorCode = t, this.layer = n, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
@@ -240,7 +240,7 @@ class M extends O {
|
|
|
240
240
|
super(e, "APP_CONFIG_INVALID", t);
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
|
-
class
|
|
243
|
+
class It extends O {
|
|
244
244
|
constructor(e, t = "config") {
|
|
245
245
|
super(e, "SESSION_TIMEOUT_INVALID", t);
|
|
246
246
|
}
|
|
@@ -270,7 +270,7 @@ const At = (r) => {
|
|
|
270
270
|
provided: r.sessionTimeout,
|
|
271
271
|
min: z,
|
|
272
272
|
max: G
|
|
273
|
-
}), new
|
|
273
|
+
}), new It(p.INVALID_SESSION_TIMEOUT, "config");
|
|
274
274
|
if (r.globalMetadata !== void 0 && (typeof r.globalMetadata != "object" || r.globalMetadata === null))
|
|
275
275
|
throw a.clientError("ConfigValidation", "Global metadata must be an object", {
|
|
276
276
|
provided: r.globalMetadata,
|
|
@@ -545,9 +545,9 @@ const At = (r) => {
|
|
|
545
545
|
} : r.length === 0 ? {
|
|
546
546
|
valid: !1,
|
|
547
547
|
error: "Event name cannot be empty"
|
|
548
|
-
} : r.length >
|
|
548
|
+
} : r.length > Ie ? {
|
|
549
549
|
valid: !1,
|
|
550
|
-
error: `Event name is too long (max ${
|
|
550
|
+
error: `Event name is too long (max ${Ie} characters)`
|
|
551
551
|
} : r.includes("<") || r.includes(">") || r.includes("&") ? {
|
|
552
552
|
valid: !1,
|
|
553
553
|
error: "Event name contains invalid characters"
|
|
@@ -1492,7 +1492,7 @@ class Yt extends f {
|
|
|
1492
1492
|
this.visibilityChangeHandler || this.beforeUnloadHandler || (this.visibilityChangeHandler = () => {
|
|
1493
1493
|
document.hidden ? this.clearSessionTimeout() : this.get("sessionId") && this.setupSessionTimeout();
|
|
1494
1494
|
}, this.beforeUnloadHandler = () => {
|
|
1495
|
-
this.
|
|
1495
|
+
this.endSession("page_unload");
|
|
1496
1496
|
}, document.addEventListener("visibilitychange", this.visibilityChangeHandler), window.addEventListener("beforeunload", this.beforeUnloadHandler));
|
|
1497
1497
|
}
|
|
1498
1498
|
cleanupLifecycleListeners() {
|
|
@@ -1765,22 +1765,33 @@ class Jt extends f {
|
|
|
1765
1765
|
limitWarningLogged = !1;
|
|
1766
1766
|
minDepthChange = ye;
|
|
1767
1767
|
minIntervalMs = Te;
|
|
1768
|
-
maxEventsPerSession =
|
|
1768
|
+
maxEventsPerSession = _e;
|
|
1769
1769
|
constructor(e) {
|
|
1770
1770
|
super(), this.eventManager = e;
|
|
1771
1771
|
}
|
|
1772
1772
|
startTracking() {
|
|
1773
1773
|
this.limitWarningLogged = !1, this.applyConfigOverrides(), this.set("scrollEventCount", 0);
|
|
1774
|
-
const e = this.get("config").scrollContainerSelectors,
|
|
1775
|
-
|
|
1776
|
-
for (const s of n)
|
|
1777
|
-
this.setupScrollContainer(s);
|
|
1774
|
+
const e = this.get("config").scrollContainerSelectors, t = Array.isArray(e) ? e : typeof e == "string" ? [e] : [];
|
|
1775
|
+
t.length === 0 ? this.setupScrollContainer(window) : this.trySetupContainers(t, 0);
|
|
1778
1776
|
}
|
|
1779
1777
|
stopTracking() {
|
|
1780
1778
|
for (const e of this.containers)
|
|
1781
1779
|
this.clearContainerTimer(e), e.element instanceof Window ? window.removeEventListener("scroll", e.listener) : e.element.removeEventListener("scroll", e.listener);
|
|
1782
1780
|
this.containers.length = 0, this.set("scrollEventCount", 0), this.limitWarningLogged = !1;
|
|
1783
1781
|
}
|
|
1782
|
+
trySetupContainers(e, t) {
|
|
1783
|
+
const n = e.map((s) => this.safeQuerySelector(s)).filter((s) => s instanceof HTMLElement);
|
|
1784
|
+
if (n.length > 0) {
|
|
1785
|
+
for (const s of n)
|
|
1786
|
+
this.containers.some((o) => o.element === s) || this.setupScrollContainer(s);
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1789
|
+
if (t < 5) {
|
|
1790
|
+
setTimeout(() => this.trySetupContainers(e, t + 1), 200);
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
this.containers.length === 0 && this.setupScrollContainer(window);
|
|
1794
|
+
}
|
|
1784
1795
|
setupScrollContainer(e) {
|
|
1785
1796
|
if (e !== window && !this.isElementScrollable(e))
|
|
1786
1797
|
return;
|
|
@@ -1836,7 +1847,7 @@ class Jt extends f {
|
|
|
1836
1847
|
}));
|
|
1837
1848
|
}
|
|
1838
1849
|
applyConfigOverrides() {
|
|
1839
|
-
this.minDepthChange = ye, this.minIntervalMs = Te, this.maxEventsPerSession =
|
|
1850
|
+
this.minDepthChange = ye, this.minIntervalMs = Te, this.maxEventsPerSession = _e;
|
|
1840
1851
|
}
|
|
1841
1852
|
isWindowScrollable() {
|
|
1842
1853
|
return document.documentElement.scrollHeight > window.innerHeight;
|
|
@@ -2048,7 +2059,7 @@ class tr extends f {
|
|
|
2048
2059
|
"largest-contentful-paint",
|
|
2049
2060
|
(n) => {
|
|
2050
2061
|
const s = n.getEntries(), i = s[s.length - 1];
|
|
2051
|
-
i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(
|
|
2062
|
+
i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(I)) });
|
|
2052
2063
|
},
|
|
2053
2064
|
{ type: "largest-contentful-paint", buffered: !0 },
|
|
2054
2065
|
!0
|
|
@@ -2066,14 +2077,14 @@ class tr extends f {
|
|
|
2066
2077
|
const c = typeof o.value == "number" ? o.value : 0;
|
|
2067
2078
|
e += c;
|
|
2068
2079
|
}
|
|
2069
|
-
this.sendVital({ type: "CLS", value: Number(e.toFixed(
|
|
2080
|
+
this.sendVital({ type: "CLS", value: Number(e.toFixed(I)) });
|
|
2070
2081
|
},
|
|
2071
2082
|
{ type: "layout-shift", buffered: !0 }
|
|
2072
2083
|
), this.safeObserve(
|
|
2073
2084
|
"paint",
|
|
2074
2085
|
(n) => {
|
|
2075
2086
|
for (const s of n.getEntries())
|
|
2076
|
-
s.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(s.startTime.toFixed(
|
|
2087
|
+
s.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(s.startTime.toFixed(I)) });
|
|
2077
2088
|
},
|
|
2078
2089
|
{ type: "paint", buffered: !0 },
|
|
2079
2090
|
!0
|
|
@@ -2086,7 +2097,7 @@ class tr extends f {
|
|
|
2086
2097
|
const c = (o.processingEnd ?? 0) - (o.startTime ?? 0);
|
|
2087
2098
|
s = Math.max(s, c);
|
|
2088
2099
|
}
|
|
2089
|
-
s > 0 && this.sendVital({ type: "INP", value: Number(s.toFixed(
|
|
2100
|
+
s > 0 && this.sendVital({ type: "INP", value: Number(s.toFixed(I)) });
|
|
2090
2101
|
},
|
|
2091
2102
|
{ type: "event", buffered: !0 }
|
|
2092
2103
|
);
|
|
@@ -2094,7 +2105,7 @@ class tr extends f {
|
|
|
2094
2105
|
async initWebVitals() {
|
|
2095
2106
|
try {
|
|
2096
2107
|
const { onLCP: e, onCLS: t, onFCP: n, onTTFB: s, onINP: i } = await Promise.resolve().then(() => Tr), o = (c) => (l) => {
|
|
2097
|
-
const u = Number(l.value.toFixed(
|
|
2108
|
+
const u = Number(l.value.toFixed(I));
|
|
2098
2109
|
this.sendVital({ type: c, value: u });
|
|
2099
2110
|
};
|
|
2100
2111
|
e(o("LCP")), t(o("CLS")), n(o("FCP")), s(o("TTFB")), i(o("INP"));
|
|
@@ -2110,7 +2121,7 @@ class tr extends f {
|
|
|
2110
2121
|
if (!e)
|
|
2111
2122
|
return;
|
|
2112
2123
|
const t = e.responseStart;
|
|
2113
|
-
typeof t == "number" && Number.isFinite(t) && this.sendVital({ type: "TTFB", value: Number(t.toFixed(
|
|
2124
|
+
typeof t == "number" && Number.isFinite(t) && this.sendVital({ type: "TTFB", value: Number(t.toFixed(I)) });
|
|
2114
2125
|
} catch (e) {
|
|
2115
2126
|
a.warn("PerformanceHandler", "Failed to report TTFB", {
|
|
2116
2127
|
error: e instanceof Error ? e.message : "Unknown error"
|
|
@@ -2123,7 +2134,7 @@ class tr extends f {
|
|
|
2123
2134
|
(e) => {
|
|
2124
2135
|
const t = e.getEntries();
|
|
2125
2136
|
for (const n of t) {
|
|
2126
|
-
const s = Number(n.duration.toFixed(
|
|
2137
|
+
const s = Number(n.duration.toFixed(I)), i = Date.now();
|
|
2127
2138
|
i - this.lastLongTaskSentAt >= mt && (this.shouldSendVital("LONG_TASK", s) && this.trackWebVital("LONG_TASK", s), this.lastLongTaskSentAt = i);
|
|
2128
2139
|
}
|
|
2129
2140
|
},
|
|
@@ -2455,10 +2466,10 @@ const sr = async (r) => {
|
|
|
2455
2466
|
} finally {
|
|
2456
2467
|
q = !1;
|
|
2457
2468
|
}
|
|
2458
|
-
},
|
|
2469
|
+
}, _r = {
|
|
2459
2470
|
WEB_VITALS_THRESHOLDS: Fe
|
|
2460
2471
|
// Business thresholds for performance analysis
|
|
2461
|
-
},
|
|
2472
|
+
}, Ir = {
|
|
2462
2473
|
PII_PATTERNS: ze
|
|
2463
2474
|
// Patterns for sensitive data protection
|
|
2464
2475
|
}, wr = {
|
|
@@ -2743,7 +2754,7 @@ export {
|
|
|
2743
2754
|
Cr as ANALYTICS_QUERY_LIMITS,
|
|
2744
2755
|
Pr as ANOMALY_DETECTION,
|
|
2745
2756
|
Mr as CONTENT_ANALYTICS,
|
|
2746
|
-
|
|
2757
|
+
Ir as DATA_PROTECTION,
|
|
2747
2758
|
br as DEVICE_ANALYTICS,
|
|
2748
2759
|
y as DeviceType,
|
|
2749
2760
|
wr as ENGAGEMENT_THRESHOLDS,
|
|
@@ -2751,13 +2762,13 @@ export {
|
|
|
2751
2762
|
d as EventType,
|
|
2752
2763
|
Rr as INSIGHT_THRESHOLDS,
|
|
2753
2764
|
H as Mode,
|
|
2754
|
-
|
|
2765
|
+
_r as PERFORMANCE_CONFIG,
|
|
2755
2766
|
Nr as SEGMENTATION_ANALYTICS,
|
|
2756
2767
|
Ar as SESSION_ANALYTICS,
|
|
2757
2768
|
Or as SPECIAL_PAGE_URLS,
|
|
2758
2769
|
x as ScrollDirection,
|
|
2759
2770
|
Lr as TEMPORAL_ANALYSIS,
|
|
2760
|
-
|
|
2771
|
+
_t as TagConditionOperator,
|
|
2761
2772
|
Tt as TagConditionType,
|
|
2762
2773
|
yt as TagLogicalOperator,
|
|
2763
2774
|
Dr as tracelog
|
package/dist/cjs/api.d.ts
CHANGED
|
@@ -28,14 +28,14 @@ export declare const event: (name: string, metadata?: Record<string, MetadataTyp
|
|
|
28
28
|
* @param event - Event name to listen to
|
|
29
29
|
* @param callback - Function to call when event is emitted
|
|
30
30
|
* @example
|
|
31
|
-
* // Listen for
|
|
32
|
-
* tracelog.on('
|
|
33
|
-
* console.log('Event tracked:', data.type
|
|
31
|
+
* // Listen for tracked events
|
|
32
|
+
* tracelog.on('event', (data) => {
|
|
33
|
+
* console.log('Event tracked:', data.type);
|
|
34
34
|
* });
|
|
35
35
|
*
|
|
36
|
-
* // Listen for sent
|
|
37
|
-
* tracelog.on('
|
|
38
|
-
* console.log('Events sent:', data.
|
|
36
|
+
* // Listen for event queues being sent
|
|
37
|
+
* tracelog.on('queue', (data) => {
|
|
38
|
+
* console.log('Events sent:', data.events.length);
|
|
39
39
|
* });
|
|
40
40
|
*/
|
|
41
41
|
export declare const on: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
|
|
@@ -45,7 +45,7 @@ export declare const on: <K extends keyof EmitterMap>(event: K, callback: Emitte
|
|
|
45
45
|
* @param callback - The same function reference that was used in on()
|
|
46
46
|
* @example
|
|
47
47
|
* // Remove a specific listener
|
|
48
|
-
* tracelog.off('
|
|
48
|
+
* tracelog.off('event', myCallback);
|
|
49
49
|
*/
|
|
50
50
|
export declare const off: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
|
|
51
51
|
/**
|
package/dist/cjs/api.js
CHANGED
|
@@ -96,14 +96,14 @@ exports.event = event;
|
|
|
96
96
|
* @param event - Event name to listen to
|
|
97
97
|
* @param callback - Function to call when event is emitted
|
|
98
98
|
* @example
|
|
99
|
-
* // Listen for
|
|
100
|
-
* tracelog.on('
|
|
101
|
-
* console.log('Event tracked:', data.type
|
|
99
|
+
* // Listen for tracked events
|
|
100
|
+
* tracelog.on('event', (data) => {
|
|
101
|
+
* console.log('Event tracked:', data.type);
|
|
102
102
|
* });
|
|
103
103
|
*
|
|
104
|
-
* // Listen for sent
|
|
105
|
-
* tracelog.on('
|
|
106
|
-
* console.log('Events sent:', data.
|
|
104
|
+
* // Listen for event queues being sent
|
|
105
|
+
* tracelog.on('queue', (data) => {
|
|
106
|
+
* console.log('Events sent:', data.events.length);
|
|
107
107
|
* });
|
|
108
108
|
*/
|
|
109
109
|
const on = (event, callback) => {
|
|
@@ -119,7 +119,7 @@ exports.on = on;
|
|
|
119
119
|
* @param callback - The same function reference that was used in on()
|
|
120
120
|
* @example
|
|
121
121
|
* // Remove a specific listener
|
|
122
|
-
* tracelog.off('
|
|
122
|
+
* tracelog.off('event', myCallback);
|
|
123
123
|
*/
|
|
124
124
|
const off = (event, callback) => {
|
|
125
125
|
if (!app) {
|
package/dist/cjs/app.types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Mode, EventType, DeviceType, ScrollDirection, ErrorType, TagConditionOperator, TagLogicalOperator, TagConditionType, } from './types';
|
|
2
|
-
export type { ScrollData, ClickData, CustomEventData, MetadataType, WebVitalsData, ErrorData, PageViewData, UTM, EventData, AppConfig, ApiConfig, ExtendedEventsQueueDto, TagConfig, BaseEventsQueueDto, WebVitalType, SessionEndReason, } from './types';
|
|
2
|
+
export type { ScrollData, ClickData, CustomEventData, MetadataType, WebVitalsData, ErrorData, PageViewData, UTM, EventLocation, EventData, AppConfig, ApiConfig, ExtendedEventsQueueDto, TagConfig, BaseEventsQueueDto, WebVitalType, SessionEndReason, } from './types';
|
|
@@ -10,6 +10,7 @@ export declare class ScrollHandler extends StateManager {
|
|
|
10
10
|
constructor(eventManager: EventManager);
|
|
11
11
|
startTracking(): void;
|
|
12
12
|
stopTracking(): void;
|
|
13
|
+
private trySetupContainers;
|
|
13
14
|
private setupScrollContainer;
|
|
14
15
|
private processScrollEvent;
|
|
15
16
|
private shouldEmitScrollEvent;
|
|
@@ -21,14 +21,11 @@ class ScrollHandler extends state_manager_1.StateManager {
|
|
|
21
21
|
this.set('scrollEventCount', 0);
|
|
22
22
|
const raw = this.get('config').scrollContainerSelectors;
|
|
23
23
|
const selectors = Array.isArray(raw) ? raw : typeof raw === 'string' ? [raw] : [];
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.filter((element) => element instanceof HTMLElement);
|
|
27
|
-
if (elements.length === 0) {
|
|
28
|
-
elements.push(window);
|
|
24
|
+
if (selectors.length === 0) {
|
|
25
|
+
this.setupScrollContainer(window);
|
|
29
26
|
}
|
|
30
|
-
|
|
31
|
-
this.
|
|
27
|
+
else {
|
|
28
|
+
this.trySetupContainers(selectors, 0);
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
31
|
stopTracking() {
|
|
@@ -45,6 +42,27 @@ class ScrollHandler extends state_manager_1.StateManager {
|
|
|
45
42
|
this.set('scrollEventCount', 0);
|
|
46
43
|
this.limitWarningLogged = false;
|
|
47
44
|
}
|
|
45
|
+
trySetupContainers(selectors, attempt) {
|
|
46
|
+
const elements = selectors
|
|
47
|
+
.map((sel) => this.safeQuerySelector(sel))
|
|
48
|
+
.filter((element) => element instanceof HTMLElement);
|
|
49
|
+
if (elements.length > 0) {
|
|
50
|
+
for (const element of elements) {
|
|
51
|
+
const isAlreadyTracking = this.containers.some((c) => c.element === element);
|
|
52
|
+
if (!isAlreadyTracking) {
|
|
53
|
+
this.setupScrollContainer(element);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (attempt < 5) {
|
|
59
|
+
setTimeout(() => this.trySetupContainers(selectors, attempt + 1), 200);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (this.containers.length === 0) {
|
|
63
|
+
this.setupScrollContainer(window);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
48
66
|
setupScrollContainer(element) {
|
|
49
67
|
// Skip setup for non-scrollable elements
|
|
50
68
|
if (element !== window && !this.isElementScrollable(element)) {
|
|
@@ -250,7 +250,7 @@ class SessionManager extends state_manager_1.StateManager {
|
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
252
|
this.beforeUnloadHandler = () => {
|
|
253
|
-
this.
|
|
253
|
+
this.endSession('page_unload');
|
|
254
254
|
};
|
|
255
255
|
// Handle tab visibility changes
|
|
256
256
|
document.addEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
@@ -75,6 +75,10 @@ export interface PageViewData {
|
|
|
75
75
|
search?: string;
|
|
76
76
|
hash?: string;
|
|
77
77
|
}
|
|
78
|
+
export interface EventLocation {
|
|
79
|
+
country: string;
|
|
80
|
+
country_code: string;
|
|
81
|
+
}
|
|
78
82
|
export interface VitalSample {
|
|
79
83
|
type: WebVitalType;
|
|
80
84
|
value: number;
|
|
@@ -94,6 +98,7 @@ export interface EventData {
|
|
|
94
98
|
session_end_reason?: SessionEndReason;
|
|
95
99
|
error_data?: ErrorData;
|
|
96
100
|
utm?: UTM;
|
|
101
|
+
location?: EventLocation;
|
|
97
102
|
tags?: string[] | {
|
|
98
103
|
id: string;
|
|
99
104
|
key: string;
|
package/dist/esm/api.d.ts
CHANGED
|
@@ -28,14 +28,14 @@ export declare const event: (name: string, metadata?: Record<string, MetadataTyp
|
|
|
28
28
|
* @param event - Event name to listen to
|
|
29
29
|
* @param callback - Function to call when event is emitted
|
|
30
30
|
* @example
|
|
31
|
-
* // Listen for
|
|
32
|
-
* tracelog.on('
|
|
33
|
-
* console.log('Event tracked:', data.type
|
|
31
|
+
* // Listen for tracked events
|
|
32
|
+
* tracelog.on('event', (data) => {
|
|
33
|
+
* console.log('Event tracked:', data.type);
|
|
34
34
|
* });
|
|
35
35
|
*
|
|
36
|
-
* // Listen for sent
|
|
37
|
-
* tracelog.on('
|
|
38
|
-
* console.log('Events sent:', data.
|
|
36
|
+
* // Listen for event queues being sent
|
|
37
|
+
* tracelog.on('queue', (data) => {
|
|
38
|
+
* console.log('Events sent:', data.events.length);
|
|
39
39
|
* });
|
|
40
40
|
*/
|
|
41
41
|
export declare const on: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
|
|
@@ -45,7 +45,7 @@ export declare const on: <K extends keyof EmitterMap>(event: K, callback: Emitte
|
|
|
45
45
|
* @param callback - The same function reference that was used in on()
|
|
46
46
|
* @example
|
|
47
47
|
* // Remove a specific listener
|
|
48
|
-
* tracelog.off('
|
|
48
|
+
* tracelog.off('event', myCallback);
|
|
49
49
|
*/
|
|
50
50
|
export declare const off: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
|
|
51
51
|
/**
|
package/dist/esm/api.js
CHANGED
|
@@ -91,14 +91,14 @@ export const event = (name, metadata) => {
|
|
|
91
91
|
* @param event - Event name to listen to
|
|
92
92
|
* @param callback - Function to call when event is emitted
|
|
93
93
|
* @example
|
|
94
|
-
* // Listen for
|
|
95
|
-
* tracelog.on('
|
|
96
|
-
* console.log('Event tracked:', data.type
|
|
94
|
+
* // Listen for tracked events
|
|
95
|
+
* tracelog.on('event', (data) => {
|
|
96
|
+
* console.log('Event tracked:', data.type);
|
|
97
97
|
* });
|
|
98
98
|
*
|
|
99
|
-
* // Listen for sent
|
|
100
|
-
* tracelog.on('
|
|
101
|
-
* console.log('Events sent:', data.
|
|
99
|
+
* // Listen for event queues being sent
|
|
100
|
+
* tracelog.on('queue', (data) => {
|
|
101
|
+
* console.log('Events sent:', data.events.length);
|
|
102
102
|
* });
|
|
103
103
|
*/
|
|
104
104
|
export const on = (event, callback) => {
|
|
@@ -113,7 +113,7 @@ export const on = (event, callback) => {
|
|
|
113
113
|
* @param callback - The same function reference that was used in on()
|
|
114
114
|
* @example
|
|
115
115
|
* // Remove a specific listener
|
|
116
|
-
* tracelog.off('
|
|
116
|
+
* tracelog.off('event', myCallback);
|
|
117
117
|
*/
|
|
118
118
|
export const off = (event, callback) => {
|
|
119
119
|
if (!app) {
|
package/dist/esm/app.types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Mode, EventType, DeviceType, ScrollDirection, ErrorType, TagConditionOperator, TagLogicalOperator, TagConditionType, } from './types';
|
|
2
|
-
export type { ScrollData, ClickData, CustomEventData, MetadataType, WebVitalsData, ErrorData, PageViewData, UTM, EventData, AppConfig, ApiConfig, ExtendedEventsQueueDto, TagConfig, BaseEventsQueueDto, WebVitalType, SessionEndReason, } from './types';
|
|
2
|
+
export type { ScrollData, ClickData, CustomEventData, MetadataType, WebVitalsData, ErrorData, PageViewData, UTM, EventLocation, EventData, AppConfig, ApiConfig, ExtendedEventsQueueDto, TagConfig, BaseEventsQueueDto, WebVitalType, SessionEndReason, } from './types';
|
|
@@ -10,6 +10,7 @@ export declare class ScrollHandler extends StateManager {
|
|
|
10
10
|
constructor(eventManager: EventManager);
|
|
11
11
|
startTracking(): void;
|
|
12
12
|
stopTracking(): void;
|
|
13
|
+
private trySetupContainers;
|
|
13
14
|
private setupScrollContainer;
|
|
14
15
|
private processScrollEvent;
|
|
15
16
|
private shouldEmitScrollEvent;
|
|
@@ -18,14 +18,11 @@ export class ScrollHandler extends StateManager {
|
|
|
18
18
|
this.set('scrollEventCount', 0);
|
|
19
19
|
const raw = this.get('config').scrollContainerSelectors;
|
|
20
20
|
const selectors = Array.isArray(raw) ? raw : typeof raw === 'string' ? [raw] : [];
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
.filter((element) => element instanceof HTMLElement);
|
|
24
|
-
if (elements.length === 0) {
|
|
25
|
-
elements.push(window);
|
|
21
|
+
if (selectors.length === 0) {
|
|
22
|
+
this.setupScrollContainer(window);
|
|
26
23
|
}
|
|
27
|
-
|
|
28
|
-
this.
|
|
24
|
+
else {
|
|
25
|
+
this.trySetupContainers(selectors, 0);
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
28
|
stopTracking() {
|
|
@@ -42,6 +39,27 @@ export class ScrollHandler extends StateManager {
|
|
|
42
39
|
this.set('scrollEventCount', 0);
|
|
43
40
|
this.limitWarningLogged = false;
|
|
44
41
|
}
|
|
42
|
+
trySetupContainers(selectors, attempt) {
|
|
43
|
+
const elements = selectors
|
|
44
|
+
.map((sel) => this.safeQuerySelector(sel))
|
|
45
|
+
.filter((element) => element instanceof HTMLElement);
|
|
46
|
+
if (elements.length > 0) {
|
|
47
|
+
for (const element of elements) {
|
|
48
|
+
const isAlreadyTracking = this.containers.some((c) => c.element === element);
|
|
49
|
+
if (!isAlreadyTracking) {
|
|
50
|
+
this.setupScrollContainer(element);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (attempt < 5) {
|
|
56
|
+
setTimeout(() => this.trySetupContainers(selectors, attempt + 1), 200);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (this.containers.length === 0) {
|
|
60
|
+
this.setupScrollContainer(window);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
45
63
|
setupScrollContainer(element) {
|
|
46
64
|
// Skip setup for non-scrollable elements
|
|
47
65
|
if (element !== window && !this.isElementScrollable(element)) {
|
|
@@ -247,7 +247,7 @@ export class SessionManager extends StateManager {
|
|
|
247
247
|
}
|
|
248
248
|
};
|
|
249
249
|
this.beforeUnloadHandler = () => {
|
|
250
|
-
this.
|
|
250
|
+
this.endSession('page_unload');
|
|
251
251
|
};
|
|
252
252
|
// Handle tab visibility changes
|
|
253
253
|
document.addEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
@@ -75,6 +75,10 @@ export interface PageViewData {
|
|
|
75
75
|
search?: string;
|
|
76
76
|
hash?: string;
|
|
77
77
|
}
|
|
78
|
+
export interface EventLocation {
|
|
79
|
+
country: string;
|
|
80
|
+
country_code: string;
|
|
81
|
+
}
|
|
78
82
|
export interface VitalSample {
|
|
79
83
|
type: WebVitalType;
|
|
80
84
|
value: number;
|
|
@@ -94,6 +98,7 @@ export interface EventData {
|
|
|
94
98
|
session_end_reason?: SessionEndReason;
|
|
95
99
|
error_data?: ErrorData;
|
|
96
100
|
utm?: UTM;
|
|
101
|
+
location?: EventLocation;
|
|
97
102
|
tags?: string[] | {
|
|
98
103
|
id: string;
|
|
99
104
|
key: string;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@tracelog/lib",
|
|
3
3
|
"description": "JavaScript library for web analytics and real-time event tracking",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.4.0",
|
|
6
6
|
"main": "./dist/cjs/public-api.js",
|
|
7
7
|
"module": "./dist/esm/public-api.js",
|
|
8
8
|
"types": "./dist/esm/public-api.d.ts",
|