@crelora/mark 0.2.2 → 0.3.2
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 +20 -3
- package/dist/browser.es.js +215 -170
- package/dist/browser.es.js.map +1 -1
- package/dist/browser.umd.js +1 -1
- package/dist/browser.umd.js.map +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.es.js +119 -95
- package/dist/node.es.js.map +1 -1
- package/dist/types/browser/BrowserStorage.d.ts +9 -0
- package/dist/types/browser/Mark.d.ts +9 -0
- package/dist/types/browser/pageEngagement.d.ts +1 -0
- package/dist/types/core/DeliveryQueue.d.ts +2 -2
- package/dist/types/core/MarkCore.d.ts +7 -1
- package/dist/types/core/adapters.d.ts +1 -0
- package/dist/types/core/visitorId.d.ts +5 -0
- package/dist/types/node/StatelessStorage.d.ts +1 -0
- package/dist/types/node/index.d.ts +6 -0
- package/dist/types/types.d.ts +9 -0
- package/package.json +2 -2
package/dist/browser.es.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
const
|
|
2
|
-
class
|
|
1
|
+
const H = "https://ingest.onelence.com";
|
|
2
|
+
class g extends Error {
|
|
3
3
|
status;
|
|
4
4
|
retryAfterMs;
|
|
5
5
|
constructor(e, t = {}) {
|
|
6
6
|
super(e), this.name = "TransportError", this.status = t.status, this.retryAfterMs = t.retryAfterMs;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
-
function
|
|
9
|
+
function z(r) {
|
|
10
10
|
return !(typeof r != "number" || r < 400 || r >= 500 || r === 408 || r === 429);
|
|
11
11
|
}
|
|
12
|
-
function
|
|
12
|
+
function M(r) {
|
|
13
13
|
if (!r) return;
|
|
14
14
|
const e = r.trim();
|
|
15
15
|
if (!e) return;
|
|
@@ -22,10 +22,10 @@ function V(r) {
|
|
|
22
22
|
return n > 0 ? n : 0;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
const
|
|
26
|
-
class
|
|
25
|
+
const $ = 5, Y = 300, j = 15e3, Q = 2880 * 60 * 1e3;
|
|
26
|
+
class W {
|
|
27
27
|
constructor(e, t = {}) {
|
|
28
|
-
this.transport = e, this.maxAttempts = t.maxAttempts ??
|
|
28
|
+
this.transport = e, this.maxAttempts = t.maxAttempts ?? $, this.baseBackoffMs = t.baseBackoffMs ?? Y, this.maxBackoffMs = t.maxBackoffMs ?? j, this.maxItemAgeMs = t.maxItemAgeMs ?? Q, this.debug = t.debug ?? !1, this.loadPersisted = t.loadPersisted, this.savePersisted = t.savePersisted, this.onError = t.onError;
|
|
29
29
|
const i = this.loadPersisted?.() ?? [];
|
|
30
30
|
if (i.length > 0) {
|
|
31
31
|
const n = Date.now();
|
|
@@ -66,8 +66,8 @@ class Y {
|
|
|
66
66
|
await this.process(!0), await this.transport.flush?.();
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
|
-
* Best-effort synchronous drain
|
|
70
|
-
*
|
|
69
|
+
* Best-effort synchronous drain on page unload. Uses fetch keepalive (via
|
|
70
|
+
* preferBeacon) so auth headers are included.
|
|
71
71
|
*/
|
|
72
72
|
drainViaBeacon() {
|
|
73
73
|
if (this.queue.length === 0) return;
|
|
@@ -117,8 +117,8 @@ class Y {
|
|
|
117
117
|
delete i.__prefer_beacon, await this.transport.send(t.path, i, { preferBeacon: n }), this.queue.shift(), this.sent += 1, this.persist();
|
|
118
118
|
} catch (i) {
|
|
119
119
|
this.failed += 1, this.onError?.(i, t.data);
|
|
120
|
-
const n = i instanceof
|
|
121
|
-
if (
|
|
120
|
+
const n = i instanceof g ? i.status : void 0;
|
|
121
|
+
if (z(n)) {
|
|
122
122
|
this.queue.shift(), this.dropped += 1, this.persist(), this.debug && console.error("[Mark] Dropping event after non-retriable status", n, t.path);
|
|
123
123
|
continue;
|
|
124
124
|
}
|
|
@@ -126,7 +126,7 @@ class Y {
|
|
|
126
126
|
this.queue.shift(), this.dropped += 1, this.persist(), this.debug && console.error("[Mark] Dropping event after max retries", t.path, i);
|
|
127
127
|
continue;
|
|
128
128
|
}
|
|
129
|
-
const o = i instanceof
|
|
129
|
+
const o = i instanceof g ? i.retryAfterMs : void 0;
|
|
130
130
|
let a;
|
|
131
131
|
if (typeof o == "number")
|
|
132
132
|
a = Math.min(this.maxBackoffMs, Math.max(0, o));
|
|
@@ -147,7 +147,15 @@ class Y {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
|
-
const
|
|
150
|
+
const G = 256;
|
|
151
|
+
function T(r) {
|
|
152
|
+
if (typeof r != "string")
|
|
153
|
+
return;
|
|
154
|
+
const e = r.trim();
|
|
155
|
+
if (!(!e || e.length > G) && !e.includes("@") && !/\s/.test(e))
|
|
156
|
+
return e;
|
|
157
|
+
}
|
|
158
|
+
const X = /* @__PURE__ */ new Set(["event_name", "user_id", "consent_state", "source", "is_conversion"]), J = /* @__PURE__ */ new Set([
|
|
151
159
|
"user_id",
|
|
152
160
|
"visitor_id",
|
|
153
161
|
"click_id",
|
|
@@ -156,13 +164,13 @@ const Q = /* @__PURE__ */ new Set(["event_name", "user_id", "consent_state", "so
|
|
|
156
164
|
"consent_state",
|
|
157
165
|
"source"
|
|
158
166
|
]);
|
|
159
|
-
class
|
|
167
|
+
class Z {
|
|
160
168
|
constructor(e, t) {
|
|
161
169
|
this.deps = t, this.validateConfig(e), this.config = {
|
|
162
|
-
endpoint: e.endpoint ??
|
|
170
|
+
endpoint: e.endpoint ?? H,
|
|
163
171
|
...e,
|
|
164
172
|
include_page_context: e.include_page_context ?? !0
|
|
165
|
-
}, this.consentRequirement = e.require_consent ?? !1, this.siteId = e.site_id, this.siteHost = e.site_host, this.sessionTimeoutMs = e.session_timeout_ms ?? 1800 * 1e3, this.queue = new
|
|
173
|
+
}, this.consentRequirement = e.require_consent ?? !1, this.siteId = e.site_id, this.siteHost = e.site_host, this.sessionTimeoutMs = e.session_timeout_ms ?? 1800 * 1e3, this.queue = new W(this.deps.transport, {
|
|
166
174
|
debug: this.config.debug,
|
|
167
175
|
loadPersisted: () => this.deps.storage.getOutbox?.() ?? [],
|
|
168
176
|
savePersisted: (i) => this.deps.storage.setOutbox?.(i),
|
|
@@ -180,7 +188,7 @@ class G {
|
|
|
180
188
|
tcfCachedAllowed = !1;
|
|
181
189
|
/**
|
|
182
190
|
* Best-effort synchronous drain that dispatches all queued events via
|
|
183
|
-
*
|
|
191
|
+
* fetch keepalive. Intended for use on page unload (visibilitychange=hidden,
|
|
184
192
|
* pagehide) where async fetch may be cancelled by the browser.
|
|
185
193
|
*/
|
|
186
194
|
drainViaBeacon() {
|
|
@@ -213,8 +221,8 @@ class G {
|
|
|
213
221
|
...a
|
|
214
222
|
};
|
|
215
223
|
i && (c.is_conversion = !0);
|
|
216
|
-
const f = o.site_id ?? this.siteId,
|
|
217
|
-
f && (c.site_id = f),
|
|
224
|
+
const f = o.site_id ?? this.siteId, u = o.site_host ?? this.siteHost;
|
|
225
|
+
f && (c.site_id = f), u && (c.site_host = u), this.config.include_page_context && typeof window < "u" && (this.applyPageContext(c), !u && c.site && (c.site_host = c.site)), this.applyInternalFlag(c, o.is_internal);
|
|
218
226
|
const d = this.config.before_send ? this.config.before_send(c) : c;
|
|
219
227
|
return d ? (this.ensureSession(), this.applySessionFields(d), this.config.batching?.enabled && !i && !n?.preferBeacon ? (this.enqueueBatch(d), !0) : (this.queue.enqueue("/event", { ...d, __prefer_beacon: n?.preferBeacon === !0 }), !0)) : !0;
|
|
220
228
|
}
|
|
@@ -251,6 +259,15 @@ class G {
|
|
|
251
259
|
getVisitorId() {
|
|
252
260
|
return this.deps.storage.getVisitorId();
|
|
253
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Adopts or replaces the stored visitor id with a trusted first-party value.
|
|
264
|
+
* Use when an external anonymous id (for example a platform client id) arrives
|
|
265
|
+
* after init. Returns false when the id is invalid.
|
|
266
|
+
*/
|
|
267
|
+
setVisitorId(e) {
|
|
268
|
+
const t = T(e);
|
|
269
|
+
return t ? this.deps.storage.setVisitorId ? this.deps.storage.setVisitorId(t) : (this.deps.storage.getVisitorId() === t || this.deps.storage.update({ visitor_id: t }), !0) : (this.config.debug && console.warn("[Mark] setVisitorId called with an invalid visitor id."), !1);
|
|
270
|
+
}
|
|
254
271
|
setConsent(e) {
|
|
255
272
|
const t = this.deps.storage.getConsentStatus();
|
|
256
273
|
this.deps.storage.setConsentStatus(e), e === "denied" ? (this.deps.storage.clearAttribution?.(), this.deps.storage.clearCookieVisitorId?.(), this.deps.storage.setInternal?.(!1)) : e === "granted" && t === "denied" && this.config.rotate_visitor_on_consent_change && this.deps.storage.rotateVisitorId?.();
|
|
@@ -318,10 +335,10 @@ class G {
|
|
|
318
335
|
t === !0 || i ? e.is_internal = !0 : delete e.is_internal;
|
|
319
336
|
}
|
|
320
337
|
getIdentityFields(e) {
|
|
321
|
-
const t = e?.visitor_id ?? this.deps.storage.getVisitorId(), i = e?.user_id ?? this.deps.storage.getUserId?.(), n = e?.click_id ?? this.deps.storage.getLastClickId(), o = e?.campaign_id ?? this.deps.storage.getCampaignId(), a = e?.session_id ?? this.deps.storage.getSessionId?.(), c = this.deps.storage.getQueryParams() ?? {}, f = e?.query ?? {},
|
|
338
|
+
const t = e?.visitor_id ?? this.deps.storage.getVisitorId(), i = e?.user_id ?? this.deps.storage.getUserId?.(), n = e?.click_id ?? this.deps.storage.getLastClickId(), o = e?.campaign_id ?? this.deps.storage.getCampaignId(), a = e?.session_id ?? this.deps.storage.getSessionId?.(), c = this.deps.storage.getQueryParams() ?? {}, f = e?.query ?? {}, u = { ...c, ...f }, d = {};
|
|
322
339
|
t && (d.visitor_id = t), i && (d.user_id = i), n && (d.click_id = n), o && (d.campaign_id = o), a && (d.session_id = a);
|
|
323
340
|
const h = this.deps.storage.getSessionStartedAt?.();
|
|
324
|
-
return a && h && (d.session_started_at = h, d.session_elapsed_ms = Date.now() - Date.parse(h)), Object.keys(
|
|
341
|
+
return a && h && (d.session_started_at = h, d.session_elapsed_ms = Date.now() - Date.parse(h)), Object.keys(u).length > 0 && (d.query = u), d;
|
|
325
342
|
}
|
|
326
343
|
/**
|
|
327
344
|
* Patches session fields after ensureSession when the first event in a session was built
|
|
@@ -346,13 +363,13 @@ class G {
|
|
|
346
363
|
sanitizeTrackData(e) {
|
|
347
364
|
const t = {};
|
|
348
365
|
for (const [i, n] of Object.entries(e))
|
|
349
|
-
|
|
366
|
+
X.has(i) || (t[i] = n);
|
|
350
367
|
return t;
|
|
351
368
|
}
|
|
352
369
|
sanitizeIdentifyTraits(e) {
|
|
353
370
|
const t = {};
|
|
354
371
|
for (const [i, n] of Object.entries(e))
|
|
355
|
-
|
|
372
|
+
J.has(i) || (t[i] = n);
|
|
356
373
|
return t;
|
|
357
374
|
}
|
|
358
375
|
validateConfig(e) {
|
|
@@ -368,6 +385,8 @@ class G {
|
|
|
368
385
|
throw new Error("[Mark] `site_id` cannot be an empty string.");
|
|
369
386
|
if (typeof e.site_host == "string" && !e.site_host.trim())
|
|
370
387
|
throw new Error("[Mark] `site_host` cannot be an empty string.");
|
|
388
|
+
if (e.visitor_id !== void 0 && !T(e.visitor_id))
|
|
389
|
+
throw new Error("[Mark] `visitor_id` must be a non-empty string (max 256 characters).");
|
|
371
390
|
}
|
|
372
391
|
applyPageContext(e) {
|
|
373
392
|
typeof document > "u" || (e.site || (e.site = window.location.host), e.page || (e.page = window.location.pathname), e.title || (e.title = document.title), !e.referrer && document.referrer && (e.referrer = this.scrubReferrer(document.referrer)));
|
|
@@ -462,7 +481,7 @@ class G {
|
|
|
462
481
|
return;
|
|
463
482
|
}
|
|
464
483
|
const f = a.purpose?.consents ?? {};
|
|
465
|
-
this.tcfCachedAllowed = t.every((
|
|
484
|
+
this.tcfCachedAllowed = t.every((u) => f[String(u)] === !0);
|
|
466
485
|
});
|
|
467
486
|
} catch {
|
|
468
487
|
this.tcfCachedAllowed = !1;
|
|
@@ -471,12 +490,12 @@ class G {
|
|
|
471
490
|
i(10);
|
|
472
491
|
}
|
|
473
492
|
}
|
|
474
|
-
class
|
|
493
|
+
class ee {
|
|
475
494
|
config;
|
|
476
495
|
endpoint;
|
|
477
496
|
pending = /* @__PURE__ */ new Set();
|
|
478
497
|
constructor(e) {
|
|
479
|
-
this.config = e, this.endpoint = e.endpoint ??
|
|
498
|
+
this.config = e, this.endpoint = e.endpoint ?? H;
|
|
480
499
|
}
|
|
481
500
|
async send(e, t, i) {
|
|
482
501
|
const n = this.sendInternal(e, t, i);
|
|
@@ -495,48 +514,41 @@ class J {
|
|
|
495
514
|
"Content-Type": "application/json",
|
|
496
515
|
[o.startsWith("sk_") ? "x-secret-key" : "x-publishable-key"]: o
|
|
497
516
|
};
|
|
498
|
-
this.config.debug && console.log("[Mark] Sending", n, t)
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
const u = new Blob([c], { type: "application/json" });
|
|
502
|
-
if (navigator.sendBeacon(n, u))
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
if (typeof fetch != "function")
|
|
506
|
-
throw this.config.debug && console.error("[Mark] Global fetch is not available in this runtime."), new p("[Mark] Global fetch is not available in this runtime.");
|
|
507
|
-
const f = this.config.request_timeout_ms ?? 1e4, l = new AbortController();
|
|
517
|
+
if (this.config.debug && console.log("[Mark] Sending", n, t), typeof fetch != "function")
|
|
518
|
+
throw this.config.debug && console.error("[Mark] Global fetch is not available in this runtime."), new g("[Mark] Global fetch is not available in this runtime.");
|
|
519
|
+
const c = JSON.stringify(t), f = this.config.request_timeout_ms ?? 1e4, u = new AbortController();
|
|
508
520
|
let d = !1;
|
|
509
521
|
const h = setTimeout(() => {
|
|
510
|
-
d = !0,
|
|
522
|
+
d = !0, u.abort();
|
|
511
523
|
}, f);
|
|
512
524
|
try {
|
|
513
|
-
const
|
|
525
|
+
const l = await fetch(n, {
|
|
514
526
|
method: "POST",
|
|
515
527
|
headers: a,
|
|
516
528
|
body: c,
|
|
517
|
-
keepalive: !0,
|
|
518
|
-
signal:
|
|
529
|
+
keepalive: i?.preferBeacon === !0,
|
|
530
|
+
signal: u.signal
|
|
519
531
|
});
|
|
520
|
-
if (!
|
|
521
|
-
const
|
|
532
|
+
if (!l.ok) {
|
|
533
|
+
const p = await this.readErrorSnippet(l), m = M(l.headers.get("Retry-After"));
|
|
522
534
|
throw this.config.debug && console.error("[Mark] Request rejected", {
|
|
523
535
|
url: n,
|
|
524
|
-
status:
|
|
525
|
-
statusText:
|
|
526
|
-
body:
|
|
527
|
-
retryAfterMs:
|
|
528
|
-
}), new
|
|
529
|
-
`[Mark] Request rejected with status ${
|
|
530
|
-
{ status:
|
|
536
|
+
status: l.status,
|
|
537
|
+
statusText: l.statusText,
|
|
538
|
+
body: p,
|
|
539
|
+
retryAfterMs: m
|
|
540
|
+
}), new g(
|
|
541
|
+
`[Mark] Request rejected with status ${l.status}: ${p}`,
|
|
542
|
+
{ status: l.status, retryAfterMs: m }
|
|
531
543
|
);
|
|
532
544
|
}
|
|
533
|
-
} catch (
|
|
534
|
-
if (this.config.debug && console.error("[Mark] Failed to send", n,
|
|
535
|
-
throw
|
|
545
|
+
} catch (l) {
|
|
546
|
+
if (this.config.debug && console.error("[Mark] Failed to send", n, l), l instanceof g)
|
|
547
|
+
throw l;
|
|
536
548
|
if (d)
|
|
537
|
-
throw new
|
|
538
|
-
const
|
|
539
|
-
throw new
|
|
549
|
+
throw new g(`[Mark] Request timed out after ${f}ms`, { status: 408 });
|
|
550
|
+
const p = l instanceof Error ? l.message : String(l);
|
|
551
|
+
throw new g(`[Mark] Network error: ${p}`);
|
|
540
552
|
} finally {
|
|
541
553
|
clearTimeout(h);
|
|
542
554
|
}
|
|
@@ -553,8 +565,8 @@ class J {
|
|
|
553
565
|
}
|
|
554
566
|
}
|
|
555
567
|
}
|
|
556
|
-
const
|
|
557
|
-
class
|
|
568
|
+
const te = "crelora_mark_data", ie = "crelora_mark_outbox", L = "crelora_mark_vid";
|
|
569
|
+
class ne {
|
|
558
570
|
data;
|
|
559
571
|
storageKey;
|
|
560
572
|
outboxKey;
|
|
@@ -563,11 +575,13 @@ class ee {
|
|
|
563
575
|
bridgeReady = !1;
|
|
564
576
|
bridgeOrigin;
|
|
565
577
|
constructor(e) {
|
|
566
|
-
if (this.options = e ?? {}, this.storageKey = this.options.storageKey ??
|
|
578
|
+
if (this.options = e ?? {}, this.storageKey = this.options.storageKey ?? te, this.outboxKey = this.options.outboxKey ?? ie, typeof window > "u") {
|
|
567
579
|
this.data = {};
|
|
568
580
|
return;
|
|
569
581
|
}
|
|
570
|
-
this.data = this.load()
|
|
582
|
+
this.data = this.load();
|
|
583
|
+
const t = T(this.options.seed_visitor_id);
|
|
584
|
+
!this.data.visitor_id && t && (this.data.visitor_id = t, this.save()), 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);
|
|
571
585
|
}
|
|
572
586
|
getVisitorId() {
|
|
573
587
|
return this.data.visitor_id;
|
|
@@ -616,11 +630,19 @@ class ee {
|
|
|
616
630
|
});
|
|
617
631
|
}
|
|
618
632
|
clearCookieVisitorId() {
|
|
619
|
-
this.setCookie(
|
|
633
|
+
this.setCookie(L, "", -1);
|
|
620
634
|
}
|
|
621
635
|
rotateVisitorId() {
|
|
622
636
|
this.update({ visitor_id: this.generateUUID() });
|
|
623
637
|
}
|
|
638
|
+
/**
|
|
639
|
+
* Adopts or replaces the stored visitor id with a trusted first-party value.
|
|
640
|
+
* No-op when the id is invalid or already set to the same value.
|
|
641
|
+
*/
|
|
642
|
+
setVisitorId(e) {
|
|
643
|
+
const t = T(e);
|
|
644
|
+
return t ? (this.data.visitor_id === t || this.update({ visitor_id: t }), !0) : !1;
|
|
645
|
+
}
|
|
624
646
|
getOutbox() {
|
|
625
647
|
if (typeof window > "u") return [];
|
|
626
648
|
try {
|
|
@@ -648,7 +670,7 @@ class ee {
|
|
|
648
670
|
return JSON.parse(t);
|
|
649
671
|
} catch {
|
|
650
672
|
}
|
|
651
|
-
const e = this.getCookie(
|
|
673
|
+
const e = this.getCookie(L);
|
|
652
674
|
return e ? { visitor_id: e } : {};
|
|
653
675
|
}
|
|
654
676
|
save() {
|
|
@@ -657,7 +679,7 @@ class ee {
|
|
|
657
679
|
localStorage.setItem(this.storageKey, JSON.stringify(this.data));
|
|
658
680
|
} catch {
|
|
659
681
|
}
|
|
660
|
-
this.data.visitor_id && this.isCookieEnabled() && (this.setCookie(
|
|
682
|
+
this.data.visitor_id && this.isCookieEnabled() && (this.setCookie(L, this.data.visitor_id, 365), this.options.bridge?.url && this.bridgeReady && this.postBridgeMessage({
|
|
661
683
|
type: "MARK_SYNC_UPDATE",
|
|
662
684
|
visitorId: this.data.visitor_id
|
|
663
685
|
}));
|
|
@@ -753,7 +775,7 @@ class ee {
|
|
|
753
775
|
}
|
|
754
776
|
};
|
|
755
777
|
}
|
|
756
|
-
const
|
|
778
|
+
const se = [
|
|
757
779
|
"click_id",
|
|
758
780
|
"ch_click_id",
|
|
759
781
|
"gclid",
|
|
@@ -765,7 +787,7 @@ const te = [
|
|
|
765
787
|
"ttclid",
|
|
766
788
|
"twclid",
|
|
767
789
|
"li_fat_id"
|
|
768
|
-
],
|
|
790
|
+
], re = ["cid", "campaign_id"], oe = [
|
|
769
791
|
"utm_source",
|
|
770
792
|
"utm_medium",
|
|
771
793
|
"utm_campaign",
|
|
@@ -787,80 +809,80 @@ const te = [
|
|
|
787
809
|
"ttclid",
|
|
788
810
|
"twclid",
|
|
789
811
|
"li_fat_id"
|
|
790
|
-
],
|
|
812
|
+
], ae = {
|
|
791
813
|
referral: "ref",
|
|
792
814
|
affiliate_id: "ref",
|
|
793
815
|
ch_click_id: "click_id",
|
|
794
816
|
cid: "campaign_id"
|
|
795
|
-
},
|
|
796
|
-
function
|
|
797
|
-
const t = new URLSearchParams(r), i =
|
|
817
|
+
}, ce = ["email", "phone", "token", "auth", "password", "code"], de = 30, ue = 256;
|
|
818
|
+
function R(r, e = {}) {
|
|
819
|
+
const t = new URLSearchParams(r), i = fe(t), n = F(i, se), o = F(i, re), a = le(t, e), c = {};
|
|
798
820
|
return n && (c.last_click_id = n), o && (c.campaign_id = o), Object.keys(a).length > 0 && (c.query_params = a), c;
|
|
799
821
|
}
|
|
800
|
-
function
|
|
801
|
-
const t = {}, i = new Set(
|
|
822
|
+
function le(r, e) {
|
|
823
|
+
const t = {}, i = new Set(B(e.query_param_denylist, ce)), n = O(
|
|
802
824
|
e.max_captured_query_params,
|
|
803
|
-
|
|
804
|
-
), o =
|
|
825
|
+
de
|
|
826
|
+
), o = O(
|
|
805
827
|
e.max_query_param_value_length,
|
|
806
|
-
|
|
828
|
+
ue
|
|
807
829
|
), c = e.capture_all_query_params ?? !1 ? null : /* @__PURE__ */ new Set([
|
|
808
|
-
...
|
|
809
|
-
...
|
|
830
|
+
...oe.map(x),
|
|
831
|
+
...B(e.capture_query_params, [])
|
|
810
832
|
]);
|
|
811
|
-
for (const [f,
|
|
812
|
-
const d =
|
|
833
|
+
for (const [f, u] of r.entries()) {
|
|
834
|
+
const d = x(f);
|
|
813
835
|
if (!d)
|
|
814
836
|
continue;
|
|
815
|
-
const h =
|
|
837
|
+
const h = ae[d] ?? d;
|
|
816
838
|
if (i.has(d) || i.has(h) || c && !c.has(d))
|
|
817
839
|
continue;
|
|
818
|
-
const
|
|
819
|
-
if (
|
|
840
|
+
const l = u.trim();
|
|
841
|
+
if (l) {
|
|
820
842
|
if (!(h in t) && Object.keys(t).length >= n)
|
|
821
843
|
break;
|
|
822
|
-
t[h] =
|
|
844
|
+
t[h] = l.slice(0, o);
|
|
823
845
|
}
|
|
824
846
|
}
|
|
825
847
|
return t;
|
|
826
848
|
}
|
|
827
|
-
function
|
|
849
|
+
function F(r, e) {
|
|
828
850
|
for (const t of e) {
|
|
829
|
-
const i =
|
|
851
|
+
const i = x(t), n = r[i]?.trim();
|
|
830
852
|
if (n)
|
|
831
853
|
return n;
|
|
832
854
|
}
|
|
833
855
|
}
|
|
834
|
-
function
|
|
856
|
+
function fe(r) {
|
|
835
857
|
const e = {};
|
|
836
858
|
for (const [t, i] of r.entries()) {
|
|
837
|
-
const n =
|
|
859
|
+
const n = x(t);
|
|
838
860
|
!n || n in e || (e[n] = i);
|
|
839
861
|
}
|
|
840
862
|
return e;
|
|
841
863
|
}
|
|
842
|
-
function
|
|
864
|
+
function x(r) {
|
|
843
865
|
return r.trim().toLowerCase();
|
|
844
866
|
}
|
|
845
|
-
function
|
|
867
|
+
function B(r, e) {
|
|
846
868
|
const t = r ?? e, i = /* @__PURE__ */ new Set();
|
|
847
869
|
for (const n of t) {
|
|
848
870
|
if (typeof n != "string") continue;
|
|
849
|
-
const o =
|
|
871
|
+
const o = x(n);
|
|
850
872
|
o && i.add(o);
|
|
851
873
|
}
|
|
852
874
|
return Array.from(i);
|
|
853
875
|
}
|
|
854
|
-
function
|
|
876
|
+
function O(r, e) {
|
|
855
877
|
if (typeof r != "number" || !Number.isFinite(r))
|
|
856
878
|
return e;
|
|
857
879
|
const t = Math.floor(r);
|
|
858
880
|
return t < 0 ? e : t;
|
|
859
881
|
}
|
|
860
|
-
function
|
|
882
|
+
function k(r) {
|
|
861
883
|
return r.length > 1 && r.endsWith("/") ? r.slice(0, -1) : r;
|
|
862
884
|
}
|
|
863
|
-
function
|
|
885
|
+
function he(r) {
|
|
864
886
|
if (!r || r === "?")
|
|
865
887
|
return "";
|
|
866
888
|
const e = r.startsWith("?") ? r.slice(1) : r;
|
|
@@ -869,9 +891,9 @@ function ue(r) {
|
|
|
869
891
|
const t = new URLSearchParams(e), i = [];
|
|
870
892
|
t.forEach((a, c) => {
|
|
871
893
|
i.push([c, a]);
|
|
872
|
-
}), i.sort(([a, c], [f,
|
|
894
|
+
}), i.sort(([a, c], [f, u]) => {
|
|
873
895
|
const d = a.localeCompare(f);
|
|
874
|
-
return d !== 0 ? d : c.localeCompare(
|
|
896
|
+
return d !== 0 ? d : c.localeCompare(u);
|
|
875
897
|
});
|
|
876
898
|
const n = new URLSearchParams();
|
|
877
899
|
for (const [a, c] of i)
|
|
@@ -879,86 +901,86 @@ function ue(r) {
|
|
|
879
901
|
const o = n.toString();
|
|
880
902
|
return o === "" ? "" : `?${o}`;
|
|
881
903
|
}
|
|
882
|
-
function
|
|
883
|
-
const e =
|
|
904
|
+
function P(r) {
|
|
905
|
+
const e = k(r.pathname), t = he(r.search);
|
|
884
906
|
return `${r.origin}${e}${t}${r.hash}`;
|
|
885
907
|
}
|
|
886
|
-
let
|
|
887
|
-
const
|
|
888
|
-
let b = null,
|
|
889
|
-
function
|
|
908
|
+
let q = !1, w = null;
|
|
909
|
+
const y = [], _ = [], v = [];
|
|
910
|
+
let b = null, A = null, I = null, S = null, E = null;
|
|
911
|
+
function D() {
|
|
890
912
|
if (typeof window > "u") return;
|
|
891
|
-
const r =
|
|
892
|
-
if (r ===
|
|
893
|
-
const e = { previousKey:
|
|
894
|
-
for (const t of w)
|
|
895
|
-
t(e);
|
|
896
|
-
m = r;
|
|
913
|
+
const r = P(window.location);
|
|
914
|
+
if (r === w) return;
|
|
915
|
+
const e = { previousKey: w, nextKey: r };
|
|
897
916
|
for (const t of y)
|
|
898
917
|
t(e);
|
|
918
|
+
w = r;
|
|
919
|
+
for (const t of _)
|
|
920
|
+
t(e);
|
|
899
921
|
}
|
|
900
|
-
function
|
|
901
|
-
for (const r of
|
|
922
|
+
function ge() {
|
|
923
|
+
for (const r of v)
|
|
902
924
|
r();
|
|
903
925
|
}
|
|
904
|
-
function
|
|
905
|
-
if (
|
|
926
|
+
function pe(r = {}) {
|
|
927
|
+
if (q || typeof window > "u" || typeof document > "u")
|
|
906
928
|
return;
|
|
907
|
-
|
|
929
|
+
q = !0;
|
|
908
930
|
const e = r.trackRouteChanges ?? !0;
|
|
909
|
-
|
|
931
|
+
w = P(window.location), E = ge, window.addEventListener("pagehide", E), e && (b = history.pushState, A = history.replaceState, history.pushState = function(...t) {
|
|
910
932
|
const i = b.apply(this, t);
|
|
911
|
-
return
|
|
933
|
+
return D(), i;
|
|
912
934
|
}, history.replaceState = function(...t) {
|
|
913
|
-
const i =
|
|
914
|
-
return
|
|
915
|
-
},
|
|
916
|
-
}
|
|
917
|
-
function he(r) {
|
|
918
|
-
return w.push(r), () => {
|
|
919
|
-
const e = w.indexOf(r);
|
|
920
|
-
e >= 0 && w.splice(e, 1);
|
|
921
|
-
};
|
|
935
|
+
const i = A.apply(this, t);
|
|
936
|
+
return D(), i;
|
|
937
|
+
}, I = D, window.addEventListener("popstate", I), S = D, window.addEventListener("hashchange", S));
|
|
922
938
|
}
|
|
923
|
-
function
|
|
939
|
+
function me(r) {
|
|
924
940
|
return y.push(r), () => {
|
|
925
941
|
const e = y.indexOf(r);
|
|
926
942
|
e >= 0 && y.splice(e, 1);
|
|
927
943
|
};
|
|
928
944
|
}
|
|
929
|
-
function
|
|
945
|
+
function U(r) {
|
|
930
946
|
return _.push(r), () => {
|
|
931
947
|
const e = _.indexOf(r);
|
|
932
948
|
e >= 0 && _.splice(e, 1);
|
|
933
949
|
};
|
|
934
950
|
}
|
|
935
|
-
function
|
|
936
|
-
|
|
951
|
+
function we(r) {
|
|
952
|
+
return v.push(r), () => {
|
|
953
|
+
const e = v.indexOf(r);
|
|
954
|
+
e >= 0 && v.splice(e, 1);
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
function ye() {
|
|
958
|
+
!q || typeof window > "u" || (b && (history.pushState = b), A && (history.replaceState = A), I && window.removeEventListener("popstate", I), S && window.removeEventListener("hashchange", S), E && window.removeEventListener("pagehide", E), b = null, A = null, I = null, S = null, E = null, y.length = 0, _.length = 0, v.length = 0, w = null, q = !1);
|
|
937
959
|
}
|
|
938
|
-
let
|
|
939
|
-
function
|
|
940
|
-
|
|
960
|
+
let C = 0;
|
|
961
|
+
function V() {
|
|
962
|
+
C = 0;
|
|
941
963
|
}
|
|
942
|
-
function
|
|
943
|
-
return
|
|
964
|
+
function _e() {
|
|
965
|
+
return C;
|
|
944
966
|
}
|
|
945
|
-
function
|
|
967
|
+
function ve() {
|
|
946
968
|
if (typeof document > "u" || typeof window > "u")
|
|
947
969
|
return 0;
|
|
948
970
|
const r = document.documentElement, e = window.scrollY || r.scrollTop, t = Math.max(1, r.scrollHeight - window.innerHeight);
|
|
949
971
|
return Math.min(100, Math.round(e / t * 100));
|
|
950
972
|
}
|
|
951
973
|
function K() {
|
|
952
|
-
const r =
|
|
953
|
-
return r >
|
|
974
|
+
const r = ve();
|
|
975
|
+
return r > C && (C = r), r;
|
|
954
976
|
}
|
|
955
|
-
const
|
|
956
|
-
function
|
|
977
|
+
const be = [25, 50, 75, 100];
|
|
978
|
+
function Ae(r, e = be) {
|
|
957
979
|
if (typeof window > "u") return;
|
|
958
980
|
const t = /* @__PURE__ */ new Set(), i = () => {
|
|
959
|
-
t.clear(),
|
|
981
|
+
t.clear(), V();
|
|
960
982
|
};
|
|
961
|
-
i(),
|
|
983
|
+
i(), U(() => {
|
|
962
984
|
i();
|
|
963
985
|
}), window.addEventListener(
|
|
964
986
|
"scroll",
|
|
@@ -970,49 +992,55 @@ function _e(r, e = ye) {
|
|
|
970
992
|
{ passive: !0 }
|
|
971
993
|
);
|
|
972
994
|
}
|
|
973
|
-
const
|
|
974
|
-
function
|
|
975
|
-
return r === !0 ? { minActiveMs:
|
|
976
|
-
minActiveMs: r.min_active_ms ??
|
|
995
|
+
const N = 1e4;
|
|
996
|
+
function Ie(r) {
|
|
997
|
+
return r === !0 ? { minActiveMs: N, useBeacon: !0 } : {
|
|
998
|
+
minActiveMs: r.min_active_ms ?? N,
|
|
977
999
|
useBeacon: r.use_beacon !== !1
|
|
978
1000
|
};
|
|
979
1001
|
}
|
|
980
|
-
function
|
|
1002
|
+
function Se(r, e) {
|
|
981
1003
|
if (typeof window > "u" || typeof document > "u") return;
|
|
982
|
-
let t = Date.now(), i = 0, n = document.visibilityState === "visible" ? Date.now() : null, o =
|
|
1004
|
+
let t = Date.now(), i = 0, n = document.visibilityState === "visible" ? Date.now() : null, o = k(window.location.pathname), a = !1;
|
|
983
1005
|
const c = () => {
|
|
984
1006
|
n !== null && (i += Date.now() - n, n = null);
|
|
985
1007
|
}, f = () => {
|
|
986
1008
|
document.visibilityState === "visible" && n === null && (n = Date.now());
|
|
987
|
-
},
|
|
1009
|
+
}, u = () => {
|
|
1010
|
+
document.visibilityState === "visible" ? f() : c();
|
|
1011
|
+
}, d = (l) => {
|
|
988
1012
|
if (!a) {
|
|
989
1013
|
a = !0;
|
|
990
1014
|
try {
|
|
991
|
-
if (c(), K(), i < e.minActiveMs)
|
|
1015
|
+
if (c(), K(), i < e.minActiveMs) {
|
|
1016
|
+
e.debug && console.debug("[Mark] page_engagement skipped (active time below min_active_ms)", {
|
|
1017
|
+
page: o,
|
|
1018
|
+
active_time_ms: i,
|
|
1019
|
+
min_active_ms: e.minActiveMs
|
|
1020
|
+
});
|
|
992
1021
|
return;
|
|
993
|
-
|
|
1022
|
+
}
|
|
1023
|
+
const p = Date.now() - t, m = {
|
|
994
1024
|
page: o,
|
|
995
1025
|
active_time_ms: i,
|
|
996
|
-
total_time_ms:
|
|
997
|
-
max_scroll_percent:
|
|
1026
|
+
total_time_ms: p,
|
|
1027
|
+
max_scroll_percent: _e()
|
|
998
1028
|
};
|
|
999
|
-
e.useBeacon &&
|
|
1029
|
+
e.useBeacon && l ? r.trackWithOptions("page_engagement", m, { preferBeacon: !0 }) : r.track("page_engagement", m);
|
|
1000
1030
|
} finally {
|
|
1001
1031
|
a = !1;
|
|
1002
1032
|
}
|
|
1003
1033
|
}
|
|
1004
|
-
},
|
|
1005
|
-
t = Date.now(), i = 0, o =
|
|
1034
|
+
}, h = () => {
|
|
1035
|
+
t = Date.now(), i = 0, o = k(window.location.pathname), V(), f();
|
|
1006
1036
|
};
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
}),
|
|
1010
|
-
|
|
1011
|
-
}),
|
|
1012
|
-
|
|
1013
|
-
}), document.addEventListener("visibilitychange", ()
|
|
1014
|
-
document.visibilityState === "hidden" ? c() : f();
|
|
1015
|
-
});
|
|
1037
|
+
h(), me(() => {
|
|
1038
|
+
d(!1), c();
|
|
1039
|
+
}), U(() => {
|
|
1040
|
+
h();
|
|
1041
|
+
}), we(() => {
|
|
1042
|
+
d(!0);
|
|
1043
|
+
}), document.addEventListener("visibilitychange", u), window.addEventListener("pageshow", u), window.addEventListener("focus", u), queueMicrotask(u), typeof requestAnimationFrame == "function" && requestAnimationFrame(u);
|
|
1016
1044
|
}
|
|
1017
1045
|
class s {
|
|
1018
1046
|
static client = null;
|
|
@@ -1028,8 +1056,11 @@ class s {
|
|
|
1028
1056
|
static kickTimer = null;
|
|
1029
1057
|
static init(e) {
|
|
1030
1058
|
if (!s.client) {
|
|
1031
|
-
const t = new
|
|
1032
|
-
|
|
1059
|
+
const t = new ne({
|
|
1060
|
+
...e.cross_domain,
|
|
1061
|
+
seed_visitor_id: e.visitor_id
|
|
1062
|
+
}), i = new ee(e);
|
|
1063
|
+
s.client = new Z(e, { storage: t, transport: i }), s.storage = t, s.config = e, s.refreshAttribution(t, e), typeof window < "u" && (s.installPageLifecycleIfNeeded(e), e.autocapture?.pageview && s.installPageviewTracking(e, t), s.installExtendedAutocapture(e), s.installLifecycleFlushing());
|
|
1033
1064
|
}
|
|
1034
1065
|
return s.client;
|
|
1035
1066
|
}
|
|
@@ -1084,6 +1115,17 @@ class s {
|
|
|
1084
1115
|
if (!(!s.client || !s.storage || !s.config || (s.config.require_consent ?? !1) && s.storage.getConsentStatus() !== "granted"))
|
|
1085
1116
|
return s.client.getVisitorId();
|
|
1086
1117
|
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Adopts or replaces the stored visitor id with a trusted first-party value.
|
|
1120
|
+
* Updates in-memory storage, localStorage, and the visitor cookie immediately.
|
|
1121
|
+
* Use when an external anonymous id (for example a platform client id) is
|
|
1122
|
+
* available after init. Theme embeds and pixels should call this with the
|
|
1123
|
+
* same source id. Returns false when the id is invalid or the SDK is not
|
|
1124
|
+
* initialized.
|
|
1125
|
+
*/
|
|
1126
|
+
static setVisitorId(e) {
|
|
1127
|
+
return s.client ? s.client.setVisitorId(e) : (s.config?.debug && console.warn("[Mark] Not initialized. Call init() first."), !1);
|
|
1128
|
+
}
|
|
1087
1129
|
static flush() {
|
|
1088
1130
|
return s.client ? s.client.flush() : Promise.resolve();
|
|
1089
1131
|
}
|
|
@@ -1118,13 +1160,13 @@ class s {
|
|
|
1118
1160
|
return s.client?.getStats() ?? { queued: 0, sent: 0, failed: 0, dropped: 0 };
|
|
1119
1161
|
}
|
|
1120
1162
|
static destroy() {
|
|
1121
|
-
typeof window > "u" || (
|
|
1163
|
+
typeof window > "u" || (ye(), s.beaconDrainHandler && (window.removeEventListener("pagehide", s.beaconDrainHandler), window.removeEventListener("beforeunload", s.beaconDrainHandler)), s.visibilityHandler && typeof document < "u" && document.removeEventListener("visibilitychange", s.visibilityHandler), s.onlineHandler && window.removeEventListener("online", s.onlineHandler), s.kickTimer && clearInterval(s.kickTimer), s.beaconDrainHandler = null, s.visibilityHandler = null, s.onlineHandler = null, s.kickTimer = null, s.pageviewTrackerInstalled = !1);
|
|
1122
1164
|
}
|
|
1123
1165
|
static installPageLifecycleIfNeeded(e) {
|
|
1124
1166
|
const t = e.autocapture;
|
|
1125
1167
|
if (!(!!t?.pageview || !!t?.scroll_depth || !!t?.page_engagement)) return;
|
|
1126
1168
|
const n = e.track_route_changes ?? !0;
|
|
1127
|
-
|
|
1169
|
+
pe({ trackRouteChanges: n });
|
|
1128
1170
|
}
|
|
1129
1171
|
static installPageviewTracking(e, t) {
|
|
1130
1172
|
if (s.pageviewTrackerInstalled) return;
|
|
@@ -1132,23 +1174,23 @@ class s {
|
|
|
1132
1174
|
const i = () => {
|
|
1133
1175
|
if (!s.client) return;
|
|
1134
1176
|
s.refreshAttribution(t, e);
|
|
1135
|
-
const o =
|
|
1177
|
+
const o = P(window.location);
|
|
1136
1178
|
if (o === s.lastPageviewDedupeKey) return;
|
|
1137
1179
|
s.client.track("page_view", {
|
|
1138
1180
|
site: window.location.host,
|
|
1139
|
-
page:
|
|
1181
|
+
page: k(window.location.pathname),
|
|
1140
1182
|
title: document.title,
|
|
1141
1183
|
referrer: document.referrer || void 0
|
|
1142
1184
|
}) && (s.lastPageviewDedupeKey = o);
|
|
1143
1185
|
};
|
|
1144
|
-
s.emitAutoPageview = i, i(), (e.track_route_changes ?? !0) &&
|
|
1186
|
+
s.emitAutoPageview = i, i(), (e.track_route_changes ?? !0) && U(() => {
|
|
1145
1187
|
i();
|
|
1146
1188
|
});
|
|
1147
1189
|
}
|
|
1148
1190
|
static refreshAttribution(e, t) {
|
|
1149
1191
|
if (typeof window > "u")
|
|
1150
1192
|
return;
|
|
1151
|
-
const i =
|
|
1193
|
+
const i = R(window.location.search, t);
|
|
1152
1194
|
if (Object.keys(i).length !== 0) {
|
|
1153
1195
|
if (s.shouldPersistAttribution(e, t)) {
|
|
1154
1196
|
const n = s.mergeAttributionUpdates(s.pendingAttribution, i);
|
|
@@ -1162,7 +1204,7 @@ class s {
|
|
|
1162
1204
|
const e = s.storage, t = s.config;
|
|
1163
1205
|
if (!e || !t || typeof window > "u")
|
|
1164
1206
|
return;
|
|
1165
|
-
const i =
|
|
1207
|
+
const i = R(window.location.search, t), n = s.mergeAttributionUpdates(s.pendingAttribution, i);
|
|
1166
1208
|
Object.keys(n).length > 0 && e.update(n), s.pendingAttribution = {};
|
|
1167
1209
|
}
|
|
1168
1210
|
static shouldPersistAttribution(e, t) {
|
|
@@ -1208,7 +1250,10 @@ class s {
|
|
|
1208
1250
|
o.origin !== a.origin && s.client?.trackWithOptions("outbound_link_click", { href: o.toString() }, { preferBeacon: !0 });
|
|
1209
1251
|
} catch {
|
|
1210
1252
|
}
|
|
1211
|
-
}), t.scroll_depth && s.client &&
|
|
1253
|
+
}), t.scroll_depth && s.client && Ae(s.client), t.page_engagement && s.client && Se(s.client, {
|
|
1254
|
+
...Ie(t.page_engagement),
|
|
1255
|
+
debug: e.debug
|
|
1256
|
+
}), t.web_vitals && import("./web-vitals-CrnTllyu.js").then((i) => {
|
|
1212
1257
|
const n = (o) => {
|
|
1213
1258
|
s.client?.track("web_vital", {
|
|
1214
1259
|
metric: o.name,
|