@levo-so/insights 0.1.86 → 0.1.108
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/index.js +194 -202
- package/dist/lib/insights.d.ts +5 -4
- package/dist/stores/config.d.ts +5 -0
- package/dist/stores/readiness.d.ts +23 -0
- package/dist/stores/session.d.ts +8 -12
- package/dist/stores.d.ts +2 -1
- package/dist/stores.js +2 -2
- package/dist/{textSelection-DC99Tbqq.js → textSelection-eSp_MmZH.js} +132 -119
- package/dist/types/options.d.ts +6 -1
- package/dist/utils/onceTrue.d.ts +10 -0
- package/package.json +23 -22
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity pipeline gate — flipped when getUserProperties + getReferrer
|
|
3
|
+
* have settled and the result has been written to $session.identity.
|
|
4
|
+
* Independent of network configuration.
|
|
5
|
+
*/
|
|
6
|
+
declare const $isIdentityReady: import('nanostores').PreinitializedWritableAtom<boolean> & object;
|
|
7
|
+
/**
|
|
8
|
+
* Network pipeline gate — flipped when detectMode has resolved (or was
|
|
9
|
+
* skipped because $session.insightsBaseUrl was already cached). Stays
|
|
10
|
+
* false forever when no insightsUrl is configured.
|
|
11
|
+
*/
|
|
12
|
+
declare const $isBaseUrlReady: import('nanostores').PreinitializedWritableAtom<boolean> & object;
|
|
13
|
+
/**
|
|
14
|
+
* Local-store readiness. Trackers and tracker-only consumers (popups) gate
|
|
15
|
+
* on this — they need session + identity, not a resolved base URL.
|
|
16
|
+
*/
|
|
17
|
+
declare const $isIdentityContextReady: import('nanostores').ReadableAtom<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Network readiness. /welcome and the initial page view gate on this.
|
|
20
|
+
* Implies identity context is ready and a usable base URL is known.
|
|
21
|
+
*/
|
|
22
|
+
declare const $isNetworkReady: import('nanostores').ReadableAtom<boolean>;
|
|
23
|
+
export { $isIdentityReady, $isBaseUrlReady, $isIdentityContextReady, $isNetworkReady };
|
package/dist/stores/session.d.ts
CHANGED
|
@@ -24,17 +24,13 @@ interface ISession {
|
|
|
24
24
|
identity: IIdentity | null;
|
|
25
25
|
}
|
|
26
26
|
declare const $session: import('nanostores').PreinitializedWritableAtom<ISession> & object;
|
|
27
|
-
/** Calls cb immediately if the session is already loaded, otherwise queues it. */
|
|
28
|
-
declare const onSessionReady: (cb: () => void) => void;
|
|
29
|
-
declare const isSessionReady: () => boolean;
|
|
30
|
-
declare const getSession: () => ISession;
|
|
31
|
-
declare const updateSession: (v: Partial<ISession>) => void;
|
|
32
|
-
export { $session, getSession, updateSession, onSessionReady, isSessionReady, type ISession };
|
|
33
27
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
28
|
+
* Becomes true once the session is loaded from storage (synchronous for
|
|
29
|
+
* localStorage, up to 150ms for BroadcastChannel handshake). Downstream
|
|
30
|
+
* pipelines (identity, network) gate on this so writes via updateSession
|
|
31
|
+
* survive the BroadcastChannel full-replace handshake.
|
|
38
32
|
*/
|
|
39
|
-
declare const $
|
|
40
|
-
|
|
33
|
+
declare const $isSessionHydrated: import('nanostores').PreinitializedWritableAtom<boolean> & object;
|
|
34
|
+
declare const getSession: () => ISession;
|
|
35
|
+
declare const updateSession: (v: Partial<ISession>) => void;
|
|
36
|
+
export { $session, $isSessionHydrated, getSession, updateSession, type ISession };
|
package/dist/stores.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { $config } from './stores/config';
|
|
2
2
|
export { $eventQueue, $lifetimePageCount, $totalEventCount } from './stores/events';
|
|
3
|
-
export { $
|
|
3
|
+
export { $isIdentityContextReady } from './stores/readiness';
|
|
4
|
+
export { $session } from './stores/session';
|
|
4
5
|
export { $activity } from './tracking/activity';
|
|
5
6
|
export { $pageLifecycle } from './tracking/bounce';
|
|
6
7
|
export { $currentTab } from './tracking/currentTab';
|
package/dist/stores.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { M as e, O as t, a as n, b as r, d as i, g as a, p as o, r as s, t as c, x as l, y as u } from "./textSelection-eSp_MmZH.js";
|
|
2
|
+
export { o as $activity, e as $config, n as $currentTab, u as $eventQueue, a as $isIdentityContextReady, r as $lifetimePageCount, i as $pageLifecycle, s as $scrollBehavior, c as $selectedText, t as $session, l as $totalEventCount };
|
|
@@ -7,7 +7,8 @@ var o = n({
|
|
|
7
7
|
workspace: null,
|
|
8
8
|
page_id: null,
|
|
9
9
|
site_id: null,
|
|
10
|
-
debug: !1
|
|
10
|
+
debug: !1,
|
|
11
|
+
insightsUrl: null
|
|
11
12
|
}), s = () => o.get(), c = (e) => o.set({
|
|
12
13
|
...s(),
|
|
13
14
|
...e
|
|
@@ -50,12 +51,8 @@ var o = n({
|
|
|
50
51
|
} catch {
|
|
51
52
|
return p;
|
|
52
53
|
}
|
|
53
|
-
}, g = e(p), _ = g.set, v = !1, y =
|
|
54
|
-
v || (
|
|
55
|
-
e();
|
|
56
|
-
}), y.length = 0);
|
|
57
|
-
}, ee = (e) => {
|
|
58
|
-
v ? e() : y.push(e);
|
|
54
|
+
}, g = e(p), _ = g.set, v = e(!1), y = () => {
|
|
55
|
+
v.get() || v.set(!0);
|
|
59
56
|
};
|
|
60
57
|
if (f()) {
|
|
61
58
|
let e = () => {
|
|
@@ -80,7 +77,7 @@ if (f()) {
|
|
|
80
77
|
...h(n),
|
|
81
78
|
isIdentified: r.isIdentified,
|
|
82
79
|
isIdentifying: !1
|
|
83
|
-
}),
|
|
80
|
+
}), y(), g.set = (e) => {
|
|
84
81
|
_(e);
|
|
85
82
|
try {
|
|
86
83
|
localStorage.setItem(d.session, m(e));
|
|
@@ -96,26 +93,26 @@ if (f()) {
|
|
|
96
93
|
let e = new BroadcastChannel(d.session);
|
|
97
94
|
e.onmessage = (t) => {
|
|
98
95
|
let { type: n, value: r } = t.data;
|
|
99
|
-
n === "UPDATE" && r ? _(r) : n === "QUERY" ? v && e.postMessage({
|
|
96
|
+
n === "UPDATE" && r ? _(r) : n === "QUERY" ? v.get() && e.postMessage({
|
|
100
97
|
type: "RESPONSE",
|
|
101
98
|
value: g.get()
|
|
102
|
-
}) : n === "RESPONSE" && r && (_(r),
|
|
99
|
+
}) : n === "RESPONSE" && r && (_(r), y());
|
|
103
100
|
}, g.set = (t) => {
|
|
104
101
|
_(t), e.postMessage({
|
|
105
102
|
type: "UPDATE",
|
|
106
103
|
value: t
|
|
107
104
|
});
|
|
108
105
|
}, e.postMessage({ type: "QUERY" }), setTimeout(() => {
|
|
109
|
-
|
|
106
|
+
y();
|
|
110
107
|
}, 150);
|
|
111
|
-
} else
|
|
112
|
-
var
|
|
108
|
+
} else y();
|
|
109
|
+
var b = () => g.get(), x = (e) => {
|
|
113
110
|
g.set({
|
|
114
|
-
...
|
|
111
|
+
...b(),
|
|
115
112
|
...e
|
|
116
113
|
});
|
|
117
|
-
},
|
|
118
|
-
let { workspace: t, debug: n, site_id: r, page_id: i } = s(), { isIdentified: a, mode: o, sessionId: c, deviceId: l, sessionToken: d, deviceToken: f, insightsBaseUrl: p } =
|
|
114
|
+
}, ee = 10, te = 2e3, S = 500, C = e([]), w = e(0), T = t(C, (e) => e.length ?? 0), E = e(null), D = () => C.get(), ne = () => T.get(), O = (e) => {
|
|
115
|
+
let { workspace: t, debug: n, site_id: r, page_id: i } = s(), { isIdentified: a, mode: o, sessionId: c, deviceId: l, sessionToken: d, deviceToken: f, insightsBaseUrl: p } = b();
|
|
119
116
|
if (e.length === 0 || !a || !p || !t) return;
|
|
120
117
|
let m = e.map((e) => ({
|
|
121
118
|
workspace_id: t,
|
|
@@ -135,11 +132,15 @@ var x = () => g.get(), S = (e) => {
|
|
|
135
132
|
resource: e.resource ?? "page",
|
|
136
133
|
properties: e.properties ?? {}
|
|
137
134
|
}));
|
|
138
|
-
if (
|
|
135
|
+
if (C.set([]), n) {
|
|
139
136
|
console.log("[@levo-so/insights] Debug mode enabled. Events batch:", m);
|
|
140
137
|
return;
|
|
141
138
|
}
|
|
142
|
-
let h =
|
|
139
|
+
let h = new URLSearchParams({ workspace: t });
|
|
140
|
+
o === "direct" && (f && h.set("device_token", f), d && h.set("session_token", d));
|
|
141
|
+
let g = `${p}/v1/insights/event/bulk?${h.toString()}`;
|
|
142
|
+
if (navigator.sendBeacon && navigator.sendBeacon(g, JSON.stringify(m))) return;
|
|
143
|
+
let _ = {
|
|
143
144
|
"Content-Type": "application/json",
|
|
144
145
|
...u({
|
|
145
146
|
deviceToken: f,
|
|
@@ -147,85 +148,97 @@ var x = () => g.get(), S = (e) => {
|
|
|
147
148
|
mode: o
|
|
148
149
|
})
|
|
149
150
|
};
|
|
150
|
-
|
|
151
|
+
fetch(g, {
|
|
151
152
|
method: "POST",
|
|
152
153
|
body: JSON.stringify(m),
|
|
153
|
-
headers:
|
|
154
|
+
headers: _,
|
|
154
155
|
keepalive: !0,
|
|
155
156
|
credentials: o === "proxy" ? "include" : "omit"
|
|
156
157
|
}).catch((e) => {
|
|
157
158
|
console.warn("[@levo-so/insights] Event flush failed, batch lost:", e);
|
|
158
159
|
});
|
|
159
|
-
},
|
|
160
|
-
if (
|
|
160
|
+
}, k = () => {
|
|
161
|
+
if (E.get()) return;
|
|
161
162
|
let e = setTimeout(() => {
|
|
162
|
-
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
},
|
|
166
|
-
let e =
|
|
167
|
-
e && (clearTimeout(e),
|
|
168
|
-
},
|
|
169
|
-
let { debug: t } = s()
|
|
170
|
-
if (n
|
|
171
|
-
t && console.warn(
|
|
163
|
+
O(D()), E.set(null);
|
|
164
|
+
}, te);
|
|
165
|
+
E.set(e);
|
|
166
|
+
}, A = () => {
|
|
167
|
+
let e = E.get();
|
|
168
|
+
e && (clearTimeout(e), E.set(null));
|
|
169
|
+
}, re = (e) => {
|
|
170
|
+
let { debug: t, insightsUrl: n } = s();
|
|
171
|
+
if (!n) {
|
|
172
|
+
t && console.warn("[@levo-so/insights] Event dropped — insightsUrl not configured.", {
|
|
173
|
+
event: e.event,
|
|
174
|
+
resource: e.resource
|
|
175
|
+
});
|
|
172
176
|
return;
|
|
173
177
|
}
|
|
174
|
-
T.set(n + 1);
|
|
175
178
|
let r = w.get();
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
179
|
+
if (r >= S) {
|
|
180
|
+
t && console.warn(`[@levo-so/core] Event limit (${S}) reached for this page`);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
w.set(r + 1);
|
|
184
|
+
let i = C.get();
|
|
185
|
+
C.set([...i, e]);
|
|
186
|
+
let { isIdentified: a } = b();
|
|
187
|
+
ne() >= ee ? (A(), O(D())) : a && k();
|
|
188
|
+
}, ie = () => w.set(0), j = g.get().isIdentified;
|
|
180
189
|
g.subscribe((e) => {
|
|
181
|
-
e.isIdentified && !
|
|
190
|
+
e.isIdentified && !j && C.get().length > 0 && (e.insightsBaseUrl ? O(D()) : k()), j = e.isIdentified;
|
|
182
191
|
});
|
|
183
|
-
var
|
|
184
|
-
|
|
185
|
-
|
|
192
|
+
var M = g.get().insightsBaseUrl;
|
|
193
|
+
g.subscribe((e) => {
|
|
194
|
+
e.insightsBaseUrl && !M && e.isIdentified && C.get().length > 0 && O(D()), M = e.insightsBaseUrl;
|
|
195
|
+
});
|
|
196
|
+
var ae = () => {
|
|
197
|
+
C.set([]), w.set(0), A();
|
|
198
|
+
}, N = e(!1), oe = e(!1), se = t([v, N], (e, t) => e && t), ce = t([se, oe], (e, t) => e && t), P = n({
|
|
186
199
|
status: "active",
|
|
187
200
|
seconds: 0
|
|
188
|
-
}),
|
|
201
|
+
}), le = (e) => {
|
|
189
202
|
if (typeof window > "u") return () => {};
|
|
190
203
|
let t = r({
|
|
191
204
|
timeout: 6e4,
|
|
192
205
|
throttle: 1e3,
|
|
193
206
|
onIdle: (e) => {
|
|
194
|
-
|
|
207
|
+
P.set({
|
|
195
208
|
status: "idle",
|
|
196
209
|
seconds: e
|
|
197
210
|
});
|
|
198
211
|
},
|
|
199
212
|
onWakeUp: (e) => {
|
|
200
|
-
|
|
213
|
+
P.set({
|
|
201
214
|
status: "active",
|
|
202
215
|
seconds: e
|
|
203
216
|
});
|
|
204
217
|
}
|
|
205
|
-
}), n =
|
|
218
|
+
}), n = P.listen((t) => {
|
|
206
219
|
t.seconds > 0 && (t.status === "idle" ? e.track("user.idle", { seconds_active: t.seconds }) : e.track("user.active", { seconds_idle: t.seconds }));
|
|
207
220
|
});
|
|
208
221
|
return () => {
|
|
209
|
-
n(), t.disable(),
|
|
222
|
+
n(), t.disable(), P.set({
|
|
210
223
|
status: "active",
|
|
211
224
|
seconds: 0
|
|
212
225
|
});
|
|
213
226
|
};
|
|
214
|
-
},
|
|
227
|
+
}, ue = () => P.get(), F = /* @__PURE__ */ function(e) {
|
|
215
228
|
return e.ACTIVE = "active", e.PASSIVE = "passive", e.HIDDEN = "hidden", e.FROZEN = "frozen", e.TERMINATED = "terminated", e;
|
|
216
|
-
}(
|
|
229
|
+
}(F || {}), I = e(F.ACTIVE), de = () => typeof document > "u" ? F.ACTIVE : document.visibilityState === "hidden" ? F.HIDDEN : document.hasFocus() ? F.ACTIVE : F.PASSIVE, fe = (e) => {
|
|
217
230
|
if (typeof window > "u") return () => {};
|
|
218
231
|
let t = !1, n = (n) => {
|
|
219
232
|
if (t) return;
|
|
220
233
|
t = !0;
|
|
221
|
-
let r =
|
|
234
|
+
let r = ue(), a = {};
|
|
222
235
|
r.seconds > 0 && (r.status === "idle" ? a.seconds_idle = r.seconds : a.seconds_active = r.seconds);
|
|
223
236
|
try {
|
|
224
237
|
e.track("page.bounce", {
|
|
225
238
|
resource: "page",
|
|
226
239
|
...a,
|
|
227
240
|
...n
|
|
228
|
-
}, {}, () =>
|
|
241
|
+
}, {}, () => O(D()));
|
|
229
242
|
} catch (e) {
|
|
230
243
|
console.error("[insights] Failed to send bounce event", i(e));
|
|
231
244
|
}
|
|
@@ -249,13 +262,13 @@ var se = () => {
|
|
|
249
262
|
case "blur":
|
|
250
263
|
case "focus":
|
|
251
264
|
case "visibilitychange":
|
|
252
|
-
|
|
265
|
+
I.set(de());
|
|
253
266
|
break;
|
|
254
267
|
case "freeze":
|
|
255
|
-
|
|
268
|
+
I.set(F.FROZEN);
|
|
256
269
|
break;
|
|
257
270
|
case "pagehide":
|
|
258
|
-
|
|
271
|
+
I.set(e.persisted ? F.FROZEN : F.TERMINATED);
|
|
259
272
|
break;
|
|
260
273
|
}
|
|
261
274
|
}, s = [
|
|
@@ -270,32 +283,32 @@ var se = () => {
|
|
|
270
283
|
s.forEach((e) => {
|
|
271
284
|
window.addEventListener(e, a, { capture: !0 });
|
|
272
285
|
}), window.addEventListener("beforeunload", r);
|
|
273
|
-
let c =
|
|
274
|
-
e ===
|
|
286
|
+
let c = I.listen((e) => {
|
|
287
|
+
e === F.FROZEN || e === F.TERMINATED ? n({
|
|
275
288
|
state: e,
|
|
276
289
|
trigger: "lifecycle"
|
|
277
|
-
}) : e ===
|
|
290
|
+
}) : e === F.HIDDEN && O(D());
|
|
278
291
|
}), l = o.get().page_id, u = o.listen((e) => {
|
|
279
292
|
e.page_id !== l && (t = !1, l = e.page_id);
|
|
280
|
-
}), d =
|
|
293
|
+
}), d = w.listen((e) => {
|
|
281
294
|
e === 0 && (t = !1);
|
|
282
295
|
});
|
|
283
296
|
return () => {
|
|
284
297
|
s.forEach((e) => {
|
|
285
298
|
window.removeEventListener(e, a, { capture: !0 });
|
|
286
|
-
}), window.removeEventListener("beforeunload", r), c(), u(), d(), t = !1,
|
|
299
|
+
}), window.removeEventListener("beforeunload", r), c(), u(), d(), t = !1, I.set(F.ACTIVE);
|
|
287
300
|
};
|
|
288
|
-
},
|
|
289
|
-
function
|
|
301
|
+
}, L = (e) => Object.prototype.toString.call(e) == "[object String]", pe = (e, t) => e.indexOf(t) !== -1, R = (e) => e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ""), z = (e) => e === void 0, me = (e) => e === null, B = (e) => z(e) || me(e), V = (e) => !!e && e?.nodeType === 3;
|
|
302
|
+
function he(e) {
|
|
290
303
|
return !!e && e?.nodeType === 1;
|
|
291
304
|
}
|
|
292
|
-
function
|
|
305
|
+
function ge(e, t) {
|
|
293
306
|
return !!e && !!e?.tagName && e?.tagName.toLowerCase() === t.toLowerCase();
|
|
294
307
|
}
|
|
295
|
-
function ge(e) {
|
|
296
|
-
return e ? L(e).split(/\s+/) : [];
|
|
297
|
-
}
|
|
298
308
|
function _e(e) {
|
|
309
|
+
return e ? R(e).split(/\s+/) : [];
|
|
310
|
+
}
|
|
311
|
+
function ve(e) {
|
|
299
312
|
let t = "";
|
|
300
313
|
switch (typeof e?.className) {
|
|
301
314
|
case "string":
|
|
@@ -306,9 +319,9 @@ function _e(e) {
|
|
|
306
319
|
break;
|
|
307
320
|
default: t = "";
|
|
308
321
|
}
|
|
309
|
-
return
|
|
322
|
+
return _e(t);
|
|
310
323
|
}
|
|
311
|
-
var
|
|
324
|
+
var H = (e, t = 255) => B(e) ? "" : R(e).split(/(\s+)/).filter((e) => J(e)).join("").replace(/[\r\n]/g, " ").replace(/[ ]+/g, " ").substring(0, t), U = [
|
|
312
325
|
"span",
|
|
313
326
|
"strong",
|
|
314
327
|
"em",
|
|
@@ -320,25 +333,25 @@ var V = (e, t = 255) => z(e) ? "" : L(e).split(/(\s+)/).filter((e) => q(e)).join
|
|
|
320
333
|
"sub",
|
|
321
334
|
"sup",
|
|
322
335
|
"label"
|
|
323
|
-
],
|
|
336
|
+
], W = (e) => {
|
|
324
337
|
let t = "";
|
|
325
|
-
if (
|
|
326
|
-
for (let n of e.childNodes)
|
|
327
|
-
if (!
|
|
328
|
-
let n = e.querySelectorAll(
|
|
338
|
+
if (xe(e) && e?.childNodes && e?.childNodes.length) {
|
|
339
|
+
for (let n of e.childNodes) V(n) && n.textContent && (t += H(n.textContent) ?? "");
|
|
340
|
+
if (!R(t)) {
|
|
341
|
+
let n = e.querySelectorAll(U.join(", "));
|
|
329
342
|
for (let e of n) {
|
|
330
343
|
let n = e.textContent;
|
|
331
|
-
n && (t += `${
|
|
344
|
+
n && (t += `${H(n)} `);
|
|
332
345
|
}
|
|
333
346
|
}
|
|
334
|
-
if (!
|
|
347
|
+
if (!R(t) && e instanceof HTMLElement) {
|
|
335
348
|
let n = e.innerText;
|
|
336
|
-
n && (t =
|
|
349
|
+
n && (t = H(n.substring(0, 500)));
|
|
337
350
|
}
|
|
338
351
|
}
|
|
339
|
-
return
|
|
340
|
-
},
|
|
341
|
-
if (!window || !e ||
|
|
352
|
+
return R(t);
|
|
353
|
+
}, G = (e) => z(e.target) ? e?.srcElement || null : e?.composedPath?.()[0] || e?.target || null, ye = (e, t) => {
|
|
354
|
+
if (!window || !e || ge(e, "html") || !he(e)) return !1;
|
|
342
355
|
let n = window.getComputedStyle(e);
|
|
343
356
|
if (n && n.getPropertyValue("cursor") === "pointer" && t.type === "click") return !0;
|
|
344
357
|
switch (e?.tagName.toLowerCase()) {
|
|
@@ -349,7 +362,7 @@ var V = (e, t = 255) => z(e) ? "" : L(e).split(/(\s+)/).filter((e) => q(e)).join
|
|
|
349
362
|
case "textarea": return ["change", "click"].includes(t.type);
|
|
350
363
|
default: return t.type === "click";
|
|
351
364
|
}
|
|
352
|
-
},
|
|
365
|
+
}, be = new Set([
|
|
353
366
|
"password",
|
|
354
367
|
"passwd",
|
|
355
368
|
"pwd",
|
|
@@ -370,73 +383,73 @@ var V = (e, t = 255) => z(e) ? "" : L(e).split(/(\s+)/).filter((e) => q(e)).join
|
|
|
370
383
|
"apikey",
|
|
371
384
|
"accesstoken"
|
|
372
385
|
]);
|
|
373
|
-
function
|
|
374
|
-
if (
|
|
386
|
+
function xe(e) {
|
|
387
|
+
if (pe(ve(e), "ph-include")) return !0;
|
|
375
388
|
let t = e.type || "";
|
|
376
|
-
if (
|
|
389
|
+
if (L(t)) switch (t.toLowerCase()) {
|
|
377
390
|
case "hidden": return !1;
|
|
378
391
|
case "password": return !1;
|
|
379
392
|
}
|
|
380
393
|
let n = e.name || e?.id || "";
|
|
381
|
-
if (
|
|
394
|
+
if (L(n)) {
|
|
382
395
|
let e = n.toLowerCase().replace(/[^a-z]/g, "");
|
|
383
|
-
if (
|
|
396
|
+
if (be.has(e)) return !1;
|
|
384
397
|
}
|
|
385
398
|
return !0;
|
|
386
399
|
}
|
|
387
|
-
var
|
|
388
|
-
let t =
|
|
389
|
-
return t = `${t} ${Y(e)}`.trim(),
|
|
400
|
+
var K = "(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11})", Se = RegExp(`^(?:${K})$`), Ce = new RegExp(K), q = "\\d{3}-?\\d{2}-?\\d{4}", we = RegExp(`^(${q})$`), Te = RegExp(`(${q})`), J = (e, t = !0) => !(B(e) || L(e) && (e = R(e), (t ? Se : Ce).test((e || "").replace(/[- ]/g, "")) || (t ? we : Te).test(e))), Ee = (e) => L(e) ? e.substring(0, 10) === "_ngcontent" || e.substring(0, 7) === "_nghost" : !1, De = (e) => {
|
|
401
|
+
let t = W(e);
|
|
402
|
+
return t = `${t} ${Y(e)}`.trim(), J(t) ? t : "";
|
|
390
403
|
};
|
|
391
404
|
function Y(e) {
|
|
392
405
|
let t = "";
|
|
393
406
|
if (e?.childNodes.length) for (let n of e.childNodes) {
|
|
394
407
|
let e = n.tagName?.toLowerCase();
|
|
395
|
-
if (n && e &&
|
|
396
|
-
let e =
|
|
408
|
+
if (n && e && U.includes(e)) try {
|
|
409
|
+
let e = W(n);
|
|
397
410
|
t = `${t} ${e}`.trim(), n?.childNodes.length && (t = `${t} ${Y(n)}`.trim());
|
|
398
411
|
} catch {}
|
|
399
412
|
}
|
|
400
413
|
return t;
|
|
401
414
|
}
|
|
402
|
-
var
|
|
403
|
-
let t = e.tagName?.toLowerCase(), n = t === "a" || t === "button" ?
|
|
415
|
+
var Oe = (e) => {
|
|
416
|
+
let t = e.tagName?.toLowerCase(), n = t === "a" || t === "button" ? De(e) : W(e);
|
|
404
417
|
if (n) return {
|
|
405
418
|
text: n,
|
|
406
419
|
source: "text"
|
|
407
420
|
};
|
|
408
421
|
let r = e.getAttribute("aria-label");
|
|
409
422
|
if (r) return {
|
|
410
|
-
text:
|
|
423
|
+
text: H(r),
|
|
411
424
|
source: "aria-label"
|
|
412
425
|
};
|
|
413
426
|
let i = e.getAttribute("title");
|
|
414
427
|
if (i) return {
|
|
415
|
-
text:
|
|
428
|
+
text: H(i),
|
|
416
429
|
source: "title"
|
|
417
430
|
};
|
|
418
431
|
let a = e.getAttribute("data-track-label");
|
|
419
432
|
if (a) return {
|
|
420
|
-
text:
|
|
433
|
+
text: H(a),
|
|
421
434
|
source: "data-track-label"
|
|
422
435
|
};
|
|
423
436
|
let o = e.querySelector("img[alt], svg[aria-label]");
|
|
424
437
|
if (o) {
|
|
425
438
|
let e = o.getAttribute("alt") || o.getAttribute("aria-label");
|
|
426
439
|
if (e) return {
|
|
427
|
-
text:
|
|
440
|
+
text: H(e),
|
|
428
441
|
source: "alt"
|
|
429
442
|
};
|
|
430
443
|
}
|
|
431
444
|
let s = e.getAttribute("placeholder");
|
|
432
445
|
if (s) return {
|
|
433
|
-
text:
|
|
446
|
+
text: H(s),
|
|
434
447
|
source: "placeholder"
|
|
435
448
|
};
|
|
436
449
|
if (e instanceof HTMLElement && e.innerText) {
|
|
437
450
|
let t = e.innerText.substring(0, 500);
|
|
438
451
|
if (t.trim()) return {
|
|
439
|
-
text:
|
|
452
|
+
text: H(t),
|
|
440
453
|
source: "innerText"
|
|
441
454
|
};
|
|
442
455
|
}
|
|
@@ -444,48 +457,48 @@ var Ee = (e) => {
|
|
|
444
457
|
text: "",
|
|
445
458
|
source: "none"
|
|
446
459
|
};
|
|
447
|
-
},
|
|
460
|
+
}, ke = [
|
|
448
461
|
"input",
|
|
449
462
|
"textarea",
|
|
450
463
|
"select"
|
|
451
464
|
], X = (e) => {
|
|
452
|
-
let t = e?.tagName?.toLowerCase(), n = { element: t }, r =
|
|
465
|
+
let t = e?.tagName?.toLowerCase(), n = { element: t }, r = Oe(e);
|
|
453
466
|
n.text = r.text, n.text_source = r.source;
|
|
454
467
|
let i = e.getAttribute("aria-label");
|
|
455
|
-
i && (n.aria_label =
|
|
468
|
+
i && (n.aria_label = H(i));
|
|
456
469
|
let a = e.getAttribute("role");
|
|
457
470
|
a && (n.role = a);
|
|
458
471
|
let o = {};
|
|
459
|
-
for (let t of e.attributes) (t.name.startsWith("data-track-") || t.name.startsWith("data-analytics-")) && (o[t.name] =
|
|
472
|
+
for (let t of e.attributes) (t.name.startsWith("data-track-") || t.name.startsWith("data-analytics-")) && (o[t.name] = H(t.value));
|
|
460
473
|
if (Object.keys(o).length && (n.tracking_data = o), n.attributes = Array.from(e.attributes).reduce((e, t) => {
|
|
461
|
-
if (
|
|
474
|
+
if (J(t.value) && !Ee(t.name)) {
|
|
462
475
|
if (t.name === "class" || t.name.startsWith("data-track-") || t.name.startsWith("data-analytics-")) return e;
|
|
463
|
-
e[t.name] = typeof t?.value == "string" ?
|
|
476
|
+
e[t.name] = typeof t?.value == "string" ? H(t.value) : t.value;
|
|
464
477
|
}
|
|
465
478
|
return e;
|
|
466
|
-
}, {}),
|
|
479
|
+
}, {}), ke.includes(t) || e?.getAttribute("contenteditable") === "true") {
|
|
467
480
|
let t;
|
|
468
|
-
e.matches("input[type=\"checkbox\"], input[type=\"radio\"]") ? t = e.checked : e.matches("input, select, textarea") && !e.matches("input[type=\"password\"]") && (t = e.value), t !== void 0 && (n.value = typeof t == "string" || t === null ?
|
|
481
|
+
e.matches("input[type=\"checkbox\"], input[type=\"radio\"]") ? t = e.checked : e.matches("input, select, textarea") && !e.matches("input[type=\"password\"]") && (t = e.value), t !== void 0 && (n.value = typeof t == "string" || t === null ? H(t, 1024) : t);
|
|
469
482
|
let r = "";
|
|
470
|
-
n?.attributes.id && (r =
|
|
483
|
+
n?.attributes.id && (r = H(document.querySelector(`label[for="${n?.attributes.id}"]`)?.textContent?.trim() || ""));
|
|
471
484
|
let i = e.closest("label");
|
|
472
|
-
r ||=
|
|
485
|
+
r ||= H(i?.textContent?.trim() || ""), r && (n.label = r);
|
|
473
486
|
}
|
|
474
487
|
return n;
|
|
475
|
-
},
|
|
476
|
-
let n =
|
|
477
|
-
|
|
488
|
+
}, Ae = (e, t) => {
|
|
489
|
+
let n = G(e);
|
|
490
|
+
V(n) && (n = n.parentNode || null);
|
|
478
491
|
let r = ["copy", "cut"].includes(t);
|
|
479
|
-
if (n && (r ||
|
|
492
|
+
if (n && (r || ye(n, e))) {
|
|
480
493
|
let t = X(n);
|
|
481
494
|
if (r) {
|
|
482
|
-
let n =
|
|
495
|
+
let n = H(window?.getSelection()?.toString()), r = e?.type || "clipboard";
|
|
483
496
|
t.copy_text = n ?? "", t.copy_type = r ?? "";
|
|
484
497
|
}
|
|
485
498
|
return t;
|
|
486
499
|
}
|
|
487
500
|
return null;
|
|
488
|
-
}, Z = e(null),
|
|
501
|
+
}, Z = e(null), je = (e) => {
|
|
489
502
|
if (typeof window > "u") return () => {};
|
|
490
503
|
let t = null;
|
|
491
504
|
try {
|
|
@@ -499,21 +512,21 @@ var Ee = (e) => {
|
|
|
499
512
|
} catch {}
|
|
500
513
|
}
|
|
501
514
|
let r = t;
|
|
502
|
-
Z.set(r), n.includes(r) ||
|
|
515
|
+
Z.set(r), n.includes(r) || x({ allTabs: [...n, r] });
|
|
503
516
|
let i = () => {
|
|
504
517
|
if (!r) return;
|
|
505
518
|
let { allTabs: e } = g.get();
|
|
506
|
-
e.includes(r) &&
|
|
519
|
+
e.includes(r) && x({ allTabs: e.filter((e) => e !== r) });
|
|
507
520
|
};
|
|
508
521
|
return window.addEventListener("beforeunload", i), () => {
|
|
509
522
|
window.removeEventListener("beforeunload", i), i(), Z.set(null);
|
|
510
523
|
};
|
|
511
|
-
},
|
|
524
|
+
}, Me = () => Z.get(), Q = n({
|
|
512
525
|
depth: 0,
|
|
513
526
|
milestone: 0,
|
|
514
527
|
speedCategory: "read",
|
|
515
528
|
direction: "down"
|
|
516
|
-
}),
|
|
529
|
+
}), Ne = (e) => {
|
|
517
530
|
if (typeof window > "u") return () => {};
|
|
518
531
|
let t = {
|
|
519
532
|
prevMilestone: -1,
|
|
@@ -550,7 +563,7 @@ var Ee = (e) => {
|
|
|
550
563
|
direction: "down"
|
|
551
564
|
});
|
|
552
565
|
};
|
|
553
|
-
}, $ = e(null),
|
|
566
|
+
}, $ = e(null), Pe = (e) => {
|
|
554
567
|
if (typeof window > "u") return () => {};
|
|
555
568
|
let t = a(() => {
|
|
556
569
|
let e = window.getSelection();
|
|
@@ -561,11 +574,11 @@ var Ee = (e) => {
|
|
|
561
574
|
}, 1e3);
|
|
562
575
|
document.addEventListener("selectionchange", t);
|
|
563
576
|
let n = $.listen((t) => {
|
|
564
|
-
t && e.track("page.selection", { text:
|
|
577
|
+
t && e.track("page.selection", { text: H(t) });
|
|
565
578
|
});
|
|
566
579
|
return () => {
|
|
567
580
|
document.removeEventListener("selectionchange", t), t.cancel(), n(), $.set(null);
|
|
568
581
|
};
|
|
569
582
|
};
|
|
570
583
|
//#endregion
|
|
571
|
-
export {
|
|
584
|
+
export { x as A, O as C, v as D, ie as E, l as F, o as M, s as N, g as O, c as P, ae as S, re as T, N as _, Z as a, w as b, X as c, I as d, fe as f, se as g, oe as h, Ne as i, u as j, b as k, G as l, le as m, Pe as n, Me as o, P as p, Q as r, je as s, $ as t, Ae as u, ce as v, D as w, T as x, C as y };
|
package/dist/types/options.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export interface IInsightOptions {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Reverse-proxy URL for analytics. When null/undefined, identity tracking
|
|
4
|
+
* and DOM trackers still run (popup triggers stay functional), but no
|
|
5
|
+
* network calls are made and queued events are dropped.
|
|
6
|
+
*/
|
|
7
|
+
insightsUrl: string | null;
|
|
3
8
|
/** Site ID for analytics tracking */
|
|
4
9
|
site?: string | null;
|
|
5
10
|
/** Page ID for analytics tracking */
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReadableAtom } from 'nanostores';
|
|
2
|
+
/**
|
|
3
|
+
* Run `cb` once when `store` becomes (or already is) true.
|
|
4
|
+
*
|
|
5
|
+
* Returns an unsubscribe function so callers can cancel the pending callback
|
|
6
|
+
* during teardown (e.g. push into the cleanups array in init/destroy). If the
|
|
7
|
+
* store is already true at call time, fires synchronously and returns a no-op
|
|
8
|
+
* unsubscribe.
|
|
9
|
+
*/
|
|
10
|
+
export declare const onceTrue: (store: ReadableAtom<boolean>, cb: () => void) => (() => void);
|