@crelora/mark 0.0.18 → 0.1.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 +38 -11
- package/dist/browser.es.js +618 -124
- package/dist/browser.es.js.map +1 -0
- package/dist/browser.umd.js +2 -1
- package/dist/browser.umd.js.map +1 -0
- package/dist/node.cjs +2 -1
- package/dist/node.cjs.map +1 -0
- package/dist/node.es.js +431 -66
- package/dist/node.es.js.map +1 -0
- package/dist/types/browser/BrowserStorage.d.ts +12 -0
- package/dist/types/browser/Mark.d.ts +18 -0
- package/dist/types/core/DeliveryQueue.d.ts +57 -0
- package/dist/types/core/HttpTransport.d.ts +6 -2
- package/dist/types/core/MarkCore.d.ts +46 -2
- package/dist/types/core/TransportError.d.ts +15 -0
- package/dist/types/core/adapters.d.ts +14 -1
- package/dist/types/node/StatelessStorage.d.ts +7 -0
- package/dist/types/node/index.d.ts +8 -0
- package/dist/types/types.d.ts +37 -0
- package/dist/web-vitals-CrnTllyu.js +221 -0
- package/dist/web-vitals-CrnTllyu.js.map +1 -0
- package/package.json +18 -2
package/dist/browser.es.js
CHANGED
|
@@ -1,4 +1,153 @@
|
|
|
1
|
-
const
|
|
1
|
+
const S = "https://ingest.onelence.com";
|
|
2
|
+
class h extends Error {
|
|
3
|
+
status;
|
|
4
|
+
retryAfterMs;
|
|
5
|
+
constructor(t, e = {}) {
|
|
6
|
+
super(t), this.name = "TransportError", this.status = e.status, this.retryAfterMs = e.retryAfterMs;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function I(c) {
|
|
10
|
+
return !(typeof c != "number" || c < 400 || c >= 500 || c === 408 || c === 429);
|
|
11
|
+
}
|
|
12
|
+
function E(c) {
|
|
13
|
+
if (!c) return;
|
|
14
|
+
const t = c.trim();
|
|
15
|
+
if (!t) return;
|
|
16
|
+
const e = Number(t);
|
|
17
|
+
if (Number.isFinite(e) && e >= 0)
|
|
18
|
+
return Math.floor(e * 1e3);
|
|
19
|
+
const i = Date.parse(t);
|
|
20
|
+
if (Number.isFinite(i)) {
|
|
21
|
+
const s = i - Date.now();
|
|
22
|
+
return s > 0 ? s : 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const x = 5, q = 300, T = 15e3, k = 2880 * 60 * 1e3;
|
|
26
|
+
class D {
|
|
27
|
+
constructor(t, e = {}) {
|
|
28
|
+
this.transport = t, this.maxAttempts = e.maxAttempts ?? x, this.baseBackoffMs = e.baseBackoffMs ?? q, this.maxBackoffMs = e.maxBackoffMs ?? T, this.maxItemAgeMs = e.maxItemAgeMs ?? k, this.debug = e.debug ?? !1, this.loadPersisted = e.loadPersisted, this.savePersisted = e.savePersisted, this.onError = e.onError;
|
|
29
|
+
const i = this.loadPersisted?.() ?? [];
|
|
30
|
+
if (i.length > 0) {
|
|
31
|
+
const s = Date.now();
|
|
32
|
+
for (const r of i) {
|
|
33
|
+
const o = r.enqueuedAt ?? s;
|
|
34
|
+
if (s - o > this.maxItemAgeMs) {
|
|
35
|
+
this.dropped += 1;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
this.queue.push({ ...r, enqueuedAt: o });
|
|
39
|
+
}
|
|
40
|
+
this.persist();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
queue = [];
|
|
44
|
+
flushing = !1;
|
|
45
|
+
sent = 0;
|
|
46
|
+
failed = 0;
|
|
47
|
+
dropped = 0;
|
|
48
|
+
maxAttempts;
|
|
49
|
+
baseBackoffMs;
|
|
50
|
+
maxBackoffMs;
|
|
51
|
+
maxItemAgeMs;
|
|
52
|
+
debug;
|
|
53
|
+
loadPersisted;
|
|
54
|
+
savePersisted;
|
|
55
|
+
onError;
|
|
56
|
+
enqueue(t, e) {
|
|
57
|
+
this.queue.push({
|
|
58
|
+
path: t,
|
|
59
|
+
data: e,
|
|
60
|
+
attempts: 0,
|
|
61
|
+
nextAttemptAt: Date.now(),
|
|
62
|
+
enqueuedAt: Date.now()
|
|
63
|
+
}), this.persist(), this.process();
|
|
64
|
+
}
|
|
65
|
+
async flush() {
|
|
66
|
+
await this.process(!0), await this.transport.flush?.();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Best-effort synchronous drain using sendBeacon. Intended for page unload;
|
|
70
|
+
* errors are swallowed because the tab is going away.
|
|
71
|
+
*/
|
|
72
|
+
drainViaBeacon() {
|
|
73
|
+
if (this.queue.length === 0) return;
|
|
74
|
+
const t = this.queue.splice(0, this.queue.length);
|
|
75
|
+
this.persist();
|
|
76
|
+
for (const e of t) {
|
|
77
|
+
const i = { ...e.data };
|
|
78
|
+
delete i.__prefer_beacon;
|
|
79
|
+
try {
|
|
80
|
+
this.transport.send(e.path, i, { preferBeacon: !0 });
|
|
81
|
+
} catch {
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
getStats() {
|
|
86
|
+
return {
|
|
87
|
+
queued: this.queue.length,
|
|
88
|
+
sent: this.sent,
|
|
89
|
+
failed: this.failed,
|
|
90
|
+
dropped: this.dropped
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
clear() {
|
|
94
|
+
this.queue.splice(0, this.queue.length), this.persist();
|
|
95
|
+
}
|
|
96
|
+
persist() {
|
|
97
|
+
this.savePersisted?.(this.queue);
|
|
98
|
+
}
|
|
99
|
+
evictExpired() {
|
|
100
|
+
if (this.queue.length === 0) return;
|
|
101
|
+
const e = Date.now() - this.maxItemAgeMs;
|
|
102
|
+
let i = 0;
|
|
103
|
+
for (let s = this.queue.length - 1; s >= 0; s -= 1)
|
|
104
|
+
this.queue[s].enqueuedAt <= e && (this.queue.splice(s, 1), this.dropped += 1, i += 1);
|
|
105
|
+
i > 0 && this.persist();
|
|
106
|
+
}
|
|
107
|
+
async process(t = !1) {
|
|
108
|
+
if (!this.flushing) {
|
|
109
|
+
this.flushing = !0;
|
|
110
|
+
try {
|
|
111
|
+
for (this.evictExpired(); this.queue.length > 0; ) {
|
|
112
|
+
const e = this.queue[0];
|
|
113
|
+
if (!t && e.nextAttemptAt > Date.now())
|
|
114
|
+
break;
|
|
115
|
+
try {
|
|
116
|
+
const i = { ...e.data }, s = i.__prefer_beacon === !0;
|
|
117
|
+
delete i.__prefer_beacon, await this.transport.send(e.path, i, { preferBeacon: s }), this.queue.shift(), this.sent += 1, this.persist();
|
|
118
|
+
} catch (i) {
|
|
119
|
+
this.failed += 1, this.onError?.(i, e.data);
|
|
120
|
+
const s = i instanceof h ? i.status : void 0;
|
|
121
|
+
if (I(s)) {
|
|
122
|
+
this.queue.shift(), this.dropped += 1, this.persist(), this.debug && console.error("[Mark] Dropping event after non-retriable status", s, e.path);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (e.attempts += 1, e.attempts >= this.maxAttempts) {
|
|
126
|
+
this.queue.shift(), this.dropped += 1, this.persist(), this.debug && console.error("[Mark] Dropping event after max retries", e.path, i);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const r = i instanceof h ? i.retryAfterMs : void 0;
|
|
130
|
+
let o;
|
|
131
|
+
if (typeof r == "number")
|
|
132
|
+
o = Math.min(this.maxBackoffMs, Math.max(0, r));
|
|
133
|
+
else {
|
|
134
|
+
const a = Math.random() * this.baseBackoffMs;
|
|
135
|
+
o = Math.min(
|
|
136
|
+
this.maxBackoffMs,
|
|
137
|
+
this.baseBackoffMs * 2 ** (e.attempts - 1) + a
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
e.nextAttemptAt = Date.now() + o, this.persist();
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} finally {
|
|
145
|
+
this.flushing = !1;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const C = /* @__PURE__ */ new Set(["event_name", "user_id", "consent_state", "source", "is_conversion"]), U = /* @__PURE__ */ new Set([
|
|
2
151
|
"user_id",
|
|
3
152
|
"visitor_id",
|
|
4
153
|
"click_id",
|
|
@@ -7,56 +156,94 @@ const w = "https://ingest.onelence.com", v = /* @__PURE__ */ new Set(["event_nam
|
|
|
7
156
|
"consent_state",
|
|
8
157
|
"source"
|
|
9
158
|
]);
|
|
10
|
-
class
|
|
159
|
+
class L {
|
|
11
160
|
constructor(t, e) {
|
|
12
161
|
this.deps = e, this.validateConfig(t), this.config = {
|
|
13
|
-
endpoint: t.endpoint ??
|
|
162
|
+
endpoint: t.endpoint ?? S,
|
|
14
163
|
...t,
|
|
15
164
|
include_page_context: t.include_page_context ?? !0
|
|
16
|
-
}, this.consentRequirement = t.require_consent ?? !1, this.siteId = t.site_id, this.siteHost = t.site_host
|
|
165
|
+
}, this.consentRequirement = t.require_consent ?? !1, this.siteId = t.site_id, this.siteHost = t.site_host, this.sessionTimeoutMs = t.session_timeout_ms ?? 1800 * 1e3, this.queue = new D(this.deps.transport, {
|
|
166
|
+
debug: this.config.debug,
|
|
167
|
+
loadPersisted: () => this.deps.storage.getOutbox?.() ?? [],
|
|
168
|
+
savePersisted: (i) => this.deps.storage.setOutbox?.(i),
|
|
169
|
+
onError: (i, s) => this.config.on_error?.(i, s)
|
|
170
|
+
}), this.warnMisconfiguredSiteHost(), this.subscribeTcf();
|
|
17
171
|
}
|
|
18
172
|
config;
|
|
19
173
|
consentRequirement;
|
|
20
174
|
siteId;
|
|
21
175
|
siteHost;
|
|
176
|
+
queue;
|
|
177
|
+
sessionTimeoutMs;
|
|
178
|
+
batchTimer = null;
|
|
179
|
+
batchedEvents = [];
|
|
180
|
+
tcfCachedAllowed = !1;
|
|
181
|
+
/**
|
|
182
|
+
* Best-effort synchronous drain that dispatches all queued events via
|
|
183
|
+
* sendBeacon. Intended for use on page unload (visibilitychange=hidden,
|
|
184
|
+
* pagehide) where async fetch may be cancelled by the browser.
|
|
185
|
+
*/
|
|
186
|
+
drainViaBeacon() {
|
|
187
|
+
this.flushBatch(), this.queue.drainViaBeacon();
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Kicks the queue to retry any pending items now. Safe to call repeatedly;
|
|
191
|
+
* used by the browser wrapper in response to `online` events or periodic
|
|
192
|
+
* timers.
|
|
193
|
+
*/
|
|
194
|
+
kickQueue() {
|
|
195
|
+
this.queue.flush();
|
|
196
|
+
}
|
|
22
197
|
track(t, e = {}) {
|
|
23
198
|
return this.trackInternal(t, e, !1);
|
|
24
199
|
}
|
|
25
|
-
trackInternal(t, e = {}, i = !1) {
|
|
200
|
+
trackInternal(t, e = {}, i = !1, s) {
|
|
26
201
|
if (!t)
|
|
27
202
|
return this.config.debug && console.warn("[Mark] track called without event name"), !1;
|
|
28
|
-
if (!this.hasConsent())
|
|
203
|
+
if (!this.hasConsent() || this.isDntBlocked())
|
|
29
204
|
return this.config.debug && console.warn("[Mark] Tracking blocked due to consent requirement."), !1;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const o = {
|
|
205
|
+
if (!i && !this.shouldSampleTrack())
|
|
206
|
+
return !0;
|
|
207
|
+
const r = this.sanitizeTrackData(e), o = { ...r };
|
|
208
|
+
"query" in o && delete o.query, "site_id" in o && delete o.site_id, "site_host" in o && delete o.site_host;
|
|
209
|
+
const a = {
|
|
33
210
|
event_name: t,
|
|
34
|
-
|
|
35
|
-
...r
|
|
211
|
+
message_id: this.createMessageId(),
|
|
212
|
+
...this.getIdentityFields(r),
|
|
213
|
+
...o
|
|
36
214
|
};
|
|
37
|
-
i && (
|
|
38
|
-
const
|
|
39
|
-
|
|
215
|
+
i && (a.is_conversion = !0);
|
|
216
|
+
const l = r.site_id ?? this.siteId, f = r.site_host ?? this.siteHost;
|
|
217
|
+
l && (a.site_id = l), f && (a.site_host = f), this.config.include_page_context && typeof window < "u" && (this.applyPageContext(a), !f && a.site && (a.site_host = a.site));
|
|
218
|
+
const d = this.config.before_send ? this.config.before_send(a) : a;
|
|
219
|
+
return d ? (this.ensureSession(), this.config.batching?.enabled && !i && !s?.preferBeacon ? (this.enqueueBatch(d), !0) : (this.queue.enqueue("/event", { ...d, __prefer_beacon: s?.preferBeacon === !0 }), !0)) : !0;
|
|
40
220
|
}
|
|
41
221
|
identify(t, e = {}) {
|
|
42
222
|
if (!t) {
|
|
43
223
|
this.config.debug && console.warn("[Mark] identify called without userId");
|
|
44
224
|
return;
|
|
45
225
|
}
|
|
46
|
-
if (!this.hasConsent()) {
|
|
226
|
+
if (!this.hasConsent() || this.isDntBlocked()) {
|
|
47
227
|
this.config.debug && console.warn("[Mark] Identify blocked due to consent requirement.");
|
|
48
228
|
return;
|
|
49
229
|
}
|
|
230
|
+
this.deps.storage.update({ user_id: t });
|
|
50
231
|
const i = {
|
|
51
232
|
user_id: t,
|
|
233
|
+
message_id: this.createMessageId(),
|
|
52
234
|
...this.sanitizeIdentifyTraits(e),
|
|
53
235
|
...this.getIdentityFields()
|
|
54
236
|
};
|
|
55
|
-
this.siteId && (i.site_id = this.siteId), this.siteHost && (i.site_host = this.siteHost)
|
|
237
|
+
this.siteId && (i.site_id = this.siteId), this.siteHost && (i.site_host = this.siteHost);
|
|
238
|
+
const s = this.config.before_send ? this.config.before_send(i) : i;
|
|
239
|
+
s && this.queue.enqueue("/identify", s);
|
|
56
240
|
}
|
|
57
241
|
conversion(t, e = {}) {
|
|
58
242
|
return this.trackInternal(t, e, !0);
|
|
59
243
|
}
|
|
244
|
+
trackWithOptions(t, e = {}, i) {
|
|
245
|
+
return this.trackInternal(t, e, !1, i);
|
|
246
|
+
}
|
|
60
247
|
/**
|
|
61
248
|
* Returns the current visitor ID from storage, if any.
|
|
62
249
|
* Used by browser/Node wrappers to expose a stable pseudonymous ID for server-side attribution.
|
|
@@ -65,19 +252,42 @@ class I {
|
|
|
65
252
|
return this.deps.storage.getVisitorId();
|
|
66
253
|
}
|
|
67
254
|
setConsent(t) {
|
|
68
|
-
this.deps.storage.
|
|
69
|
-
|
|
255
|
+
const e = this.deps.storage.getConsentStatus();
|
|
256
|
+
this.deps.storage.setConsentStatus(t), t === "denied" ? (this.deps.storage.clearAttribution?.(), this.deps.storage.clearCookieVisitorId?.()) : t === "granted" && e === "denied" && this.config.rotate_visitor_on_consent_change && this.deps.storage.rotateVisitorId?.();
|
|
257
|
+
const i = {
|
|
70
258
|
visitor_id: this.deps.storage.getVisitorId(),
|
|
71
259
|
consent_state: t,
|
|
72
|
-
source: "sdk"
|
|
260
|
+
source: "sdk",
|
|
261
|
+
message_id: this.createMessageId()
|
|
73
262
|
};
|
|
74
|
-
this.siteId && (
|
|
263
|
+
this.siteId && (i.site_id = this.siteId), this.siteHost && (i.site_host = this.siteHost);
|
|
264
|
+
const s = this.config.before_send ? this.config.before_send(i) : i;
|
|
265
|
+
s && this.queue.enqueue("/consent", s);
|
|
266
|
+
}
|
|
267
|
+
reset() {
|
|
268
|
+
this.deps.storage.update({
|
|
269
|
+
user_id: void 0,
|
|
270
|
+
last_click_id: void 0,
|
|
271
|
+
campaign_id: void 0,
|
|
272
|
+
query_params: void 0,
|
|
273
|
+
session_id: void 0,
|
|
274
|
+
session_started_at: void 0,
|
|
275
|
+
last_activity_at: void 0
|
|
276
|
+
}), this.deps.storage.rotateVisitorId?.();
|
|
277
|
+
}
|
|
278
|
+
flush() {
|
|
279
|
+
return this.flushBatch(), this.queue.flush();
|
|
280
|
+
}
|
|
281
|
+
getStats() {
|
|
282
|
+
return this.queue.getStats();
|
|
75
283
|
}
|
|
76
284
|
getIdentityFields(t) {
|
|
77
|
-
const e = t?.visitor_id ?? this.deps.storage.getVisitorId(), i = t?.click_id ?? this.deps.storage.getLastClickId(),
|
|
78
|
-
return e && (
|
|
285
|
+
const e = t?.visitor_id ?? this.deps.storage.getVisitorId(), i = t?.user_id ?? this.deps.storage.getUserId?.(), s = t?.click_id ?? this.deps.storage.getLastClickId(), r = t?.campaign_id ?? this.deps.storage.getCampaignId(), o = t?.session_id ?? this.deps.storage.getSessionId?.(), a = this.deps.storage.getQueryParams() ?? {}, l = t?.query ?? {}, f = { ...a, ...l }, d = {};
|
|
286
|
+
return e && (d.visitor_id = e), i && (d.user_id = i), s && (d.click_id = s), r && (d.campaign_id = r), o && (d.session_id = o), Object.keys(f).length > 0 && (d.query = f), d;
|
|
79
287
|
}
|
|
80
288
|
hasConsent() {
|
|
289
|
+
if (this.config.consent_source?.type === "tcf" && typeof window < "u" && !this.tcfCachedAllowed)
|
|
290
|
+
return !1;
|
|
81
291
|
if (!this.consentRequirement)
|
|
82
292
|
return !0;
|
|
83
293
|
const e = this.deps.storage.getConsentStatus();
|
|
@@ -86,13 +296,13 @@ class I {
|
|
|
86
296
|
sanitizeTrackData(t) {
|
|
87
297
|
const e = {};
|
|
88
298
|
for (const [i, s] of Object.entries(t))
|
|
89
|
-
|
|
299
|
+
C.has(i) || (e[i] = s);
|
|
90
300
|
return e;
|
|
91
301
|
}
|
|
92
302
|
sanitizeIdentifyTraits(t) {
|
|
93
303
|
const e = {};
|
|
94
304
|
for (const [i, s] of Object.entries(t))
|
|
95
|
-
|
|
305
|
+
U.has(i) || (e[i] = s);
|
|
96
306
|
return e;
|
|
97
307
|
}
|
|
98
308
|
validateConfig(t) {
|
|
@@ -110,42 +320,175 @@ class I {
|
|
|
110
320
|
throw new Error("[Mark] `site_host` cannot be an empty string.");
|
|
111
321
|
}
|
|
112
322
|
applyPageContext(t) {
|
|
113
|
-
|
|
323
|
+
typeof document > "u" || (t.site || (t.site = window.location.host), t.page || (t.page = window.location.pathname), t.title || (t.title = document.title), !t.referrer && document.referrer && (t.referrer = this.scrubReferrer(document.referrer)));
|
|
324
|
+
}
|
|
325
|
+
enqueueBatch(t) {
|
|
326
|
+
this.batchedEvents.push(t);
|
|
327
|
+
const e = this.config.batching?.max_size ?? 20;
|
|
328
|
+
if (this.batchedEvents.length >= e) {
|
|
329
|
+
this.flushBatch();
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
if (!this.batchTimer) {
|
|
333
|
+
const i = this.config.batching?.flush_interval_ms ?? 2e3;
|
|
334
|
+
this.batchTimer = setTimeout(() => {
|
|
335
|
+
this.batchTimer = null, this.flushBatch();
|
|
336
|
+
}, i);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
flushBatch() {
|
|
340
|
+
if (this.batchedEvents.length === 0) return;
|
|
341
|
+
const t = this.config.batching?.endpoint_path ?? "/events", e = this.batchedEvents.splice(0, this.batchedEvents.length);
|
|
342
|
+
this.queue.enqueue(t, { events: e, message_id: this.createMessageId() });
|
|
343
|
+
}
|
|
344
|
+
createMessageId() {
|
|
345
|
+
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `msg_${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
|
346
|
+
}
|
|
347
|
+
ensureSession() {
|
|
348
|
+
const t = Date.now(), e = this.deps.storage.getSessionId?.(), i = this.deps.storage.getLastActivityAt?.(), s = i ? Date.parse(i) : 0;
|
|
349
|
+
if (!e || !s || t - s >= this.sessionTimeoutMs || this.crossedUtcDay(s, t)) {
|
|
350
|
+
const o = this.createMessageId(), a = new Date(t).toISOString();
|
|
351
|
+
this.deps.storage.update({
|
|
352
|
+
session_id: o,
|
|
353
|
+
session_started_at: a,
|
|
354
|
+
last_activity_at: a
|
|
355
|
+
});
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
this.deps.storage.update({ last_activity_at: new Date(t).toISOString() });
|
|
359
|
+
}
|
|
360
|
+
crossedUtcDay(t, e) {
|
|
361
|
+
const i = new Date(t), s = new Date(e);
|
|
362
|
+
return i.getUTCFullYear() !== s.getUTCFullYear() || i.getUTCMonth() !== s.getUTCMonth() || i.getUTCDate() !== s.getUTCDate();
|
|
363
|
+
}
|
|
364
|
+
shouldSampleTrack() {
|
|
365
|
+
return typeof this.config.sample_rate != "number" ? !0 : this.config.sample_rate <= 0 ? !1 : this.config.sample_rate >= 1 ? !0 : Math.random() <= this.config.sample_rate;
|
|
366
|
+
}
|
|
367
|
+
isDntBlocked() {
|
|
368
|
+
if (!this.config.honor_dnt || typeof navigator > "u")
|
|
369
|
+
return !1;
|
|
370
|
+
const t = navigator.doNotTrack, e = navigator.globalPrivacyControl;
|
|
371
|
+
return t === "1" || e === !0;
|
|
372
|
+
}
|
|
373
|
+
scrubReferrer(t) {
|
|
374
|
+
try {
|
|
375
|
+
const e = new URL(t);
|
|
376
|
+
if (typeof window > "u") return t;
|
|
377
|
+
const i = new URL(window.location.href);
|
|
378
|
+
return e.origin !== i.origin ? (e.search = "", e.toString()) : t;
|
|
379
|
+
} catch {
|
|
380
|
+
return t;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
warnMisconfiguredSiteHost() {
|
|
384
|
+
!this.config.debug || !this.siteHost || typeof window > "u" || (window.location.host !== this.siteHost && console.warn("[Mark] config.site_host does not match current host", {
|
|
385
|
+
expected: this.siteHost,
|
|
386
|
+
actual: window.location.host
|
|
387
|
+
}), this.siteId && !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(this.siteId) && console.warn("[Mark] config.site_id does not look like UUID v4", this.siteId));
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Subscribes to the IAB TCF v2 CMP via `__tcfapi('addEventListener', ...)`.
|
|
391
|
+
* Result is cached in `tcfCachedAllowed` so the synchronous `hasConsent()`
|
|
392
|
+
* path does not need to await the CMP. If the CMP is not yet present, we
|
|
393
|
+
* poll briefly (CMPs commonly load asynchronously) and give up after ~2s.
|
|
394
|
+
*/
|
|
395
|
+
subscribeTcf() {
|
|
396
|
+
const t = this.config.consent_source;
|
|
397
|
+
if (t?.type !== "tcf" || typeof window > "u") return;
|
|
398
|
+
const e = t.purposes, i = (s) => {
|
|
399
|
+
try {
|
|
400
|
+
const r = window;
|
|
401
|
+
if (typeof r.__tcfapi != "function") {
|
|
402
|
+
s > 0 && setTimeout(() => i(s - 1), 200);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
r.__tcfapi("addEventListener", 2, (o, a) => {
|
|
406
|
+
if (!a || !o) {
|
|
407
|
+
this.tcfCachedAllowed = !1;
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (o.gdprApplies === !1) {
|
|
411
|
+
this.tcfCachedAllowed = !0;
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
const l = o.purpose?.consents ?? {};
|
|
415
|
+
this.tcfCachedAllowed = e.every((f) => l[String(f)] === !0);
|
|
416
|
+
});
|
|
417
|
+
} catch {
|
|
418
|
+
this.tcfCachedAllowed = !1;
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
i(10);
|
|
114
422
|
}
|
|
115
423
|
}
|
|
116
|
-
class
|
|
424
|
+
class P {
|
|
117
425
|
config;
|
|
118
426
|
endpoint;
|
|
427
|
+
pending = /* @__PURE__ */ new Set();
|
|
119
428
|
constructor(t) {
|
|
120
|
-
this.
|
|
429
|
+
this.config = t, this.endpoint = t.endpoint ?? S;
|
|
121
430
|
}
|
|
122
|
-
async send(t, e) {
|
|
123
|
-
const
|
|
431
|
+
async send(t, e, i) {
|
|
432
|
+
const s = this.sendInternal(t, e, i);
|
|
433
|
+
this.pending.add(s);
|
|
434
|
+
try {
|
|
435
|
+
await s;
|
|
436
|
+
} finally {
|
|
437
|
+
this.pending.delete(s);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
async flush() {
|
|
441
|
+
this.pending.size !== 0 && await Promise.allSettled(Array.from(this.pending));
|
|
442
|
+
}
|
|
443
|
+
async sendInternal(t, e, i) {
|
|
444
|
+
const s = this.joinUrl(this.endpoint, t), r = this.config.key, o = {
|
|
124
445
|
"Content-Type": "application/json",
|
|
125
|
-
[
|
|
446
|
+
[r.startsWith("sk_") ? "x-secret-key" : "x-publishable-key"]: r
|
|
126
447
|
};
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
448
|
+
this.config.debug && console.log("[Mark] Sending", s, e);
|
|
449
|
+
const a = JSON.stringify(e);
|
|
450
|
+
if (i?.preferBeacon && typeof navigator < "u" && typeof navigator.sendBeacon == "function") {
|
|
451
|
+
const u = new Blob([a], { type: "application/json" });
|
|
452
|
+
if (navigator.sendBeacon(s, u))
|
|
453
|
+
return;
|
|
130
454
|
}
|
|
455
|
+
if (typeof fetch != "function")
|
|
456
|
+
throw this.config.debug && console.error("[Mark] Global fetch is not available in this runtime."), new h("[Mark] Global fetch is not available in this runtime.");
|
|
457
|
+
const l = this.config.request_timeout_ms ?? 1e4, f = new AbortController();
|
|
458
|
+
let d = !1;
|
|
459
|
+
const p = setTimeout(() => {
|
|
460
|
+
d = !0, f.abort();
|
|
461
|
+
}, l);
|
|
131
462
|
try {
|
|
132
|
-
const
|
|
463
|
+
const u = await fetch(s, {
|
|
133
464
|
method: "POST",
|
|
134
|
-
headers:
|
|
135
|
-
body:
|
|
136
|
-
keepalive: !0
|
|
465
|
+
headers: o,
|
|
466
|
+
body: a,
|
|
467
|
+
keepalive: !0,
|
|
468
|
+
signal: f.signal
|
|
137
469
|
});
|
|
138
|
-
if (!
|
|
139
|
-
const
|
|
140
|
-
console.error("[Mark] Request rejected", {
|
|
141
|
-
url:
|
|
142
|
-
status:
|
|
143
|
-
statusText:
|
|
144
|
-
body:
|
|
145
|
-
|
|
470
|
+
if (!u.ok) {
|
|
471
|
+
const g = await this.readErrorSnippet(u), y = E(u.headers.get("Retry-After"));
|
|
472
|
+
throw this.config.debug && console.error("[Mark] Request rejected", {
|
|
473
|
+
url: s,
|
|
474
|
+
status: u.status,
|
|
475
|
+
statusText: u.statusText,
|
|
476
|
+
body: g,
|
|
477
|
+
retryAfterMs: y
|
|
478
|
+
}), new h(
|
|
479
|
+
`[Mark] Request rejected with status ${u.status}: ${g}`,
|
|
480
|
+
{ status: u.status, retryAfterMs: y }
|
|
481
|
+
);
|
|
146
482
|
}
|
|
147
|
-
} catch (
|
|
148
|
-
this.config.debug && console.error("[Mark] Failed to send",
|
|
483
|
+
} catch (u) {
|
|
484
|
+
if (this.config.debug && console.error("[Mark] Failed to send", s, u), u instanceof h)
|
|
485
|
+
throw u;
|
|
486
|
+
if (d)
|
|
487
|
+
throw new h(`[Mark] Request timed out after ${l}ms`, { status: 408 });
|
|
488
|
+
const g = u instanceof Error ? u.message : String(u);
|
|
489
|
+
throw new h(`[Mark] Network error: ${g}`);
|
|
490
|
+
} finally {
|
|
491
|
+
clearTimeout(p);
|
|
149
492
|
}
|
|
150
493
|
}
|
|
151
494
|
joinUrl(t, e) {
|
|
@@ -159,27 +502,22 @@ class E {
|
|
|
159
502
|
return "";
|
|
160
503
|
}
|
|
161
504
|
}
|
|
162
|
-
validateConfig(t) {
|
|
163
|
-
if (!t.key || !t.key.trim())
|
|
164
|
-
throw new Error("[Mark] `key` must be a non-empty string.");
|
|
165
|
-
if (t.endpoint)
|
|
166
|
-
try {
|
|
167
|
-
new URL(t.endpoint);
|
|
168
|
-
} catch {
|
|
169
|
-
throw new Error("[Mark] `endpoint` must be a valid absolute URL.");
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
505
|
}
|
|
173
|
-
const
|
|
174
|
-
class
|
|
506
|
+
const R = "crelora_mark_data", B = "crelora_mark_outbox", w = "crelora_mark_vid";
|
|
507
|
+
class F {
|
|
175
508
|
data;
|
|
176
509
|
storageKey;
|
|
510
|
+
outboxKey;
|
|
177
511
|
options;
|
|
178
512
|
bridgeFrame;
|
|
179
513
|
bridgeReady = !1;
|
|
180
514
|
bridgeOrigin;
|
|
181
515
|
constructor(t) {
|
|
182
|
-
this.options = t ?? {}, this.storageKey = this.options.storageKey ??
|
|
516
|
+
if (this.options = t ?? {}, this.storageKey = this.options.storageKey ?? R, this.outboxKey = this.options.outboxKey ?? B, typeof window > "u") {
|
|
517
|
+
this.data = {};
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
this.data = this.load(), this.data.visitor_id || (this.data.visitor_id = this.generateUUID(), this.save()), typeof window < "u" && this.options.bridge?.url && this.setupBridge(this.options.bridge), window.addEventListener("storage", this.handleStorageEvent);
|
|
183
521
|
}
|
|
184
522
|
getVisitorId() {
|
|
185
523
|
return this.data.visitor_id;
|
|
@@ -196,33 +534,82 @@ class x {
|
|
|
196
534
|
getConsentStatus() {
|
|
197
535
|
return this.data.consent_status;
|
|
198
536
|
}
|
|
537
|
+
getUserId() {
|
|
538
|
+
return this.data.user_id;
|
|
539
|
+
}
|
|
540
|
+
getSessionId() {
|
|
541
|
+
return this.data.session_id;
|
|
542
|
+
}
|
|
543
|
+
getSessionStartedAt() {
|
|
544
|
+
return this.data.session_started_at;
|
|
545
|
+
}
|
|
546
|
+
getLastActivityAt() {
|
|
547
|
+
return this.data.last_activity_at;
|
|
548
|
+
}
|
|
199
549
|
update(t) {
|
|
200
550
|
this.data = { ...this.data, ...t }, this.save();
|
|
201
551
|
}
|
|
202
552
|
setConsentStatus(t) {
|
|
203
553
|
this.data.consent_status = t, this.save();
|
|
204
554
|
}
|
|
555
|
+
clearAttribution() {
|
|
556
|
+
this.update({
|
|
557
|
+
last_click_id: void 0,
|
|
558
|
+
campaign_id: void 0,
|
|
559
|
+
query_params: void 0
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
clearCookieVisitorId() {
|
|
563
|
+
this.setCookie(w, "", -1);
|
|
564
|
+
}
|
|
565
|
+
rotateVisitorId() {
|
|
566
|
+
this.update({ visitor_id: this.generateUUID() });
|
|
567
|
+
}
|
|
568
|
+
getOutbox() {
|
|
569
|
+
if (typeof window > "u") return [];
|
|
570
|
+
try {
|
|
571
|
+
const t = localStorage.getItem(this.outboxKey);
|
|
572
|
+
if (!t) return [];
|
|
573
|
+
const e = JSON.parse(t);
|
|
574
|
+
return Array.isArray(e) ? e : [];
|
|
575
|
+
} catch {
|
|
576
|
+
return [];
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
setOutbox(t) {
|
|
580
|
+
if (!(typeof window > "u"))
|
|
581
|
+
try {
|
|
582
|
+
localStorage.setItem(this.outboxKey, JSON.stringify(t.slice(-200)));
|
|
583
|
+
} catch {
|
|
584
|
+
}
|
|
585
|
+
}
|
|
205
586
|
load() {
|
|
587
|
+
if (typeof window > "u")
|
|
588
|
+
return {};
|
|
206
589
|
try {
|
|
207
590
|
const e = localStorage.getItem(this.storageKey);
|
|
208
591
|
if (e)
|
|
209
592
|
return JSON.parse(e);
|
|
210
593
|
} catch {
|
|
211
594
|
}
|
|
212
|
-
const t = this.getCookie(
|
|
595
|
+
const t = this.getCookie(w);
|
|
213
596
|
return t ? { visitor_id: t } : {};
|
|
214
597
|
}
|
|
215
598
|
save() {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
599
|
+
if (!(typeof window > "u")) {
|
|
600
|
+
try {
|
|
601
|
+
localStorage.setItem(this.storageKey, JSON.stringify(this.data));
|
|
602
|
+
} catch {
|
|
603
|
+
}
|
|
604
|
+
this.data.visitor_id && this.isCookieEnabled() && (this.setCookie(w, this.data.visitor_id, 365), this.options.bridge?.url && this.bridgeReady && this.postBridgeMessage({
|
|
605
|
+
type: "MARK_SYNC_UPDATE",
|
|
606
|
+
visitorId: this.data.visitor_id
|
|
607
|
+
}));
|
|
219
608
|
}
|
|
220
|
-
this.data.visitor_id && this.isCookieEnabled() && (this.setCookie(g, this.data.visitor_id, 365), this.options.bridge?.url && this.bridgeReady && this.postBridgeMessage({
|
|
221
|
-
type: "MARK_SYNC_UPDATE",
|
|
222
|
-
visitorId: this.data.visitor_id
|
|
223
|
-
}));
|
|
224
609
|
}
|
|
225
610
|
getCookie(t) {
|
|
611
|
+
if (typeof document > "u")
|
|
612
|
+
return null;
|
|
226
613
|
try {
|
|
227
614
|
const e = document.cookie.match(new RegExp(`(^| )${t}=([^;]+)`));
|
|
228
615
|
if (e) return e[2];
|
|
@@ -231,15 +618,24 @@ class x {
|
|
|
231
618
|
return null;
|
|
232
619
|
}
|
|
233
620
|
setCookie(t, e, i) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
621
|
+
if (!(typeof document > "u"))
|
|
622
|
+
try {
|
|
623
|
+
const s = new Date(Date.now() + i * 24 * 60 * 60 * 1e3), r = this.options.cookie_domain ? `;domain=${this.options.cookie_domain}` : "";
|
|
624
|
+
document.cookie = `${t}=${e};expires=${s.toUTCString()};path=/;SameSite=Lax${r}`;
|
|
625
|
+
} catch {
|
|
626
|
+
}
|
|
239
627
|
}
|
|
240
628
|
generateUUID() {
|
|
241
|
-
|
|
242
|
-
|
|
629
|
+
if (typeof crypto < "u" && crypto.randomUUID)
|
|
630
|
+
return crypto.randomUUID();
|
|
631
|
+
if (typeof crypto < "u" && typeof crypto.getRandomValues == "function") {
|
|
632
|
+
const t = crypto.getRandomValues(new Uint8Array(16));
|
|
633
|
+
t[6] = t[6] & 15 | 64, t[8] = t[8] & 63 | 128;
|
|
634
|
+
const e = Array.from(t, (i) => i.toString(16).padStart(2, "0")).join("");
|
|
635
|
+
return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
|
|
636
|
+
}
|
|
637
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (t) => {
|
|
638
|
+
const e = (Date.now() + Math.random() * 16) % 16 | 0;
|
|
243
639
|
return (t === "x" ? e : e & 3 | 8).toString(16);
|
|
244
640
|
});
|
|
245
641
|
}
|
|
@@ -293,8 +689,15 @@ class x {
|
|
|
293
689
|
return !1;
|
|
294
690
|
}
|
|
295
691
|
}
|
|
692
|
+
handleStorageEvent = (t) => {
|
|
693
|
+
if (!(t.key !== this.storageKey || typeof t.newValue != "string"))
|
|
694
|
+
try {
|
|
695
|
+
this.data = JSON.parse(t.newValue);
|
|
696
|
+
} catch {
|
|
697
|
+
}
|
|
698
|
+
};
|
|
296
699
|
}
|
|
297
|
-
const
|
|
700
|
+
const H = [
|
|
298
701
|
"click_id",
|
|
299
702
|
"ch_click_id",
|
|
300
703
|
"gclid",
|
|
@@ -306,7 +709,7 @@ const S = [
|
|
|
306
709
|
"ttclid",
|
|
307
710
|
"twclid",
|
|
308
711
|
"li_fat_id"
|
|
309
|
-
],
|
|
712
|
+
], O = ["cid", "campaign_id"], N = [
|
|
310
713
|
"utm_source",
|
|
311
714
|
"utm_medium",
|
|
312
715
|
"utm_campaign",
|
|
@@ -328,74 +731,74 @@ const S = [
|
|
|
328
731
|
"ttclid",
|
|
329
732
|
"twclid",
|
|
330
733
|
"li_fat_id"
|
|
331
|
-
],
|
|
734
|
+
], K = {
|
|
332
735
|
referral: "ref",
|
|
333
736
|
affiliate_id: "ref",
|
|
334
737
|
ch_click_id: "click_id",
|
|
335
738
|
cid: "campaign_id"
|
|
336
|
-
},
|
|
337
|
-
function
|
|
338
|
-
const e = new URLSearchParams(
|
|
739
|
+
}, V = ["email", "phone", "token", "auth", "password", "code"], z = 30, $ = 256;
|
|
740
|
+
function b(c, t = {}) {
|
|
741
|
+
const e = new URLSearchParams(c), i = Y(e), s = v(i, H), r = v(i, O), o = j(e, t), a = {};
|
|
339
742
|
return s && (a.last_click_id = s), r && (a.campaign_id = r), Object.keys(o).length > 0 && (a.query_params = o), a;
|
|
340
743
|
}
|
|
341
|
-
function
|
|
342
|
-
const e = {}, i = new Set(
|
|
744
|
+
function j(c, t) {
|
|
745
|
+
const e = {}, i = new Set(_(t.query_param_denylist, V)), s = A(
|
|
343
746
|
t.max_captured_query_params,
|
|
344
|
-
|
|
345
|
-
), r =
|
|
747
|
+
z
|
|
748
|
+
), r = A(
|
|
346
749
|
t.max_query_param_value_length,
|
|
347
|
-
|
|
750
|
+
$
|
|
348
751
|
), a = t.capture_all_query_params ?? !1 ? null : /* @__PURE__ */ new Set([
|
|
349
|
-
...
|
|
350
|
-
...
|
|
752
|
+
...N.map(m),
|
|
753
|
+
..._(t.capture_query_params, [])
|
|
351
754
|
]);
|
|
352
|
-
for (const [
|
|
353
|
-
const
|
|
354
|
-
if (!
|
|
755
|
+
for (const [l, f] of c.entries()) {
|
|
756
|
+
const d = m(l);
|
|
757
|
+
if (!d)
|
|
355
758
|
continue;
|
|
356
|
-
const
|
|
357
|
-
if (i.has(
|
|
759
|
+
const p = K[d] ?? d;
|
|
760
|
+
if (i.has(d) || i.has(p) || a && !a.has(d))
|
|
358
761
|
continue;
|
|
359
|
-
const
|
|
360
|
-
if (
|
|
361
|
-
if (!(
|
|
762
|
+
const u = f.trim();
|
|
763
|
+
if (u) {
|
|
764
|
+
if (!(p in e) && Object.keys(e).length >= s)
|
|
362
765
|
break;
|
|
363
|
-
e[
|
|
766
|
+
e[p] = u.slice(0, r);
|
|
364
767
|
}
|
|
365
768
|
}
|
|
366
769
|
return e;
|
|
367
770
|
}
|
|
368
|
-
function
|
|
771
|
+
function v(c, t) {
|
|
369
772
|
for (const e of t) {
|
|
370
|
-
const i =
|
|
773
|
+
const i = m(e), s = c[i]?.trim();
|
|
371
774
|
if (s)
|
|
372
775
|
return s;
|
|
373
776
|
}
|
|
374
777
|
}
|
|
375
|
-
function
|
|
778
|
+
function Y(c) {
|
|
376
779
|
const t = {};
|
|
377
|
-
for (const [e, i] of
|
|
378
|
-
const s =
|
|
780
|
+
for (const [e, i] of c.entries()) {
|
|
781
|
+
const s = m(e);
|
|
379
782
|
!s || s in t || (t[s] = i);
|
|
380
783
|
}
|
|
381
784
|
return t;
|
|
382
785
|
}
|
|
383
|
-
function
|
|
384
|
-
return
|
|
786
|
+
function m(c) {
|
|
787
|
+
return c.trim().toLowerCase();
|
|
385
788
|
}
|
|
386
|
-
function
|
|
387
|
-
const e =
|
|
789
|
+
function _(c, t) {
|
|
790
|
+
const e = c ?? t, i = /* @__PURE__ */ new Set();
|
|
388
791
|
for (const s of e) {
|
|
389
792
|
if (typeof s != "string") continue;
|
|
390
|
-
const r =
|
|
793
|
+
const r = m(s);
|
|
391
794
|
r && i.add(r);
|
|
392
795
|
}
|
|
393
796
|
return Array.from(i);
|
|
394
797
|
}
|
|
395
|
-
function
|
|
396
|
-
if (typeof
|
|
798
|
+
function A(c, t) {
|
|
799
|
+
if (typeof c != "number" || !Number.isFinite(c))
|
|
397
800
|
return t;
|
|
398
|
-
const e = Math.floor(
|
|
801
|
+
const e = Math.floor(c);
|
|
399
802
|
return e < 0 ? t : e;
|
|
400
803
|
}
|
|
401
804
|
class n {
|
|
@@ -406,37 +809,57 @@ class n {
|
|
|
406
809
|
static lastPageviewHref = null;
|
|
407
810
|
static emitAutoPageview = null;
|
|
408
811
|
static pendingAttribution = {};
|
|
812
|
+
static originalPushState = null;
|
|
813
|
+
static originalReplaceState = null;
|
|
814
|
+
static popstateHandler = null;
|
|
815
|
+
static beaconDrainHandler = null;
|
|
816
|
+
static visibilityHandler = null;
|
|
817
|
+
static onlineHandler = null;
|
|
818
|
+
static kickTimer = null;
|
|
409
819
|
static init(t) {
|
|
410
820
|
if (!n.client) {
|
|
411
|
-
const e = new
|
|
412
|
-
n.client = new
|
|
821
|
+
const e = new F(t.cross_domain), i = new P(t);
|
|
822
|
+
n.client = new L(t, { storage: e, transport: i }), n.storage = e, n.config = t, n.refreshAttribution(e, t), typeof window < "u" && t.autocapture?.pageview && n.installPageviewTracking(t, e), typeof window < "u" && (n.installExtendedAutocapture(t), n.installLifecycleFlushing());
|
|
413
823
|
}
|
|
414
824
|
return n.client;
|
|
415
825
|
}
|
|
826
|
+
static installLifecycleFlushing() {
|
|
827
|
+
if (typeof window > "u" || n.beaconDrainHandler) return;
|
|
828
|
+
const t = () => {
|
|
829
|
+
n.client?.drainViaBeacon();
|
|
830
|
+
}, e = () => {
|
|
831
|
+
typeof document < "u" && document.visibilityState === "hidden" && t();
|
|
832
|
+
}, i = () => {
|
|
833
|
+
n.client?.kickQueue();
|
|
834
|
+
};
|
|
835
|
+
n.beaconDrainHandler = t, n.visibilityHandler = e, n.onlineHandler = i, typeof document < "u" && typeof document.addEventListener == "function" && document.addEventListener("visibilitychange", e), typeof window.addEventListener == "function" && (window.addEventListener("pagehide", t), window.addEventListener("beforeunload", t), window.addEventListener("online", i)), typeof setInterval == "function" && (n.kickTimer = setInterval(() => {
|
|
836
|
+
n.client?.kickQueue();
|
|
837
|
+
}, 3e4));
|
|
838
|
+
}
|
|
416
839
|
static track(t, e = {}) {
|
|
417
840
|
if (!n.client) {
|
|
418
|
-
console.warn("[Mark] Not initialized. Call init() first.");
|
|
841
|
+
n.config?.debug && console.warn("[Mark] Not initialized. Call init() first.");
|
|
419
842
|
return;
|
|
420
843
|
}
|
|
421
844
|
n.client.track(t, e);
|
|
422
845
|
}
|
|
423
846
|
static identify(t, e = {}) {
|
|
424
847
|
if (!n.client) {
|
|
425
|
-
console.warn("[Mark] Not initialized. Call init() first.");
|
|
848
|
+
n.config?.debug && console.warn("[Mark] Not initialized. Call init() first.");
|
|
426
849
|
return;
|
|
427
850
|
}
|
|
428
851
|
n.client.identify(t, e);
|
|
429
852
|
}
|
|
430
853
|
static conversion(t, e = {}) {
|
|
431
854
|
if (!n.client) {
|
|
432
|
-
console.warn("[Mark] Not initialized. Call init() first.");
|
|
855
|
+
n.config?.debug && console.warn("[Mark] Not initialized. Call init() first.");
|
|
433
856
|
return;
|
|
434
857
|
}
|
|
435
858
|
n.client.conversion(t, e);
|
|
436
859
|
}
|
|
437
860
|
static setConsent(t) {
|
|
438
861
|
if (!n.client) {
|
|
439
|
-
console.warn("[Mark] Not initialized. Call init() first.");
|
|
862
|
+
n.config?.debug && console.warn("[Mark] Not initialized. Call init() first.");
|
|
440
863
|
return;
|
|
441
864
|
}
|
|
442
865
|
n.client.setConsent(t), t === "granted" && (n.flushPendingAttribution(), n.emitAutoPageview?.());
|
|
@@ -451,6 +874,18 @@ class n {
|
|
|
451
874
|
if (!(!n.client || !n.storage || !n.config || (n.config.require_consent ?? !1) && n.storage.getConsentStatus() !== "granted"))
|
|
452
875
|
return n.client.getVisitorId();
|
|
453
876
|
}
|
|
877
|
+
static flush() {
|
|
878
|
+
return n.client ? n.client.flush() : Promise.resolve();
|
|
879
|
+
}
|
|
880
|
+
static reset() {
|
|
881
|
+
n.client?.reset(), n.pendingAttribution = {}, n.lastPageviewHref = null;
|
|
882
|
+
}
|
|
883
|
+
static getStats() {
|
|
884
|
+
return n.client?.getStats() ?? { queued: 0, sent: 0, failed: 0, dropped: 0 };
|
|
885
|
+
}
|
|
886
|
+
static destroy() {
|
|
887
|
+
typeof window > "u" || (n.originalPushState && (history.pushState = n.originalPushState), n.originalReplaceState && (history.replaceState = n.originalReplaceState), n.popstateHandler && window.removeEventListener("popstate", n.popstateHandler), n.beaconDrainHandler && (window.removeEventListener("pagehide", n.beaconDrainHandler), window.removeEventListener("beforeunload", n.beaconDrainHandler)), n.visibilityHandler && typeof document < "u" && document.removeEventListener("visibilitychange", n.visibilityHandler), n.onlineHandler && window.removeEventListener("online", n.onlineHandler), n.kickTimer && clearInterval(n.kickTimer), n.originalPushState = null, n.originalReplaceState = null, n.popstateHandler = null, n.beaconDrainHandler = null, n.visibilityHandler = null, n.onlineHandler = null, n.kickTimer = null, n.pageviewTrackerInstalled = !1);
|
|
888
|
+
}
|
|
454
889
|
static installPageviewTracking(t, e) {
|
|
455
890
|
if (n.pageviewTrackerInstalled) return;
|
|
456
891
|
n.pageviewTrackerInstalled = !0;
|
|
@@ -468,18 +903,18 @@ class n {
|
|
|
468
903
|
};
|
|
469
904
|
if (n.emitAutoPageview = i, i(), !(t.track_route_changes ?? !0)) return;
|
|
470
905
|
const r = history.pushState, o = history.replaceState;
|
|
471
|
-
history.pushState = function(...a) {
|
|
472
|
-
const
|
|
473
|
-
return i(),
|
|
906
|
+
n.originalPushState = r, n.originalReplaceState = o, history.pushState = function(...a) {
|
|
907
|
+
const l = r.apply(this, a);
|
|
908
|
+
return i(), l;
|
|
474
909
|
}, history.replaceState = function(...a) {
|
|
475
|
-
const
|
|
476
|
-
return i(),
|
|
477
|
-
}, window.addEventListener("popstate", i);
|
|
910
|
+
const l = o.apply(this, a);
|
|
911
|
+
return i(), l;
|
|
912
|
+
}, n.popstateHandler = i, window.addEventListener("popstate", i);
|
|
478
913
|
}
|
|
479
914
|
static refreshAttribution(t, e) {
|
|
480
915
|
if (typeof window > "u")
|
|
481
916
|
return;
|
|
482
|
-
const i =
|
|
917
|
+
const i = b(window.location.search, e);
|
|
483
918
|
if (Object.keys(i).length !== 0) {
|
|
484
919
|
if (n.shouldPersistAttribution(t, e)) {
|
|
485
920
|
const s = n.mergeAttributionUpdates(n.pendingAttribution, i);
|
|
@@ -493,7 +928,7 @@ class n {
|
|
|
493
928
|
const t = n.storage, e = n.config;
|
|
494
929
|
if (!t || !e || typeof window > "u")
|
|
495
930
|
return;
|
|
496
|
-
const i =
|
|
931
|
+
const i = b(window.location.search, e), s = n.mergeAttributionUpdates(n.pendingAttribution, i);
|
|
497
932
|
Object.keys(s).length > 0 && t.update(s), n.pendingAttribution = {};
|
|
498
933
|
}
|
|
499
934
|
static shouldPersistAttribution(t, e) {
|
|
@@ -509,9 +944,68 @@ class n {
|
|
|
509
944
|
}
|
|
510
945
|
};
|
|
511
946
|
}
|
|
947
|
+
static installExtendedAutocapture(t) {
|
|
948
|
+
if (!n.client || typeof document > "u") return;
|
|
949
|
+
const e = t.autocapture;
|
|
950
|
+
if (e) {
|
|
951
|
+
if (e.click && document.addEventListener("click", (i) => {
|
|
952
|
+
const s = i.target;
|
|
953
|
+
if (!s) return;
|
|
954
|
+
const r = typeof e.click == "object" ? e.click.selector : void 0, o = r ? s.closest(r) : s.closest("[data-mark-event]");
|
|
955
|
+
if (!o) return;
|
|
956
|
+
const a = o.getAttribute("data-mark-event") || "click";
|
|
957
|
+
n.client?.track(a, {
|
|
958
|
+
element_id: o.id || void 0,
|
|
959
|
+
element_classes: o.className || void 0,
|
|
960
|
+
text: o.textContent?.trim().slice(0, 120) || void 0,
|
|
961
|
+
href: o.href || void 0
|
|
962
|
+
});
|
|
963
|
+
}), e.form_submit && document.addEventListener("submit", (i) => {
|
|
964
|
+
const s = i.target;
|
|
965
|
+
s && n.client?.track("form_submit", {
|
|
966
|
+
form_id: s.id || void 0,
|
|
967
|
+
form_name: s.name || void 0,
|
|
968
|
+
action: s.action || void 0
|
|
969
|
+
});
|
|
970
|
+
}), e.outbound_link && document.addEventListener("click", (i) => {
|
|
971
|
+
const s = i.target?.closest("a[href]");
|
|
972
|
+
if (!(!s || !s.href))
|
|
973
|
+
try {
|
|
974
|
+
const r = new URL(s.href, window.location.href), o = new URL(window.location.href);
|
|
975
|
+
r.origin !== o.origin && n.client?.trackWithOptions("outbound_link_click", { href: r.toString() }, { preferBeacon: !0 });
|
|
976
|
+
} catch {
|
|
977
|
+
}
|
|
978
|
+
}), e.scroll_depth) {
|
|
979
|
+
const i = [25, 50, 75, 100], s = /* @__PURE__ */ new Set();
|
|
980
|
+
window.addEventListener(
|
|
981
|
+
"scroll",
|
|
982
|
+
() => {
|
|
983
|
+
const r = document.documentElement, o = window.scrollY || r.scrollTop, a = Math.max(1, r.scrollHeight - window.innerHeight), l = Math.min(100, Math.round(o / a * 100));
|
|
984
|
+
for (const f of i)
|
|
985
|
+
l >= f && !s.has(f) && (s.add(f), n.client?.track("scroll_depth", { percent: f }));
|
|
986
|
+
},
|
|
987
|
+
{ passive: !0 }
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
e.web_vitals && import("./web-vitals-CrnTllyu.js").then((i) => {
|
|
991
|
+
const s = (r) => {
|
|
992
|
+
n.client?.track("web_vital", {
|
|
993
|
+
metric: r.name,
|
|
994
|
+
value: r.value,
|
|
995
|
+
rating: r.rating,
|
|
996
|
+
metric_id: r.id
|
|
997
|
+
});
|
|
998
|
+
};
|
|
999
|
+
i.onLCP(s), i.onCLS(s), i.onINP(s), i.onTTFB(s);
|
|
1000
|
+
}).catch(() => {
|
|
1001
|
+
t.debug && console.warn("[Mark] web-vitals package not available; skipping autocapture.web_vitals.");
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
512
1005
|
}
|
|
513
1006
|
typeof window < "u" && (window.Mark = n);
|
|
514
1007
|
export {
|
|
515
1008
|
n as Mark,
|
|
516
1009
|
n as default
|
|
517
1010
|
};
|
|
1011
|
+
//# sourceMappingURL=browser.es.js.map
|