@levo-so/insights 0.1.79 → 0.1.80

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.
@@ -1,140 +0,0 @@
1
- import { getLevoError as S } from "@levo-so/core";
2
- import { Analytics as j } from "analytics";
3
- import { getConfig as k } from "../stores/config.js";
4
- import { resetRateLimit as z } from "../stores/events.js";
5
- import { getSession as f, updateSession as a } from "../stores/session.js";
6
- import { getCurrentTab as D } from "../tracking/currentTab.js";
7
- import { getAuthHeaders as M } from "../utils/getAuthHeaders.js";
8
- const q = (r, p, s) => {
9
- const { debug: I } = k();
10
- if (!r)
11
- return null;
12
- const h = {
13
- name: r.workspace,
14
- /**
15
- * Handle track events (custom events like clicks, scrolls, etc.)
16
- *
17
- * Enriches the event with:
18
- * - Session/device IDs
19
- * - Page metadata (URL, title, etc.)
20
- * - Tab information
21
- * - Timestamp
22
- *
23
- * Then queues for batched sending.
24
- */
25
- track: ({ payload: e }) => {
26
- if (!s()) return;
27
- const o = e?.properties || {};
28
- p(e.event, o);
29
- },
30
- /**
31
- * Handle page view events.
32
- *
33
- * Called when navigating to a new page (in SPAs) or on initial load.
34
- * Resets the rate limit counter and tracks a page.view event.
35
- */
36
- page: ({ payload: e }) => {
37
- if (!s()) return;
38
- z();
39
- const o = e?.properties || {};
40
- p("page.view", {
41
- ...o,
42
- resource: "page"
43
- });
44
- },
45
- /**
46
- * Handle identify events (session establishment).
47
- *
48
- * This is called when identify() is invoked. It:
49
- * 1. Reads identity from session store (set by init())
50
- * 2. Checks if already identified (via BroadcastChannel) - if so, skip
51
- * 3. Calls /welcome API to get session/device IDs
52
- * 4. On success, broadcasts session to other tabs
53
- *
54
- * The /welcome API uses HttpOnly cookies to maintain persistent
55
- * device identity across sessions.
56
- */
57
- identify: ({ payload: e }) => {
58
- if (!s()) return;
59
- const { workspace: o, site_id: w, debug: l } = k(), {
60
- mode: d,
61
- isIdentified: m,
62
- isIdentifying: g,
63
- sessionToken: _,
64
- deviceToken: b,
65
- insightsBaseUrl: u,
66
- identity: i
67
- } = f(), y = D(), T = f().allTabs.length;
68
- if (!u || !i)
69
- return;
70
- const v = {
71
- ...{
72
- private_mode: e.traits?.private_mode ?? i.privateMode ?? !1,
73
- dark_mode: e.traits?.dark_mode ?? i.darkMode ?? !1,
74
- timezone: e.traits?.timezone ?? i.timezone ?? "",
75
- locale: e.traits?.locale ?? i.locale ?? "",
76
- referrer: e.traits?.referrer ?? i.referrer ?? { type: "", referrer: {}, data: {} },
77
- properties: {
78
- ...i.properties
79
- }
80
- },
81
- workspace_id: o ?? "",
82
- site_id: w ?? void 0,
83
- hostname: window.location.hostname,
84
- pathname: window.location.pathname,
85
- page_title: document.title,
86
- url: window.location.href,
87
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
88
- tab_id: y ?? "",
89
- tab_count: T ?? 0
90
- };
91
- if (l && console.log("[@levo-so/insights] Identification triggered:", {
92
- isIdentified: m,
93
- isIdentifying: g,
94
- welcomeInput: v
95
- }), m || g)
96
- return;
97
- if (a({ isIdentifying: !0 }), l) {
98
- console.log("[@levo-so/insights] Debug mode enabled. Mocking session identification."), a({
99
- isIdentified: !0,
100
- isIdentifying: !1,
101
- sessionId: "debug-session",
102
- deviceId: "debug-device"
103
- });
104
- return;
105
- }
106
- const A = {
107
- Accept: "application/json",
108
- "Content-Type": "application/json",
109
- ...M({ sessionToken: _, deviceToken: b, mode: d })
110
- };
111
- r.fetch.url(u, !0).url("/v1/insights/event/welcome").options({
112
- keepAlive: !0,
113
- credentials: d === "proxy" ? "include" : "omit"
114
- }).headers(A).post(v).json().then((t) => {
115
- if (!s()) return;
116
- const { isIdentified: C } = f();
117
- if (!C) {
118
- const n = { isIdentified: !0 };
119
- if (t?.content?.data?.session && (n.sessionId = t?.content?.data?.session), t?.content?.data?.device && (n.deviceId = t?.content?.data?.device), d === "direct" && t?.content?.meta) {
120
- const c = t.content.meta;
121
- c.device_token && (n.deviceToken = c.device_token), c.session_token && (n.sessionToken = c.session_token);
122
- }
123
- a(n);
124
- }
125
- }).catch((t) => {
126
- console.log("/welcome failed with error", S(t));
127
- }).finally(() => {
128
- a({ isIdentifying: !1 });
129
- });
130
- }
131
- };
132
- return j({
133
- app: r.workspace || "",
134
- debug: !!I,
135
- plugins: [h]
136
- });
137
- };
138
- export {
139
- q as createAnalytics
140
- };
@@ -1,141 +0,0 @@
1
- import { setConfig as b, getConfig as h, updateConfigKey as _ } from "../stores/config.js";
2
- import { queueEvent as T, flushEventQueue as C, getEventQueue as E, clearEventQueue as S, initSessionFlushListener as I } from "../stores/events.js";
3
- import { updateSession as s, getSession as f, onSessionReady as B, $isContextReady as U } from "../stores/session.js";
4
- import { initActivityTracker as z } from "../tracking/activity.js";
5
- import { initBounceTracker as M } from "../tracking/bounce.js";
6
- import { initClicksTracker as P } from "../tracking/clicks.js";
7
- import { initClipboardTracker as x } from "../tracking/clipboard.js";
8
- import { getCurrentTab as L, initCurrentTabTracker as Q } from "../tracking/currentTab.js";
9
- import { initFormsTracker as q } from "../tracking/forms.js";
10
- import { initPageTracker as A } from "../tracking/page.js";
11
- import { initScrollBehaviorTracker as D } from "../tracking/scrollBehavior.js";
12
- import { initTextSelectionTracker as F } from "../tracking/textSelection.js";
13
- import { detectMode as N } from "../utils/detectMode.js";
14
- import { getReferrer as O } from "../utils/getReferrer.js";
15
- import { getUserProperties as K } from "../utils/getUserProperties.js";
16
- import { createAnalytics as V } from "./analytics.js";
17
- let t = null, n = !1;
18
- const d = [], de = (c, m) => {
19
- const { insightsUrl: l, debug: p = !1, site: v = null } = m;
20
- b({
21
- workspace: c.workspace,
22
- debug: p,
23
- site_id: v
24
- }), typeof window < "u" && Promise.all([K(), O()]).then(([i, e]) => {
25
- const r = e?.type ? {
26
- type: e.type,
27
- referrer: e.referrer,
28
- data: e.data,
29
- raw: e.raw ?? ""
30
- } : null;
31
- s({
32
- identity: {
33
- locale: i.locale,
34
- timezone: i.timezone,
35
- darkMode: i.dark_mode,
36
- privateMode: i.private_mode,
37
- referrer: r,
38
- properties: i.properties
39
- }
40
- });
41
- }).catch(() => {
42
- s({
43
- identity: {
44
- locale: null,
45
- timezone: null,
46
- darkMode: null,
47
- privateMode: null,
48
- referrer: null,
49
- properties: null
50
- }
51
- });
52
- });
53
- const g = async (i, e) => {
54
- if (typeof window > "u")
55
- return;
56
- const { page_id: r } = h(), { allTabs: u } = f(), a = L(), o = u.length, k = {
57
- event: i,
58
- version: e?.version || 1,
59
- properties: {
60
- ...e,
61
- version: void 0,
62
- resource: void 0,
63
- identifier: void 0,
64
- hostname: void 0,
65
- pathname: void 0,
66
- url: void 0,
67
- page_title: void 0,
68
- created_at: void 0
69
- },
70
- hostname: window.location.hostname,
71
- pathname: window.location.pathname,
72
- url: e?.url ?? window.location.href,
73
- page_title: e?.page_title ?? document.title,
74
- resource: e?.resource ?? "page",
75
- identifier: e?.id ?? r ?? void 0,
76
- created_at: e?.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
77
- tab_id: a ?? "",
78
- tab_count: o
79
- };
80
- T(k);
81
- }, w = (i) => {
82
- !t || !n || t.identify("", { withLock: !0 });
83
- }, y = (i) => {
84
- const { page_id: e } = h();
85
- e !== i && _("page_id", i);
86
- };
87
- return {
88
- init: (i = {}) => {
89
- if (typeof window > "u")
90
- throw new Error("[@levo-so/insights] init() should only be called on the client side.");
91
- const { pageId: e } = i;
92
- if (e && y(e), !n && !(c.NODE_ENV === "development" && !p)) {
93
- if (!l) {
94
- console.error(
95
- "[@levo-so/insights] The utility could not be initialized due to missing insights endpoint."
96
- );
97
- return;
98
- }
99
- n = !0, B(() => {
100
- if (!n) return;
101
- const { insightsBaseUrl: r } = f();
102
- r || N(m).then(({ mode: a, url: o }) => {
103
- n && o && s({ mode: a, insightsBaseUrl: o });
104
- }).catch(() => {
105
- l && s({ mode: "proxy", insightsBaseUrl: l });
106
- });
107
- const u = U.subscribe((a) => {
108
- if (!(!a || !n) && !t) {
109
- const o = V(c, g, () => t === o);
110
- t = o, f().insightsBaseUrl && t && (d.push(
111
- I(),
112
- z(t),
113
- M(t),
114
- P(t),
115
- x(t),
116
- Q(),
117
- q(t),
118
- A(t),
119
- D(t),
120
- F(t)
121
- ), w(), t.page({ resource: "page" }));
122
- }
123
- });
124
- d.push(u);
125
- });
126
- }
127
- },
128
- destroy: () => {
129
- n && (C(E()), S(), d.forEach((i) => {
130
- i();
131
- }), d.length = 0, t = null, n = !1);
132
- },
133
- track: g,
134
- get instance() {
135
- return t;
136
- }
137
- };
138
- };
139
- export {
140
- de as createLevoInsights
141
- };
@@ -1,13 +0,0 @@
1
- import { map as n } from "nanostores";
2
- const t = n({
3
- workspace: null,
4
- page_id: null,
5
- site_id: null,
6
- debug: !1
7
- }), s = () => t.get(), i = (e) => t.set({ ...s(), ...e }), l = (e, o) => t.setKey(e, o);
8
- export {
9
- t as $config,
10
- s as getConfig,
11
- i as setConfig,
12
- l as updateConfigKey
13
- };
@@ -1,90 +0,0 @@
1
- import { atom as l, computed as $ } from "nanostores";
2
- import { getAuthHeaders as k } from "../utils/getAuthHeaders.js";
3
- import { getConfig as h } from "./config.js";
4
- import { getSession as v, $session as y } from "./session.js";
5
- const A = 10, B = 2e3, p = 500, o = l([]), c = l(0), N = $(o, (e) => e.length ?? 0), i = l(null), O = () => {
6
- let e = !1;
7
- return y.subscribe((t) => {
8
- if (t.isIdentified && !e) {
9
- e = !0;
10
- const s = o.get();
11
- s.length > 0 && f(s);
12
- }
13
- });
14
- }, _ = () => o.get(), P = () => N.get(), f = (e) => {
15
- const { workspace: t, debug: s, site_id: r, page_id: a } = h(), { isIdentified: T, mode: u, sessionId: b, deviceId: w, sessionToken: C, deviceToken: I, insightsBaseUrl: g } = v();
16
- if (e.length === 0 || !T || !g || !t)
17
- return;
18
- const d = e.map(
19
- (n) => ({
20
- // Default values from stores
21
- workspace_id: t,
22
- site_id: r ?? void 0,
23
- session_id: b ?? void 0,
24
- device_id: w ?? void 0,
25
- identifier: a ?? void 0,
26
- hostname: window.location.hostname,
27
- pathname: window.location.pathname,
28
- page_title: document.title,
29
- url: window.location.href,
30
- tab_id: "",
31
- tab_count: 0,
32
- // Event values override defaults (includes tab_id, tab_count captured at track time)
33
- ...n,
34
- // Ensure required fields have values
35
- event: n.event,
36
- created_at: n.created_at,
37
- resource: n.resource ?? "page",
38
- properties: n.properties ?? {}
39
- })
40
- );
41
- if (o.set([]), s) {
42
- console.log("[@levo-so/insights] Debug mode enabled. Events batch:", d);
43
- return;
44
- }
45
- const m = `${g}/v1/insights/event/bulk?workspace=${t}`, S = {
46
- "Content-Type": "application/json",
47
- ...k({ deviceToken: I, sessionToken: C, mode: u })
48
- };
49
- u === "proxy" && navigator.sendBeacon && navigator.sendBeacon(m, JSON.stringify(d)) || fetch(m, {
50
- method: "POST",
51
- body: JSON.stringify(d),
52
- headers: S,
53
- keepalive: !0,
54
- credentials: u === "proxy" ? "include" : "omit"
55
- }).catch(() => {
56
- });
57
- }, Q = () => {
58
- if (i.get()) return;
59
- const e = setTimeout(() => {
60
- f(_()), i.set(null);
61
- }, B);
62
- i.set(e);
63
- }, E = () => {
64
- const e = i.get();
65
- e && (clearTimeout(e), i.set(null));
66
- }, R = (e) => {
67
- const { debug: t } = h(), s = c.get();
68
- if (s >= p) {
69
- t && console.warn(`[@levo-so/core] Event limit (${p}) reached for this page`);
70
- return;
71
- }
72
- c.set(s + 1);
73
- const r = o.get();
74
- o.set([...r, e]);
75
- const { isIdentified: a } = v();
76
- P() >= A ? (E(), f(_())) : a && Q();
77
- }, q = () => c.set(0), J = () => {
78
- o.set([]), c.set(0), E();
79
- };
80
- export {
81
- o as $eventQueue,
82
- c as $lifetimePageCount,
83
- N as $totalEventCount,
84
- J as clearEventQueue,
85
- f as flushEventQueue,
86
- _ as getEventQueue,
87
- O as initSessionFlushListener,
88
- R as queueEvent,
89
- q as resetRateLimit
90
- };
@@ -1,66 +0,0 @@
1
- import { computed as u, atom as g } from "nanostores";
2
- import { STORAGE_KEYS as i } from "../constants/storageKeys.js";
3
- import { checkLocalStorageAvailable as y } from "../utils/checkLocalStorage.js";
4
- const c = {
5
- isIdentified: !1,
6
- isIdentifying: !1,
7
- sessionId: null,
8
- deviceId: null,
9
- deviceToken: null,
10
- sessionToken: null,
11
- allTabs: [],
12
- mode: "proxy",
13
- insightsBaseUrl: null,
14
- identity: null
15
- }, S = JSON.stringify, f = (e) => {
16
- if (!e) return c;
17
- try {
18
- return JSON.parse(e);
19
- } catch {
20
- return c;
21
- }
22
- }, t = g(c), n = t.set;
23
- let l = !1;
24
- const d = [], a = () => {
25
- l || (l = !0, d.forEach((e) => {
26
- e();
27
- }), d.length = 0);
28
- }, I = (e) => {
29
- l ? e() : d.push(e);
30
- };
31
- if (y()) {
32
- const e = localStorage.getItem(i.session);
33
- e && n(f(e)), a(), t.set = (s) => {
34
- n(s);
35
- try {
36
- localStorage.setItem(i.session, S(s));
37
- } catch {
38
- }
39
- }, window.addEventListener("storage", (s) => {
40
- s.key === i.session && n(f(s.newValue));
41
- });
42
- } else if (typeof BroadcastChannel < "u") {
43
- const e = new BroadcastChannel(i.session);
44
- e.onmessage = (s) => {
45
- const { type: r, value: o } = s.data;
46
- r === "UPDATE" && o ? n(o) : r === "QUERY" ? l && e.postMessage({ type: "RESPONSE", value: t.get() }) : r === "RESPONSE" && o && (n(o), a());
47
- }, t.set = (s) => {
48
- n(s), e.postMessage({ type: "UPDATE", value: s });
49
- }, e.postMessage({ type: "QUERY" }), setTimeout(() => {
50
- a();
51
- }, 150);
52
- } else
53
- a();
54
- const p = () => t.get(), R = (e) => {
55
- t.set({ ...p(), ...e });
56
- }, T = u(
57
- t,
58
- (e) => e.insightsBaseUrl !== null && e.identity !== null
59
- );
60
- export {
61
- T as $isContextReady,
62
- t as $session,
63
- p as getSession,
64
- I as onSessionReady,
65
- R as updateSession
66
- };
@@ -1,33 +0,0 @@
1
- import { onUserActivity as o } from "@analytics/activity-utils";
2
- import { map as n } from "nanostores";
3
- const s = n({
4
- status: "active",
5
- seconds: 0
6
- }), T = (e) => {
7
- if (typeof window > "u") return () => {
8
- };
9
- const i = o({
10
- timeout: 6e4,
11
- throttle: 1e3,
12
- onIdle: (t) => {
13
- s.set({ status: "idle", seconds: t });
14
- },
15
- onWakeUp: (t) => {
16
- s.set({ status: "active", seconds: t });
17
- }
18
- }), c = s.listen((t) => {
19
- t.seconds > 0 && (t.status === "idle" ? e.track("user.idle", {
20
- seconds_active: t.seconds
21
- }) : e.track("user.active", {
22
- seconds_idle: t.seconds
23
- }));
24
- });
25
- return () => {
26
- c(), i.disable(), s.set({ status: "active", seconds: 0 });
27
- };
28
- }, v = () => s.get();
29
- export {
30
- s as $activity,
31
- v as getActivityStatus,
32
- T as initActivityTracker
33
- };
@@ -1,90 +0,0 @@
1
- import { getLevoError as u } from "@levo-so/core";
2
- import { atom as y } from "nanostores";
3
- import { $config as l } from "../stores/config.js";
4
- import { flushEventQueue as g, getEventQueue as p } from "../stores/events.js";
5
- import { getActivityStatus as w } from "./activity.js";
6
- const n = y(
7
- "active"
8
- /* ACTIVE */
9
- ), b = () => typeof document > "u" ? "active" : document.visibilityState === "hidden" ? "hidden" : document.hasFocus() ? "active" : "passive", S = (v) => {
10
- if (typeof window > "u") return () => {
11
- };
12
- let o = !1;
13
- const r = (e) => {
14
- if (o) return;
15
- o = !0;
16
- const i = w(), t = {};
17
- i.seconds > 0 && (i.status === "idle" ? t.seconds_idle = i.seconds : t.seconds_active = i.seconds);
18
- try {
19
- v.track("page.bounce", {
20
- resource: "page",
21
- ...t,
22
- ...e
23
- }), g(p());
24
- } catch (f) {
25
- console.error("[insights] Failed to send bounce event", u(f));
26
- }
27
- }, a = () => {
28
- const e = performance.getEntriesByType("navigation")?.[0];
29
- let i = e?.type === "navigate";
30
- if (!i)
31
- try {
32
- const t = document.activeElement;
33
- t?.tagName === "A" && t.href && new URL(t.href).origin !== window.location.origin && (i = !0);
34
- } catch (t) {
35
- console.warn("[insights] Failed to parse link destination", u(t));
36
- }
37
- r({
38
- is_navigating_away: i,
39
- navigation_type: e?.type,
40
- trigger: "beforeunload"
41
- });
42
- }, s = (e) => {
43
- switch (e.type) {
44
- case "pageshow":
45
- case "resume":
46
- case "blur":
47
- case "focus":
48
- case "visibilitychange":
49
- n.set(b());
50
- break;
51
- case "freeze":
52
- n.set(
53
- "frozen"
54
- /* FROZEN */
55
- );
56
- break;
57
- case "pagehide":
58
- n.set(
59
- e.persisted ? "frozen" : "terminated"
60
- /* TERMINATED */
61
- );
62
- break;
63
- }
64
- }, c = ["pageshow", "pagehide", "focus", "blur", "visibilitychange", "resume", "freeze"];
65
- c.forEach((e) => {
66
- window.addEventListener(e, s, { capture: !0 });
67
- }), window.addEventListener("beforeunload", a);
68
- const m = n.listen((e) => {
69
- e === "frozen" || e === "terminated" ? r({
70
- state: e,
71
- trigger: "lifecycle"
72
- }) : e === "hidden" && g(p());
73
- });
74
- let d = l.get().page_id;
75
- const h = l.listen((e) => {
76
- e.page_id !== d && (o = !1, d = e.page_id);
77
- });
78
- return () => {
79
- c.forEach((e) => {
80
- window.removeEventListener(e, s, { capture: !0 });
81
- }), window.removeEventListener("beforeunload", a), m(), h(), o = !1, n.set(
82
- "active"
83
- /* ACTIVE */
84
- );
85
- };
86
- };
87
- export {
88
- n as $pageLifecycle,
89
- S as initBounceTracker
90
- };
@@ -1,122 +0,0 @@
1
- import { getLevoError as s } from "@levo-so/core";
2
- import { getAttributes as g } from "../utils/autocapture.js";
3
- import { isRageClick as y } from "../utils/rageclick.js";
4
- const w = (c) => {
5
- let i = c, e = 0;
6
- for (; i && e < 10; ) {
7
- const o = i.getAttribute?.("href");
8
- if (o)
9
- return o;
10
- i = i.parentElement, e++;
11
- }
12
- return null;
13
- }, u = (c) => {
14
- const i = c.closest("a[href]"), e = i?.getAttribute("href") || w(c);
15
- if (!e) return { type: null, href: null };
16
- if (i?.hasAttribute("download"))
17
- return { type: "download", href: e };
18
- if (e.startsWith("tel:")) return { type: "tel", href: e };
19
- if (e.startsWith("mailto:")) return { type: "mailto", href: e };
20
- if (e.startsWith("#")) return { type: "anchor", href: e };
21
- try {
22
- return {
23
- type: new URL(e, window.location.origin).origin === window.location.origin ? "internal" : "external",
24
- href: e
25
- };
26
- } catch (o) {
27
- return console.warn("[insights] Failed to classify link", s(o)), { type: "internal", href: e };
28
- }
29
- }, _ = (c) => {
30
- if (typeof window > "u") return () => {
31
- };
32
- let i = 0, e = null;
33
- const o = (t, r = !1) => {
34
- const n = t.target, l = "clientX" in t ? t.clientX : t.changedTouches?.[0]?.clientX ?? 0, m = "clientY" in t ? t.clientY : t.changedTouches?.[0]?.clientY ?? 0;
35
- let a = {
36
- hostname: window.location.hostname,
37
- pathname: window.location.pathname,
38
- page_title: document.title,
39
- url: window.location.href,
40
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
41
- event_type: r ? "dblclick" : "click",
42
- button_type: "button" in t ? t.button : 0
43
- };
44
- return n instanceof HTMLElement && (a.rage_click = y(l, m, Date.now()), a = {
45
- ...a,
46
- ...g(n)
47
- }), a;
48
- }, k = (t, r) => {
49
- try {
50
- if (Date.now() - i < 300) return;
51
- const n = o(t);
52
- c.track("page.click", {
53
- ...n,
54
- href: r.href || void 0,
55
- link_type: r.type,
56
- is_navigation: !0
57
- });
58
- } catch (n) {
59
- console.error("[insights] Failed to track navigation click", s(n));
60
- }
61
- }, d = (t, r = !1) => {
62
- try {
63
- if (!(t.target instanceof HTMLElement) || Date.now() - i < 300) return;
64
- const n = o(t, r), l = u(t.target);
65
- c.track("page.click", {
66
- ...n,
67
- href: l.href || void 0,
68
- link_type: l.type || void 0
69
- });
70
- } catch (n) {
71
- console.error("[insights] Failed to track click", s(n));
72
- }
73
- }, f = (t) => {
74
- if (!(t.target instanceof HTMLElement)) return;
75
- const r = u(t.target);
76
- if (r.type === "external" || r.type === "download") {
77
- k(t, r);
78
- return;
79
- }
80
- if (e) {
81
- clearTimeout(e), e = null;
82
- return;
83
- }
84
- e = setTimeout(() => {
85
- d(t, !1), e = null;
86
- }, 250);
87
- }, h = (t) => {
88
- e && (clearTimeout(e), e = null), d(t, !0);
89
- }, p = (t) => {
90
- try {
91
- if (!(t.target instanceof HTMLElement)) return;
92
- i = Date.now();
93
- const r = u(t.target);
94
- if (r.type === "external" || r.type === "download") {
95
- const l = o(t);
96
- c.track("page.click", {
97
- ...l,
98
- href: r.href || void 0,
99
- link_type: r.type,
100
- is_navigation: !0,
101
- is_touch: !0
102
- });
103
- return;
104
- }
105
- const n = o(t);
106
- c.track("page.click", {
107
- ...n,
108
- href: r.href || void 0,
109
- link_type: r.type || void 0,
110
- is_touch: !0
111
- });
112
- } catch (r) {
113
- console.error("[insights] Failed to track touch", s(r));
114
- }
115
- };
116
- return document.addEventListener("click", f), document.addEventListener("dblclick", h), document.addEventListener("touchend", p, { passive: !0 }), () => {
117
- document.removeEventListener("click", f), document.removeEventListener("dblclick", h), document.removeEventListener("touchend", p), e && clearTimeout(e);
118
- };
119
- };
120
- export {
121
- _ as initClicksTracker
122
- };