@aranova/tracking-next 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/README.md +48 -1
- 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.d.mts +1 -1
- package/dist/calendar-server.d.ts +1 -1
- package/dist/calendar-server.js.map +1 -1
- package/dist/calendar-server.mjs.map +1 -1
- package/dist/calendar.d.mts +14 -3
- package/dist/calendar.d.ts +14 -3
- package/dist/calendar.js +212 -18
- package/dist/calendar.js.map +1 -1
- package/dist/calendar.mjs +211 -18
- 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 +10 -9
- package/dist/index.d.ts +10 -9
- package/dist/index.js +491 -284
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +490 -284
- 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 +17 -1
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +17 -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/dist/{transport-I_cMSFQ6.d.mts → transport-BlXQZs9Z.d.mts} +120 -50
- package/dist/{transport-CDmGOiCq.d.ts → transport-CAZYrZbB.d.ts} +120 -50
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -308,6 +308,7 @@ var TRACKING_CAPABILITIES = [
|
|
|
308
308
|
"consent_controls",
|
|
309
309
|
"conversion_goals_auto",
|
|
310
310
|
"conversion_goals_manual",
|
|
311
|
+
"cross_site_linker",
|
|
311
312
|
"cta_click_capture",
|
|
312
313
|
"form_capture",
|
|
313
314
|
"phone_click_capture",
|
|
@@ -334,6 +335,9 @@ function readDomMarkers() {
|
|
|
334
335
|
return found;
|
|
335
336
|
}
|
|
336
337
|
|
|
338
|
+
// ../tracking-core/src/cross-site-link.ts
|
|
339
|
+
var z = __toESM(require("zod/mini"));
|
|
340
|
+
|
|
337
341
|
// ../tracking-core/src/tracking.ts
|
|
338
342
|
var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
|
|
339
343
|
var TRACKING_PARAM_KEYS = [
|
|
@@ -672,6 +676,244 @@ function buildLandingPayloadFields(sessionId, override) {
|
|
|
672
676
|
};
|
|
673
677
|
}
|
|
674
678
|
|
|
679
|
+
// ../tracking-core/src/session.ts
|
|
680
|
+
var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
|
|
681
|
+
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
682
|
+
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
683
|
+
function safeUuid() {
|
|
684
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
|
|
685
|
+
return crypto.randomUUID();
|
|
686
|
+
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
|
|
687
|
+
}
|
|
688
|
+
function readLocalStorage(key) {
|
|
689
|
+
try {
|
|
690
|
+
return window.localStorage.getItem(key);
|
|
691
|
+
} catch {
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
function writeLocalStorage(key, value) {
|
|
696
|
+
try {
|
|
697
|
+
window.localStorage.setItem(key, value);
|
|
698
|
+
} catch {
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
function getVisitorId() {
|
|
702
|
+
if (typeof window === "undefined") return safeUuid();
|
|
703
|
+
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
704
|
+
if (existing && existing.length > 0) return existing;
|
|
705
|
+
const fresh = safeUuid();
|
|
706
|
+
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
707
|
+
return fresh;
|
|
708
|
+
}
|
|
709
|
+
function adoptVisitorId(visitorId) {
|
|
710
|
+
if (typeof window === "undefined" || visitorId.length === 0) return false;
|
|
711
|
+
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
712
|
+
if (existing && existing.length > 0) return false;
|
|
713
|
+
writeLocalStorage(VISITOR_STORAGE_KEY, visitorId);
|
|
714
|
+
return readLocalStorage(VISITOR_STORAGE_KEY) === visitorId;
|
|
715
|
+
}
|
|
716
|
+
function getOrRotateSessionId(now = Date.now()) {
|
|
717
|
+
if (typeof window === "undefined") return { id: safeUuid(), isNew: true };
|
|
718
|
+
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
719
|
+
if (raw) {
|
|
720
|
+
try {
|
|
721
|
+
const parsed = JSON.parse(raw);
|
|
722
|
+
if (typeof parsed.id === "string" && typeof parsed.last_event_at === "number") {
|
|
723
|
+
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
724
|
+
const refreshed = { id: parsed.id, last_event_at: now };
|
|
725
|
+
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
726
|
+
return { id: parsed.id, isNew: false };
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
} catch {
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
const fresh = { id: safeUuid(), last_event_at: now };
|
|
733
|
+
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
734
|
+
return { id: fresh.id, isNew: true };
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// ../tracking-core/src/cross-site-link.ts
|
|
738
|
+
var LINK_PARAM = "_arv";
|
|
739
|
+
var LINK_TOKEN_VERSION = "1";
|
|
740
|
+
var LINK_TOKEN_TTL_MS = 5 * 60 * 1e3;
|
|
741
|
+
var FUTURE_SKEW_MS = 60 * 1e3;
|
|
742
|
+
var CARRIED_KEYS = {
|
|
743
|
+
g: "gclid",
|
|
744
|
+
w: "wbraid",
|
|
745
|
+
gb: "gbraid",
|
|
746
|
+
f: "fbclid",
|
|
747
|
+
y: "ylpcid"
|
|
748
|
+
};
|
|
749
|
+
var CARRIED_ENTRIES = Object.entries(CARRIED_KEYS);
|
|
750
|
+
var identifier = z.string().check(z.minLength(1), z.maxLength(128));
|
|
751
|
+
var optionalIdentifier = z.optional(identifier);
|
|
752
|
+
var linkTokenSchema = z.object({
|
|
753
|
+
v: identifier,
|
|
754
|
+
s: identifier,
|
|
755
|
+
// Epoch ms in base36.
|
|
756
|
+
t: z.string().check(z.regex(/^[0-9a-z]{1,12}$/)),
|
|
757
|
+
g: optionalIdentifier,
|
|
758
|
+
w: optionalIdentifier,
|
|
759
|
+
gb: optionalIdentifier,
|
|
760
|
+
f: optionalIdentifier,
|
|
761
|
+
fc: optionalIdentifier,
|
|
762
|
+
y: optionalIdentifier
|
|
763
|
+
});
|
|
764
|
+
function toBase64Url(input) {
|
|
765
|
+
const bytes = new TextEncoder().encode(input);
|
|
766
|
+
let binary = "";
|
|
767
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
768
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
769
|
+
}
|
|
770
|
+
function fromBase64Url(input) {
|
|
771
|
+
try {
|
|
772
|
+
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
773
|
+
const binary = atob(padded + "=".repeat((4 - padded.length % 4) % 4));
|
|
774
|
+
const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
775
|
+
return new TextDecoder().decode(bytes);
|
|
776
|
+
} catch {
|
|
777
|
+
return null;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
function encodeLinkToken(payload) {
|
|
781
|
+
const params = new URLSearchParams();
|
|
782
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
783
|
+
if (typeof value === "string" && value.length > 0) params.set(key, value);
|
|
784
|
+
}
|
|
785
|
+
return `${LINK_TOKEN_VERSION}.${toBase64Url(params.toString())}`;
|
|
786
|
+
}
|
|
787
|
+
function decodeLinkToken(raw) {
|
|
788
|
+
const dot = raw.indexOf(".");
|
|
789
|
+
if (dot <= 0 || raw.slice(0, dot) !== LINK_TOKEN_VERSION) return null;
|
|
790
|
+
const decoded = fromBase64Url(raw.slice(dot + 1));
|
|
791
|
+
if (decoded === null) return null;
|
|
792
|
+
const params = new URLSearchParams(decoded);
|
|
793
|
+
const candidate = {};
|
|
794
|
+
params.forEach((value, key) => {
|
|
795
|
+
candidate[key] = value;
|
|
796
|
+
});
|
|
797
|
+
const result = linkTokenSchema.safeParse(candidate);
|
|
798
|
+
return result.success ? result.data : null;
|
|
799
|
+
}
|
|
800
|
+
function payloadToLink(payload) {
|
|
801
|
+
const carried = {};
|
|
802
|
+
for (const [wire, param] of CARRIED_ENTRIES) {
|
|
803
|
+
const value = payload[wire];
|
|
804
|
+
if (value) carried[param] = value;
|
|
805
|
+
}
|
|
806
|
+
return {
|
|
807
|
+
visitorId: payload.v,
|
|
808
|
+
sessionId: payload.s,
|
|
809
|
+
linkedAt: Number.parseInt(payload.t, 36),
|
|
810
|
+
carried,
|
|
811
|
+
fbc: payload.fc ?? null
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
function stripWww(hostname) {
|
|
815
|
+
return hostname.toLowerCase().replace(/^www\./, "");
|
|
816
|
+
}
|
|
817
|
+
function isSiblingHost(hostname, sibling) {
|
|
818
|
+
const host = stripWww(hostname);
|
|
819
|
+
const target = stripWww(sibling);
|
|
820
|
+
return host === target || host.endsWith(`.${target}`);
|
|
821
|
+
}
|
|
822
|
+
function resolveCrossSiteLink(url, linkedHostnames, now = Date.now()) {
|
|
823
|
+
if (typeof window === "undefined" || linkedHostnames.length === 0) return null;
|
|
824
|
+
let target;
|
|
825
|
+
try {
|
|
826
|
+
target = new URL(url, window.location.href);
|
|
827
|
+
} catch {
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
if (target.protocol !== "http:" && target.protocol !== "https:") return null;
|
|
831
|
+
const here = window.location.hostname;
|
|
832
|
+
if (here && isSiblingHost(target.hostname, here)) return null;
|
|
833
|
+
const hostname = linkedHostnames.find((sibling) => isSiblingHost(target.hostname, sibling));
|
|
834
|
+
if (hostname === void 0) return null;
|
|
835
|
+
const consent = getConsentChoice();
|
|
836
|
+
if (consent.state === "denied" && consent.source === "explicit") {
|
|
837
|
+
return { hostname, decorated: url };
|
|
838
|
+
}
|
|
839
|
+
target.searchParams.set(LINK_PARAM, buildOutboundLinkToken(now));
|
|
840
|
+
return { hostname, decorated: target.href };
|
|
841
|
+
}
|
|
842
|
+
function stripLinkParam(url) {
|
|
843
|
+
try {
|
|
844
|
+
const parsed = new URL(url, typeof window === "undefined" ? void 0 : window.location.href);
|
|
845
|
+
if (!parsed.searchParams.has(LINK_PARAM)) return url;
|
|
846
|
+
parsed.searchParams.delete(LINK_PARAM);
|
|
847
|
+
return parsed.href;
|
|
848
|
+
} catch {
|
|
849
|
+
return url;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
function stripLinkParamFromSearch(search) {
|
|
853
|
+
if (!search.includes(LINK_PARAM)) return search;
|
|
854
|
+
const params = new URLSearchParams(search);
|
|
855
|
+
if (!params.has(LINK_PARAM)) return search;
|
|
856
|
+
params.delete(LINK_PARAM);
|
|
857
|
+
const rest = params.toString();
|
|
858
|
+
return rest.length > 0 ? `?${rest}` : "";
|
|
859
|
+
}
|
|
860
|
+
function readCarried() {
|
|
861
|
+
const out = {};
|
|
862
|
+
for (const [wire, param] of CARRIED_ENTRIES) {
|
|
863
|
+
const value = readCookieValue(param);
|
|
864
|
+
if (value) out[wire] = value;
|
|
865
|
+
}
|
|
866
|
+
return out;
|
|
867
|
+
}
|
|
868
|
+
function buildOutboundLinkToken(now = Date.now()) {
|
|
869
|
+
const fbc = getFbcCookie();
|
|
870
|
+
return encodeLinkToken({
|
|
871
|
+
v: getVisitorId(),
|
|
872
|
+
s: getOrRotateSessionId(now).id,
|
|
873
|
+
t: now.toString(36),
|
|
874
|
+
...readCarried(),
|
|
875
|
+
...fbc ? { fc: fbc } : {}
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
function decorateCrossSiteUrl(url, linkedHostnames, now = Date.now()) {
|
|
879
|
+
return resolveCrossSiteLink(url, linkedHostnames, now)?.decorated ?? url;
|
|
880
|
+
}
|
|
881
|
+
function consumeInboundLink(href = typeof window === "undefined" ? "" : window.location.href, now = Date.now()) {
|
|
882
|
+
if (typeof window === "undefined" || !href) return null;
|
|
883
|
+
let raw;
|
|
884
|
+
try {
|
|
885
|
+
raw = new URL(href, window.location.href).searchParams.get(LINK_PARAM);
|
|
886
|
+
} catch {
|
|
887
|
+
return null;
|
|
888
|
+
}
|
|
889
|
+
if (!raw) return null;
|
|
890
|
+
const payload = decodeLinkToken(raw);
|
|
891
|
+
if (payload === null) return { outcome: "invalid", link: null, adoptedVisitor: false };
|
|
892
|
+
const link = payloadToLink(payload);
|
|
893
|
+
const age = now - link.linkedAt;
|
|
894
|
+
if (!Number.isFinite(age) || age < -FUTURE_SKEW_MS) {
|
|
895
|
+
return { outcome: "invalid", link: null, adoptedVisitor: false };
|
|
896
|
+
}
|
|
897
|
+
if (age > LINK_TOKEN_TTL_MS) {
|
|
898
|
+
return { outcome: "stale", link: null, adoptedVisitor: false };
|
|
899
|
+
}
|
|
900
|
+
const adoptedVisitor = adoptVisitorId(link.visitorId);
|
|
901
|
+
for (const [param, value] of Object.entries(link.carried)) {
|
|
902
|
+
if (!readCookieValue(param)) setTrackingCookie(param, value);
|
|
903
|
+
}
|
|
904
|
+
if (link.fbc && !getFbcCookie()) persistCookieValue(FBC_COOKIE, link.fbc);
|
|
905
|
+
return { outcome: "linked", link, adoptedVisitor };
|
|
906
|
+
}
|
|
907
|
+
function stripLinkParamFromLocation() {
|
|
908
|
+
if (typeof window === "undefined" || typeof history === "undefined") return;
|
|
909
|
+
const clean = stripLinkParam(window.location.href);
|
|
910
|
+
if (clean === window.location.href) return;
|
|
911
|
+
try {
|
|
912
|
+
history.replaceState(null, "", clean);
|
|
913
|
+
} catch {
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
675
917
|
// ../tracking-core/src/resources/conversion-firing.ts
|
|
676
918
|
var DEDUP_PREFIX = "_aranova_conv_";
|
|
677
919
|
function dedupKey(input) {
|
|
@@ -778,7 +1020,8 @@ function parseConversionConfig(raw) {
|
|
|
778
1020
|
gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
|
|
779
1021
|
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
780
1022
|
services,
|
|
781
|
-
goals
|
|
1023
|
+
goals,
|
|
1024
|
+
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : []
|
|
782
1025
|
};
|
|
783
1026
|
}
|
|
784
1027
|
var CACHE_PREFIX = "_aranova_cfg_";
|
|
@@ -862,6 +1105,7 @@ function resolveConversionConfig(options) {
|
|
|
862
1105
|
getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
|
|
863
1106
|
getGoal: (key) => goalsByKey.get(key) ?? null,
|
|
864
1107
|
listGoals: () => [...goalsByKey.values()],
|
|
1108
|
+
linkedHostnames: () => current?.linked_hostnames ?? [],
|
|
865
1109
|
current: () => current,
|
|
866
1110
|
isReady: () => current !== null,
|
|
867
1111
|
onResolve: (listener) => {
|
|
@@ -1046,7 +1290,7 @@ function validateConfig(config, ref) {
|
|
|
1046
1290
|
function pageViewSnapshot() {
|
|
1047
1291
|
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
1048
1292
|
return {
|
|
1049
|
-
href: window.location.href,
|
|
1293
|
+
href: stripLinkParam(window.location.href),
|
|
1050
1294
|
title: document.title || null,
|
|
1051
1295
|
referrer: document.referrer || null
|
|
1052
1296
|
};
|
|
@@ -1197,6 +1441,10 @@ var TrackingConfigRuntime = class {
|
|
|
1197
1441
|
listGoals() {
|
|
1198
1442
|
return this.current?.goals ?? [];
|
|
1199
1443
|
}
|
|
1444
|
+
/** Sibling hostnames for the linker — read from the cached object even while unconfirmed. */
|
|
1445
|
+
linkedHostnames() {
|
|
1446
|
+
return this.current?.linked_hostnames ?? [];
|
|
1447
|
+
}
|
|
1200
1448
|
async revalidateNow() {
|
|
1201
1449
|
try {
|
|
1202
1450
|
const headers = {};
|
|
@@ -1434,83 +1682,32 @@ function withConversionAutoFire(client, autoFire) {
|
|
|
1434
1682
|
};
|
|
1435
1683
|
}
|
|
1436
1684
|
|
|
1437
|
-
// ../tracking-core/src/session.ts
|
|
1438
|
-
var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
|
|
1439
|
-
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
1440
|
-
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
1441
|
-
function safeUuid() {
|
|
1442
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
|
|
1443
|
-
return crypto.randomUUID();
|
|
1444
|
-
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
|
|
1445
|
-
}
|
|
1446
|
-
function readLocalStorage(key) {
|
|
1447
|
-
try {
|
|
1448
|
-
return window.localStorage.getItem(key);
|
|
1449
|
-
} catch {
|
|
1450
|
-
return null;
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
|
-
function writeLocalStorage(key, value) {
|
|
1454
|
-
try {
|
|
1455
|
-
window.localStorage.setItem(key, value);
|
|
1456
|
-
} catch {
|
|
1457
|
-
}
|
|
1458
|
-
}
|
|
1459
|
-
function getVisitorId() {
|
|
1460
|
-
if (typeof window === "undefined") return safeUuid();
|
|
1461
|
-
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
1462
|
-
if (existing && existing.length > 0) return existing;
|
|
1463
|
-
const fresh = safeUuid();
|
|
1464
|
-
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
1465
|
-
return fresh;
|
|
1466
|
-
}
|
|
1467
|
-
function getOrRotateSessionId(now = Date.now()) {
|
|
1468
|
-
if (typeof window === "undefined") return { id: safeUuid(), isNew: true };
|
|
1469
|
-
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
1470
|
-
if (raw) {
|
|
1471
|
-
try {
|
|
1472
|
-
const parsed = JSON.parse(raw);
|
|
1473
|
-
if (typeof parsed.id === "string" && typeof parsed.last_event_at === "number") {
|
|
1474
|
-
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
1475
|
-
const refreshed = { id: parsed.id, last_event_at: now };
|
|
1476
|
-
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
1477
|
-
return { id: parsed.id, isNew: false };
|
|
1478
|
-
}
|
|
1479
|
-
}
|
|
1480
|
-
} catch {
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
const fresh = { id: safeUuid(), last_event_at: now };
|
|
1484
|
-
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
1485
|
-
return { id: fresh.id, isNew: true };
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
1685
|
// ../tracking-core/src/page-view.ts
|
|
1489
1686
|
var import_mini = require("zod/mini");
|
|
1490
1687
|
|
|
1491
1688
|
// ../tracking-core/src/events/page-view.ts
|
|
1492
|
-
var
|
|
1493
|
-
var pageViewMetadataSchema =
|
|
1494
|
-
page:
|
|
1495
|
-
title:
|
|
1496
|
-
path:
|
|
1497
|
-
search:
|
|
1498
|
-
hash:
|
|
1689
|
+
var z2 = __toESM(require("zod/mini"));
|
|
1690
|
+
var pageViewMetadataSchema = z2.strictObject({
|
|
1691
|
+
page: z2.strictObject({
|
|
1692
|
+
title: z2.nullable(z2.string()),
|
|
1693
|
+
path: z2.string(),
|
|
1694
|
+
search: z2.string(),
|
|
1695
|
+
hash: z2.string()
|
|
1499
1696
|
}),
|
|
1500
|
-
referrer:
|
|
1697
|
+
referrer: z2.nullable(z2.string()),
|
|
1501
1698
|
// Optional + nullable — absent (undefined) OR explicit null OR a
|
|
1502
1699
|
// real viewport object. Mirrors Pydantic's `_Viewport | None = None`
|
|
1503
1700
|
// on the backend side so the drift test stays clean.
|
|
1504
|
-
viewport:
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
w:
|
|
1508
|
-
h:
|
|
1701
|
+
viewport: z2.optional(
|
|
1702
|
+
z2.nullable(
|
|
1703
|
+
z2.strictObject({
|
|
1704
|
+
w: z2.number(),
|
|
1705
|
+
h: z2.number()
|
|
1509
1706
|
})
|
|
1510
1707
|
)
|
|
1511
1708
|
)
|
|
1512
1709
|
});
|
|
1513
|
-
var pageViewConfigSchema =
|
|
1710
|
+
var pageViewConfigSchema = z2.strictObject({});
|
|
1514
1711
|
|
|
1515
1712
|
// ../tracking-core/src/page-view.ts
|
|
1516
1713
|
var LAST_FIRED_URL_STORAGE_KEY = "aranova_tracking_last_fired_url";
|
|
@@ -1550,7 +1747,7 @@ function buildPageViewMetadata(referrerOverride) {
|
|
|
1550
1747
|
page: {
|
|
1551
1748
|
title: document.title || null,
|
|
1552
1749
|
path: window.location.pathname,
|
|
1553
|
-
search: window.location.search,
|
|
1750
|
+
search: stripLinkParamFromSearch(window.location.search),
|
|
1554
1751
|
hash: window.location.hash
|
|
1555
1752
|
},
|
|
1556
1753
|
referrer: referrerOverride !== void 0 ? referrerOverride : document.referrer || null,
|
|
@@ -1811,11 +2008,19 @@ function createTrackingClient(config) {
|
|
|
1811
2008
|
let firstPage = null;
|
|
1812
2009
|
let initialParams = createEmptyTrackingParams();
|
|
1813
2010
|
let destroyed = false;
|
|
2011
|
+
let inboundLink = null;
|
|
2012
|
+
if (typeof window !== "undefined") {
|
|
2013
|
+
try {
|
|
2014
|
+
inboundLink = consumeInboundLink();
|
|
2015
|
+
} catch {
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
let originLink = inboundLink?.link ?? null;
|
|
1814
2019
|
const visitorId = getVisitorId();
|
|
1815
2020
|
const initialSession = getOrRotateSessionId();
|
|
1816
2021
|
let sessionId = initialSession.id;
|
|
1817
2022
|
if (typeof window !== "undefined") {
|
|
1818
|
-
firstPage = window.location.href;
|
|
2023
|
+
firstPage = stripLinkParam(window.location.href);
|
|
1819
2024
|
try {
|
|
1820
2025
|
initialParams = captureTrackingParamsFromLocation();
|
|
1821
2026
|
} catch {
|
|
@@ -1826,25 +2031,50 @@ function createTrackingClient(config) {
|
|
|
1826
2031
|
} catch {
|
|
1827
2032
|
}
|
|
1828
2033
|
}
|
|
1829
|
-
function
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
packageName,
|
|
1834
|
-
config.triggers ?? null,
|
|
1835
|
-
activeGtagIds,
|
|
1836
|
-
config.configSiteId ?? null
|
|
1837
|
-
);
|
|
2034
|
+
function currentPageUrl() {
|
|
2035
|
+
return typeof window === "undefined" ? null : stripLinkParam(window.location.href);
|
|
2036
|
+
}
|
|
2037
|
+
function enqueueInternal(eventType, metadata, pageUrl) {
|
|
1838
2038
|
queue.push({
|
|
1839
|
-
event_type:
|
|
1840
|
-
page_url:
|
|
2039
|
+
event_type: eventType,
|
|
2040
|
+
page_url: pageUrl,
|
|
1841
2041
|
metadata,
|
|
1842
2042
|
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1843
2043
|
});
|
|
1844
2044
|
}
|
|
2045
|
+
function enqueueHeartbeat() {
|
|
2046
|
+
enqueueInternal(
|
|
2047
|
+
"sdk_heartbeat",
|
|
2048
|
+
buildHeartbeatMetadata(
|
|
2049
|
+
config.surface,
|
|
2050
|
+
sdkVersion,
|
|
2051
|
+
packageName,
|
|
2052
|
+
config.triggers ?? null,
|
|
2053
|
+
activeGtagIds,
|
|
2054
|
+
config.configSiteId ?? null
|
|
2055
|
+
),
|
|
2056
|
+
currentPageUrl()
|
|
2057
|
+
);
|
|
2058
|
+
}
|
|
1845
2059
|
if (initialSession.isNew) {
|
|
1846
2060
|
enqueueHeartbeat();
|
|
1847
2061
|
}
|
|
2062
|
+
if (inboundLink !== null && typeof window !== "undefined") {
|
|
2063
|
+
const link = inboundLink.link;
|
|
2064
|
+
enqueueInternal(
|
|
2065
|
+
"site_link_arrival",
|
|
2066
|
+
{
|
|
2067
|
+
outcome: inboundLink.outcome,
|
|
2068
|
+
origin_session_id: link?.sessionId ?? null,
|
|
2069
|
+
origin_visitor_id: link?.visitorId ?? null,
|
|
2070
|
+
transit_ms: link ? Math.max(0, Date.now() - link.linkedAt) : null,
|
|
2071
|
+
adopted_visitor: inboundLink.adoptedVisitor,
|
|
2072
|
+
page: { path: window.location.pathname }
|
|
2073
|
+
},
|
|
2074
|
+
firstPage
|
|
2075
|
+
);
|
|
2076
|
+
scheduleFlush();
|
|
2077
|
+
}
|
|
1848
2078
|
if (pending.length > 0) {
|
|
1849
2079
|
scheduleFlush();
|
|
1850
2080
|
}
|
|
@@ -1852,6 +2082,7 @@ function createTrackingClient(config) {
|
|
|
1852
2082
|
const rotated = getOrRotateSessionId();
|
|
1853
2083
|
if (rotated.isNew && rotated.id !== sessionId) {
|
|
1854
2084
|
enqueueHeartbeat();
|
|
2085
|
+
originLink = null;
|
|
1855
2086
|
}
|
|
1856
2087
|
sessionId = rotated.id;
|
|
1857
2088
|
const params = mergeTrackingParams(readTrackingParams(), initialParams);
|
|
@@ -1882,6 +2113,11 @@ function createTrackingClient(config) {
|
|
|
1882
2113
|
// landing), reused from the stored record otherwise. Keys are omitted
|
|
1883
2114
|
// entirely when the landing isn't observable (SSR).
|
|
1884
2115
|
...buildLandingPayloadFields(sessionId),
|
|
2116
|
+
...originLink ? {
|
|
2117
|
+
origin_session_id: originLink.sessionId,
|
|
2118
|
+
origin_visitor_id: originLink.visitorId,
|
|
2119
|
+
origin_linked_at: new Date(originLink.linkedAt).toISOString()
|
|
2120
|
+
} : {},
|
|
1885
2121
|
first_page: firstPage,
|
|
1886
2122
|
consent_state: consentSnapshot(),
|
|
1887
2123
|
context
|
|
@@ -1958,7 +2194,8 @@ function createTrackingClient(config) {
|
|
|
1958
2194
|
const occurredAt = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : typeof input.occurredAt === "string" ? input.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
1959
2195
|
queue.push({
|
|
1960
2196
|
event_type: input.eventType,
|
|
1961
|
-
|
|
2197
|
+
// A caller's href still carries `_arv` until the surface strips it after hydration.
|
|
2198
|
+
page_url: input.pageUrl != null ? stripLinkParam(input.pageUrl) : currentPageUrl(),
|
|
1962
2199
|
metadata: input.metadata ?? null,
|
|
1963
2200
|
occurred_at: occurredAt
|
|
1964
2201
|
});
|
|
@@ -2008,112 +2245,112 @@ function createTrackingClient(config) {
|
|
|
2008
2245
|
var import_mini2 = require("zod/mini");
|
|
2009
2246
|
|
|
2010
2247
|
// ../tracking-core/src/events/cta-click.ts
|
|
2011
|
-
var
|
|
2012
|
-
var ctaClickMetadataSchema =
|
|
2013
|
-
cta_name:
|
|
2014
|
-
page:
|
|
2015
|
-
path:
|
|
2248
|
+
var z3 = __toESM(require("zod/mini"));
|
|
2249
|
+
var ctaClickMetadataSchema = z3.strictObject({
|
|
2250
|
+
cta_name: z3.string(),
|
|
2251
|
+
page: z3.strictObject({
|
|
2252
|
+
path: z3.string()
|
|
2016
2253
|
}),
|
|
2017
|
-
section:
|
|
2018
|
-
destination_url:
|
|
2254
|
+
section: z3.optional(z3.nullable(z3.string())),
|
|
2255
|
+
destination_url: z3.optional(z3.nullable(z3.string())),
|
|
2019
2256
|
// Set by auto-capture (and available to manual callers): the link target
|
|
2020
2257
|
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
2021
|
-
href:
|
|
2022
|
-
element:
|
|
2258
|
+
href: z3.optional(z3.nullable(z3.string())),
|
|
2259
|
+
element: z3.optional(z3.nullable(z3.string()))
|
|
2023
2260
|
});
|
|
2024
|
-
var ctaClickConfigSchema =
|
|
2025
|
-
autoCapture:
|
|
2026
|
-
|
|
2027
|
-
selector:
|
|
2261
|
+
var ctaClickConfigSchema = z3.strictObject({
|
|
2262
|
+
autoCapture: z3.optional(
|
|
2263
|
+
z3.strictObject({
|
|
2264
|
+
selector: z3.optional(z3.string())
|
|
2028
2265
|
})
|
|
2029
2266
|
)
|
|
2030
2267
|
});
|
|
2031
2268
|
|
|
2032
2269
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
2033
|
-
var
|
|
2034
|
-
var sdkHeartbeatTriggersSchema =
|
|
2035
|
-
automatic:
|
|
2036
|
-
manual:
|
|
2270
|
+
var z4 = __toESM(require("zod/mini"));
|
|
2271
|
+
var sdkHeartbeatTriggersSchema = z4.strictObject({
|
|
2272
|
+
automatic: z4.array(z4.string()),
|
|
2273
|
+
manual: z4.array(z4.string())
|
|
2037
2274
|
});
|
|
2038
|
-
var sdkHeartbeatMetadataSchema =
|
|
2039
|
-
sdk_version:
|
|
2040
|
-
package_name:
|
|
2041
|
-
surface:
|
|
2275
|
+
var sdkHeartbeatMetadataSchema = z4.strictObject({
|
|
2276
|
+
sdk_version: z4.string(),
|
|
2277
|
+
package_name: z4.nullable(z4.string()),
|
|
2278
|
+
surface: z4.enum(["next", "react", "script"]),
|
|
2042
2279
|
triggers: sdkHeartbeatTriggersSchema,
|
|
2043
|
-
trigger_config:
|
|
2044
|
-
configured_gtag_ids:
|
|
2280
|
+
trigger_config: z4.optional(z4.nullable(z4.record(z4.string(), z4.record(z4.string(), z4.unknown())))),
|
|
2281
|
+
configured_gtag_ids: z4.optional(z4.nullable(z4.record(z4.string(), z4.string()))),
|
|
2045
2282
|
// Site whose config object the SDK resolves; null on a legacy business ref.
|
|
2046
|
-
config_site_id:
|
|
2283
|
+
config_site_id: z4.optional(z4.nullable(z4.uuid()))
|
|
2047
2284
|
});
|
|
2048
|
-
var sdkHeartbeatConfigSchema =
|
|
2285
|
+
var sdkHeartbeatConfigSchema = z4.strictObject({});
|
|
2049
2286
|
|
|
2050
2287
|
// ../tracking-core/src/events/form-start.ts
|
|
2051
|
-
var
|
|
2052
|
-
var formStartMetadataSchema =
|
|
2053
|
-
form:
|
|
2054
|
-
id:
|
|
2055
|
-
action:
|
|
2288
|
+
var z5 = __toESM(require("zod/mini"));
|
|
2289
|
+
var formStartMetadataSchema = z5.strictObject({
|
|
2290
|
+
form: z5.strictObject({
|
|
2291
|
+
id: z5.string(),
|
|
2292
|
+
action: z5.nullable(z5.string())
|
|
2056
2293
|
}),
|
|
2057
|
-
page:
|
|
2058
|
-
path:
|
|
2294
|
+
page: z5.strictObject({
|
|
2295
|
+
path: z5.string()
|
|
2059
2296
|
})
|
|
2060
2297
|
});
|
|
2061
|
-
var formStartConfigSchema =
|
|
2062
|
-
selector:
|
|
2298
|
+
var formStartConfigSchema = z5.strictObject({
|
|
2299
|
+
selector: z5.optional(z5.string())
|
|
2063
2300
|
});
|
|
2064
2301
|
|
|
2065
2302
|
// ../tracking-core/src/events/form-submit.ts
|
|
2066
|
-
var
|
|
2067
|
-
var jsonValueSchema =
|
|
2068
|
-
() =>
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2303
|
+
var z6 = __toESM(require("zod/mini"));
|
|
2304
|
+
var jsonValueSchema = z6.lazy(
|
|
2305
|
+
() => z6.union([
|
|
2306
|
+
z6.string(),
|
|
2307
|
+
z6.number(),
|
|
2308
|
+
z6.boolean(),
|
|
2309
|
+
z6.null(),
|
|
2310
|
+
z6.array(jsonValueSchema),
|
|
2311
|
+
z6.record(z6.string(), jsonValueSchema)
|
|
2075
2312
|
])
|
|
2076
|
-
).register(
|
|
2077
|
-
var formSubmitMetadataSchema =
|
|
2078
|
-
form:
|
|
2079
|
-
id:
|
|
2080
|
-
action:
|
|
2081
|
-
fields:
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
name:
|
|
2085
|
-
type:
|
|
2086
|
-
label:
|
|
2313
|
+
).register(z6.globalRegistry, { id: "JsonSerializableValue" });
|
|
2314
|
+
var formSubmitMetadataSchema = z6.strictObject({
|
|
2315
|
+
form: z6.strictObject({
|
|
2316
|
+
id: z6.string(),
|
|
2317
|
+
action: z6.nullable(z6.string()),
|
|
2318
|
+
fields: z6.optional(
|
|
2319
|
+
z6.array(
|
|
2320
|
+
z6.strictObject({
|
|
2321
|
+
name: z6.string(),
|
|
2322
|
+
type: z6.string(),
|
|
2323
|
+
label: z6.nullable(z6.string()),
|
|
2087
2324
|
value: jsonValueSchema
|
|
2088
2325
|
})
|
|
2089
2326
|
)
|
|
2090
2327
|
)
|
|
2091
2328
|
}),
|
|
2092
|
-
page:
|
|
2093
|
-
path:
|
|
2329
|
+
page: z6.strictObject({
|
|
2330
|
+
path: z6.string()
|
|
2094
2331
|
})
|
|
2095
2332
|
});
|
|
2096
|
-
var formSubmitConfigSchema =
|
|
2333
|
+
var formSubmitConfigSchema = z6.strictObject({});
|
|
2097
2334
|
|
|
2098
2335
|
// ../tracking-core/src/events/multi-page-session.ts
|
|
2099
|
-
var
|
|
2100
|
-
var multiPageSessionMetadataSchema =
|
|
2101
|
-
page_count:
|
|
2102
|
-
page:
|
|
2103
|
-
path:
|
|
2336
|
+
var z7 = __toESM(require("zod/mini"));
|
|
2337
|
+
var multiPageSessionMetadataSchema = z7.strictObject({
|
|
2338
|
+
page_count: z7.int().check(z7.gte(2)),
|
|
2339
|
+
page: z7.strictObject({
|
|
2340
|
+
path: z7.string()
|
|
2104
2341
|
})
|
|
2105
2342
|
});
|
|
2106
|
-
var multiPageSessionConfigSchema =
|
|
2107
|
-
pageThreshold:
|
|
2343
|
+
var multiPageSessionConfigSchema = z7.strictObject({
|
|
2344
|
+
pageThreshold: z7.int().check(z7.gte(2))
|
|
2108
2345
|
});
|
|
2109
2346
|
|
|
2110
2347
|
// ../tracking-core/src/events/page-exit.ts
|
|
2111
|
-
var
|
|
2112
|
-
var pageExitMetadataSchema =
|
|
2113
|
-
dwell_ms:
|
|
2348
|
+
var z8 = __toESM(require("zod/mini"));
|
|
2349
|
+
var pageExitMetadataSchema = z8.strictObject({
|
|
2350
|
+
dwell_ms: z8.int().check(z8.gte(0)),
|
|
2114
2351
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
2115
2352
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
2116
|
-
max_scroll_percent:
|
|
2353
|
+
max_scroll_percent: z8.nullable(z8.int().check(z8.gte(0), z8.lte(100))),
|
|
2117
2354
|
// The gating baseline: the fraction of the page visible at load with
|
|
2118
2355
|
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
2119
2356
|
// (skeleton/streaming renders), the first-scroll position that
|
|
@@ -2121,80 +2358,104 @@ var pageExitMetadataSchema = z7.strictObject({
|
|
|
2121
2358
|
// ended before the snapshot. Optionality is load-bearing: SDK builds
|
|
2122
2359
|
// predating this field keep POSTing page_exit without the key —
|
|
2123
2360
|
// requiring it would 422 whole keepalive beacon batches.
|
|
2124
|
-
scroll_baseline_percent:
|
|
2125
|
-
page:
|
|
2126
|
-
path:
|
|
2361
|
+
scroll_baseline_percent: z8.optional(z8.nullable(z8.int().check(z8.gte(0), z8.lte(100)))),
|
|
2362
|
+
page: z8.strictObject({
|
|
2363
|
+
path: z8.string()
|
|
2127
2364
|
})
|
|
2128
2365
|
});
|
|
2129
|
-
var pageExitConfigSchema =
|
|
2366
|
+
var pageExitConfigSchema = z8.strictObject({});
|
|
2130
2367
|
|
|
2131
2368
|
// ../tracking-core/src/events/phone-click.ts
|
|
2132
|
-
var
|
|
2133
|
-
var phoneClickMetadataSchema =
|
|
2134
|
-
phone_number:
|
|
2135
|
-
page:
|
|
2136
|
-
path:
|
|
2369
|
+
var z9 = __toESM(require("zod/mini"));
|
|
2370
|
+
var phoneClickMetadataSchema = z9.strictObject({
|
|
2371
|
+
phone_number: z9.string(),
|
|
2372
|
+
page: z9.strictObject({
|
|
2373
|
+
path: z9.string()
|
|
2137
2374
|
}),
|
|
2138
|
-
section:
|
|
2375
|
+
section: z9.optional(z9.nullable(z9.string()))
|
|
2139
2376
|
});
|
|
2140
|
-
var phoneClickConfigSchema =
|
|
2141
|
-
autoCapture:
|
|
2142
|
-
|
|
2143
|
-
selector:
|
|
2377
|
+
var phoneClickConfigSchema = z9.strictObject({
|
|
2378
|
+
autoCapture: z9.optional(
|
|
2379
|
+
z9.strictObject({
|
|
2380
|
+
selector: z9.optional(z9.string())
|
|
2144
2381
|
})
|
|
2145
2382
|
)
|
|
2146
2383
|
});
|
|
2147
2384
|
|
|
2148
2385
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
2149
|
-
var
|
|
2150
|
-
var scrollDepthMetadataSchema =
|
|
2151
|
-
depth_percent:
|
|
2152
|
-
page:
|
|
2153
|
-
path:
|
|
2386
|
+
var z10 = __toESM(require("zod/mini"));
|
|
2387
|
+
var scrollDepthMetadataSchema = z10.strictObject({
|
|
2388
|
+
depth_percent: z10.int().check(z10.gte(1), z10.lte(100)),
|
|
2389
|
+
page: z10.strictObject({
|
|
2390
|
+
path: z10.string()
|
|
2154
2391
|
})
|
|
2155
2392
|
});
|
|
2156
|
-
var scrollDepthConfigSchema =
|
|
2157
|
-
thresholds:
|
|
2393
|
+
var scrollDepthConfigSchema = z10.strictObject({
|
|
2394
|
+
thresholds: z10.array(z10.int().check(z10.gte(1), z10.lte(100))).check(z10.minLength(1))
|
|
2158
2395
|
});
|
|
2159
2396
|
|
|
2160
2397
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
2161
|
-
var
|
|
2398
|
+
var z11 = __toESM(require("zod/mini"));
|
|
2162
2399
|
var PAGE_IDENTITY_MAX_LENGTH = 64;
|
|
2163
2400
|
var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
|
|
2164
|
-
var pageIdentitySchema =
|
|
2165
|
-
|
|
2166
|
-
|
|
2401
|
+
var pageIdentitySchema = z11.string().check(
|
|
2402
|
+
z11.maxLength(PAGE_IDENTITY_MAX_LENGTH),
|
|
2403
|
+
z11.regex(PAGE_IDENTITY_PATTERN, {
|
|
2167
2404
|
message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
|
|
2168
2405
|
})
|
|
2169
2406
|
);
|
|
2170
2407
|
var specificPageNameSchema = pageIdentitySchema;
|
|
2171
|
-
var specificPageVisitMetadataSchema =
|
|
2408
|
+
var specificPageVisitMetadataSchema = z11.strictObject({
|
|
2172
2409
|
page_name: specificPageNameSchema,
|
|
2173
|
-
page:
|
|
2174
|
-
path:
|
|
2410
|
+
page: z11.strictObject({
|
|
2411
|
+
path: z11.string()
|
|
2175
2412
|
})
|
|
2176
2413
|
});
|
|
2177
|
-
var specificPageVisitConfigSchema =
|
|
2178
|
-
pages:
|
|
2179
|
-
|
|
2414
|
+
var specificPageVisitConfigSchema = z11.strictObject({
|
|
2415
|
+
pages: z11.array(
|
|
2416
|
+
z11.strictObject({
|
|
2180
2417
|
name: specificPageNameSchema,
|
|
2181
|
-
pathPattern:
|
|
2418
|
+
pathPattern: z11.custom((value) => value instanceof RegExp, {
|
|
2182
2419
|
message: "pathPattern must be a RegExp"
|
|
2183
2420
|
})
|
|
2184
2421
|
})
|
|
2185
|
-
).check(
|
|
2422
|
+
).check(z11.minLength(1))
|
|
2186
2423
|
});
|
|
2187
2424
|
|
|
2425
|
+
// ../tracking-core/src/events/site-link.ts
|
|
2426
|
+
var z12 = __toESM(require("zod/mini"));
|
|
2427
|
+
var siteLinkClickMetadataSchema = z12.strictObject({
|
|
2428
|
+
destination_host: z12.string(),
|
|
2429
|
+
destination_url: z12.string(),
|
|
2430
|
+
page: z12.strictObject({
|
|
2431
|
+
path: z12.string()
|
|
2432
|
+
})
|
|
2433
|
+
});
|
|
2434
|
+
var siteLinkClickConfigSchema = z12.strictObject({});
|
|
2435
|
+
var siteLinkArrivalMetadataSchema = z12.strictObject({
|
|
2436
|
+
outcome: z12.enum(["linked", "stale", "invalid"]),
|
|
2437
|
+
origin_session_id: z12.optional(z12.nullable(z12.string())),
|
|
2438
|
+
origin_visitor_id: z12.optional(z12.nullable(z12.string())),
|
|
2439
|
+
// Milliseconds between the origin click and this page load.
|
|
2440
|
+
transit_ms: z12.optional(z12.nullable(z12.number())),
|
|
2441
|
+
// True when this browser had no visitor id and took the origin's.
|
|
2442
|
+
adopted_visitor: z12.boolean(),
|
|
2443
|
+
page: z12.strictObject({
|
|
2444
|
+
path: z12.string()
|
|
2445
|
+
})
|
|
2446
|
+
});
|
|
2447
|
+
var siteLinkArrivalConfigSchema = z12.strictObject({});
|
|
2448
|
+
|
|
2188
2449
|
// ../tracking-core/src/events/time-on-site.ts
|
|
2189
|
-
var
|
|
2190
|
-
var timeOnSiteMetadataSchema =
|
|
2191
|
-
duration_ms:
|
|
2192
|
-
page:
|
|
2193
|
-
path:
|
|
2450
|
+
var z13 = __toESM(require("zod/mini"));
|
|
2451
|
+
var timeOnSiteMetadataSchema = z13.strictObject({
|
|
2452
|
+
duration_ms: z13.int().check(z13.nonnegative()),
|
|
2453
|
+
page: z13.strictObject({
|
|
2454
|
+
path: z13.string()
|
|
2194
2455
|
})
|
|
2195
2456
|
});
|
|
2196
|
-
var timeOnSiteConfigSchema =
|
|
2197
|
-
thresholdSeconds:
|
|
2457
|
+
var timeOnSiteConfigSchema = z13.strictObject({
|
|
2458
|
+
thresholdSeconds: z13.int().check(z13.positive())
|
|
2198
2459
|
});
|
|
2199
2460
|
|
|
2200
2461
|
// ../tracking-core/src/events/semantics.ts
|
|
@@ -2264,6 +2525,18 @@ var EVENT_SEMANTICS = {
|
|
|
2264
2525
|
category: "engagement",
|
|
2265
2526
|
outcomeRole: "engagement",
|
|
2266
2527
|
clientVisibility: "simple"
|
|
2528
|
+
},
|
|
2529
|
+
site_link_click: {
|
|
2530
|
+
label: "Left for sibling site",
|
|
2531
|
+
category: "page",
|
|
2532
|
+
outcomeRole: "navigation",
|
|
2533
|
+
clientVisibility: "detailed"
|
|
2534
|
+
},
|
|
2535
|
+
site_link_arrival: {
|
|
2536
|
+
label: "Arrived from sibling site",
|
|
2537
|
+
category: "page",
|
|
2538
|
+
outcomeRole: "navigation",
|
|
2539
|
+
clientVisibility: "simple"
|
|
2267
2540
|
}
|
|
2268
2541
|
};
|
|
2269
2542
|
|
|
@@ -2319,6 +2592,20 @@ var EVENT_REGISTRY = {
|
|
|
2319
2592
|
metadataSchema: pageExitMetadataSchema,
|
|
2320
2593
|
configSchema: pageExitConfigSchema
|
|
2321
2594
|
},
|
|
2595
|
+
// Cross-site linkage: emitted by the linker (roster comes from the site
|
|
2596
|
+
// config, not the trigger registry), so neither is consumer-configurable.
|
|
2597
|
+
site_link_click: {
|
|
2598
|
+
kind: "automatic",
|
|
2599
|
+
semantics: EVENT_SEMANTICS.site_link_click,
|
|
2600
|
+
metadataSchema: siteLinkClickMetadataSchema,
|
|
2601
|
+
configSchema: siteLinkClickConfigSchema
|
|
2602
|
+
},
|
|
2603
|
+
site_link_arrival: {
|
|
2604
|
+
kind: "automatic",
|
|
2605
|
+
semantics: EVENT_SEMANTICS.site_link_arrival,
|
|
2606
|
+
metadataSchema: siteLinkArrivalMetadataSchema,
|
|
2607
|
+
configSchema: siteLinkArrivalConfigSchema
|
|
2608
|
+
},
|
|
2322
2609
|
// --- manual triggers ---
|
|
2323
2610
|
form_submit: {
|
|
2324
2611
|
kind: "manual",
|
|
@@ -2789,6 +3076,57 @@ function attachCtaClickCapture(client, config) {
|
|
|
2789
3076
|
};
|
|
2790
3077
|
}
|
|
2791
3078
|
|
|
3079
|
+
// ../tracking-core/src/triggers/site-link-capture.ts
|
|
3080
|
+
function anchorFrom(target) {
|
|
3081
|
+
if (!(target instanceof Element)) return null;
|
|
3082
|
+
const anchor = target.closest("a[href]");
|
|
3083
|
+
return anchor instanceof HTMLAnchorElement ? anchor : null;
|
|
3084
|
+
}
|
|
3085
|
+
function opensTheLink(event) {
|
|
3086
|
+
return event.button === 0 || event.button === 1;
|
|
3087
|
+
}
|
|
3088
|
+
function attachSiteLinkCapture(client, options) {
|
|
3089
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
3090
|
+
return () => {
|
|
3091
|
+
};
|
|
3092
|
+
}
|
|
3093
|
+
registerCapability("cross_site_linker");
|
|
3094
|
+
function hopFrom(event) {
|
|
3095
|
+
const anchor = anchorFrom(event.target);
|
|
3096
|
+
if (anchor === null) return null;
|
|
3097
|
+
const link = resolveCrossSiteLink(anchor.href, options.linkedHostnames());
|
|
3098
|
+
return link === null ? null : { anchor, link };
|
|
3099
|
+
}
|
|
3100
|
+
function onPointerDown(event) {
|
|
3101
|
+
if (!opensTheLink(event)) return;
|
|
3102
|
+
const hop = hopFrom(event);
|
|
3103
|
+
if (hop !== null) hop.anchor.href = hop.link.decorated;
|
|
3104
|
+
}
|
|
3105
|
+
function onClick(event) {
|
|
3106
|
+
if (!opensTheLink(event)) return;
|
|
3107
|
+
const hop = hopFrom(event);
|
|
3108
|
+
if (hop === null) return;
|
|
3109
|
+
hop.anchor.href = hop.link.decorated;
|
|
3110
|
+
client.trackEvent({
|
|
3111
|
+
eventType: "site_link_click",
|
|
3112
|
+
metadata: {
|
|
3113
|
+
destination_host: hop.anchor.hostname,
|
|
3114
|
+
destination_url: stripLinkParam(hop.anchor.href),
|
|
3115
|
+
page: { path: window.location.pathname }
|
|
3116
|
+
},
|
|
3117
|
+
pageUrl: window.location.href,
|
|
3118
|
+
occurredAt: null
|
|
3119
|
+
});
|
|
3120
|
+
client.flushBeacon();
|
|
3121
|
+
}
|
|
3122
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
3123
|
+
document.addEventListener("click", onClick, true);
|
|
3124
|
+
return () => {
|
|
3125
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
3126
|
+
document.removeEventListener("click", onClick, true);
|
|
3127
|
+
};
|
|
3128
|
+
}
|
|
3129
|
+
|
|
2792
3130
|
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2793
3131
|
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2794
3132
|
function safeDecodeURIComponent(value) {
|
|
@@ -3183,7 +3521,7 @@ function GoogleAdsTracking(props) {
|
|
|
3183
3521
|
var import_navigation3 = require("next/navigation");
|
|
3184
3522
|
|
|
3185
3523
|
// package.json
|
|
3186
|
-
var version = "1.
|
|
3524
|
+
var version = "1.2.0";
|
|
3187
3525
|
|
|
3188
3526
|
// src/factory.tsx
|
|
3189
3527
|
var import_react5 = require("react");
|
|
@@ -3280,9 +3618,16 @@ var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
|
3280
3618
|
function PageViewTracker({ fire }) {
|
|
3281
3619
|
const pathname = (0, import_navigation3.usePathname)();
|
|
3282
3620
|
const searchParams = (0, import_navigation3.useSearchParams)();
|
|
3621
|
+
const search = stripLinkParamFromSearch(`?${searchParams.toString()}`);
|
|
3622
|
+
const carriesToken = searchParams.has(LINK_PARAM);
|
|
3283
3623
|
(0, import_react5.useEffect)(() => {
|
|
3284
3624
|
fire();
|
|
3285
|
-
}, [pathname,
|
|
3625
|
+
}, [pathname, search, fire]);
|
|
3626
|
+
(0, import_react5.useEffect)(() => {
|
|
3627
|
+
if (!carriesToken) return;
|
|
3628
|
+
const timer = window.setTimeout(stripLinkParamFromLocation, 0);
|
|
3629
|
+
return () => window.clearTimeout(timer);
|
|
3630
|
+
}, [carriesToken]);
|
|
3286
3631
|
return null;
|
|
3287
3632
|
}
|
|
3288
3633
|
function createTracking(options) {
|
|
@@ -3315,9 +3660,11 @@ function createTracking(options) {
|
|
|
3315
3660
|
};
|
|
3316
3661
|
return {
|
|
3317
3662
|
TrackingProvider: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children }),
|
|
3318
|
-
useTracking: () => noopClient
|
|
3663
|
+
useTracking: () => noopClient,
|
|
3664
|
+
decorateUrl: (url) => url
|
|
3319
3665
|
};
|
|
3320
3666
|
}
|
|
3667
|
+
const linkedHostnames = () => trackingConfig ? getTrackingConfigRuntime(trackingConfig).linkedHostnames() : [];
|
|
3321
3668
|
const TrackingContext = (0, import_react5.createContext)(null);
|
|
3322
3669
|
const specificPageVisitConfig = triggers.automatic.specific_page_visit ?? null;
|
|
3323
3670
|
const timeOnSiteConfig = triggers.automatic.time_on_site ?? null;
|
|
@@ -3429,6 +3776,11 @@ function createTracking(options) {
|
|
|
3429
3776
|
if (timeOnSiteConfig) {
|
|
3430
3777
|
detachers.push(attachTimeOnSite(detectorClient, timeOnSiteConfig));
|
|
3431
3778
|
}
|
|
3779
|
+
detachers.push(
|
|
3780
|
+
attachSiteLinkCapture(detectorClient, {
|
|
3781
|
+
linkedHostnames: () => conversionStore?.linkedHostnames() ?? []
|
|
3782
|
+
})
|
|
3783
|
+
);
|
|
3432
3784
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
3433
3785
|
if (scrollDepth) {
|
|
3434
3786
|
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
@@ -3451,7 +3803,7 @@ function createTracking(options) {
|
|
|
3451
3803
|
}
|
|
3452
3804
|
};
|
|
3453
3805
|
});
|
|
3454
|
-
}, [rawClient, wrapClient]);
|
|
3806
|
+
}, [conversionStore, rawClient, wrapClient]);
|
|
3455
3807
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(TrackingContext.Provider, { value: client, children: [
|
|
3456
3808
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react5.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PageViewTracker, { fire: firePageView }) }),
|
|
3457
3809
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children })
|
|
@@ -3466,7 +3818,11 @@ function createTracking(options) {
|
|
|
3466
3818
|
}
|
|
3467
3819
|
return client;
|
|
3468
3820
|
}
|
|
3469
|
-
return {
|
|
3821
|
+
return {
|
|
3822
|
+
TrackingProvider,
|
|
3823
|
+
useTracking,
|
|
3824
|
+
decorateUrl: (url) => decorateCrossSiteUrl(url, linkedHostnames())
|
|
3825
|
+
};
|
|
3470
3826
|
}
|
|
3471
3827
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3472
3828
|
0 && (module.exports = {
|