@aranova/tracking-react 1.0.0 → 1.2.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/client.d.mts +9 -3
- package/dist/client.d.ts +9 -3
- package/dist/client.js +549 -197
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +549 -197
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +217 -141
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +217 -141
- package/dist/index.mjs.map +1 -1
- package/dist/{ingest-typed-BdKmlouW.d.ts → ingest-typed-MBuMe9Pn.d.ts} +94 -2
- package/dist/{ingest-typed-Bo7WPmpU.d.mts → ingest-typed-UA13xTfI.d.mts} +94 -2
- package/dist/{phone-utils-CubQif9Z.d.mts → phone-utils-C0ds6cqZ.d.mts} +6 -0
- package/dist/{phone-utils-CubQif9Z.d.ts → phone-utils-C0ds6cqZ.d.ts} +6 -0
- package/dist/phone.d.mts +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/{sales-C7Xjsq-a.d.mts → sales-BuKD_bdo.d.mts} +1 -1
- package/dist/{sales-Bhh9mLBA.d.ts → sales-C3O_xxZ_.d.ts} +1 -1
- package/dist/sales.d.mts +2 -2
- package/dist/sales.d.ts +2 -2
- package/dist/sales.js +17 -1
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +17 -1
- package/dist/sales.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/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -294,6 +294,7 @@ var TRACKING_CAPABILITIES = [
|
|
|
294
294
|
"consent_controls",
|
|
295
295
|
"conversion_goals_auto",
|
|
296
296
|
"conversion_goals_manual",
|
|
297
|
+
"cross_site_linker",
|
|
297
298
|
"cta_click_capture",
|
|
298
299
|
"form_capture",
|
|
299
300
|
"phone_click_capture",
|
|
@@ -320,6 +321,9 @@ function readDomMarkers() {
|
|
|
320
321
|
return found;
|
|
321
322
|
}
|
|
322
323
|
|
|
324
|
+
// ../tracking-core/src/cross-site-link.ts
|
|
325
|
+
var z = __toESM(require("zod/mini"));
|
|
326
|
+
|
|
323
327
|
// ../tracking-core/src/tracking.ts
|
|
324
328
|
var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
|
|
325
329
|
var TRACKING_PARAM_KEYS = [
|
|
@@ -687,6 +691,244 @@ function buildLandingPayloadFields(sessionId, override) {
|
|
|
687
691
|
};
|
|
688
692
|
}
|
|
689
693
|
|
|
694
|
+
// ../tracking-core/src/session.ts
|
|
695
|
+
var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
|
|
696
|
+
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
697
|
+
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
698
|
+
function safeUuid() {
|
|
699
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
|
|
700
|
+
return crypto.randomUUID();
|
|
701
|
+
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
|
|
702
|
+
}
|
|
703
|
+
function readLocalStorage(key) {
|
|
704
|
+
try {
|
|
705
|
+
return window.localStorage.getItem(key);
|
|
706
|
+
} catch {
|
|
707
|
+
return null;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
function writeLocalStorage(key, value) {
|
|
711
|
+
try {
|
|
712
|
+
window.localStorage.setItem(key, value);
|
|
713
|
+
} catch {
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
function getVisitorId() {
|
|
717
|
+
if (typeof window === "undefined") return safeUuid();
|
|
718
|
+
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
719
|
+
if (existing && existing.length > 0) return existing;
|
|
720
|
+
const fresh = safeUuid();
|
|
721
|
+
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
722
|
+
return fresh;
|
|
723
|
+
}
|
|
724
|
+
function adoptVisitorId(visitorId) {
|
|
725
|
+
if (typeof window === "undefined" || visitorId.length === 0) return false;
|
|
726
|
+
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
727
|
+
if (existing && existing.length > 0) return false;
|
|
728
|
+
writeLocalStorage(VISITOR_STORAGE_KEY, visitorId);
|
|
729
|
+
return readLocalStorage(VISITOR_STORAGE_KEY) === visitorId;
|
|
730
|
+
}
|
|
731
|
+
function getOrRotateSessionId(now = Date.now()) {
|
|
732
|
+
if (typeof window === "undefined") return { id: safeUuid(), isNew: true };
|
|
733
|
+
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
734
|
+
if (raw) {
|
|
735
|
+
try {
|
|
736
|
+
const parsed = JSON.parse(raw);
|
|
737
|
+
if (typeof parsed.id === "string" && typeof parsed.last_event_at === "number") {
|
|
738
|
+
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
739
|
+
const refreshed = { id: parsed.id, last_event_at: now };
|
|
740
|
+
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
741
|
+
return { id: parsed.id, isNew: false };
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
} catch {
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
const fresh = { id: safeUuid(), last_event_at: now };
|
|
748
|
+
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
749
|
+
return { id: fresh.id, isNew: true };
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// ../tracking-core/src/cross-site-link.ts
|
|
753
|
+
var LINK_PARAM = "_arv";
|
|
754
|
+
var LINK_TOKEN_VERSION = "1";
|
|
755
|
+
var LINK_TOKEN_TTL_MS = 5 * 60 * 1e3;
|
|
756
|
+
var FUTURE_SKEW_MS = 60 * 1e3;
|
|
757
|
+
var CARRIED_KEYS = {
|
|
758
|
+
g: "gclid",
|
|
759
|
+
w: "wbraid",
|
|
760
|
+
gb: "gbraid",
|
|
761
|
+
f: "fbclid",
|
|
762
|
+
y: "ylpcid"
|
|
763
|
+
};
|
|
764
|
+
var CARRIED_ENTRIES = Object.entries(CARRIED_KEYS);
|
|
765
|
+
var identifier = z.string().check(z.minLength(1), z.maxLength(128));
|
|
766
|
+
var optionalIdentifier = z.optional(identifier);
|
|
767
|
+
var linkTokenSchema = z.object({
|
|
768
|
+
v: identifier,
|
|
769
|
+
s: identifier,
|
|
770
|
+
// Epoch ms in base36.
|
|
771
|
+
t: z.string().check(z.regex(/^[0-9a-z]{1,12}$/)),
|
|
772
|
+
g: optionalIdentifier,
|
|
773
|
+
w: optionalIdentifier,
|
|
774
|
+
gb: optionalIdentifier,
|
|
775
|
+
f: optionalIdentifier,
|
|
776
|
+
fc: optionalIdentifier,
|
|
777
|
+
y: optionalIdentifier
|
|
778
|
+
});
|
|
779
|
+
function toBase64Url(input) {
|
|
780
|
+
const bytes = new TextEncoder().encode(input);
|
|
781
|
+
let binary = "";
|
|
782
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
783
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
784
|
+
}
|
|
785
|
+
function fromBase64Url(input) {
|
|
786
|
+
try {
|
|
787
|
+
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
788
|
+
const binary = atob(padded + "=".repeat((4 - padded.length % 4) % 4));
|
|
789
|
+
const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
790
|
+
return new TextDecoder().decode(bytes);
|
|
791
|
+
} catch {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
function encodeLinkToken(payload) {
|
|
796
|
+
const params = new URLSearchParams();
|
|
797
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
798
|
+
if (typeof value === "string" && value.length > 0) params.set(key, value);
|
|
799
|
+
}
|
|
800
|
+
return `${LINK_TOKEN_VERSION}.${toBase64Url(params.toString())}`;
|
|
801
|
+
}
|
|
802
|
+
function decodeLinkToken(raw) {
|
|
803
|
+
const dot = raw.indexOf(".");
|
|
804
|
+
if (dot <= 0 || raw.slice(0, dot) !== LINK_TOKEN_VERSION) return null;
|
|
805
|
+
const decoded = fromBase64Url(raw.slice(dot + 1));
|
|
806
|
+
if (decoded === null) return null;
|
|
807
|
+
const params = new URLSearchParams(decoded);
|
|
808
|
+
const candidate = {};
|
|
809
|
+
params.forEach((value, key) => {
|
|
810
|
+
candidate[key] = value;
|
|
811
|
+
});
|
|
812
|
+
const result = linkTokenSchema.safeParse(candidate);
|
|
813
|
+
return result.success ? result.data : null;
|
|
814
|
+
}
|
|
815
|
+
function payloadToLink(payload) {
|
|
816
|
+
const carried = {};
|
|
817
|
+
for (const [wire, param] of CARRIED_ENTRIES) {
|
|
818
|
+
const value = payload[wire];
|
|
819
|
+
if (value) carried[param] = value;
|
|
820
|
+
}
|
|
821
|
+
return {
|
|
822
|
+
visitorId: payload.v,
|
|
823
|
+
sessionId: payload.s,
|
|
824
|
+
linkedAt: Number.parseInt(payload.t, 36),
|
|
825
|
+
carried,
|
|
826
|
+
fbc: payload.fc ?? null
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
function stripWww(hostname) {
|
|
830
|
+
return hostname.toLowerCase().replace(/^www\./, "");
|
|
831
|
+
}
|
|
832
|
+
function isSiblingHost(hostname, sibling) {
|
|
833
|
+
const host = stripWww(hostname);
|
|
834
|
+
const target = stripWww(sibling);
|
|
835
|
+
return host === target || host.endsWith(`.${target}`);
|
|
836
|
+
}
|
|
837
|
+
function resolveCrossSiteLink(url, linkedHostnames, now = Date.now()) {
|
|
838
|
+
if (typeof window === "undefined" || linkedHostnames.length === 0) return null;
|
|
839
|
+
let target;
|
|
840
|
+
try {
|
|
841
|
+
target = new URL(url, window.location.href);
|
|
842
|
+
} catch {
|
|
843
|
+
return null;
|
|
844
|
+
}
|
|
845
|
+
if (target.protocol !== "http:" && target.protocol !== "https:") return null;
|
|
846
|
+
const here = window.location.hostname;
|
|
847
|
+
if (here && isSiblingHost(target.hostname, here)) return null;
|
|
848
|
+
const hostname = linkedHostnames.find((sibling) => isSiblingHost(target.hostname, sibling));
|
|
849
|
+
if (hostname === void 0) return null;
|
|
850
|
+
const consent = getConsentChoice();
|
|
851
|
+
if (consent.state === "denied" && consent.source === "explicit") {
|
|
852
|
+
return { hostname, decorated: url };
|
|
853
|
+
}
|
|
854
|
+
target.searchParams.set(LINK_PARAM, buildOutboundLinkToken(now));
|
|
855
|
+
return { hostname, decorated: target.href };
|
|
856
|
+
}
|
|
857
|
+
function stripLinkParam(url) {
|
|
858
|
+
try {
|
|
859
|
+
const parsed = new URL(url, typeof window === "undefined" ? void 0 : window.location.href);
|
|
860
|
+
if (!parsed.searchParams.has(LINK_PARAM)) return url;
|
|
861
|
+
parsed.searchParams.delete(LINK_PARAM);
|
|
862
|
+
return parsed.href;
|
|
863
|
+
} catch {
|
|
864
|
+
return url;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
function stripLinkParamFromSearch(search) {
|
|
868
|
+
if (!search.includes(LINK_PARAM)) return search;
|
|
869
|
+
const params = new URLSearchParams(search);
|
|
870
|
+
if (!params.has(LINK_PARAM)) return search;
|
|
871
|
+
params.delete(LINK_PARAM);
|
|
872
|
+
const rest = params.toString();
|
|
873
|
+
return rest.length > 0 ? `?${rest}` : "";
|
|
874
|
+
}
|
|
875
|
+
function readCarried() {
|
|
876
|
+
const out = {};
|
|
877
|
+
for (const [wire, param] of CARRIED_ENTRIES) {
|
|
878
|
+
const value = readCookieValue(param);
|
|
879
|
+
if (value) out[wire] = value;
|
|
880
|
+
}
|
|
881
|
+
return out;
|
|
882
|
+
}
|
|
883
|
+
function buildOutboundLinkToken(now = Date.now()) {
|
|
884
|
+
const fbc = getFbcCookie();
|
|
885
|
+
return encodeLinkToken({
|
|
886
|
+
v: getVisitorId(),
|
|
887
|
+
s: getOrRotateSessionId(now).id,
|
|
888
|
+
t: now.toString(36),
|
|
889
|
+
...readCarried(),
|
|
890
|
+
...fbc ? { fc: fbc } : {}
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
function decorateCrossSiteUrl(url, linkedHostnames, now = Date.now()) {
|
|
894
|
+
return resolveCrossSiteLink(url, linkedHostnames, now)?.decorated ?? url;
|
|
895
|
+
}
|
|
896
|
+
function consumeInboundLink(href = typeof window === "undefined" ? "" : window.location.href, now = Date.now()) {
|
|
897
|
+
if (typeof window === "undefined" || !href) return null;
|
|
898
|
+
let raw;
|
|
899
|
+
try {
|
|
900
|
+
raw = new URL(href, window.location.href).searchParams.get(LINK_PARAM);
|
|
901
|
+
} catch {
|
|
902
|
+
return null;
|
|
903
|
+
}
|
|
904
|
+
if (!raw) return null;
|
|
905
|
+
const payload = decodeLinkToken(raw);
|
|
906
|
+
if (payload === null) return { outcome: "invalid", link: null, adoptedVisitor: false };
|
|
907
|
+
const link = payloadToLink(payload);
|
|
908
|
+
const age = now - link.linkedAt;
|
|
909
|
+
if (!Number.isFinite(age) || age < -FUTURE_SKEW_MS) {
|
|
910
|
+
return { outcome: "invalid", link: null, adoptedVisitor: false };
|
|
911
|
+
}
|
|
912
|
+
if (age > LINK_TOKEN_TTL_MS) {
|
|
913
|
+
return { outcome: "stale", link: null, adoptedVisitor: false };
|
|
914
|
+
}
|
|
915
|
+
const adoptedVisitor = adoptVisitorId(link.visitorId);
|
|
916
|
+
for (const [param, value] of Object.entries(link.carried)) {
|
|
917
|
+
if (!readCookieValue(param)) setTrackingCookie(param, value);
|
|
918
|
+
}
|
|
919
|
+
if (link.fbc && !getFbcCookie()) persistCookieValue(FBC_COOKIE, link.fbc);
|
|
920
|
+
return { outcome: "linked", link, adoptedVisitor };
|
|
921
|
+
}
|
|
922
|
+
function stripLinkParamFromLocation() {
|
|
923
|
+
if (typeof window === "undefined" || typeof history === "undefined") return;
|
|
924
|
+
const clean = stripLinkParam(window.location.href);
|
|
925
|
+
if (clean === window.location.href) return;
|
|
926
|
+
try {
|
|
927
|
+
history.replaceState(null, "", clean);
|
|
928
|
+
} catch {
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
|
|
690
932
|
// ../tracking-core/src/resources/conversion-firing.ts
|
|
691
933
|
var DEDUP_PREFIX = "_aranova_conv_";
|
|
692
934
|
function dedupKey(input) {
|
|
@@ -793,7 +1035,8 @@ function parseConversionConfig(raw) {
|
|
|
793
1035
|
gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
|
|
794
1036
|
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
795
1037
|
services,
|
|
796
|
-
goals
|
|
1038
|
+
goals,
|
|
1039
|
+
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : []
|
|
797
1040
|
};
|
|
798
1041
|
}
|
|
799
1042
|
var CACHE_PREFIX = "_aranova_cfg_";
|
|
@@ -877,6 +1120,7 @@ function resolveConversionConfig(options) {
|
|
|
877
1120
|
getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
|
|
878
1121
|
getGoal: (key) => goalsByKey.get(key) ?? null,
|
|
879
1122
|
listGoals: () => [...goalsByKey.values()],
|
|
1123
|
+
linkedHostnames: () => current?.linked_hostnames ?? [],
|
|
880
1124
|
current: () => current,
|
|
881
1125
|
isReady: () => current !== null,
|
|
882
1126
|
onResolve: (listener) => {
|
|
@@ -1061,7 +1305,7 @@ function validateConfig(config, ref) {
|
|
|
1061
1305
|
function pageViewSnapshot() {
|
|
1062
1306
|
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
1063
1307
|
return {
|
|
1064
|
-
href: window.location.href,
|
|
1308
|
+
href: stripLinkParam(window.location.href),
|
|
1065
1309
|
title: document.title || null,
|
|
1066
1310
|
referrer: document.referrer || null
|
|
1067
1311
|
};
|
|
@@ -1212,6 +1456,10 @@ var TrackingConfigRuntime = class {
|
|
|
1212
1456
|
listGoals() {
|
|
1213
1457
|
return this.current?.goals ?? [];
|
|
1214
1458
|
}
|
|
1459
|
+
/** Sibling hostnames for the linker — read from the cached object even while unconfirmed. */
|
|
1460
|
+
linkedHostnames() {
|
|
1461
|
+
return this.current?.linked_hostnames ?? [];
|
|
1462
|
+
}
|
|
1215
1463
|
async revalidateNow() {
|
|
1216
1464
|
try {
|
|
1217
1465
|
const headers = {};
|
|
@@ -1449,83 +1697,32 @@ function withConversionAutoFire(client, autoFire) {
|
|
|
1449
1697
|
};
|
|
1450
1698
|
}
|
|
1451
1699
|
|
|
1452
|
-
// ../tracking-core/src/session.ts
|
|
1453
|
-
var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
|
|
1454
|
-
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
1455
|
-
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
1456
|
-
function safeUuid() {
|
|
1457
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
|
|
1458
|
-
return crypto.randomUUID();
|
|
1459
|
-
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
|
|
1460
|
-
}
|
|
1461
|
-
function readLocalStorage(key) {
|
|
1462
|
-
try {
|
|
1463
|
-
return window.localStorage.getItem(key);
|
|
1464
|
-
} catch {
|
|
1465
|
-
return null;
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
function writeLocalStorage(key, value) {
|
|
1469
|
-
try {
|
|
1470
|
-
window.localStorage.setItem(key, value);
|
|
1471
|
-
} catch {
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
function getVisitorId() {
|
|
1475
|
-
if (typeof window === "undefined") return safeUuid();
|
|
1476
|
-
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
1477
|
-
if (existing && existing.length > 0) return existing;
|
|
1478
|
-
const fresh = safeUuid();
|
|
1479
|
-
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
1480
|
-
return fresh;
|
|
1481
|
-
}
|
|
1482
|
-
function getOrRotateSessionId(now = Date.now()) {
|
|
1483
|
-
if (typeof window === "undefined") return { id: safeUuid(), isNew: true };
|
|
1484
|
-
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
1485
|
-
if (raw) {
|
|
1486
|
-
try {
|
|
1487
|
-
const parsed = JSON.parse(raw);
|
|
1488
|
-
if (typeof parsed.id === "string" && typeof parsed.last_event_at === "number") {
|
|
1489
|
-
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
1490
|
-
const refreshed = { id: parsed.id, last_event_at: now };
|
|
1491
|
-
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
1492
|
-
return { id: parsed.id, isNew: false };
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
} catch {
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
const fresh = { id: safeUuid(), last_event_at: now };
|
|
1499
|
-
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
1500
|
-
return { id: fresh.id, isNew: true };
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
1700
|
// ../tracking-core/src/page-view.ts
|
|
1504
1701
|
var import_mini = require("zod/mini");
|
|
1505
1702
|
|
|
1506
1703
|
// ../tracking-core/src/events/page-view.ts
|
|
1507
|
-
var
|
|
1508
|
-
var pageViewMetadataSchema =
|
|
1509
|
-
page:
|
|
1510
|
-
title:
|
|
1511
|
-
path:
|
|
1512
|
-
search:
|
|
1513
|
-
hash:
|
|
1704
|
+
var z2 = __toESM(require("zod/mini"));
|
|
1705
|
+
var pageViewMetadataSchema = z2.strictObject({
|
|
1706
|
+
page: z2.strictObject({
|
|
1707
|
+
title: z2.nullable(z2.string()),
|
|
1708
|
+
path: z2.string(),
|
|
1709
|
+
search: z2.string(),
|
|
1710
|
+
hash: z2.string()
|
|
1514
1711
|
}),
|
|
1515
|
-
referrer:
|
|
1712
|
+
referrer: z2.nullable(z2.string()),
|
|
1516
1713
|
// Optional + nullable — absent (undefined) OR explicit null OR a
|
|
1517
1714
|
// real viewport object. Mirrors Pydantic's `_Viewport | None = None`
|
|
1518
1715
|
// on the backend side so the drift test stays clean.
|
|
1519
|
-
viewport:
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
w:
|
|
1523
|
-
h:
|
|
1716
|
+
viewport: z2.optional(
|
|
1717
|
+
z2.nullable(
|
|
1718
|
+
z2.strictObject({
|
|
1719
|
+
w: z2.number(),
|
|
1720
|
+
h: z2.number()
|
|
1524
1721
|
})
|
|
1525
1722
|
)
|
|
1526
1723
|
)
|
|
1527
1724
|
});
|
|
1528
|
-
var pageViewConfigSchema =
|
|
1725
|
+
var pageViewConfigSchema = z2.strictObject({});
|
|
1529
1726
|
|
|
1530
1727
|
// ../tracking-core/src/page-view.ts
|
|
1531
1728
|
var LAST_FIRED_URL_STORAGE_KEY = "aranova_tracking_last_fired_url";
|
|
@@ -1565,7 +1762,7 @@ function buildPageViewMetadata(referrerOverride) {
|
|
|
1565
1762
|
page: {
|
|
1566
1763
|
title: document.title || null,
|
|
1567
1764
|
path: window.location.pathname,
|
|
1568
|
-
search: window.location.search,
|
|
1765
|
+
search: stripLinkParamFromSearch(window.location.search),
|
|
1569
1766
|
hash: window.location.hash
|
|
1570
1767
|
},
|
|
1571
1768
|
referrer: referrerOverride !== void 0 ? referrerOverride : document.referrer || null,
|
|
@@ -1864,11 +2061,19 @@ function createTrackingClient(config) {
|
|
|
1864
2061
|
let firstPage = null;
|
|
1865
2062
|
let initialParams = createEmptyTrackingParams();
|
|
1866
2063
|
let destroyed = false;
|
|
2064
|
+
let inboundLink = null;
|
|
2065
|
+
if (typeof window !== "undefined") {
|
|
2066
|
+
try {
|
|
2067
|
+
inboundLink = consumeInboundLink();
|
|
2068
|
+
} catch {
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
let originLink = inboundLink?.link ?? null;
|
|
1867
2072
|
const visitorId = getVisitorId();
|
|
1868
2073
|
const initialSession = getOrRotateSessionId();
|
|
1869
2074
|
let sessionId = initialSession.id;
|
|
1870
2075
|
if (typeof window !== "undefined") {
|
|
1871
|
-
firstPage = window.location.href;
|
|
2076
|
+
firstPage = stripLinkParam(window.location.href);
|
|
1872
2077
|
try {
|
|
1873
2078
|
initialParams = captureTrackingParamsFromLocation();
|
|
1874
2079
|
} catch {
|
|
@@ -1879,25 +2084,50 @@ function createTrackingClient(config) {
|
|
|
1879
2084
|
} catch {
|
|
1880
2085
|
}
|
|
1881
2086
|
}
|
|
1882
|
-
function
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
packageName,
|
|
1887
|
-
config.triggers ?? null,
|
|
1888
|
-
activeGtagIds,
|
|
1889
|
-
config.configSiteId ?? null
|
|
1890
|
-
);
|
|
2087
|
+
function currentPageUrl() {
|
|
2088
|
+
return typeof window === "undefined" ? null : stripLinkParam(window.location.href);
|
|
2089
|
+
}
|
|
2090
|
+
function enqueueInternal(eventType, metadata, pageUrl) {
|
|
1891
2091
|
queue.push({
|
|
1892
|
-
event_type:
|
|
1893
|
-
page_url:
|
|
2092
|
+
event_type: eventType,
|
|
2093
|
+
page_url: pageUrl,
|
|
1894
2094
|
metadata,
|
|
1895
2095
|
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1896
2096
|
});
|
|
1897
2097
|
}
|
|
2098
|
+
function enqueueHeartbeat() {
|
|
2099
|
+
enqueueInternal(
|
|
2100
|
+
"sdk_heartbeat",
|
|
2101
|
+
buildHeartbeatMetadata(
|
|
2102
|
+
config.surface,
|
|
2103
|
+
sdkVersion,
|
|
2104
|
+
packageName,
|
|
2105
|
+
config.triggers ?? null,
|
|
2106
|
+
activeGtagIds,
|
|
2107
|
+
config.configSiteId ?? null
|
|
2108
|
+
),
|
|
2109
|
+
currentPageUrl()
|
|
2110
|
+
);
|
|
2111
|
+
}
|
|
1898
2112
|
if (initialSession.isNew) {
|
|
1899
2113
|
enqueueHeartbeat();
|
|
1900
2114
|
}
|
|
2115
|
+
if (inboundLink !== null && typeof window !== "undefined") {
|
|
2116
|
+
const link = inboundLink.link;
|
|
2117
|
+
enqueueInternal(
|
|
2118
|
+
"site_link_arrival",
|
|
2119
|
+
{
|
|
2120
|
+
outcome: inboundLink.outcome,
|
|
2121
|
+
origin_session_id: link?.sessionId ?? null,
|
|
2122
|
+
origin_visitor_id: link?.visitorId ?? null,
|
|
2123
|
+
transit_ms: link ? Math.max(0, Date.now() - link.linkedAt) : null,
|
|
2124
|
+
adopted_visitor: inboundLink.adoptedVisitor,
|
|
2125
|
+
page: { path: window.location.pathname }
|
|
2126
|
+
},
|
|
2127
|
+
firstPage
|
|
2128
|
+
);
|
|
2129
|
+
scheduleFlush();
|
|
2130
|
+
}
|
|
1901
2131
|
if (pending.length > 0) {
|
|
1902
2132
|
scheduleFlush();
|
|
1903
2133
|
}
|
|
@@ -1905,6 +2135,7 @@ function createTrackingClient(config) {
|
|
|
1905
2135
|
const rotated = getOrRotateSessionId();
|
|
1906
2136
|
if (rotated.isNew && rotated.id !== sessionId) {
|
|
1907
2137
|
enqueueHeartbeat();
|
|
2138
|
+
originLink = null;
|
|
1908
2139
|
}
|
|
1909
2140
|
sessionId = rotated.id;
|
|
1910
2141
|
const params = mergeTrackingParams(readTrackingParams(), initialParams);
|
|
@@ -1935,6 +2166,11 @@ function createTrackingClient(config) {
|
|
|
1935
2166
|
// landing), reused from the stored record otherwise. Keys are omitted
|
|
1936
2167
|
// entirely when the landing isn't observable (SSR).
|
|
1937
2168
|
...buildLandingPayloadFields(sessionId),
|
|
2169
|
+
...originLink ? {
|
|
2170
|
+
origin_session_id: originLink.sessionId,
|
|
2171
|
+
origin_visitor_id: originLink.visitorId,
|
|
2172
|
+
origin_linked_at: new Date(originLink.linkedAt).toISOString()
|
|
2173
|
+
} : {},
|
|
1938
2174
|
first_page: firstPage,
|
|
1939
2175
|
consent_state: consentSnapshot(),
|
|
1940
2176
|
context
|
|
@@ -2011,7 +2247,8 @@ function createTrackingClient(config) {
|
|
|
2011
2247
|
const occurredAt = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : typeof input.occurredAt === "string" ? input.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
2012
2248
|
queue.push({
|
|
2013
2249
|
event_type: input.eventType,
|
|
2014
|
-
|
|
2250
|
+
// A caller's href still carries `_arv` until the surface strips it after hydration.
|
|
2251
|
+
page_url: input.pageUrl != null ? stripLinkParam(input.pageUrl) : currentPageUrl(),
|
|
2015
2252
|
metadata: input.metadata ?? null,
|
|
2016
2253
|
occurred_at: occurredAt
|
|
2017
2254
|
});
|
|
@@ -2061,112 +2298,112 @@ function createTrackingClient(config) {
|
|
|
2061
2298
|
var import_mini2 = require("zod/mini");
|
|
2062
2299
|
|
|
2063
2300
|
// ../tracking-core/src/events/cta-click.ts
|
|
2064
|
-
var
|
|
2065
|
-
var ctaClickMetadataSchema =
|
|
2066
|
-
cta_name:
|
|
2067
|
-
page:
|
|
2068
|
-
path:
|
|
2301
|
+
var z3 = __toESM(require("zod/mini"));
|
|
2302
|
+
var ctaClickMetadataSchema = z3.strictObject({
|
|
2303
|
+
cta_name: z3.string(),
|
|
2304
|
+
page: z3.strictObject({
|
|
2305
|
+
path: z3.string()
|
|
2069
2306
|
}),
|
|
2070
|
-
section:
|
|
2071
|
-
destination_url:
|
|
2307
|
+
section: z3.optional(z3.nullable(z3.string())),
|
|
2308
|
+
destination_url: z3.optional(z3.nullable(z3.string())),
|
|
2072
2309
|
// Set by auto-capture (and available to manual callers): the link target
|
|
2073
2310
|
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
2074
|
-
href:
|
|
2075
|
-
element:
|
|
2311
|
+
href: z3.optional(z3.nullable(z3.string())),
|
|
2312
|
+
element: z3.optional(z3.nullable(z3.string()))
|
|
2076
2313
|
});
|
|
2077
|
-
var ctaClickConfigSchema =
|
|
2078
|
-
autoCapture:
|
|
2079
|
-
|
|
2080
|
-
selector:
|
|
2314
|
+
var ctaClickConfigSchema = z3.strictObject({
|
|
2315
|
+
autoCapture: z3.optional(
|
|
2316
|
+
z3.strictObject({
|
|
2317
|
+
selector: z3.optional(z3.string())
|
|
2081
2318
|
})
|
|
2082
2319
|
)
|
|
2083
2320
|
});
|
|
2084
2321
|
|
|
2085
2322
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
2086
|
-
var
|
|
2087
|
-
var sdkHeartbeatTriggersSchema =
|
|
2088
|
-
automatic:
|
|
2089
|
-
manual:
|
|
2323
|
+
var z4 = __toESM(require("zod/mini"));
|
|
2324
|
+
var sdkHeartbeatTriggersSchema = z4.strictObject({
|
|
2325
|
+
automatic: z4.array(z4.string()),
|
|
2326
|
+
manual: z4.array(z4.string())
|
|
2090
2327
|
});
|
|
2091
|
-
var sdkHeartbeatMetadataSchema =
|
|
2092
|
-
sdk_version:
|
|
2093
|
-
package_name:
|
|
2094
|
-
surface:
|
|
2328
|
+
var sdkHeartbeatMetadataSchema = z4.strictObject({
|
|
2329
|
+
sdk_version: z4.string(),
|
|
2330
|
+
package_name: z4.nullable(z4.string()),
|
|
2331
|
+
surface: z4.enum(["next", "react", "script"]),
|
|
2095
2332
|
triggers: sdkHeartbeatTriggersSchema,
|
|
2096
|
-
trigger_config:
|
|
2097
|
-
configured_gtag_ids:
|
|
2333
|
+
trigger_config: z4.optional(z4.nullable(z4.record(z4.string(), z4.record(z4.string(), z4.unknown())))),
|
|
2334
|
+
configured_gtag_ids: z4.optional(z4.nullable(z4.record(z4.string(), z4.string()))),
|
|
2098
2335
|
// Site whose config object the SDK resolves; null on a legacy business ref.
|
|
2099
|
-
config_site_id:
|
|
2336
|
+
config_site_id: z4.optional(z4.nullable(z4.uuid()))
|
|
2100
2337
|
});
|
|
2101
|
-
var sdkHeartbeatConfigSchema =
|
|
2338
|
+
var sdkHeartbeatConfigSchema = z4.strictObject({});
|
|
2102
2339
|
|
|
2103
2340
|
// ../tracking-core/src/events/form-start.ts
|
|
2104
|
-
var
|
|
2105
|
-
var formStartMetadataSchema =
|
|
2106
|
-
form:
|
|
2107
|
-
id:
|
|
2108
|
-
action:
|
|
2341
|
+
var z5 = __toESM(require("zod/mini"));
|
|
2342
|
+
var formStartMetadataSchema = z5.strictObject({
|
|
2343
|
+
form: z5.strictObject({
|
|
2344
|
+
id: z5.string(),
|
|
2345
|
+
action: z5.nullable(z5.string())
|
|
2109
2346
|
}),
|
|
2110
|
-
page:
|
|
2111
|
-
path:
|
|
2347
|
+
page: z5.strictObject({
|
|
2348
|
+
path: z5.string()
|
|
2112
2349
|
})
|
|
2113
2350
|
});
|
|
2114
|
-
var formStartConfigSchema =
|
|
2115
|
-
selector:
|
|
2351
|
+
var formStartConfigSchema = z5.strictObject({
|
|
2352
|
+
selector: z5.optional(z5.string())
|
|
2116
2353
|
});
|
|
2117
2354
|
|
|
2118
2355
|
// ../tracking-core/src/events/form-submit.ts
|
|
2119
|
-
var
|
|
2120
|
-
var jsonValueSchema =
|
|
2121
|
-
() =>
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2356
|
+
var z6 = __toESM(require("zod/mini"));
|
|
2357
|
+
var jsonValueSchema = z6.lazy(
|
|
2358
|
+
() => z6.union([
|
|
2359
|
+
z6.string(),
|
|
2360
|
+
z6.number(),
|
|
2361
|
+
z6.boolean(),
|
|
2362
|
+
z6.null(),
|
|
2363
|
+
z6.array(jsonValueSchema),
|
|
2364
|
+
z6.record(z6.string(), jsonValueSchema)
|
|
2128
2365
|
])
|
|
2129
|
-
).register(
|
|
2130
|
-
var formSubmitMetadataSchema =
|
|
2131
|
-
form:
|
|
2132
|
-
id:
|
|
2133
|
-
action:
|
|
2134
|
-
fields:
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
name:
|
|
2138
|
-
type:
|
|
2139
|
-
label:
|
|
2366
|
+
).register(z6.globalRegistry, { id: "JsonSerializableValue" });
|
|
2367
|
+
var formSubmitMetadataSchema = z6.strictObject({
|
|
2368
|
+
form: z6.strictObject({
|
|
2369
|
+
id: z6.string(),
|
|
2370
|
+
action: z6.nullable(z6.string()),
|
|
2371
|
+
fields: z6.optional(
|
|
2372
|
+
z6.array(
|
|
2373
|
+
z6.strictObject({
|
|
2374
|
+
name: z6.string(),
|
|
2375
|
+
type: z6.string(),
|
|
2376
|
+
label: z6.nullable(z6.string()),
|
|
2140
2377
|
value: jsonValueSchema
|
|
2141
2378
|
})
|
|
2142
2379
|
)
|
|
2143
2380
|
)
|
|
2144
2381
|
}),
|
|
2145
|
-
page:
|
|
2146
|
-
path:
|
|
2382
|
+
page: z6.strictObject({
|
|
2383
|
+
path: z6.string()
|
|
2147
2384
|
})
|
|
2148
2385
|
});
|
|
2149
|
-
var formSubmitConfigSchema =
|
|
2386
|
+
var formSubmitConfigSchema = z6.strictObject({});
|
|
2150
2387
|
|
|
2151
2388
|
// ../tracking-core/src/events/multi-page-session.ts
|
|
2152
|
-
var
|
|
2153
|
-
var multiPageSessionMetadataSchema =
|
|
2154
|
-
page_count:
|
|
2155
|
-
page:
|
|
2156
|
-
path:
|
|
2389
|
+
var z7 = __toESM(require("zod/mini"));
|
|
2390
|
+
var multiPageSessionMetadataSchema = z7.strictObject({
|
|
2391
|
+
page_count: z7.int().check(z7.gte(2)),
|
|
2392
|
+
page: z7.strictObject({
|
|
2393
|
+
path: z7.string()
|
|
2157
2394
|
})
|
|
2158
2395
|
});
|
|
2159
|
-
var multiPageSessionConfigSchema =
|
|
2160
|
-
pageThreshold:
|
|
2396
|
+
var multiPageSessionConfigSchema = z7.strictObject({
|
|
2397
|
+
pageThreshold: z7.int().check(z7.gte(2))
|
|
2161
2398
|
});
|
|
2162
2399
|
|
|
2163
2400
|
// ../tracking-core/src/events/page-exit.ts
|
|
2164
|
-
var
|
|
2165
|
-
var pageExitMetadataSchema =
|
|
2166
|
-
dwell_ms:
|
|
2401
|
+
var z8 = __toESM(require("zod/mini"));
|
|
2402
|
+
var pageExitMetadataSchema = z8.strictObject({
|
|
2403
|
+
dwell_ms: z8.int().check(z8.gte(0)),
|
|
2167
2404
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
2168
2405
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
2169
|
-
max_scroll_percent:
|
|
2406
|
+
max_scroll_percent: z8.nullable(z8.int().check(z8.gte(0), z8.lte(100))),
|
|
2170
2407
|
// The gating baseline: the fraction of the page visible at load with
|
|
2171
2408
|
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
2172
2409
|
// (skeleton/streaming renders), the first-scroll position that
|
|
@@ -2174,80 +2411,104 @@ var pageExitMetadataSchema = z7.strictObject({
|
|
|
2174
2411
|
// ended before the snapshot. Optionality is load-bearing: SDK builds
|
|
2175
2412
|
// predating this field keep POSTing page_exit without the key —
|
|
2176
2413
|
// requiring it would 422 whole keepalive beacon batches.
|
|
2177
|
-
scroll_baseline_percent:
|
|
2178
|
-
page:
|
|
2179
|
-
path:
|
|
2414
|
+
scroll_baseline_percent: z8.optional(z8.nullable(z8.int().check(z8.gte(0), z8.lte(100)))),
|
|
2415
|
+
page: z8.strictObject({
|
|
2416
|
+
path: z8.string()
|
|
2180
2417
|
})
|
|
2181
2418
|
});
|
|
2182
|
-
var pageExitConfigSchema =
|
|
2419
|
+
var pageExitConfigSchema = z8.strictObject({});
|
|
2183
2420
|
|
|
2184
2421
|
// ../tracking-core/src/events/phone-click.ts
|
|
2185
|
-
var
|
|
2186
|
-
var phoneClickMetadataSchema =
|
|
2187
|
-
phone_number:
|
|
2188
|
-
page:
|
|
2189
|
-
path:
|
|
2422
|
+
var z9 = __toESM(require("zod/mini"));
|
|
2423
|
+
var phoneClickMetadataSchema = z9.strictObject({
|
|
2424
|
+
phone_number: z9.string(),
|
|
2425
|
+
page: z9.strictObject({
|
|
2426
|
+
path: z9.string()
|
|
2190
2427
|
}),
|
|
2191
|
-
section:
|
|
2428
|
+
section: z9.optional(z9.nullable(z9.string()))
|
|
2192
2429
|
});
|
|
2193
|
-
var phoneClickConfigSchema =
|
|
2194
|
-
autoCapture:
|
|
2195
|
-
|
|
2196
|
-
selector:
|
|
2430
|
+
var phoneClickConfigSchema = z9.strictObject({
|
|
2431
|
+
autoCapture: z9.optional(
|
|
2432
|
+
z9.strictObject({
|
|
2433
|
+
selector: z9.optional(z9.string())
|
|
2197
2434
|
})
|
|
2198
2435
|
)
|
|
2199
2436
|
});
|
|
2200
2437
|
|
|
2201
2438
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
2202
|
-
var
|
|
2203
|
-
var scrollDepthMetadataSchema =
|
|
2204
|
-
depth_percent:
|
|
2205
|
-
page:
|
|
2206
|
-
path:
|
|
2439
|
+
var z10 = __toESM(require("zod/mini"));
|
|
2440
|
+
var scrollDepthMetadataSchema = z10.strictObject({
|
|
2441
|
+
depth_percent: z10.int().check(z10.gte(1), z10.lte(100)),
|
|
2442
|
+
page: z10.strictObject({
|
|
2443
|
+
path: z10.string()
|
|
2207
2444
|
})
|
|
2208
2445
|
});
|
|
2209
|
-
var scrollDepthConfigSchema =
|
|
2210
|
-
thresholds:
|
|
2446
|
+
var scrollDepthConfigSchema = z10.strictObject({
|
|
2447
|
+
thresholds: z10.array(z10.int().check(z10.gte(1), z10.lte(100))).check(z10.minLength(1))
|
|
2211
2448
|
});
|
|
2212
2449
|
|
|
2213
2450
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
2214
|
-
var
|
|
2451
|
+
var z11 = __toESM(require("zod/mini"));
|
|
2215
2452
|
var PAGE_IDENTITY_MAX_LENGTH = 64;
|
|
2216
2453
|
var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
|
|
2217
|
-
var pageIdentitySchema =
|
|
2218
|
-
|
|
2219
|
-
|
|
2454
|
+
var pageIdentitySchema = z11.string().check(
|
|
2455
|
+
z11.maxLength(PAGE_IDENTITY_MAX_LENGTH),
|
|
2456
|
+
z11.regex(PAGE_IDENTITY_PATTERN, {
|
|
2220
2457
|
message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
|
|
2221
2458
|
})
|
|
2222
2459
|
);
|
|
2223
2460
|
var specificPageNameSchema = pageIdentitySchema;
|
|
2224
|
-
var specificPageVisitMetadataSchema =
|
|
2461
|
+
var specificPageVisitMetadataSchema = z11.strictObject({
|
|
2225
2462
|
page_name: specificPageNameSchema,
|
|
2226
|
-
page:
|
|
2227
|
-
path:
|
|
2463
|
+
page: z11.strictObject({
|
|
2464
|
+
path: z11.string()
|
|
2228
2465
|
})
|
|
2229
2466
|
});
|
|
2230
|
-
var specificPageVisitConfigSchema =
|
|
2231
|
-
pages:
|
|
2232
|
-
|
|
2467
|
+
var specificPageVisitConfigSchema = z11.strictObject({
|
|
2468
|
+
pages: z11.array(
|
|
2469
|
+
z11.strictObject({
|
|
2233
2470
|
name: specificPageNameSchema,
|
|
2234
|
-
pathPattern:
|
|
2471
|
+
pathPattern: z11.custom((value) => value instanceof RegExp, {
|
|
2235
2472
|
message: "pathPattern must be a RegExp"
|
|
2236
2473
|
})
|
|
2237
2474
|
})
|
|
2238
|
-
).check(
|
|
2475
|
+
).check(z11.minLength(1))
|
|
2239
2476
|
});
|
|
2240
2477
|
|
|
2478
|
+
// ../tracking-core/src/events/site-link.ts
|
|
2479
|
+
var z12 = __toESM(require("zod/mini"));
|
|
2480
|
+
var siteLinkClickMetadataSchema = z12.strictObject({
|
|
2481
|
+
destination_host: z12.string(),
|
|
2482
|
+
destination_url: z12.string(),
|
|
2483
|
+
page: z12.strictObject({
|
|
2484
|
+
path: z12.string()
|
|
2485
|
+
})
|
|
2486
|
+
});
|
|
2487
|
+
var siteLinkClickConfigSchema = z12.strictObject({});
|
|
2488
|
+
var siteLinkArrivalMetadataSchema = z12.strictObject({
|
|
2489
|
+
outcome: z12.enum(["linked", "stale", "invalid"]),
|
|
2490
|
+
origin_session_id: z12.optional(z12.nullable(z12.string())),
|
|
2491
|
+
origin_visitor_id: z12.optional(z12.nullable(z12.string())),
|
|
2492
|
+
// Milliseconds between the origin click and this page load.
|
|
2493
|
+
transit_ms: z12.optional(z12.nullable(z12.number())),
|
|
2494
|
+
// True when this browser had no visitor id and took the origin's.
|
|
2495
|
+
adopted_visitor: z12.boolean(),
|
|
2496
|
+
page: z12.strictObject({
|
|
2497
|
+
path: z12.string()
|
|
2498
|
+
})
|
|
2499
|
+
});
|
|
2500
|
+
var siteLinkArrivalConfigSchema = z12.strictObject({});
|
|
2501
|
+
|
|
2241
2502
|
// ../tracking-core/src/events/time-on-site.ts
|
|
2242
|
-
var
|
|
2243
|
-
var timeOnSiteMetadataSchema =
|
|
2244
|
-
duration_ms:
|
|
2245
|
-
page:
|
|
2246
|
-
path:
|
|
2503
|
+
var z13 = __toESM(require("zod/mini"));
|
|
2504
|
+
var timeOnSiteMetadataSchema = z13.strictObject({
|
|
2505
|
+
duration_ms: z13.int().check(z13.nonnegative()),
|
|
2506
|
+
page: z13.strictObject({
|
|
2507
|
+
path: z13.string()
|
|
2247
2508
|
})
|
|
2248
2509
|
});
|
|
2249
|
-
var timeOnSiteConfigSchema =
|
|
2250
|
-
thresholdSeconds:
|
|
2510
|
+
var timeOnSiteConfigSchema = z13.strictObject({
|
|
2511
|
+
thresholdSeconds: z13.int().check(z13.positive())
|
|
2251
2512
|
});
|
|
2252
2513
|
|
|
2253
2514
|
// ../tracking-core/src/events/semantics.ts
|
|
@@ -2317,6 +2578,18 @@ var EVENT_SEMANTICS = {
|
|
|
2317
2578
|
category: "engagement",
|
|
2318
2579
|
outcomeRole: "engagement",
|
|
2319
2580
|
clientVisibility: "simple"
|
|
2581
|
+
},
|
|
2582
|
+
site_link_click: {
|
|
2583
|
+
label: "Left for sibling site",
|
|
2584
|
+
category: "page",
|
|
2585
|
+
outcomeRole: "navigation",
|
|
2586
|
+
clientVisibility: "detailed"
|
|
2587
|
+
},
|
|
2588
|
+
site_link_arrival: {
|
|
2589
|
+
label: "Arrived from sibling site",
|
|
2590
|
+
category: "page",
|
|
2591
|
+
outcomeRole: "navigation",
|
|
2592
|
+
clientVisibility: "simple"
|
|
2320
2593
|
}
|
|
2321
2594
|
};
|
|
2322
2595
|
|
|
@@ -2372,6 +2645,20 @@ var EVENT_REGISTRY = {
|
|
|
2372
2645
|
metadataSchema: pageExitMetadataSchema,
|
|
2373
2646
|
configSchema: pageExitConfigSchema
|
|
2374
2647
|
},
|
|
2648
|
+
// Cross-site linkage: emitted by the linker (roster comes from the site
|
|
2649
|
+
// config, not the trigger registry), so neither is consumer-configurable.
|
|
2650
|
+
site_link_click: {
|
|
2651
|
+
kind: "automatic",
|
|
2652
|
+
semantics: EVENT_SEMANTICS.site_link_click,
|
|
2653
|
+
metadataSchema: siteLinkClickMetadataSchema,
|
|
2654
|
+
configSchema: siteLinkClickConfigSchema
|
|
2655
|
+
},
|
|
2656
|
+
site_link_arrival: {
|
|
2657
|
+
kind: "automatic",
|
|
2658
|
+
semantics: EVENT_SEMANTICS.site_link_arrival,
|
|
2659
|
+
metadataSchema: siteLinkArrivalMetadataSchema,
|
|
2660
|
+
configSchema: siteLinkArrivalConfigSchema
|
|
2661
|
+
},
|
|
2375
2662
|
// --- manual triggers ---
|
|
2376
2663
|
form_submit: {
|
|
2377
2664
|
kind: "manual",
|
|
@@ -2977,6 +3264,57 @@ function attachCtaClickCapture(client, config) {
|
|
|
2977
3264
|
};
|
|
2978
3265
|
}
|
|
2979
3266
|
|
|
3267
|
+
// ../tracking-core/src/triggers/site-link-capture.ts
|
|
3268
|
+
function anchorFrom(target) {
|
|
3269
|
+
if (!(target instanceof Element)) return null;
|
|
3270
|
+
const anchor = target.closest("a[href]");
|
|
3271
|
+
return anchor instanceof HTMLAnchorElement ? anchor : null;
|
|
3272
|
+
}
|
|
3273
|
+
function opensTheLink(event) {
|
|
3274
|
+
return event.button === 0 || event.button === 1;
|
|
3275
|
+
}
|
|
3276
|
+
function attachSiteLinkCapture(client, options) {
|
|
3277
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
3278
|
+
return () => {
|
|
3279
|
+
};
|
|
3280
|
+
}
|
|
3281
|
+
registerCapability("cross_site_linker");
|
|
3282
|
+
function hopFrom(event) {
|
|
3283
|
+
const anchor = anchorFrom(event.target);
|
|
3284
|
+
if (anchor === null) return null;
|
|
3285
|
+
const link = resolveCrossSiteLink(anchor.href, options.linkedHostnames());
|
|
3286
|
+
return link === null ? null : { anchor, link };
|
|
3287
|
+
}
|
|
3288
|
+
function onPointerDown(event) {
|
|
3289
|
+
if (!opensTheLink(event)) return;
|
|
3290
|
+
const hop = hopFrom(event);
|
|
3291
|
+
if (hop !== null) hop.anchor.href = hop.link.decorated;
|
|
3292
|
+
}
|
|
3293
|
+
function onClick(event) {
|
|
3294
|
+
if (!opensTheLink(event)) return;
|
|
3295
|
+
const hop = hopFrom(event);
|
|
3296
|
+
if (hop === null) return;
|
|
3297
|
+
hop.anchor.href = hop.link.decorated;
|
|
3298
|
+
client.trackEvent({
|
|
3299
|
+
eventType: "site_link_click",
|
|
3300
|
+
metadata: {
|
|
3301
|
+
destination_host: hop.anchor.hostname,
|
|
3302
|
+
destination_url: stripLinkParam(hop.anchor.href),
|
|
3303
|
+
page: { path: window.location.pathname }
|
|
3304
|
+
},
|
|
3305
|
+
pageUrl: window.location.href,
|
|
3306
|
+
occurredAt: null
|
|
3307
|
+
});
|
|
3308
|
+
client.flushBeacon();
|
|
3309
|
+
}
|
|
3310
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
3311
|
+
document.addEventListener("click", onClick, true);
|
|
3312
|
+
return () => {
|
|
3313
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
3314
|
+
document.removeEventListener("click", onClick, true);
|
|
3315
|
+
};
|
|
3316
|
+
}
|
|
3317
|
+
|
|
2980
3318
|
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2981
3319
|
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2982
3320
|
function safeDecodeURIComponent(value) {
|
|
@@ -3362,7 +3700,7 @@ function GoogleAdsTracking(props) {
|
|
|
3362
3700
|
var import_react6 = require("react");
|
|
3363
3701
|
|
|
3364
3702
|
// package.json
|
|
3365
|
-
var version = "1.
|
|
3703
|
+
var version = "1.2.0";
|
|
3366
3704
|
|
|
3367
3705
|
// ../tracking-core/src/phone-react.tsx
|
|
3368
3706
|
var import_react5 = require("react");
|
|
@@ -3485,7 +3823,8 @@ function createTracking(options) {
|
|
|
3485
3823
|
// Still publish phone config so usePhoneField/<PhoneField> work even when
|
|
3486
3824
|
// tracking is disabled (missing apiKey/endpoint).
|
|
3487
3825
|
TrackingProvider: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneConfigProvider, { value: phone ?? null, children }),
|
|
3488
|
-
useTracking: () => noopTyped
|
|
3826
|
+
useTracking: () => noopTyped,
|
|
3827
|
+
decorateUrl: (url) => url
|
|
3489
3828
|
};
|
|
3490
3829
|
}
|
|
3491
3830
|
const TrackingContext = (0, import_react6.createContext)(null);
|
|
@@ -3504,8 +3843,8 @@ function createTracking(options) {
|
|
|
3504
3843
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- gtagIdsKey is stable proxy
|
|
3505
3844
|
[gtagId, gtagIdsKey]
|
|
3506
3845
|
);
|
|
3507
|
-
const rawClient = (0, import_react6.useMemo)(
|
|
3508
|
-
|
|
3846
|
+
const rawClient = (0, import_react6.useMemo)(() => {
|
|
3847
|
+
const created = getOrCreateTrackingClient({
|
|
3509
3848
|
apiKey,
|
|
3510
3849
|
endpoint,
|
|
3511
3850
|
surface: "react",
|
|
@@ -3516,9 +3855,10 @@ function createTracking(options) {
|
|
|
3516
3855
|
activeGtagIds: resolvedGtagIds,
|
|
3517
3856
|
configSiteId: trackingConfig?.siteId ?? null,
|
|
3518
3857
|
debug
|
|
3519
|
-
})
|
|
3520
|
-
|
|
3521
|
-
|
|
3858
|
+
});
|
|
3859
|
+
stripLinkParamFromLocation();
|
|
3860
|
+
return created;
|
|
3861
|
+
}, [resolvedGtagIds]);
|
|
3522
3862
|
const conversionStore = (0, import_react6.useMemo)(
|
|
3523
3863
|
() => trackingConfig ? getTrackingConfigRuntime(trackingConfig) : conversionConfig ? resolveConversionConfig({
|
|
3524
3864
|
cdnUrl: conversionConfig.cdnUrl,
|
|
@@ -3572,6 +3912,11 @@ function createTracking(options) {
|
|
|
3572
3912
|
if (timeOnSite) {
|
|
3573
3913
|
detachers.push(attachTimeOnSite(detectorClient, timeOnSite));
|
|
3574
3914
|
}
|
|
3915
|
+
detachers.push(
|
|
3916
|
+
attachSiteLinkCapture(detectorClient, {
|
|
3917
|
+
linkedHostnames: () => conversionStore?.linkedHostnames() ?? []
|
|
3918
|
+
})
|
|
3919
|
+
);
|
|
3575
3920
|
const specificPageVisit = triggers.automatic.specific_page_visit;
|
|
3576
3921
|
if (specificPageVisit) {
|
|
3577
3922
|
detachers.push(attachSpecificPageVisit(detectorClient, specificPageVisit));
|
|
@@ -3614,7 +3959,14 @@ function createTracking(options) {
|
|
|
3614
3959
|
}
|
|
3615
3960
|
return client;
|
|
3616
3961
|
}
|
|
3617
|
-
return {
|
|
3962
|
+
return {
|
|
3963
|
+
TrackingProvider,
|
|
3964
|
+
useTracking,
|
|
3965
|
+
decorateUrl: (url) => decorateCrossSiteUrl(
|
|
3966
|
+
url,
|
|
3967
|
+
trackingConfig ? getTrackingConfigRuntime(trackingConfig).linkedHostnames() : []
|
|
3968
|
+
)
|
|
3969
|
+
};
|
|
3618
3970
|
}
|
|
3619
3971
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3620
3972
|
0 && (module.exports = {
|