@aranova/tracking-next 0.27.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blog-server.d.mts +2 -1
- package/dist/blog-server.d.ts +2 -1
- package/dist/blog-server.js +121 -98
- package/dist/blog-server.js.map +1 -1
- package/dist/blog-server.mjs +86 -63
- package/dist/blog-server.mjs.map +1 -1
- package/dist/blog.d.mts +651 -1755
- package/dist/blog.d.ts +651 -1755
- package/dist/blog.js +121 -98
- package/dist/blog.js.map +1 -1
- package/dist/blog.mjs +86 -63
- package/dist/blog.mjs.map +1 -1
- package/dist/calendar-server.d.mts +2 -2
- package/dist/calendar-server.d.ts +2 -2
- package/dist/calendar-server.js +0 -26
- package/dist/calendar-server.js.map +1 -1
- package/dist/calendar-server.mjs +0 -26
- package/dist/calendar-server.mjs.map +1 -1
- package/dist/calendar.d.mts +3 -3
- package/dist/calendar.d.ts +3 -3
- package/dist/calendar.js +227 -126
- package/dist/calendar.js.map +1 -1
- package/dist/calendar.mjs +216 -125
- package/dist/calendar.mjs.map +1 -1
- package/dist/client.d.mts +11 -4
- package/dist/client.d.ts +11 -4
- package/dist/client.js +611 -347
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +611 -347
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +550 -487
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +539 -487
- package/dist/index.mjs.map +1 -1
- package/dist/ingest-typed-MBuMe9Pn.d.ts +883 -0
- package/dist/ingest-typed-UA13xTfI.d.mts +883 -0
- package/dist/middleware.js +0 -467
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +0 -467
- package/dist/middleware.mjs.map +1 -1
- package/dist/{phone-utils-BVzSNBf1.d.mts → phone-utils-C0ds6cqZ.d.mts} +24 -78
- package/dist/{phone-utils-BVzSNBf1.d.ts → phone-utils-C0ds6cqZ.d.ts} +24 -78
- package/dist/phone.d.mts +2 -2
- package/dist/phone.d.ts +2 -2
- package/dist/phone.js +0 -464
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +0 -464
- package/dist/phone.mjs.map +1 -1
- package/dist/{sales-IGC2tq4J.d.ts → sales-DQC815f3.d.ts} +90 -329
- package/dist/{sales-DQGzXSgL.d.mts → sales-w1reW_Y3.d.mts} +90 -329
- package/dist/sales.d.mts +3 -3
- package/dist/sales.d.ts +3 -3
- package/dist/sales.js +270 -127
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +259 -127
- package/dist/sales.mjs.map +1 -1
- package/dist/server.d.mts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +0 -467
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +0 -467
- package/dist/server.mjs.map +1 -1
- package/dist/{tracking-config-runtime-D7prdTE1.d.mts → tracking-config-runtime-C6H7ofmo.d.mts} +6 -0
- package/dist/{tracking-config-runtime-D7prdTE1.d.ts → tracking-config-runtime-C6H7ofmo.d.ts} +6 -0
- package/dist/transport-CDmGOiCq.d.ts +253 -0
- package/dist/transport-I_cMSFQ6.d.mts +253 -0
- package/package.json +2 -2
- package/dist/ingest-typed-BxLFlZ7N.d.mts +0 -1371
- package/dist/ingest-typed-ByQVRMvP.d.ts +0 -1371
- package/dist/transport-C-_rFSR4.d.ts +0 -721
- package/dist/transport-yUF5Wize.d.mts +0 -721
package/dist/client.mjs
CHANGED
|
@@ -262,6 +262,7 @@ var TRACKING_CAPABILITIES = [
|
|
|
262
262
|
"consent_controls",
|
|
263
263
|
"conversion_goals_auto",
|
|
264
264
|
"conversion_goals_manual",
|
|
265
|
+
"cross_site_linker",
|
|
265
266
|
"cta_click_capture",
|
|
266
267
|
"form_capture",
|
|
267
268
|
"phone_click_capture",
|
|
@@ -288,6 +289,9 @@ function readDomMarkers() {
|
|
|
288
289
|
return found;
|
|
289
290
|
}
|
|
290
291
|
|
|
292
|
+
// ../tracking-core/src/cross-site-link.ts
|
|
293
|
+
import * as z from "zod/mini";
|
|
294
|
+
|
|
291
295
|
// ../tracking-core/src/tracking.ts
|
|
292
296
|
var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
|
|
293
297
|
var TRACKING_PARAM_KEYS = [
|
|
@@ -580,10 +584,10 @@ function readStoredRecord() {
|
|
|
580
584
|
return null;
|
|
581
585
|
}
|
|
582
586
|
}
|
|
583
|
-
function writeRecord(
|
|
584
|
-
memoryRecord =
|
|
587
|
+
function writeRecord(record3) {
|
|
588
|
+
memoryRecord = record3;
|
|
585
589
|
try {
|
|
586
|
-
window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(
|
|
590
|
+
window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record3));
|
|
587
591
|
} catch {
|
|
588
592
|
}
|
|
589
593
|
}
|
|
@@ -605,9 +609,9 @@ function getOrCaptureLandingParams(sessionId, url) {
|
|
|
605
609
|
if (memoryRecord && memoryRecord.session_id === sessionId) {
|
|
606
610
|
return memoryRecord.params;
|
|
607
611
|
}
|
|
608
|
-
const
|
|
609
|
-
writeRecord(
|
|
610
|
-
return
|
|
612
|
+
const record3 = { session_id: sessionId, params: captureFromUrl(url) };
|
|
613
|
+
writeRecord(record3);
|
|
614
|
+
return record3.params;
|
|
611
615
|
}
|
|
612
616
|
function buildLandingPayloadFields(sessionId, override) {
|
|
613
617
|
const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
|
|
@@ -626,6 +630,244 @@ function buildLandingPayloadFields(sessionId, override) {
|
|
|
626
630
|
};
|
|
627
631
|
}
|
|
628
632
|
|
|
633
|
+
// ../tracking-core/src/session.ts
|
|
634
|
+
var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
|
|
635
|
+
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
636
|
+
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
637
|
+
function safeUuid() {
|
|
638
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
|
|
639
|
+
return crypto.randomUUID();
|
|
640
|
+
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
|
|
641
|
+
}
|
|
642
|
+
function readLocalStorage(key) {
|
|
643
|
+
try {
|
|
644
|
+
return window.localStorage.getItem(key);
|
|
645
|
+
} catch {
|
|
646
|
+
return null;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
function writeLocalStorage(key, value) {
|
|
650
|
+
try {
|
|
651
|
+
window.localStorage.setItem(key, value);
|
|
652
|
+
} catch {
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
function getVisitorId() {
|
|
656
|
+
if (typeof window === "undefined") return safeUuid();
|
|
657
|
+
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
658
|
+
if (existing && existing.length > 0) return existing;
|
|
659
|
+
const fresh = safeUuid();
|
|
660
|
+
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
661
|
+
return fresh;
|
|
662
|
+
}
|
|
663
|
+
function adoptVisitorId(visitorId) {
|
|
664
|
+
if (typeof window === "undefined" || visitorId.length === 0) return false;
|
|
665
|
+
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
666
|
+
if (existing && existing.length > 0) return false;
|
|
667
|
+
writeLocalStorage(VISITOR_STORAGE_KEY, visitorId);
|
|
668
|
+
return readLocalStorage(VISITOR_STORAGE_KEY) === visitorId;
|
|
669
|
+
}
|
|
670
|
+
function getOrRotateSessionId(now = Date.now()) {
|
|
671
|
+
if (typeof window === "undefined") return { id: safeUuid(), isNew: true };
|
|
672
|
+
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
673
|
+
if (raw) {
|
|
674
|
+
try {
|
|
675
|
+
const parsed = JSON.parse(raw);
|
|
676
|
+
if (typeof parsed.id === "string" && typeof parsed.last_event_at === "number") {
|
|
677
|
+
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
678
|
+
const refreshed = { id: parsed.id, last_event_at: now };
|
|
679
|
+
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
680
|
+
return { id: parsed.id, isNew: false };
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
} catch {
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
const fresh = { id: safeUuid(), last_event_at: now };
|
|
687
|
+
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
688
|
+
return { id: fresh.id, isNew: true };
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// ../tracking-core/src/cross-site-link.ts
|
|
692
|
+
var LINK_PARAM = "_arv";
|
|
693
|
+
var LINK_TOKEN_VERSION = "1";
|
|
694
|
+
var LINK_TOKEN_TTL_MS = 5 * 60 * 1e3;
|
|
695
|
+
var FUTURE_SKEW_MS = 60 * 1e3;
|
|
696
|
+
var CARRIED_KEYS = {
|
|
697
|
+
g: "gclid",
|
|
698
|
+
w: "wbraid",
|
|
699
|
+
gb: "gbraid",
|
|
700
|
+
f: "fbclid",
|
|
701
|
+
y: "ylpcid"
|
|
702
|
+
};
|
|
703
|
+
var CARRIED_ENTRIES = Object.entries(CARRIED_KEYS);
|
|
704
|
+
var identifier = z.string().check(z.minLength(1), z.maxLength(128));
|
|
705
|
+
var optionalIdentifier = z.optional(identifier);
|
|
706
|
+
var linkTokenSchema = z.object({
|
|
707
|
+
v: identifier,
|
|
708
|
+
s: identifier,
|
|
709
|
+
// Epoch ms in base36.
|
|
710
|
+
t: z.string().check(z.regex(/^[0-9a-z]{1,12}$/)),
|
|
711
|
+
g: optionalIdentifier,
|
|
712
|
+
w: optionalIdentifier,
|
|
713
|
+
gb: optionalIdentifier,
|
|
714
|
+
f: optionalIdentifier,
|
|
715
|
+
fc: optionalIdentifier,
|
|
716
|
+
y: optionalIdentifier
|
|
717
|
+
});
|
|
718
|
+
function toBase64Url(input) {
|
|
719
|
+
const bytes = new TextEncoder().encode(input);
|
|
720
|
+
let binary = "";
|
|
721
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
722
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
723
|
+
}
|
|
724
|
+
function fromBase64Url(input) {
|
|
725
|
+
try {
|
|
726
|
+
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
727
|
+
const binary = atob(padded + "=".repeat((4 - padded.length % 4) % 4));
|
|
728
|
+
const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
729
|
+
return new TextDecoder().decode(bytes);
|
|
730
|
+
} catch {
|
|
731
|
+
return null;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
function encodeLinkToken(payload) {
|
|
735
|
+
const params = new URLSearchParams();
|
|
736
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
737
|
+
if (typeof value === "string" && value.length > 0) params.set(key, value);
|
|
738
|
+
}
|
|
739
|
+
return `${LINK_TOKEN_VERSION}.${toBase64Url(params.toString())}`;
|
|
740
|
+
}
|
|
741
|
+
function decodeLinkToken(raw) {
|
|
742
|
+
const dot = raw.indexOf(".");
|
|
743
|
+
if (dot <= 0 || raw.slice(0, dot) !== LINK_TOKEN_VERSION) return null;
|
|
744
|
+
const decoded = fromBase64Url(raw.slice(dot + 1));
|
|
745
|
+
if (decoded === null) return null;
|
|
746
|
+
const params = new URLSearchParams(decoded);
|
|
747
|
+
const candidate = {};
|
|
748
|
+
params.forEach((value, key) => {
|
|
749
|
+
candidate[key] = value;
|
|
750
|
+
});
|
|
751
|
+
const result = linkTokenSchema.safeParse(candidate);
|
|
752
|
+
return result.success ? result.data : null;
|
|
753
|
+
}
|
|
754
|
+
function payloadToLink(payload) {
|
|
755
|
+
const carried = {};
|
|
756
|
+
for (const [wire, param] of CARRIED_ENTRIES) {
|
|
757
|
+
const value = payload[wire];
|
|
758
|
+
if (value) carried[param] = value;
|
|
759
|
+
}
|
|
760
|
+
return {
|
|
761
|
+
visitorId: payload.v,
|
|
762
|
+
sessionId: payload.s,
|
|
763
|
+
linkedAt: Number.parseInt(payload.t, 36),
|
|
764
|
+
carried,
|
|
765
|
+
fbc: payload.fc ?? null
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
function stripWww(hostname) {
|
|
769
|
+
return hostname.toLowerCase().replace(/^www\./, "");
|
|
770
|
+
}
|
|
771
|
+
function isSiblingHost(hostname, sibling) {
|
|
772
|
+
const host = stripWww(hostname);
|
|
773
|
+
const target = stripWww(sibling);
|
|
774
|
+
return host === target || host.endsWith(`.${target}`);
|
|
775
|
+
}
|
|
776
|
+
function resolveCrossSiteLink(url, linkedHostnames, now = Date.now()) {
|
|
777
|
+
if (typeof window === "undefined" || linkedHostnames.length === 0) return null;
|
|
778
|
+
let target;
|
|
779
|
+
try {
|
|
780
|
+
target = new URL(url, window.location.href);
|
|
781
|
+
} catch {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
if (target.protocol !== "http:" && target.protocol !== "https:") return null;
|
|
785
|
+
const here = window.location.hostname;
|
|
786
|
+
if (here && isSiblingHost(target.hostname, here)) return null;
|
|
787
|
+
const hostname = linkedHostnames.find((sibling) => isSiblingHost(target.hostname, sibling));
|
|
788
|
+
if (hostname === void 0) return null;
|
|
789
|
+
const consent = getConsentChoice();
|
|
790
|
+
if (consent.state === "denied" && consent.source === "explicit") {
|
|
791
|
+
return { hostname, decorated: url };
|
|
792
|
+
}
|
|
793
|
+
target.searchParams.set(LINK_PARAM, buildOutboundLinkToken(now));
|
|
794
|
+
return { hostname, decorated: target.href };
|
|
795
|
+
}
|
|
796
|
+
function stripLinkParam(url) {
|
|
797
|
+
try {
|
|
798
|
+
const parsed = new URL(url, typeof window === "undefined" ? void 0 : window.location.href);
|
|
799
|
+
if (!parsed.searchParams.has(LINK_PARAM)) return url;
|
|
800
|
+
parsed.searchParams.delete(LINK_PARAM);
|
|
801
|
+
return parsed.href;
|
|
802
|
+
} catch {
|
|
803
|
+
return url;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
function stripLinkParamFromSearch(search) {
|
|
807
|
+
if (!search.includes(LINK_PARAM)) return search;
|
|
808
|
+
const params = new URLSearchParams(search);
|
|
809
|
+
if (!params.has(LINK_PARAM)) return search;
|
|
810
|
+
params.delete(LINK_PARAM);
|
|
811
|
+
const rest = params.toString();
|
|
812
|
+
return rest.length > 0 ? `?${rest}` : "";
|
|
813
|
+
}
|
|
814
|
+
function readCarried() {
|
|
815
|
+
const out = {};
|
|
816
|
+
for (const [wire, param] of CARRIED_ENTRIES) {
|
|
817
|
+
const value = readCookieValue(param);
|
|
818
|
+
if (value) out[wire] = value;
|
|
819
|
+
}
|
|
820
|
+
return out;
|
|
821
|
+
}
|
|
822
|
+
function buildOutboundLinkToken(now = Date.now()) {
|
|
823
|
+
const fbc = getFbcCookie();
|
|
824
|
+
return encodeLinkToken({
|
|
825
|
+
v: getVisitorId(),
|
|
826
|
+
s: getOrRotateSessionId(now).id,
|
|
827
|
+
t: now.toString(36),
|
|
828
|
+
...readCarried(),
|
|
829
|
+
...fbc ? { fc: fbc } : {}
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
function decorateCrossSiteUrl(url, linkedHostnames, now = Date.now()) {
|
|
833
|
+
return resolveCrossSiteLink(url, linkedHostnames, now)?.decorated ?? url;
|
|
834
|
+
}
|
|
835
|
+
function consumeInboundLink(href = typeof window === "undefined" ? "" : window.location.href, now = Date.now()) {
|
|
836
|
+
if (typeof window === "undefined" || !href) return null;
|
|
837
|
+
let raw;
|
|
838
|
+
try {
|
|
839
|
+
raw = new URL(href, window.location.href).searchParams.get(LINK_PARAM);
|
|
840
|
+
} catch {
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
843
|
+
if (!raw) return null;
|
|
844
|
+
const payload = decodeLinkToken(raw);
|
|
845
|
+
if (payload === null) return { outcome: "invalid", link: null, adoptedVisitor: false };
|
|
846
|
+
const link = payloadToLink(payload);
|
|
847
|
+
const age = now - link.linkedAt;
|
|
848
|
+
if (!Number.isFinite(age) || age < -FUTURE_SKEW_MS) {
|
|
849
|
+
return { outcome: "invalid", link: null, adoptedVisitor: false };
|
|
850
|
+
}
|
|
851
|
+
if (age > LINK_TOKEN_TTL_MS) {
|
|
852
|
+
return { outcome: "stale", link: null, adoptedVisitor: false };
|
|
853
|
+
}
|
|
854
|
+
const adoptedVisitor = adoptVisitorId(link.visitorId);
|
|
855
|
+
for (const [param, value] of Object.entries(link.carried)) {
|
|
856
|
+
if (!readCookieValue(param)) setTrackingCookie(param, value);
|
|
857
|
+
}
|
|
858
|
+
if (link.fbc && !getFbcCookie()) persistCookieValue(FBC_COOKIE, link.fbc);
|
|
859
|
+
return { outcome: "linked", link, adoptedVisitor };
|
|
860
|
+
}
|
|
861
|
+
function stripLinkParamFromLocation() {
|
|
862
|
+
if (typeof window === "undefined" || typeof history === "undefined") return;
|
|
863
|
+
const clean = stripLinkParam(window.location.href);
|
|
864
|
+
if (clean === window.location.href) return;
|
|
865
|
+
try {
|
|
866
|
+
history.replaceState(null, "", clean);
|
|
867
|
+
} catch {
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
629
871
|
// ../tracking-core/src/resources/conversion-firing.ts
|
|
630
872
|
var DEDUP_PREFIX = "_aranova_conv_";
|
|
631
873
|
function dedupKey(input) {
|
|
@@ -732,7 +974,8 @@ function parseConversionConfig(raw) {
|
|
|
732
974
|
gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
|
|
733
975
|
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
734
976
|
services,
|
|
735
|
-
goals
|
|
977
|
+
goals,
|
|
978
|
+
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : []
|
|
736
979
|
};
|
|
737
980
|
}
|
|
738
981
|
var CACHE_PREFIX = "_aranova_cfg_";
|
|
@@ -816,6 +1059,7 @@ function resolveConversionConfig(options) {
|
|
|
816
1059
|
getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
|
|
817
1060
|
getGoal: (key) => goalsByKey.get(key) ?? null,
|
|
818
1061
|
listGoals: () => [...goalsByKey.values()],
|
|
1062
|
+
linkedHostnames: () => current?.linked_hostnames ?? [],
|
|
819
1063
|
current: () => current,
|
|
820
1064
|
isReady: () => current !== null,
|
|
821
1065
|
onResolve: (listener) => {
|
|
@@ -1000,7 +1244,7 @@ function validateConfig(config, ref) {
|
|
|
1000
1244
|
function pageViewSnapshot() {
|
|
1001
1245
|
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
1002
1246
|
return {
|
|
1003
|
-
href: window.location.href,
|
|
1247
|
+
href: stripLinkParam(window.location.href),
|
|
1004
1248
|
title: document.title || null,
|
|
1005
1249
|
referrer: document.referrer || null
|
|
1006
1250
|
};
|
|
@@ -1151,6 +1395,10 @@ var TrackingConfigRuntime = class {
|
|
|
1151
1395
|
listGoals() {
|
|
1152
1396
|
return this.current?.goals ?? [];
|
|
1153
1397
|
}
|
|
1398
|
+
/** Sibling hostnames for the linker — read from the cached object even while unconfirmed. */
|
|
1399
|
+
linkedHostnames() {
|
|
1400
|
+
return this.current?.linked_hostnames ?? [];
|
|
1401
|
+
}
|
|
1154
1402
|
async revalidateNow() {
|
|
1155
1403
|
try {
|
|
1156
1404
|
const headers = {};
|
|
@@ -1388,76 +1636,32 @@ function withConversionAutoFire(client, autoFire) {
|
|
|
1388
1636
|
};
|
|
1389
1637
|
}
|
|
1390
1638
|
|
|
1391
|
-
// ../tracking-core/src/
|
|
1392
|
-
|
|
1393
|
-
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
1394
|
-
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
1395
|
-
function safeUuid() {
|
|
1396
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
|
|
1397
|
-
return crypto.randomUUID();
|
|
1398
|
-
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
|
|
1399
|
-
}
|
|
1400
|
-
function readLocalStorage(key) {
|
|
1401
|
-
try {
|
|
1402
|
-
return window.localStorage.getItem(key);
|
|
1403
|
-
} catch {
|
|
1404
|
-
return null;
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
function writeLocalStorage(key, value) {
|
|
1408
|
-
try {
|
|
1409
|
-
window.localStorage.setItem(key, value);
|
|
1410
|
-
} catch {
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
function getVisitorId() {
|
|
1414
|
-
if (typeof window === "undefined") return safeUuid();
|
|
1415
|
-
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
1416
|
-
if (existing && existing.length > 0) return existing;
|
|
1417
|
-
const fresh = safeUuid();
|
|
1418
|
-
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
1419
|
-
return fresh;
|
|
1420
|
-
}
|
|
1421
|
-
function getOrRotateSessionId(now = Date.now()) {
|
|
1422
|
-
if (typeof window === "undefined") return { id: safeUuid(), isNew: true };
|
|
1423
|
-
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
1424
|
-
if (raw) {
|
|
1425
|
-
try {
|
|
1426
|
-
const parsed = JSON.parse(raw);
|
|
1427
|
-
if (typeof parsed.id === "string" && typeof parsed.last_event_at === "number") {
|
|
1428
|
-
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
1429
|
-
const refreshed = { id: parsed.id, last_event_at: now };
|
|
1430
|
-
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
1431
|
-
return { id: parsed.id, isNew: false };
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
} catch {
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
const fresh = { id: safeUuid(), last_event_at: now };
|
|
1438
|
-
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
1439
|
-
return { id: fresh.id, isNew: true };
|
|
1440
|
-
}
|
|
1639
|
+
// ../tracking-core/src/page-view.ts
|
|
1640
|
+
import { parse } from "zod/mini";
|
|
1441
1641
|
|
|
1442
1642
|
// ../tracking-core/src/events/page-view.ts
|
|
1443
|
-
import
|
|
1444
|
-
var pageViewMetadataSchema =
|
|
1445
|
-
page:
|
|
1446
|
-
title:
|
|
1447
|
-
path:
|
|
1448
|
-
search:
|
|
1449
|
-
hash:
|
|
1450
|
-
})
|
|
1451
|
-
referrer:
|
|
1452
|
-
//
|
|
1643
|
+
import * as z2 from "zod/mini";
|
|
1644
|
+
var pageViewMetadataSchema = z2.strictObject({
|
|
1645
|
+
page: z2.strictObject({
|
|
1646
|
+
title: z2.nullable(z2.string()),
|
|
1647
|
+
path: z2.string(),
|
|
1648
|
+
search: z2.string(),
|
|
1649
|
+
hash: z2.string()
|
|
1650
|
+
}),
|
|
1651
|
+
referrer: z2.nullable(z2.string()),
|
|
1652
|
+
// Optional + nullable — absent (undefined) OR explicit null OR a
|
|
1453
1653
|
// real viewport object. Mirrors Pydantic's `_Viewport | None = None`
|
|
1454
1654
|
// on the backend side so the drift test stays clean.
|
|
1455
|
-
viewport:
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1655
|
+
viewport: z2.optional(
|
|
1656
|
+
z2.nullable(
|
|
1657
|
+
z2.strictObject({
|
|
1658
|
+
w: z2.number(),
|
|
1659
|
+
h: z2.number()
|
|
1660
|
+
})
|
|
1661
|
+
)
|
|
1662
|
+
)
|
|
1663
|
+
});
|
|
1664
|
+
var pageViewConfigSchema = z2.strictObject({});
|
|
1461
1665
|
|
|
1462
1666
|
// ../tracking-core/src/page-view.ts
|
|
1463
1667
|
var LAST_FIRED_URL_STORAGE_KEY = "aranova_tracking_last_fired_url";
|
|
@@ -1493,11 +1697,11 @@ function setLastFiredUrl(url) {
|
|
|
1493
1697
|
}
|
|
1494
1698
|
function buildPageViewMetadata(referrerOverride) {
|
|
1495
1699
|
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
1496
|
-
return
|
|
1700
|
+
return parse(pageViewMetadataSchema, {
|
|
1497
1701
|
page: {
|
|
1498
1702
|
title: document.title || null,
|
|
1499
1703
|
path: window.location.pathname,
|
|
1500
|
-
search: window.location.search,
|
|
1704
|
+
search: stripLinkParamFromSearch(window.location.search),
|
|
1501
1705
|
hash: window.location.hash
|
|
1502
1706
|
},
|
|
1503
1707
|
referrer: referrerOverride !== void 0 ? referrerOverride : document.referrer || null,
|
|
@@ -1758,11 +1962,19 @@ function createTrackingClient(config) {
|
|
|
1758
1962
|
let firstPage = null;
|
|
1759
1963
|
let initialParams = createEmptyTrackingParams();
|
|
1760
1964
|
let destroyed = false;
|
|
1965
|
+
let inboundLink = null;
|
|
1966
|
+
if (typeof window !== "undefined") {
|
|
1967
|
+
try {
|
|
1968
|
+
inboundLink = consumeInboundLink();
|
|
1969
|
+
} catch {
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
let originLink = inboundLink?.link ?? null;
|
|
1761
1973
|
const visitorId = getVisitorId();
|
|
1762
1974
|
const initialSession = getOrRotateSessionId();
|
|
1763
1975
|
let sessionId = initialSession.id;
|
|
1764
1976
|
if (typeof window !== "undefined") {
|
|
1765
|
-
firstPage = window.location.href;
|
|
1977
|
+
firstPage = stripLinkParam(window.location.href);
|
|
1766
1978
|
try {
|
|
1767
1979
|
initialParams = captureTrackingParamsFromLocation();
|
|
1768
1980
|
} catch {
|
|
@@ -1773,25 +1985,50 @@ function createTrackingClient(config) {
|
|
|
1773
1985
|
} catch {
|
|
1774
1986
|
}
|
|
1775
1987
|
}
|
|
1776
|
-
function
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
packageName,
|
|
1781
|
-
config.triggers ?? null,
|
|
1782
|
-
activeGtagIds,
|
|
1783
|
-
config.configSiteId ?? null
|
|
1784
|
-
);
|
|
1988
|
+
function currentPageUrl() {
|
|
1989
|
+
return typeof window === "undefined" ? null : stripLinkParam(window.location.href);
|
|
1990
|
+
}
|
|
1991
|
+
function enqueueInternal(eventType, metadata, pageUrl) {
|
|
1785
1992
|
queue.push({
|
|
1786
|
-
event_type:
|
|
1787
|
-
page_url:
|
|
1993
|
+
event_type: eventType,
|
|
1994
|
+
page_url: pageUrl,
|
|
1788
1995
|
metadata,
|
|
1789
1996
|
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1790
1997
|
});
|
|
1791
1998
|
}
|
|
1999
|
+
function enqueueHeartbeat() {
|
|
2000
|
+
enqueueInternal(
|
|
2001
|
+
"sdk_heartbeat",
|
|
2002
|
+
buildHeartbeatMetadata(
|
|
2003
|
+
config.surface,
|
|
2004
|
+
sdkVersion,
|
|
2005
|
+
packageName,
|
|
2006
|
+
config.triggers ?? null,
|
|
2007
|
+
activeGtagIds,
|
|
2008
|
+
config.configSiteId ?? null
|
|
2009
|
+
),
|
|
2010
|
+
currentPageUrl()
|
|
2011
|
+
);
|
|
2012
|
+
}
|
|
1792
2013
|
if (initialSession.isNew) {
|
|
1793
2014
|
enqueueHeartbeat();
|
|
1794
2015
|
}
|
|
2016
|
+
if (inboundLink !== null && typeof window !== "undefined") {
|
|
2017
|
+
const link = inboundLink.link;
|
|
2018
|
+
enqueueInternal(
|
|
2019
|
+
"site_link_arrival",
|
|
2020
|
+
{
|
|
2021
|
+
outcome: inboundLink.outcome,
|
|
2022
|
+
origin_session_id: link?.sessionId ?? null,
|
|
2023
|
+
origin_visitor_id: link?.visitorId ?? null,
|
|
2024
|
+
transit_ms: link ? Math.max(0, Date.now() - link.linkedAt) : null,
|
|
2025
|
+
adopted_visitor: inboundLink.adoptedVisitor,
|
|
2026
|
+
page: { path: window.location.pathname }
|
|
2027
|
+
},
|
|
2028
|
+
firstPage
|
|
2029
|
+
);
|
|
2030
|
+
scheduleFlush();
|
|
2031
|
+
}
|
|
1795
2032
|
if (pending.length > 0) {
|
|
1796
2033
|
scheduleFlush();
|
|
1797
2034
|
}
|
|
@@ -1799,6 +2036,7 @@ function createTrackingClient(config) {
|
|
|
1799
2036
|
const rotated = getOrRotateSessionId();
|
|
1800
2037
|
if (rotated.isNew && rotated.id !== sessionId) {
|
|
1801
2038
|
enqueueHeartbeat();
|
|
2039
|
+
originLink = null;
|
|
1802
2040
|
}
|
|
1803
2041
|
sessionId = rotated.id;
|
|
1804
2042
|
const params = mergeTrackingParams(readTrackingParams(), initialParams);
|
|
@@ -1829,6 +2067,11 @@ function createTrackingClient(config) {
|
|
|
1829
2067
|
// landing), reused from the stored record otherwise. Keys are omitted
|
|
1830
2068
|
// entirely when the landing isn't observable (SSR).
|
|
1831
2069
|
...buildLandingPayloadFields(sessionId),
|
|
2070
|
+
...originLink ? {
|
|
2071
|
+
origin_session_id: originLink.sessionId,
|
|
2072
|
+
origin_visitor_id: originLink.visitorId,
|
|
2073
|
+
origin_linked_at: new Date(originLink.linkedAt).toISOString()
|
|
2074
|
+
} : {},
|
|
1832
2075
|
first_page: firstPage,
|
|
1833
2076
|
consent_state: consentSnapshot(),
|
|
1834
2077
|
context
|
|
@@ -1905,7 +2148,8 @@ function createTrackingClient(config) {
|
|
|
1905
2148
|
const occurredAt = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : typeof input.occurredAt === "string" ? input.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
1906
2149
|
queue.push({
|
|
1907
2150
|
event_type: input.eventType,
|
|
1908
|
-
|
|
2151
|
+
// A caller's href still carries `_arv` until the surface strips it after hydration.
|
|
2152
|
+
page_url: input.pageUrl != null ? stripLinkParam(input.pageUrl) : currentPageUrl(),
|
|
1909
2153
|
metadata: input.metadata ?? null,
|
|
1910
2154
|
occurred_at: occurredAt
|
|
1911
2155
|
});
|
|
@@ -1951,186 +2195,222 @@ function createTrackingClient(config) {
|
|
|
1951
2195
|
};
|
|
1952
2196
|
}
|
|
1953
2197
|
|
|
2198
|
+
// ../tracking-core/src/ingest-typed.ts
|
|
2199
|
+
import { parse as parse2 } from "zod/mini";
|
|
2200
|
+
|
|
1954
2201
|
// ../tracking-core/src/events/cta-click.ts
|
|
1955
|
-
import
|
|
1956
|
-
var ctaClickMetadataSchema =
|
|
1957
|
-
cta_name:
|
|
1958
|
-
page:
|
|
1959
|
-
path:
|
|
1960
|
-
})
|
|
1961
|
-
section:
|
|
1962
|
-
destination_url:
|
|
2202
|
+
import * as z3 from "zod/mini";
|
|
2203
|
+
var ctaClickMetadataSchema = z3.strictObject({
|
|
2204
|
+
cta_name: z3.string(),
|
|
2205
|
+
page: z3.strictObject({
|
|
2206
|
+
path: z3.string()
|
|
2207
|
+
}),
|
|
2208
|
+
section: z3.optional(z3.nullable(z3.string())),
|
|
2209
|
+
destination_url: z3.optional(z3.nullable(z3.string())),
|
|
1963
2210
|
// Set by auto-capture (and available to manual callers): the link target
|
|
1964
2211
|
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
1965
|
-
href:
|
|
1966
|
-
element:
|
|
1967
|
-
})
|
|
1968
|
-
var ctaClickConfigSchema =
|
|
1969
|
-
autoCapture:
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
})
|
|
2212
|
+
href: z3.optional(z3.nullable(z3.string())),
|
|
2213
|
+
element: z3.optional(z3.nullable(z3.string()))
|
|
2214
|
+
});
|
|
2215
|
+
var ctaClickConfigSchema = z3.strictObject({
|
|
2216
|
+
autoCapture: z3.optional(
|
|
2217
|
+
z3.strictObject({
|
|
2218
|
+
selector: z3.optional(z3.string())
|
|
2219
|
+
})
|
|
2220
|
+
)
|
|
2221
|
+
});
|
|
1973
2222
|
|
|
1974
2223
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
1975
|
-
import
|
|
1976
|
-
var sdkHeartbeatTriggersSchema =
|
|
1977
|
-
automatic:
|
|
1978
|
-
manual:
|
|
1979
|
-
})
|
|
1980
|
-
var sdkHeartbeatMetadataSchema =
|
|
1981
|
-
sdk_version:
|
|
1982
|
-
package_name:
|
|
1983
|
-
surface:
|
|
2224
|
+
import * as z4 from "zod/mini";
|
|
2225
|
+
var sdkHeartbeatTriggersSchema = z4.strictObject({
|
|
2226
|
+
automatic: z4.array(z4.string()),
|
|
2227
|
+
manual: z4.array(z4.string())
|
|
2228
|
+
});
|
|
2229
|
+
var sdkHeartbeatMetadataSchema = z4.strictObject({
|
|
2230
|
+
sdk_version: z4.string(),
|
|
2231
|
+
package_name: z4.nullable(z4.string()),
|
|
2232
|
+
surface: z4.enum(["next", "react", "script"]),
|
|
1984
2233
|
triggers: sdkHeartbeatTriggersSchema,
|
|
1985
|
-
trigger_config:
|
|
1986
|
-
configured_gtag_ids:
|
|
2234
|
+
trigger_config: z4.optional(z4.nullable(z4.record(z4.string(), z4.record(z4.string(), z4.unknown())))),
|
|
2235
|
+
configured_gtag_ids: z4.optional(z4.nullable(z4.record(z4.string(), z4.string()))),
|
|
1987
2236
|
// Site whose config object the SDK resolves; null on a legacy business ref.
|
|
1988
|
-
config_site_id:
|
|
1989
|
-
})
|
|
1990
|
-
var sdkHeartbeatConfigSchema =
|
|
2237
|
+
config_site_id: z4.optional(z4.nullable(z4.uuid()))
|
|
2238
|
+
});
|
|
2239
|
+
var sdkHeartbeatConfigSchema = z4.strictObject({});
|
|
1991
2240
|
|
|
1992
2241
|
// ../tracking-core/src/events/form-start.ts
|
|
1993
|
-
import
|
|
1994
|
-
var formStartMetadataSchema =
|
|
1995
|
-
form:
|
|
1996
|
-
id:
|
|
1997
|
-
action:
|
|
1998
|
-
})
|
|
1999
|
-
page:
|
|
2000
|
-
path:
|
|
2001
|
-
})
|
|
2002
|
-
})
|
|
2003
|
-
var formStartConfigSchema =
|
|
2004
|
-
selector:
|
|
2005
|
-
})
|
|
2242
|
+
import * as z5 from "zod/mini";
|
|
2243
|
+
var formStartMetadataSchema = z5.strictObject({
|
|
2244
|
+
form: z5.strictObject({
|
|
2245
|
+
id: z5.string(),
|
|
2246
|
+
action: z5.nullable(z5.string())
|
|
2247
|
+
}),
|
|
2248
|
+
page: z5.strictObject({
|
|
2249
|
+
path: z5.string()
|
|
2250
|
+
})
|
|
2251
|
+
});
|
|
2252
|
+
var formStartConfigSchema = z5.strictObject({
|
|
2253
|
+
selector: z5.optional(z5.string())
|
|
2254
|
+
});
|
|
2006
2255
|
|
|
2007
2256
|
// ../tracking-core/src/events/form-submit.ts
|
|
2008
|
-
import
|
|
2009
|
-
var jsonValueSchema =
|
|
2010
|
-
() =>
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2257
|
+
import * as z6 from "zod/mini";
|
|
2258
|
+
var jsonValueSchema = z6.lazy(
|
|
2259
|
+
() => z6.union([
|
|
2260
|
+
z6.string(),
|
|
2261
|
+
z6.number(),
|
|
2262
|
+
z6.boolean(),
|
|
2263
|
+
z6.null(),
|
|
2264
|
+
z6.array(jsonValueSchema),
|
|
2265
|
+
z6.record(z6.string(), jsonValueSchema)
|
|
2017
2266
|
])
|
|
2018
|
-
);
|
|
2019
|
-
var formSubmitMetadataSchema =
|
|
2020
|
-
form:
|
|
2021
|
-
id:
|
|
2022
|
-
action:
|
|
2023
|
-
fields:
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2267
|
+
).register(z6.globalRegistry, { id: "JsonSerializableValue" });
|
|
2268
|
+
var formSubmitMetadataSchema = z6.strictObject({
|
|
2269
|
+
form: z6.strictObject({
|
|
2270
|
+
id: z6.string(),
|
|
2271
|
+
action: z6.nullable(z6.string()),
|
|
2272
|
+
fields: z6.optional(
|
|
2273
|
+
z6.array(
|
|
2274
|
+
z6.strictObject({
|
|
2275
|
+
name: z6.string(),
|
|
2276
|
+
type: z6.string(),
|
|
2277
|
+
label: z6.nullable(z6.string()),
|
|
2278
|
+
value: jsonValueSchema
|
|
2279
|
+
})
|
|
2280
|
+
)
|
|
2281
|
+
)
|
|
2282
|
+
}),
|
|
2283
|
+
page: z6.strictObject({
|
|
2284
|
+
path: z6.string()
|
|
2285
|
+
})
|
|
2286
|
+
});
|
|
2287
|
+
var formSubmitConfigSchema = z6.strictObject({});
|
|
2037
2288
|
|
|
2038
2289
|
// ../tracking-core/src/events/multi-page-session.ts
|
|
2039
|
-
import
|
|
2040
|
-
var multiPageSessionMetadataSchema =
|
|
2041
|
-
page_count:
|
|
2042
|
-
page:
|
|
2043
|
-
path:
|
|
2044
|
-
})
|
|
2045
|
-
})
|
|
2046
|
-
var multiPageSessionConfigSchema =
|
|
2047
|
-
pageThreshold:
|
|
2048
|
-
})
|
|
2290
|
+
import * as z7 from "zod/mini";
|
|
2291
|
+
var multiPageSessionMetadataSchema = z7.strictObject({
|
|
2292
|
+
page_count: z7.int().check(z7.gte(2)),
|
|
2293
|
+
page: z7.strictObject({
|
|
2294
|
+
path: z7.string()
|
|
2295
|
+
})
|
|
2296
|
+
});
|
|
2297
|
+
var multiPageSessionConfigSchema = z7.strictObject({
|
|
2298
|
+
pageThreshold: z7.int().check(z7.gte(2))
|
|
2299
|
+
});
|
|
2049
2300
|
|
|
2050
2301
|
// ../tracking-core/src/events/page-exit.ts
|
|
2051
|
-
import
|
|
2052
|
-
var pageExitMetadataSchema =
|
|
2053
|
-
dwell_ms:
|
|
2302
|
+
import * as z8 from "zod/mini";
|
|
2303
|
+
var pageExitMetadataSchema = z8.strictObject({
|
|
2304
|
+
dwell_ms: z8.int().check(z8.gte(0)),
|
|
2054
2305
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
2055
2306
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
2056
|
-
max_scroll_percent:
|
|
2307
|
+
max_scroll_percent: z8.nullable(z8.int().check(z8.gte(0), z8.lte(100))),
|
|
2057
2308
|
// The gating baseline: the fraction of the page visible at load with
|
|
2058
2309
|
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
2059
2310
|
// (skeleton/streaming renders), the first-scroll position that
|
|
2060
2311
|
// established it. null = page had no scrollable range, or the segment
|
|
2061
|
-
// ended before the snapshot.
|
|
2312
|
+
// ended before the snapshot. Optionality is load-bearing: SDK builds
|
|
2062
2313
|
// predating this field keep POSTing page_exit without the key —
|
|
2063
2314
|
// requiring it would 422 whole keepalive beacon batches.
|
|
2064
|
-
scroll_baseline_percent:
|
|
2065
|
-
page:
|
|
2066
|
-
path:
|
|
2067
|
-
})
|
|
2068
|
-
})
|
|
2069
|
-
var pageExitConfigSchema =
|
|
2315
|
+
scroll_baseline_percent: z8.optional(z8.nullable(z8.int().check(z8.gte(0), z8.lte(100)))),
|
|
2316
|
+
page: z8.strictObject({
|
|
2317
|
+
path: z8.string()
|
|
2318
|
+
})
|
|
2319
|
+
});
|
|
2320
|
+
var pageExitConfigSchema = z8.strictObject({});
|
|
2070
2321
|
|
|
2071
2322
|
// ../tracking-core/src/events/phone-click.ts
|
|
2072
|
-
import
|
|
2073
|
-
var phoneClickMetadataSchema =
|
|
2074
|
-
phone_number:
|
|
2075
|
-
page:
|
|
2076
|
-
path:
|
|
2077
|
-
})
|
|
2078
|
-
section:
|
|
2079
|
-
})
|
|
2080
|
-
var phoneClickConfigSchema =
|
|
2081
|
-
autoCapture:
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
})
|
|
2323
|
+
import * as z9 from "zod/mini";
|
|
2324
|
+
var phoneClickMetadataSchema = z9.strictObject({
|
|
2325
|
+
phone_number: z9.string(),
|
|
2326
|
+
page: z9.strictObject({
|
|
2327
|
+
path: z9.string()
|
|
2328
|
+
}),
|
|
2329
|
+
section: z9.optional(z9.nullable(z9.string()))
|
|
2330
|
+
});
|
|
2331
|
+
var phoneClickConfigSchema = z9.strictObject({
|
|
2332
|
+
autoCapture: z9.optional(
|
|
2333
|
+
z9.strictObject({
|
|
2334
|
+
selector: z9.optional(z9.string())
|
|
2335
|
+
})
|
|
2336
|
+
)
|
|
2337
|
+
});
|
|
2085
2338
|
|
|
2086
2339
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
2087
|
-
import
|
|
2088
|
-
var scrollDepthMetadataSchema =
|
|
2089
|
-
depth_percent:
|
|
2090
|
-
page:
|
|
2091
|
-
path:
|
|
2092
|
-
})
|
|
2093
|
-
})
|
|
2094
|
-
var scrollDepthConfigSchema =
|
|
2095
|
-
thresholds:
|
|
2096
|
-
})
|
|
2340
|
+
import * as z10 from "zod/mini";
|
|
2341
|
+
var scrollDepthMetadataSchema = z10.strictObject({
|
|
2342
|
+
depth_percent: z10.int().check(z10.gte(1), z10.lte(100)),
|
|
2343
|
+
page: z10.strictObject({
|
|
2344
|
+
path: z10.string()
|
|
2345
|
+
})
|
|
2346
|
+
});
|
|
2347
|
+
var scrollDepthConfigSchema = z10.strictObject({
|
|
2348
|
+
thresholds: z10.array(z10.int().check(z10.gte(1), z10.lte(100))).check(z10.minLength(1))
|
|
2349
|
+
});
|
|
2097
2350
|
|
|
2098
2351
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
2099
|
-
import
|
|
2352
|
+
import * as z11 from "zod/mini";
|
|
2100
2353
|
var PAGE_IDENTITY_MAX_LENGTH = 64;
|
|
2101
2354
|
var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
|
|
2102
|
-
var pageIdentitySchema =
|
|
2103
|
-
|
|
2104
|
-
|
|
2355
|
+
var pageIdentitySchema = z11.string().check(
|
|
2356
|
+
z11.maxLength(PAGE_IDENTITY_MAX_LENGTH),
|
|
2357
|
+
z11.regex(PAGE_IDENTITY_PATTERN, {
|
|
2358
|
+
message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
|
|
2359
|
+
})
|
|
2360
|
+
);
|
|
2105
2361
|
var specificPageNameSchema = pageIdentitySchema;
|
|
2106
|
-
var specificPageVisitMetadataSchema =
|
|
2362
|
+
var specificPageVisitMetadataSchema = z11.strictObject({
|
|
2107
2363
|
page_name: specificPageNameSchema,
|
|
2108
|
-
page:
|
|
2109
|
-
path:
|
|
2110
|
-
})
|
|
2111
|
-
})
|
|
2112
|
-
var specificPageVisitConfigSchema =
|
|
2113
|
-
pages:
|
|
2114
|
-
|
|
2364
|
+
page: z11.strictObject({
|
|
2365
|
+
path: z11.string()
|
|
2366
|
+
})
|
|
2367
|
+
});
|
|
2368
|
+
var specificPageVisitConfigSchema = z11.strictObject({
|
|
2369
|
+
pages: z11.array(
|
|
2370
|
+
z11.strictObject({
|
|
2115
2371
|
name: specificPageNameSchema,
|
|
2116
|
-
pathPattern:
|
|
2372
|
+
pathPattern: z11.custom((value) => value instanceof RegExp, {
|
|
2117
2373
|
message: "pathPattern must be a RegExp"
|
|
2118
2374
|
})
|
|
2119
|
-
})
|
|
2120
|
-
).
|
|
2121
|
-
})
|
|
2375
|
+
})
|
|
2376
|
+
).check(z11.minLength(1))
|
|
2377
|
+
});
|
|
2378
|
+
|
|
2379
|
+
// ../tracking-core/src/events/site-link.ts
|
|
2380
|
+
import * as z12 from "zod/mini";
|
|
2381
|
+
var siteLinkClickMetadataSchema = z12.strictObject({
|
|
2382
|
+
destination_host: z12.string(),
|
|
2383
|
+
destination_url: z12.string(),
|
|
2384
|
+
page: z12.strictObject({
|
|
2385
|
+
path: z12.string()
|
|
2386
|
+
})
|
|
2387
|
+
});
|
|
2388
|
+
var siteLinkClickConfigSchema = z12.strictObject({});
|
|
2389
|
+
var siteLinkArrivalMetadataSchema = z12.strictObject({
|
|
2390
|
+
outcome: z12.enum(["linked", "stale", "invalid"]),
|
|
2391
|
+
origin_session_id: z12.optional(z12.nullable(z12.string())),
|
|
2392
|
+
origin_visitor_id: z12.optional(z12.nullable(z12.string())),
|
|
2393
|
+
// Milliseconds between the origin click and this page load.
|
|
2394
|
+
transit_ms: z12.optional(z12.nullable(z12.number())),
|
|
2395
|
+
// True when this browser had no visitor id and took the origin's.
|
|
2396
|
+
adopted_visitor: z12.boolean(),
|
|
2397
|
+
page: z12.strictObject({
|
|
2398
|
+
path: z12.string()
|
|
2399
|
+
})
|
|
2400
|
+
});
|
|
2401
|
+
var siteLinkArrivalConfigSchema = z12.strictObject({});
|
|
2122
2402
|
|
|
2123
2403
|
// ../tracking-core/src/events/time-on-site.ts
|
|
2124
|
-
import
|
|
2125
|
-
var timeOnSiteMetadataSchema =
|
|
2126
|
-
duration_ms:
|
|
2127
|
-
page:
|
|
2128
|
-
path:
|
|
2129
|
-
})
|
|
2130
|
-
})
|
|
2131
|
-
var timeOnSiteConfigSchema =
|
|
2132
|
-
thresholdSeconds:
|
|
2133
|
-
})
|
|
2404
|
+
import * as z13 from "zod/mini";
|
|
2405
|
+
var timeOnSiteMetadataSchema = z13.strictObject({
|
|
2406
|
+
duration_ms: z13.int().check(z13.nonnegative()),
|
|
2407
|
+
page: z13.strictObject({
|
|
2408
|
+
path: z13.string()
|
|
2409
|
+
})
|
|
2410
|
+
});
|
|
2411
|
+
var timeOnSiteConfigSchema = z13.strictObject({
|
|
2412
|
+
thresholdSeconds: z13.int().check(z13.positive())
|
|
2413
|
+
});
|
|
2134
2414
|
|
|
2135
2415
|
// ../tracking-core/src/events/semantics.ts
|
|
2136
2416
|
var EVENT_SEMANTICS = {
|
|
@@ -2199,6 +2479,18 @@ var EVENT_SEMANTICS = {
|
|
|
2199
2479
|
category: "engagement",
|
|
2200
2480
|
outcomeRole: "engagement",
|
|
2201
2481
|
clientVisibility: "simple"
|
|
2482
|
+
},
|
|
2483
|
+
site_link_click: {
|
|
2484
|
+
label: "Left for sibling site",
|
|
2485
|
+
category: "page",
|
|
2486
|
+
outcomeRole: "navigation",
|
|
2487
|
+
clientVisibility: "detailed"
|
|
2488
|
+
},
|
|
2489
|
+
site_link_arrival: {
|
|
2490
|
+
label: "Arrived from sibling site",
|
|
2491
|
+
category: "page",
|
|
2492
|
+
outcomeRole: "navigation",
|
|
2493
|
+
clientVisibility: "simple"
|
|
2202
2494
|
}
|
|
2203
2495
|
};
|
|
2204
2496
|
|
|
@@ -2254,6 +2546,20 @@ var EVENT_REGISTRY = {
|
|
|
2254
2546
|
metadataSchema: pageExitMetadataSchema,
|
|
2255
2547
|
configSchema: pageExitConfigSchema
|
|
2256
2548
|
},
|
|
2549
|
+
// Cross-site linkage: emitted by the linker (roster comes from the site
|
|
2550
|
+
// config, not the trigger registry), so neither is consumer-configurable.
|
|
2551
|
+
site_link_click: {
|
|
2552
|
+
kind: "automatic",
|
|
2553
|
+
semantics: EVENT_SEMANTICS.site_link_click,
|
|
2554
|
+
metadataSchema: siteLinkClickMetadataSchema,
|
|
2555
|
+
configSchema: siteLinkClickConfigSchema
|
|
2556
|
+
},
|
|
2557
|
+
site_link_arrival: {
|
|
2558
|
+
kind: "automatic",
|
|
2559
|
+
semantics: EVENT_SEMANTICS.site_link_arrival,
|
|
2560
|
+
metadataSchema: siteLinkArrivalMetadataSchema,
|
|
2561
|
+
configSchema: siteLinkArrivalConfigSchema
|
|
2562
|
+
},
|
|
2257
2563
|
// --- manual triggers ---
|
|
2258
2564
|
form_submit: {
|
|
2259
2565
|
kind: "manual",
|
|
@@ -2289,7 +2595,7 @@ function createTypedClient(raw, registry, options = {}) {
|
|
|
2289
2595
|
trackEvent(eventType, metadata, opts) {
|
|
2290
2596
|
if (debug) {
|
|
2291
2597
|
const def = getEventDefinition(eventType);
|
|
2292
|
-
def.metadataSchema
|
|
2598
|
+
parse2(def.metadataSchema, metadata);
|
|
2293
2599
|
}
|
|
2294
2600
|
raw.trackEvent({
|
|
2295
2601
|
eventType,
|
|
@@ -2724,6 +3030,57 @@ function attachCtaClickCapture(client, config) {
|
|
|
2724
3030
|
};
|
|
2725
3031
|
}
|
|
2726
3032
|
|
|
3033
|
+
// ../tracking-core/src/triggers/site-link-capture.ts
|
|
3034
|
+
function anchorFrom(target) {
|
|
3035
|
+
if (!(target instanceof Element)) return null;
|
|
3036
|
+
const anchor = target.closest("a[href]");
|
|
3037
|
+
return anchor instanceof HTMLAnchorElement ? anchor : null;
|
|
3038
|
+
}
|
|
3039
|
+
function opensTheLink(event) {
|
|
3040
|
+
return event.button === 0 || event.button === 1;
|
|
3041
|
+
}
|
|
3042
|
+
function attachSiteLinkCapture(client, options) {
|
|
3043
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
3044
|
+
return () => {
|
|
3045
|
+
};
|
|
3046
|
+
}
|
|
3047
|
+
registerCapability("cross_site_linker");
|
|
3048
|
+
function hopFrom(event) {
|
|
3049
|
+
const anchor = anchorFrom(event.target);
|
|
3050
|
+
if (anchor === null) return null;
|
|
3051
|
+
const link = resolveCrossSiteLink(anchor.href, options.linkedHostnames());
|
|
3052
|
+
return link === null ? null : { anchor, link };
|
|
3053
|
+
}
|
|
3054
|
+
function onPointerDown(event) {
|
|
3055
|
+
if (!opensTheLink(event)) return;
|
|
3056
|
+
const hop = hopFrom(event);
|
|
3057
|
+
if (hop !== null) hop.anchor.href = hop.link.decorated;
|
|
3058
|
+
}
|
|
3059
|
+
function onClick(event) {
|
|
3060
|
+
if (!opensTheLink(event)) return;
|
|
3061
|
+
const hop = hopFrom(event);
|
|
3062
|
+
if (hop === null) return;
|
|
3063
|
+
hop.anchor.href = hop.link.decorated;
|
|
3064
|
+
client.trackEvent({
|
|
3065
|
+
eventType: "site_link_click",
|
|
3066
|
+
metadata: {
|
|
3067
|
+
destination_host: hop.anchor.hostname,
|
|
3068
|
+
destination_url: stripLinkParam(hop.anchor.href),
|
|
3069
|
+
page: { path: window.location.pathname }
|
|
3070
|
+
},
|
|
3071
|
+
pageUrl: window.location.href,
|
|
3072
|
+
occurredAt: null
|
|
3073
|
+
});
|
|
3074
|
+
client.flushBeacon();
|
|
3075
|
+
}
|
|
3076
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
3077
|
+
document.addEventListener("click", onClick, true);
|
|
3078
|
+
return () => {
|
|
3079
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
3080
|
+
document.removeEventListener("click", onClick, true);
|
|
3081
|
+
};
|
|
3082
|
+
}
|
|
3083
|
+
|
|
2727
3084
|
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2728
3085
|
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2729
3086
|
function safeDecodeURIComponent(value) {
|
|
@@ -2778,117 +3135,6 @@ function attachPhoneClickCapture(client, config) {
|
|
|
2778
3135
|
};
|
|
2779
3136
|
}
|
|
2780
3137
|
|
|
2781
|
-
// ../tracking-core/src/resources/sales/schema.ts
|
|
2782
|
-
import { z as z12 } from "zod";
|
|
2783
|
-
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
2784
|
-
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
2785
|
-
var currencySchema = z12.enum(SUPPORTED_CURRENCIES);
|
|
2786
|
-
var centsSchema = z12.number().int().nonnegative();
|
|
2787
|
-
var quantitySchema = z12.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
2788
|
-
var metadataSchema = z12.record(z12.unknown());
|
|
2789
|
-
var saleItemSchema = z12.object({
|
|
2790
|
-
external_item_id: z12.string().nullable().optional(),
|
|
2791
|
-
name: z12.string().nullable().optional(),
|
|
2792
|
-
category: z12.string().nullable().optional(),
|
|
2793
|
-
quantity: quantitySchema,
|
|
2794
|
-
unit_price_cents: centsSchema,
|
|
2795
|
-
// Non-negativity validated on the wire — same contract as the other cents
|
|
2796
|
-
// fields — and backstopped by the DB CHECK.
|
|
2797
|
-
unit_cost_cents: centsSchema.nullable().optional()
|
|
2798
|
-
}).strict();
|
|
2799
|
-
var saleServiceSchema = z12.object({
|
|
2800
|
-
service: z12.string(),
|
|
2801
|
-
amount_cents: centsSchema
|
|
2802
|
-
}).strict();
|
|
2803
|
-
var customerNameSchema = z12.string().max(200);
|
|
2804
|
-
var customerPhoneSchema = z12.string().max(64);
|
|
2805
|
-
var customerEmailSchema = z12.string().max(320).email();
|
|
2806
|
-
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
2807
|
-
if (val.services != null) {
|
|
2808
|
-
if (val.service != null) {
|
|
2809
|
-
ctx.addIssue({
|
|
2810
|
-
code: z12.ZodIssueCode.custom,
|
|
2811
|
-
message: "pass either `service` or `services`, not both",
|
|
2812
|
-
path: ["services"]
|
|
2813
|
-
});
|
|
2814
|
-
}
|
|
2815
|
-
if (val.services.length === 0) {
|
|
2816
|
-
ctx.addIssue({
|
|
2817
|
-
code: z12.ZodIssueCode.custom,
|
|
2818
|
-
message: "`services` must not be empty",
|
|
2819
|
-
path: ["services"]
|
|
2820
|
-
});
|
|
2821
|
-
}
|
|
2822
|
-
const keys = val.services.map((s) => s.service);
|
|
2823
|
-
if (new Set(keys).size !== keys.length) {
|
|
2824
|
-
ctx.addIssue({
|
|
2825
|
-
code: z12.ZodIssueCode.custom,
|
|
2826
|
-
message: "`services` must not list the same service more than once",
|
|
2827
|
-
path: ["services"]
|
|
2828
|
-
});
|
|
2829
|
-
}
|
|
2830
|
-
if (val.amount_total_cents != null) {
|
|
2831
|
-
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
2832
|
-
if (val.amount_total_cents !== sum) {
|
|
2833
|
-
ctx.addIssue({
|
|
2834
|
-
code: z12.ZodIssueCode.custom,
|
|
2835
|
-
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
2836
|
-
path: ["amount_total_cents"]
|
|
2837
|
-
});
|
|
2838
|
-
}
|
|
2839
|
-
}
|
|
2840
|
-
} else if (requireAmount && val.amount_total_cents == null) {
|
|
2841
|
-
ctx.addIssue({
|
|
2842
|
-
code: z12.ZodIssueCode.custom,
|
|
2843
|
-
message: "amount_total_cents is required unless `services` is provided",
|
|
2844
|
-
path: ["amount_total_cents"]
|
|
2845
|
-
});
|
|
2846
|
-
}
|
|
2847
|
-
}
|
|
2848
|
-
var saleCreateSchema = z12.object({
|
|
2849
|
-
external_id: z12.string().nullable().optional(),
|
|
2850
|
-
description: z12.string().nullable().optional(),
|
|
2851
|
-
service: z12.string().nullable().optional(),
|
|
2852
|
-
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
2853
|
-
currency: currencySchema,
|
|
2854
|
-
// Optional only because the plural `services` form derives it from the sum
|
|
2855
|
-
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
2856
|
-
amount_total_cents: centsSchema.nullable().optional(),
|
|
2857
|
-
occurred_at: z12.string().datetime(),
|
|
2858
|
-
environment: z12.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
2859
|
-
items: z12.array(saleItemSchema).default([]),
|
|
2860
|
-
metadata: metadataSchema.nullable().optional(),
|
|
2861
|
-
customer_name: customerNameSchema.nullable().optional(),
|
|
2862
|
-
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2863
|
-
customer_email: customerEmailSchema.nullable().optional(),
|
|
2864
|
-
// CASL consent attestation: the customer agreed to receive SMS. Recorded
|
|
2865
|
-
// with a timestamp server-side; every SMS send path gates on it.
|
|
2866
|
-
//
|
|
2867
|
-
// Tri-state: omit it (or send null) to let the server apply the business's
|
|
2868
|
-
// configured default-opt-in policy, honouring a returning customer's
|
|
2869
|
-
// remembered preference. Send an explicit boolean to assert consent state
|
|
2870
|
-
// yourself — `false` records a deliberate opt-out.
|
|
2871
|
-
sms_consent: z12.boolean().nullable().optional()
|
|
2872
|
-
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
2873
|
-
var saleUpdateSchema = z12.object({
|
|
2874
|
-
description: z12.string().nullable().optional(),
|
|
2875
|
-
service: z12.string().nullable().optional(),
|
|
2876
|
-
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
2877
|
-
currency: currencySchema.optional(),
|
|
2878
|
-
amount_total_cents: centsSchema.optional(),
|
|
2879
|
-
occurred_at: z12.string().datetime().optional(),
|
|
2880
|
-
items: z12.array(saleItemSchema).optional(),
|
|
2881
|
-
metadata: metadataSchema.nullable().optional(),
|
|
2882
|
-
customer_name: customerNameSchema.nullable().optional(),
|
|
2883
|
-
// Re-attest when changing a filler-looking name; the server clears the
|
|
2884
|
-
// prior attestation whenever `customer_name` changes.
|
|
2885
|
-
customer_name_placeholder_confirmed: z12.boolean().optional(),
|
|
2886
|
-
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2887
|
-
customer_email: customerEmailSchema.nullable().optional(),
|
|
2888
|
-
// NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
|
|
2889
|
-
sms_consent: z12.boolean().optional()
|
|
2890
|
-
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
|
|
2891
|
-
|
|
2892
3138
|
// src/hooks.ts
|
|
2893
3139
|
function useGclid() {
|
|
2894
3140
|
const [gclid, setGclid] = useState(null);
|
|
@@ -3229,7 +3475,7 @@ function GoogleAdsTracking(props) {
|
|
|
3229
3475
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
3230
3476
|
|
|
3231
3477
|
// package.json
|
|
3232
|
-
var version = "
|
|
3478
|
+
var version = "1.1.0";
|
|
3233
3479
|
|
|
3234
3480
|
// src/factory.tsx
|
|
3235
3481
|
import {
|
|
@@ -3341,9 +3587,16 @@ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
|
3341
3587
|
function PageViewTracker({ fire }) {
|
|
3342
3588
|
const pathname = usePathname();
|
|
3343
3589
|
const searchParams = useSearchParams();
|
|
3590
|
+
const search = stripLinkParamFromSearch(`?${searchParams.toString()}`);
|
|
3591
|
+
const carriesToken = searchParams.has(LINK_PARAM);
|
|
3344
3592
|
useEffect4(() => {
|
|
3345
3593
|
fire();
|
|
3346
|
-
}, [pathname,
|
|
3594
|
+
}, [pathname, search, fire]);
|
|
3595
|
+
useEffect4(() => {
|
|
3596
|
+
if (!carriesToken) return;
|
|
3597
|
+
const timer = window.setTimeout(stripLinkParamFromLocation, 0);
|
|
3598
|
+
return () => window.clearTimeout(timer);
|
|
3599
|
+
}, [carriesToken]);
|
|
3347
3600
|
return null;
|
|
3348
3601
|
}
|
|
3349
3602
|
function createTracking(options) {
|
|
@@ -3376,9 +3629,11 @@ function createTracking(options) {
|
|
|
3376
3629
|
};
|
|
3377
3630
|
return {
|
|
3378
3631
|
TrackingProvider: ({ children }) => /* @__PURE__ */ jsx5(PhoneConfigProvider, { value: phone ?? null, children }),
|
|
3379
|
-
useTracking: () => noopClient
|
|
3632
|
+
useTracking: () => noopClient,
|
|
3633
|
+
decorateUrl: (url) => url
|
|
3380
3634
|
};
|
|
3381
3635
|
}
|
|
3636
|
+
const linkedHostnames = () => trackingConfig ? getTrackingConfigRuntime(trackingConfig).linkedHostnames() : [];
|
|
3382
3637
|
const TrackingContext = createContext2(null);
|
|
3383
3638
|
const specificPageVisitConfig = triggers.automatic.specific_page_visit ?? null;
|
|
3384
3639
|
const timeOnSiteConfig = triggers.automatic.time_on_site ?? null;
|
|
@@ -3490,6 +3745,11 @@ function createTracking(options) {
|
|
|
3490
3745
|
if (timeOnSiteConfig) {
|
|
3491
3746
|
detachers.push(attachTimeOnSite(detectorClient, timeOnSiteConfig));
|
|
3492
3747
|
}
|
|
3748
|
+
detachers.push(
|
|
3749
|
+
attachSiteLinkCapture(detectorClient, {
|
|
3750
|
+
linkedHostnames: () => conversionStore?.linkedHostnames() ?? []
|
|
3751
|
+
})
|
|
3752
|
+
);
|
|
3493
3753
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
3494
3754
|
if (scrollDepth) {
|
|
3495
3755
|
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
@@ -3512,7 +3772,7 @@ function createTracking(options) {
|
|
|
3512
3772
|
}
|
|
3513
3773
|
};
|
|
3514
3774
|
});
|
|
3515
|
-
}, [rawClient, wrapClient]);
|
|
3775
|
+
}, [conversionStore, rawClient, wrapClient]);
|
|
3516
3776
|
return /* @__PURE__ */ jsxs4(TrackingContext.Provider, { value: client, children: [
|
|
3517
3777
|
/* @__PURE__ */ jsx5(Suspense, { fallback: null, children: /* @__PURE__ */ jsx5(PageViewTracker, { fire: firePageView }) }),
|
|
3518
3778
|
/* @__PURE__ */ jsx5(PhoneConfigProvider, { value: phone ?? null, children })
|
|
@@ -3527,7 +3787,11 @@ function createTracking(options) {
|
|
|
3527
3787
|
}
|
|
3528
3788
|
return client;
|
|
3529
3789
|
}
|
|
3530
|
-
return {
|
|
3790
|
+
return {
|
|
3791
|
+
TrackingProvider,
|
|
3792
|
+
useTracking,
|
|
3793
|
+
decorateUrl: (url) => decorateCrossSiteUrl(url, linkedHostnames())
|
|
3794
|
+
};
|
|
3531
3795
|
}
|
|
3532
3796
|
export {
|
|
3533
3797
|
AdPlatformTracking,
|