@aranova/tracking-next 1.0.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.js.map +1 -1
- package/dist/blog-server.mjs.map +1 -1
- package/dist/blog.js.map +1 -1
- package/dist/blog.mjs.map +1 -1
- package/dist/calendar-server.js.map +1 -1
- package/dist/calendar-server.mjs.map +1 -1
- package/dist/calendar.js.map +1 -1
- package/dist/calendar.mjs.map +1 -1
- package/dist/client.d.mts +9 -3
- package/dist/client.d.ts +9 -3
- package/dist/client.js +550 -194
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +550 -194
- 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 +336 -271
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +336 -271
- 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-DG150g3o.d.ts → sales-DQC815f3.d.ts} +1 -1
- package/dist/{sales-D7KstKA-.d.mts → sales-w1reW_Y3.d.mts} +1 -1
- package/dist/sales.d.mts +2 -2
- package/dist/sales.d.ts +2 -2
- package/dist/sales.js +6 -1
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +6 -1
- package/dist/sales.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +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.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 = [
|
|
@@ -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,83 +1636,32 @@ function withConversionAutoFire(client, autoFire) {
|
|
|
1388
1636
|
};
|
|
1389
1637
|
}
|
|
1390
1638
|
|
|
1391
|
-
// ../tracking-core/src/session.ts
|
|
1392
|
-
var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
|
|
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
|
-
}
|
|
1441
|
-
|
|
1442
1639
|
// ../tracking-core/src/page-view.ts
|
|
1443
1640
|
import { parse } from "zod/mini";
|
|
1444
1641
|
|
|
1445
1642
|
// ../tracking-core/src/events/page-view.ts
|
|
1446
|
-
import * as
|
|
1447
|
-
var pageViewMetadataSchema =
|
|
1448
|
-
page:
|
|
1449
|
-
title:
|
|
1450
|
-
path:
|
|
1451
|
-
search:
|
|
1452
|
-
hash:
|
|
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()
|
|
1453
1650
|
}),
|
|
1454
|
-
referrer:
|
|
1651
|
+
referrer: z2.nullable(z2.string()),
|
|
1455
1652
|
// Optional + nullable — absent (undefined) OR explicit null OR a
|
|
1456
1653
|
// real viewport object. Mirrors Pydantic's `_Viewport | None = None`
|
|
1457
1654
|
// on the backend side so the drift test stays clean.
|
|
1458
|
-
viewport:
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
w:
|
|
1462
|
-
h:
|
|
1655
|
+
viewport: z2.optional(
|
|
1656
|
+
z2.nullable(
|
|
1657
|
+
z2.strictObject({
|
|
1658
|
+
w: z2.number(),
|
|
1659
|
+
h: z2.number()
|
|
1463
1660
|
})
|
|
1464
1661
|
)
|
|
1465
1662
|
)
|
|
1466
1663
|
});
|
|
1467
|
-
var pageViewConfigSchema =
|
|
1664
|
+
var pageViewConfigSchema = z2.strictObject({});
|
|
1468
1665
|
|
|
1469
1666
|
// ../tracking-core/src/page-view.ts
|
|
1470
1667
|
var LAST_FIRED_URL_STORAGE_KEY = "aranova_tracking_last_fired_url";
|
|
@@ -1504,7 +1701,7 @@ function buildPageViewMetadata(referrerOverride) {
|
|
|
1504
1701
|
page: {
|
|
1505
1702
|
title: document.title || null,
|
|
1506
1703
|
path: window.location.pathname,
|
|
1507
|
-
search: window.location.search,
|
|
1704
|
+
search: stripLinkParamFromSearch(window.location.search),
|
|
1508
1705
|
hash: window.location.hash
|
|
1509
1706
|
},
|
|
1510
1707
|
referrer: referrerOverride !== void 0 ? referrerOverride : document.referrer || null,
|
|
@@ -1765,11 +1962,19 @@ function createTrackingClient(config) {
|
|
|
1765
1962
|
let firstPage = null;
|
|
1766
1963
|
let initialParams = createEmptyTrackingParams();
|
|
1767
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;
|
|
1768
1973
|
const visitorId = getVisitorId();
|
|
1769
1974
|
const initialSession = getOrRotateSessionId();
|
|
1770
1975
|
let sessionId = initialSession.id;
|
|
1771
1976
|
if (typeof window !== "undefined") {
|
|
1772
|
-
firstPage = window.location.href;
|
|
1977
|
+
firstPage = stripLinkParam(window.location.href);
|
|
1773
1978
|
try {
|
|
1774
1979
|
initialParams = captureTrackingParamsFromLocation();
|
|
1775
1980
|
} catch {
|
|
@@ -1780,25 +1985,50 @@ function createTrackingClient(config) {
|
|
|
1780
1985
|
} catch {
|
|
1781
1986
|
}
|
|
1782
1987
|
}
|
|
1783
|
-
function
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
packageName,
|
|
1788
|
-
config.triggers ?? null,
|
|
1789
|
-
activeGtagIds,
|
|
1790
|
-
config.configSiteId ?? null
|
|
1791
|
-
);
|
|
1988
|
+
function currentPageUrl() {
|
|
1989
|
+
return typeof window === "undefined" ? null : stripLinkParam(window.location.href);
|
|
1990
|
+
}
|
|
1991
|
+
function enqueueInternal(eventType, metadata, pageUrl) {
|
|
1792
1992
|
queue.push({
|
|
1793
|
-
event_type:
|
|
1794
|
-
page_url:
|
|
1993
|
+
event_type: eventType,
|
|
1994
|
+
page_url: pageUrl,
|
|
1795
1995
|
metadata,
|
|
1796
1996
|
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1797
1997
|
});
|
|
1798
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
|
+
}
|
|
1799
2013
|
if (initialSession.isNew) {
|
|
1800
2014
|
enqueueHeartbeat();
|
|
1801
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
|
+
}
|
|
1802
2032
|
if (pending.length > 0) {
|
|
1803
2033
|
scheduleFlush();
|
|
1804
2034
|
}
|
|
@@ -1806,6 +2036,7 @@ function createTrackingClient(config) {
|
|
|
1806
2036
|
const rotated = getOrRotateSessionId();
|
|
1807
2037
|
if (rotated.isNew && rotated.id !== sessionId) {
|
|
1808
2038
|
enqueueHeartbeat();
|
|
2039
|
+
originLink = null;
|
|
1809
2040
|
}
|
|
1810
2041
|
sessionId = rotated.id;
|
|
1811
2042
|
const params = mergeTrackingParams(readTrackingParams(), initialParams);
|
|
@@ -1836,6 +2067,11 @@ function createTrackingClient(config) {
|
|
|
1836
2067
|
// landing), reused from the stored record otherwise. Keys are omitted
|
|
1837
2068
|
// entirely when the landing isn't observable (SSR).
|
|
1838
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
|
+
} : {},
|
|
1839
2075
|
first_page: firstPage,
|
|
1840
2076
|
consent_state: consentSnapshot(),
|
|
1841
2077
|
context
|
|
@@ -1912,7 +2148,8 @@ function createTrackingClient(config) {
|
|
|
1912
2148
|
const occurredAt = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : typeof input.occurredAt === "string" ? input.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
1913
2149
|
queue.push({
|
|
1914
2150
|
event_type: input.eventType,
|
|
1915
|
-
|
|
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(),
|
|
1916
2153
|
metadata: input.metadata ?? null,
|
|
1917
2154
|
occurred_at: occurredAt
|
|
1918
2155
|
});
|
|
@@ -1962,112 +2199,112 @@ function createTrackingClient(config) {
|
|
|
1962
2199
|
import { parse as parse2 } from "zod/mini";
|
|
1963
2200
|
|
|
1964
2201
|
// ../tracking-core/src/events/cta-click.ts
|
|
1965
|
-
import * as
|
|
1966
|
-
var ctaClickMetadataSchema =
|
|
1967
|
-
cta_name:
|
|
1968
|
-
page:
|
|
1969
|
-
path:
|
|
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()
|
|
1970
2207
|
}),
|
|
1971
|
-
section:
|
|
1972
|
-
destination_url:
|
|
2208
|
+
section: z3.optional(z3.nullable(z3.string())),
|
|
2209
|
+
destination_url: z3.optional(z3.nullable(z3.string())),
|
|
1973
2210
|
// Set by auto-capture (and available to manual callers): the link target
|
|
1974
2211
|
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
1975
|
-
href:
|
|
1976
|
-
element:
|
|
2212
|
+
href: z3.optional(z3.nullable(z3.string())),
|
|
2213
|
+
element: z3.optional(z3.nullable(z3.string()))
|
|
1977
2214
|
});
|
|
1978
|
-
var ctaClickConfigSchema =
|
|
1979
|
-
autoCapture:
|
|
1980
|
-
|
|
1981
|
-
selector:
|
|
2215
|
+
var ctaClickConfigSchema = z3.strictObject({
|
|
2216
|
+
autoCapture: z3.optional(
|
|
2217
|
+
z3.strictObject({
|
|
2218
|
+
selector: z3.optional(z3.string())
|
|
1982
2219
|
})
|
|
1983
2220
|
)
|
|
1984
2221
|
});
|
|
1985
2222
|
|
|
1986
2223
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
1987
|
-
import * as
|
|
1988
|
-
var sdkHeartbeatTriggersSchema =
|
|
1989
|
-
automatic:
|
|
1990
|
-
manual:
|
|
2224
|
+
import * as z4 from "zod/mini";
|
|
2225
|
+
var sdkHeartbeatTriggersSchema = z4.strictObject({
|
|
2226
|
+
automatic: z4.array(z4.string()),
|
|
2227
|
+
manual: z4.array(z4.string())
|
|
1991
2228
|
});
|
|
1992
|
-
var sdkHeartbeatMetadataSchema =
|
|
1993
|
-
sdk_version:
|
|
1994
|
-
package_name:
|
|
1995
|
-
surface:
|
|
2229
|
+
var sdkHeartbeatMetadataSchema = z4.strictObject({
|
|
2230
|
+
sdk_version: z4.string(),
|
|
2231
|
+
package_name: z4.nullable(z4.string()),
|
|
2232
|
+
surface: z4.enum(["next", "react", "script"]),
|
|
1996
2233
|
triggers: sdkHeartbeatTriggersSchema,
|
|
1997
|
-
trigger_config:
|
|
1998
|
-
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()))),
|
|
1999
2236
|
// Site whose config object the SDK resolves; null on a legacy business ref.
|
|
2000
|
-
config_site_id:
|
|
2237
|
+
config_site_id: z4.optional(z4.nullable(z4.uuid()))
|
|
2001
2238
|
});
|
|
2002
|
-
var sdkHeartbeatConfigSchema =
|
|
2239
|
+
var sdkHeartbeatConfigSchema = z4.strictObject({});
|
|
2003
2240
|
|
|
2004
2241
|
// ../tracking-core/src/events/form-start.ts
|
|
2005
|
-
import * as
|
|
2006
|
-
var formStartMetadataSchema =
|
|
2007
|
-
form:
|
|
2008
|
-
id:
|
|
2009
|
-
action:
|
|
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())
|
|
2010
2247
|
}),
|
|
2011
|
-
page:
|
|
2012
|
-
path:
|
|
2248
|
+
page: z5.strictObject({
|
|
2249
|
+
path: z5.string()
|
|
2013
2250
|
})
|
|
2014
2251
|
});
|
|
2015
|
-
var formStartConfigSchema =
|
|
2016
|
-
selector:
|
|
2252
|
+
var formStartConfigSchema = z5.strictObject({
|
|
2253
|
+
selector: z5.optional(z5.string())
|
|
2017
2254
|
});
|
|
2018
2255
|
|
|
2019
2256
|
// ../tracking-core/src/events/form-submit.ts
|
|
2020
|
-
import * as
|
|
2021
|
-
var jsonValueSchema =
|
|
2022
|
-
() =>
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
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)
|
|
2029
2266
|
])
|
|
2030
|
-
).register(
|
|
2031
|
-
var formSubmitMetadataSchema =
|
|
2032
|
-
form:
|
|
2033
|
-
id:
|
|
2034
|
-
action:
|
|
2035
|
-
fields:
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
name:
|
|
2039
|
-
type:
|
|
2040
|
-
label:
|
|
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()),
|
|
2041
2278
|
value: jsonValueSchema
|
|
2042
2279
|
})
|
|
2043
2280
|
)
|
|
2044
2281
|
)
|
|
2045
2282
|
}),
|
|
2046
|
-
page:
|
|
2047
|
-
path:
|
|
2283
|
+
page: z6.strictObject({
|
|
2284
|
+
path: z6.string()
|
|
2048
2285
|
})
|
|
2049
2286
|
});
|
|
2050
|
-
var formSubmitConfigSchema =
|
|
2287
|
+
var formSubmitConfigSchema = z6.strictObject({});
|
|
2051
2288
|
|
|
2052
2289
|
// ../tracking-core/src/events/multi-page-session.ts
|
|
2053
|
-
import * as
|
|
2054
|
-
var multiPageSessionMetadataSchema =
|
|
2055
|
-
page_count:
|
|
2056
|
-
page:
|
|
2057
|
-
path:
|
|
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()
|
|
2058
2295
|
})
|
|
2059
2296
|
});
|
|
2060
|
-
var multiPageSessionConfigSchema =
|
|
2061
|
-
pageThreshold:
|
|
2297
|
+
var multiPageSessionConfigSchema = z7.strictObject({
|
|
2298
|
+
pageThreshold: z7.int().check(z7.gte(2))
|
|
2062
2299
|
});
|
|
2063
2300
|
|
|
2064
2301
|
// ../tracking-core/src/events/page-exit.ts
|
|
2065
|
-
import * as
|
|
2066
|
-
var pageExitMetadataSchema =
|
|
2067
|
-
dwell_ms:
|
|
2302
|
+
import * as z8 from "zod/mini";
|
|
2303
|
+
var pageExitMetadataSchema = z8.strictObject({
|
|
2304
|
+
dwell_ms: z8.int().check(z8.gte(0)),
|
|
2068
2305
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
2069
2306
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
2070
|
-
max_scroll_percent:
|
|
2307
|
+
max_scroll_percent: z8.nullable(z8.int().check(z8.gte(0), z8.lte(100))),
|
|
2071
2308
|
// The gating baseline: the fraction of the page visible at load with
|
|
2072
2309
|
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
2073
2310
|
// (skeleton/streaming renders), the first-scroll position that
|
|
@@ -2075,80 +2312,104 @@ var pageExitMetadataSchema = z7.strictObject({
|
|
|
2075
2312
|
// ended before the snapshot. Optionality is load-bearing: SDK builds
|
|
2076
2313
|
// predating this field keep POSTing page_exit without the key —
|
|
2077
2314
|
// requiring it would 422 whole keepalive beacon batches.
|
|
2078
|
-
scroll_baseline_percent:
|
|
2079
|
-
page:
|
|
2080
|
-
path:
|
|
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()
|
|
2081
2318
|
})
|
|
2082
2319
|
});
|
|
2083
|
-
var pageExitConfigSchema =
|
|
2320
|
+
var pageExitConfigSchema = z8.strictObject({});
|
|
2084
2321
|
|
|
2085
2322
|
// ../tracking-core/src/events/phone-click.ts
|
|
2086
|
-
import * as
|
|
2087
|
-
var phoneClickMetadataSchema =
|
|
2088
|
-
phone_number:
|
|
2089
|
-
page:
|
|
2090
|
-
path:
|
|
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()
|
|
2091
2328
|
}),
|
|
2092
|
-
section:
|
|
2329
|
+
section: z9.optional(z9.nullable(z9.string()))
|
|
2093
2330
|
});
|
|
2094
|
-
var phoneClickConfigSchema =
|
|
2095
|
-
autoCapture:
|
|
2096
|
-
|
|
2097
|
-
selector:
|
|
2331
|
+
var phoneClickConfigSchema = z9.strictObject({
|
|
2332
|
+
autoCapture: z9.optional(
|
|
2333
|
+
z9.strictObject({
|
|
2334
|
+
selector: z9.optional(z9.string())
|
|
2098
2335
|
})
|
|
2099
2336
|
)
|
|
2100
2337
|
});
|
|
2101
2338
|
|
|
2102
2339
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
2103
|
-
import * as
|
|
2104
|
-
var scrollDepthMetadataSchema =
|
|
2105
|
-
depth_percent:
|
|
2106
|
-
page:
|
|
2107
|
-
path:
|
|
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()
|
|
2108
2345
|
})
|
|
2109
2346
|
});
|
|
2110
|
-
var scrollDepthConfigSchema =
|
|
2111
|
-
thresholds:
|
|
2347
|
+
var scrollDepthConfigSchema = z10.strictObject({
|
|
2348
|
+
thresholds: z10.array(z10.int().check(z10.gte(1), z10.lte(100))).check(z10.minLength(1))
|
|
2112
2349
|
});
|
|
2113
2350
|
|
|
2114
2351
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
2115
|
-
import * as
|
|
2352
|
+
import * as z11 from "zod/mini";
|
|
2116
2353
|
var PAGE_IDENTITY_MAX_LENGTH = 64;
|
|
2117
2354
|
var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
|
|
2118
|
-
var pageIdentitySchema =
|
|
2119
|
-
|
|
2120
|
-
|
|
2355
|
+
var pageIdentitySchema = z11.string().check(
|
|
2356
|
+
z11.maxLength(PAGE_IDENTITY_MAX_LENGTH),
|
|
2357
|
+
z11.regex(PAGE_IDENTITY_PATTERN, {
|
|
2121
2358
|
message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
|
|
2122
2359
|
})
|
|
2123
2360
|
);
|
|
2124
2361
|
var specificPageNameSchema = pageIdentitySchema;
|
|
2125
|
-
var specificPageVisitMetadataSchema =
|
|
2362
|
+
var specificPageVisitMetadataSchema = z11.strictObject({
|
|
2126
2363
|
page_name: specificPageNameSchema,
|
|
2127
|
-
page:
|
|
2128
|
-
path:
|
|
2364
|
+
page: z11.strictObject({
|
|
2365
|
+
path: z11.string()
|
|
2129
2366
|
})
|
|
2130
2367
|
});
|
|
2131
|
-
var specificPageVisitConfigSchema =
|
|
2132
|
-
pages:
|
|
2133
|
-
|
|
2368
|
+
var specificPageVisitConfigSchema = z11.strictObject({
|
|
2369
|
+
pages: z11.array(
|
|
2370
|
+
z11.strictObject({
|
|
2134
2371
|
name: specificPageNameSchema,
|
|
2135
|
-
pathPattern:
|
|
2372
|
+
pathPattern: z11.custom((value) => value instanceof RegExp, {
|
|
2136
2373
|
message: "pathPattern must be a RegExp"
|
|
2137
2374
|
})
|
|
2138
2375
|
})
|
|
2139
|
-
).check(
|
|
2376
|
+
).check(z11.minLength(1))
|
|
2140
2377
|
});
|
|
2141
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({});
|
|
2402
|
+
|
|
2142
2403
|
// ../tracking-core/src/events/time-on-site.ts
|
|
2143
|
-
import * as
|
|
2144
|
-
var timeOnSiteMetadataSchema =
|
|
2145
|
-
duration_ms:
|
|
2146
|
-
page:
|
|
2147
|
-
path:
|
|
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()
|
|
2148
2409
|
})
|
|
2149
2410
|
});
|
|
2150
|
-
var timeOnSiteConfigSchema =
|
|
2151
|
-
thresholdSeconds:
|
|
2411
|
+
var timeOnSiteConfigSchema = z13.strictObject({
|
|
2412
|
+
thresholdSeconds: z13.int().check(z13.positive())
|
|
2152
2413
|
});
|
|
2153
2414
|
|
|
2154
2415
|
// ../tracking-core/src/events/semantics.ts
|
|
@@ -2218,6 +2479,18 @@ var EVENT_SEMANTICS = {
|
|
|
2218
2479
|
category: "engagement",
|
|
2219
2480
|
outcomeRole: "engagement",
|
|
2220
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"
|
|
2221
2494
|
}
|
|
2222
2495
|
};
|
|
2223
2496
|
|
|
@@ -2273,6 +2546,20 @@ var EVENT_REGISTRY = {
|
|
|
2273
2546
|
metadataSchema: pageExitMetadataSchema,
|
|
2274
2547
|
configSchema: pageExitConfigSchema
|
|
2275
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
|
+
},
|
|
2276
2563
|
// --- manual triggers ---
|
|
2277
2564
|
form_submit: {
|
|
2278
2565
|
kind: "manual",
|
|
@@ -2743,6 +3030,57 @@ function attachCtaClickCapture(client, config) {
|
|
|
2743
3030
|
};
|
|
2744
3031
|
}
|
|
2745
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
|
+
|
|
2746
3084
|
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2747
3085
|
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2748
3086
|
function safeDecodeURIComponent(value) {
|
|
@@ -3137,7 +3475,7 @@ function GoogleAdsTracking(props) {
|
|
|
3137
3475
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
3138
3476
|
|
|
3139
3477
|
// package.json
|
|
3140
|
-
var version = "1.
|
|
3478
|
+
var version = "1.1.0";
|
|
3141
3479
|
|
|
3142
3480
|
// src/factory.tsx
|
|
3143
3481
|
import {
|
|
@@ -3249,9 +3587,16 @@ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
|
3249
3587
|
function PageViewTracker({ fire }) {
|
|
3250
3588
|
const pathname = usePathname();
|
|
3251
3589
|
const searchParams = useSearchParams();
|
|
3590
|
+
const search = stripLinkParamFromSearch(`?${searchParams.toString()}`);
|
|
3591
|
+
const carriesToken = searchParams.has(LINK_PARAM);
|
|
3252
3592
|
useEffect4(() => {
|
|
3253
3593
|
fire();
|
|
3254
|
-
}, [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]);
|
|
3255
3600
|
return null;
|
|
3256
3601
|
}
|
|
3257
3602
|
function createTracking(options) {
|
|
@@ -3284,9 +3629,11 @@ function createTracking(options) {
|
|
|
3284
3629
|
};
|
|
3285
3630
|
return {
|
|
3286
3631
|
TrackingProvider: ({ children }) => /* @__PURE__ */ jsx5(PhoneConfigProvider, { value: phone ?? null, children }),
|
|
3287
|
-
useTracking: () => noopClient
|
|
3632
|
+
useTracking: () => noopClient,
|
|
3633
|
+
decorateUrl: (url) => url
|
|
3288
3634
|
};
|
|
3289
3635
|
}
|
|
3636
|
+
const linkedHostnames = () => trackingConfig ? getTrackingConfigRuntime(trackingConfig).linkedHostnames() : [];
|
|
3290
3637
|
const TrackingContext = createContext2(null);
|
|
3291
3638
|
const specificPageVisitConfig = triggers.automatic.specific_page_visit ?? null;
|
|
3292
3639
|
const timeOnSiteConfig = triggers.automatic.time_on_site ?? null;
|
|
@@ -3398,6 +3745,11 @@ function createTracking(options) {
|
|
|
3398
3745
|
if (timeOnSiteConfig) {
|
|
3399
3746
|
detachers.push(attachTimeOnSite(detectorClient, timeOnSiteConfig));
|
|
3400
3747
|
}
|
|
3748
|
+
detachers.push(
|
|
3749
|
+
attachSiteLinkCapture(detectorClient, {
|
|
3750
|
+
linkedHostnames: () => conversionStore?.linkedHostnames() ?? []
|
|
3751
|
+
})
|
|
3752
|
+
);
|
|
3401
3753
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
3402
3754
|
if (scrollDepth) {
|
|
3403
3755
|
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
@@ -3420,7 +3772,7 @@ function createTracking(options) {
|
|
|
3420
3772
|
}
|
|
3421
3773
|
};
|
|
3422
3774
|
});
|
|
3423
|
-
}, [rawClient, wrapClient]);
|
|
3775
|
+
}, [conversionStore, rawClient, wrapClient]);
|
|
3424
3776
|
return /* @__PURE__ */ jsxs4(TrackingContext.Provider, { value: client, children: [
|
|
3425
3777
|
/* @__PURE__ */ jsx5(Suspense, { fallback: null, children: /* @__PURE__ */ jsx5(PageViewTracker, { fire: firePageView }) }),
|
|
3426
3778
|
/* @__PURE__ */ jsx5(PhoneConfigProvider, { value: phone ?? null, children })
|
|
@@ -3435,7 +3787,11 @@ function createTracking(options) {
|
|
|
3435
3787
|
}
|
|
3436
3788
|
return client;
|
|
3437
3789
|
}
|
|
3438
|
-
return {
|
|
3790
|
+
return {
|
|
3791
|
+
TrackingProvider,
|
|
3792
|
+
useTracking,
|
|
3793
|
+
decorateUrl: (url) => decorateCrossSiteUrl(url, linkedHostnames())
|
|
3794
|
+
};
|
|
3439
3795
|
}
|
|
3440
3796
|
export {
|
|
3441
3797
|
AdPlatformTracking,
|