@aranova/tracking-react 0.27.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.mts +11 -4
- package/dist/client.d.ts +11 -4
- package/dist/client.js +620 -350
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +610 -350
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +339 -393
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +328 -393
- package/dist/index.mjs.map +1 -1
- package/dist/ingest-typed-MBuMe9Pn.d.ts +883 -0
- package/dist/ingest-typed-UA13xTfI.d.mts +883 -0
- package/dist/{phone-utils-BVzSNBf1.d.mts → phone-utils-C0ds6cqZ.d.mts} +24 -78
- package/dist/{phone-utils-BVzSNBf1.d.ts → phone-utils-C0ds6cqZ.d.ts} +24 -78
- package/dist/phone.d.mts +2 -2
- package/dist/phone.d.ts +2 -2
- package/dist/phone.js +0 -464
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +0 -464
- package/dist/phone.mjs.map +1 -1
- package/dist/{sales-D4TB9gRS.d.ts → sales-BuKD_bdo.d.mts} +90 -329
- package/dist/{sales-cYjB07y8.d.mts → sales-C3O_xxZ_.d.ts} +90 -329
- package/dist/sales.d.mts +3 -3
- package/dist/sales.d.ts +3 -3
- package/dist/sales.js +270 -127
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +259 -127
- package/dist/sales.mjs.map +1 -1
- package/dist/{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 +2 -2
- package/dist/ingest-typed-BxLFlZ7N.d.mts +0 -1371
- package/dist/ingest-typed-ByQVRMvP.d.ts +0 -1371
package/dist/client.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __export = (target, all) => {
|
|
8
10
|
for (var name in all)
|
|
@@ -16,6 +18,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
}
|
|
17
19
|
return to;
|
|
18
20
|
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
19
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
30
|
|
|
21
31
|
// src/client.ts
|
|
@@ -284,6 +294,7 @@ var TRACKING_CAPABILITIES = [
|
|
|
284
294
|
"consent_controls",
|
|
285
295
|
"conversion_goals_auto",
|
|
286
296
|
"conversion_goals_manual",
|
|
297
|
+
"cross_site_linker",
|
|
287
298
|
"cta_click_capture",
|
|
288
299
|
"form_capture",
|
|
289
300
|
"phone_click_capture",
|
|
@@ -310,6 +321,9 @@ function readDomMarkers() {
|
|
|
310
321
|
return found;
|
|
311
322
|
}
|
|
312
323
|
|
|
324
|
+
// ../tracking-core/src/cross-site-link.ts
|
|
325
|
+
var z = __toESM(require("zod/mini"));
|
|
326
|
+
|
|
313
327
|
// ../tracking-core/src/tracking.ts
|
|
314
328
|
var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
|
|
315
329
|
var TRACKING_PARAM_KEYS = [
|
|
@@ -631,10 +645,10 @@ function readStoredRecord() {
|
|
|
631
645
|
return null;
|
|
632
646
|
}
|
|
633
647
|
}
|
|
634
|
-
function writeRecord(
|
|
635
|
-
memoryRecord =
|
|
648
|
+
function writeRecord(record3) {
|
|
649
|
+
memoryRecord = record3;
|
|
636
650
|
try {
|
|
637
|
-
window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(
|
|
651
|
+
window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record3));
|
|
638
652
|
} catch {
|
|
639
653
|
}
|
|
640
654
|
}
|
|
@@ -656,9 +670,9 @@ function getOrCaptureLandingParams(sessionId, url) {
|
|
|
656
670
|
if (memoryRecord && memoryRecord.session_id === sessionId) {
|
|
657
671
|
return memoryRecord.params;
|
|
658
672
|
}
|
|
659
|
-
const
|
|
660
|
-
writeRecord(
|
|
661
|
-
return
|
|
673
|
+
const record3 = { session_id: sessionId, params: captureFromUrl(url) };
|
|
674
|
+
writeRecord(record3);
|
|
675
|
+
return record3.params;
|
|
662
676
|
}
|
|
663
677
|
function buildLandingPayloadFields(sessionId, override) {
|
|
664
678
|
const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
|
|
@@ -677,6 +691,244 @@ function buildLandingPayloadFields(sessionId, override) {
|
|
|
677
691
|
};
|
|
678
692
|
}
|
|
679
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
|
+
|
|
680
932
|
// ../tracking-core/src/resources/conversion-firing.ts
|
|
681
933
|
var DEDUP_PREFIX = "_aranova_conv_";
|
|
682
934
|
function dedupKey(input) {
|
|
@@ -783,7 +1035,8 @@ function parseConversionConfig(raw) {
|
|
|
783
1035
|
gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
|
|
784
1036
|
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
785
1037
|
services,
|
|
786
|
-
goals
|
|
1038
|
+
goals,
|
|
1039
|
+
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : []
|
|
787
1040
|
};
|
|
788
1041
|
}
|
|
789
1042
|
var CACHE_PREFIX = "_aranova_cfg_";
|
|
@@ -867,6 +1120,7 @@ function resolveConversionConfig(options) {
|
|
|
867
1120
|
getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
|
|
868
1121
|
getGoal: (key) => goalsByKey.get(key) ?? null,
|
|
869
1122
|
listGoals: () => [...goalsByKey.values()],
|
|
1123
|
+
linkedHostnames: () => current?.linked_hostnames ?? [],
|
|
870
1124
|
current: () => current,
|
|
871
1125
|
isReady: () => current !== null,
|
|
872
1126
|
onResolve: (listener) => {
|
|
@@ -1051,7 +1305,7 @@ function validateConfig(config, ref) {
|
|
|
1051
1305
|
function pageViewSnapshot() {
|
|
1052
1306
|
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
1053
1307
|
return {
|
|
1054
|
-
href: window.location.href,
|
|
1308
|
+
href: stripLinkParam(window.location.href),
|
|
1055
1309
|
title: document.title || null,
|
|
1056
1310
|
referrer: document.referrer || null
|
|
1057
1311
|
};
|
|
@@ -1202,6 +1456,10 @@ var TrackingConfigRuntime = class {
|
|
|
1202
1456
|
listGoals() {
|
|
1203
1457
|
return this.current?.goals ?? [];
|
|
1204
1458
|
}
|
|
1459
|
+
/** Sibling hostnames for the linker — read from the cached object even while unconfirmed. */
|
|
1460
|
+
linkedHostnames() {
|
|
1461
|
+
return this.current?.linked_hostnames ?? [];
|
|
1462
|
+
}
|
|
1205
1463
|
async revalidateNow() {
|
|
1206
1464
|
try {
|
|
1207
1465
|
const headers = {};
|
|
@@ -1439,76 +1697,32 @@ function withConversionAutoFire(client, autoFire) {
|
|
|
1439
1697
|
};
|
|
1440
1698
|
}
|
|
1441
1699
|
|
|
1442
|
-
// ../tracking-core/src/
|
|
1443
|
-
var
|
|
1444
|
-
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
1445
|
-
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
1446
|
-
function safeUuid() {
|
|
1447
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
|
|
1448
|
-
return crypto.randomUUID();
|
|
1449
|
-
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
|
|
1450
|
-
}
|
|
1451
|
-
function readLocalStorage(key) {
|
|
1452
|
-
try {
|
|
1453
|
-
return window.localStorage.getItem(key);
|
|
1454
|
-
} catch {
|
|
1455
|
-
return null;
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
function writeLocalStorage(key, value) {
|
|
1459
|
-
try {
|
|
1460
|
-
window.localStorage.setItem(key, value);
|
|
1461
|
-
} catch {
|
|
1462
|
-
}
|
|
1463
|
-
}
|
|
1464
|
-
function getVisitorId() {
|
|
1465
|
-
if (typeof window === "undefined") return safeUuid();
|
|
1466
|
-
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
1467
|
-
if (existing && existing.length > 0) return existing;
|
|
1468
|
-
const fresh = safeUuid();
|
|
1469
|
-
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
1470
|
-
return fresh;
|
|
1471
|
-
}
|
|
1472
|
-
function getOrRotateSessionId(now = Date.now()) {
|
|
1473
|
-
if (typeof window === "undefined") return { id: safeUuid(), isNew: true };
|
|
1474
|
-
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
1475
|
-
if (raw) {
|
|
1476
|
-
try {
|
|
1477
|
-
const parsed = JSON.parse(raw);
|
|
1478
|
-
if (typeof parsed.id === "string" && typeof parsed.last_event_at === "number") {
|
|
1479
|
-
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
1480
|
-
const refreshed = { id: parsed.id, last_event_at: now };
|
|
1481
|
-
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
1482
|
-
return { id: parsed.id, isNew: false };
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
} catch {
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
|
-
const fresh = { id: safeUuid(), last_event_at: now };
|
|
1489
|
-
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
1490
|
-
return { id: fresh.id, isNew: true };
|
|
1491
|
-
}
|
|
1700
|
+
// ../tracking-core/src/page-view.ts
|
|
1701
|
+
var import_mini = require("zod/mini");
|
|
1492
1702
|
|
|
1493
1703
|
// ../tracking-core/src/events/page-view.ts
|
|
1494
|
-
var
|
|
1495
|
-
var pageViewMetadataSchema =
|
|
1496
|
-
page:
|
|
1497
|
-
title:
|
|
1498
|
-
path:
|
|
1499
|
-
search:
|
|
1500
|
-
hash:
|
|
1501
|
-
})
|
|
1502
|
-
referrer:
|
|
1503
|
-
//
|
|
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()
|
|
1711
|
+
}),
|
|
1712
|
+
referrer: z2.nullable(z2.string()),
|
|
1713
|
+
// Optional + nullable — absent (undefined) OR explicit null OR a
|
|
1504
1714
|
// real viewport object. Mirrors Pydantic's `_Viewport | None = None`
|
|
1505
1715
|
// on the backend side so the drift test stays clean.
|
|
1506
|
-
viewport:
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1716
|
+
viewport: z2.optional(
|
|
1717
|
+
z2.nullable(
|
|
1718
|
+
z2.strictObject({
|
|
1719
|
+
w: z2.number(),
|
|
1720
|
+
h: z2.number()
|
|
1721
|
+
})
|
|
1722
|
+
)
|
|
1723
|
+
)
|
|
1724
|
+
});
|
|
1725
|
+
var pageViewConfigSchema = z2.strictObject({});
|
|
1512
1726
|
|
|
1513
1727
|
// ../tracking-core/src/page-view.ts
|
|
1514
1728
|
var LAST_FIRED_URL_STORAGE_KEY = "aranova_tracking_last_fired_url";
|
|
@@ -1544,11 +1758,11 @@ function setLastFiredUrl(url) {
|
|
|
1544
1758
|
}
|
|
1545
1759
|
function buildPageViewMetadata(referrerOverride) {
|
|
1546
1760
|
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
1547
|
-
return
|
|
1761
|
+
return (0, import_mini.parse)(pageViewMetadataSchema, {
|
|
1548
1762
|
page: {
|
|
1549
1763
|
title: document.title || null,
|
|
1550
1764
|
path: window.location.pathname,
|
|
1551
|
-
search: window.location.search,
|
|
1765
|
+
search: stripLinkParamFromSearch(window.location.search),
|
|
1552
1766
|
hash: window.location.hash
|
|
1553
1767
|
},
|
|
1554
1768
|
referrer: referrerOverride !== void 0 ? referrerOverride : document.referrer || null,
|
|
@@ -1847,11 +2061,19 @@ function createTrackingClient(config) {
|
|
|
1847
2061
|
let firstPage = null;
|
|
1848
2062
|
let initialParams = createEmptyTrackingParams();
|
|
1849
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;
|
|
1850
2072
|
const visitorId = getVisitorId();
|
|
1851
2073
|
const initialSession = getOrRotateSessionId();
|
|
1852
2074
|
let sessionId = initialSession.id;
|
|
1853
2075
|
if (typeof window !== "undefined") {
|
|
1854
|
-
firstPage = window.location.href;
|
|
2076
|
+
firstPage = stripLinkParam(window.location.href);
|
|
1855
2077
|
try {
|
|
1856
2078
|
initialParams = captureTrackingParamsFromLocation();
|
|
1857
2079
|
} catch {
|
|
@@ -1862,25 +2084,50 @@ function createTrackingClient(config) {
|
|
|
1862
2084
|
} catch {
|
|
1863
2085
|
}
|
|
1864
2086
|
}
|
|
1865
|
-
function
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
packageName,
|
|
1870
|
-
config.triggers ?? null,
|
|
1871
|
-
activeGtagIds,
|
|
1872
|
-
config.configSiteId ?? null
|
|
1873
|
-
);
|
|
2087
|
+
function currentPageUrl() {
|
|
2088
|
+
return typeof window === "undefined" ? null : stripLinkParam(window.location.href);
|
|
2089
|
+
}
|
|
2090
|
+
function enqueueInternal(eventType, metadata, pageUrl) {
|
|
1874
2091
|
queue.push({
|
|
1875
|
-
event_type:
|
|
1876
|
-
page_url:
|
|
2092
|
+
event_type: eventType,
|
|
2093
|
+
page_url: pageUrl,
|
|
1877
2094
|
metadata,
|
|
1878
2095
|
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1879
2096
|
});
|
|
1880
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
|
+
}
|
|
1881
2112
|
if (initialSession.isNew) {
|
|
1882
2113
|
enqueueHeartbeat();
|
|
1883
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
|
+
}
|
|
1884
2131
|
if (pending.length > 0) {
|
|
1885
2132
|
scheduleFlush();
|
|
1886
2133
|
}
|
|
@@ -1888,6 +2135,7 @@ function createTrackingClient(config) {
|
|
|
1888
2135
|
const rotated = getOrRotateSessionId();
|
|
1889
2136
|
if (rotated.isNew && rotated.id !== sessionId) {
|
|
1890
2137
|
enqueueHeartbeat();
|
|
2138
|
+
originLink = null;
|
|
1891
2139
|
}
|
|
1892
2140
|
sessionId = rotated.id;
|
|
1893
2141
|
const params = mergeTrackingParams(readTrackingParams(), initialParams);
|
|
@@ -1918,6 +2166,11 @@ function createTrackingClient(config) {
|
|
|
1918
2166
|
// landing), reused from the stored record otherwise. Keys are omitted
|
|
1919
2167
|
// entirely when the landing isn't observable (SSR).
|
|
1920
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
|
+
} : {},
|
|
1921
2174
|
first_page: firstPage,
|
|
1922
2175
|
consent_state: consentSnapshot(),
|
|
1923
2176
|
context
|
|
@@ -1994,7 +2247,8 @@ function createTrackingClient(config) {
|
|
|
1994
2247
|
const occurredAt = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : typeof input.occurredAt === "string" ? input.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
1995
2248
|
queue.push({
|
|
1996
2249
|
event_type: input.eventType,
|
|
1997
|
-
|
|
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(),
|
|
1998
2252
|
metadata: input.metadata ?? null,
|
|
1999
2253
|
occurred_at: occurredAt
|
|
2000
2254
|
});
|
|
@@ -2040,186 +2294,222 @@ function createTrackingClient(config) {
|
|
|
2040
2294
|
};
|
|
2041
2295
|
}
|
|
2042
2296
|
|
|
2297
|
+
// ../tracking-core/src/ingest-typed.ts
|
|
2298
|
+
var import_mini2 = require("zod/mini");
|
|
2299
|
+
|
|
2043
2300
|
// ../tracking-core/src/events/cta-click.ts
|
|
2044
|
-
var
|
|
2045
|
-
var ctaClickMetadataSchema =
|
|
2046
|
-
cta_name:
|
|
2047
|
-
page:
|
|
2048
|
-
path:
|
|
2049
|
-
})
|
|
2050
|
-
section:
|
|
2051
|
-
destination_url:
|
|
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()
|
|
2306
|
+
}),
|
|
2307
|
+
section: z3.optional(z3.nullable(z3.string())),
|
|
2308
|
+
destination_url: z3.optional(z3.nullable(z3.string())),
|
|
2052
2309
|
// Set by auto-capture (and available to manual callers): the link target
|
|
2053
2310
|
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
2054
|
-
href:
|
|
2055
|
-
element:
|
|
2056
|
-
})
|
|
2057
|
-
var ctaClickConfigSchema =
|
|
2058
|
-
autoCapture:
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
})
|
|
2311
|
+
href: z3.optional(z3.nullable(z3.string())),
|
|
2312
|
+
element: z3.optional(z3.nullable(z3.string()))
|
|
2313
|
+
});
|
|
2314
|
+
var ctaClickConfigSchema = z3.strictObject({
|
|
2315
|
+
autoCapture: z3.optional(
|
|
2316
|
+
z3.strictObject({
|
|
2317
|
+
selector: z3.optional(z3.string())
|
|
2318
|
+
})
|
|
2319
|
+
)
|
|
2320
|
+
});
|
|
2062
2321
|
|
|
2063
2322
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
2064
|
-
var
|
|
2065
|
-
var sdkHeartbeatTriggersSchema =
|
|
2066
|
-
automatic:
|
|
2067
|
-
manual:
|
|
2068
|
-
})
|
|
2069
|
-
var sdkHeartbeatMetadataSchema =
|
|
2070
|
-
sdk_version:
|
|
2071
|
-
package_name:
|
|
2072
|
-
surface:
|
|
2323
|
+
var z4 = __toESM(require("zod/mini"));
|
|
2324
|
+
var sdkHeartbeatTriggersSchema = z4.strictObject({
|
|
2325
|
+
automatic: z4.array(z4.string()),
|
|
2326
|
+
manual: z4.array(z4.string())
|
|
2327
|
+
});
|
|
2328
|
+
var sdkHeartbeatMetadataSchema = z4.strictObject({
|
|
2329
|
+
sdk_version: z4.string(),
|
|
2330
|
+
package_name: z4.nullable(z4.string()),
|
|
2331
|
+
surface: z4.enum(["next", "react", "script"]),
|
|
2073
2332
|
triggers: sdkHeartbeatTriggersSchema,
|
|
2074
|
-
trigger_config:
|
|
2075
|
-
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()))),
|
|
2076
2335
|
// Site whose config object the SDK resolves; null on a legacy business ref.
|
|
2077
|
-
config_site_id:
|
|
2078
|
-
})
|
|
2079
|
-
var sdkHeartbeatConfigSchema =
|
|
2336
|
+
config_site_id: z4.optional(z4.nullable(z4.uuid()))
|
|
2337
|
+
});
|
|
2338
|
+
var sdkHeartbeatConfigSchema = z4.strictObject({});
|
|
2080
2339
|
|
|
2081
2340
|
// ../tracking-core/src/events/form-start.ts
|
|
2082
|
-
var
|
|
2083
|
-
var formStartMetadataSchema =
|
|
2084
|
-
form:
|
|
2085
|
-
id:
|
|
2086
|
-
action:
|
|
2087
|
-
})
|
|
2088
|
-
page:
|
|
2089
|
-
path:
|
|
2090
|
-
})
|
|
2091
|
-
})
|
|
2092
|
-
var formStartConfigSchema =
|
|
2093
|
-
selector:
|
|
2094
|
-
})
|
|
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())
|
|
2346
|
+
}),
|
|
2347
|
+
page: z5.strictObject({
|
|
2348
|
+
path: z5.string()
|
|
2349
|
+
})
|
|
2350
|
+
});
|
|
2351
|
+
var formStartConfigSchema = z5.strictObject({
|
|
2352
|
+
selector: z5.optional(z5.string())
|
|
2353
|
+
});
|
|
2095
2354
|
|
|
2096
2355
|
// ../tracking-core/src/events/form-submit.ts
|
|
2097
|
-
var
|
|
2098
|
-
var jsonValueSchema =
|
|
2099
|
-
() =>
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
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)
|
|
2106
2365
|
])
|
|
2107
|
-
);
|
|
2108
|
-
var formSubmitMetadataSchema =
|
|
2109
|
-
form:
|
|
2110
|
-
id:
|
|
2111
|
-
action:
|
|
2112
|
-
fields:
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
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()),
|
|
2377
|
+
value: jsonValueSchema
|
|
2378
|
+
})
|
|
2379
|
+
)
|
|
2380
|
+
)
|
|
2381
|
+
}),
|
|
2382
|
+
page: z6.strictObject({
|
|
2383
|
+
path: z6.string()
|
|
2384
|
+
})
|
|
2385
|
+
});
|
|
2386
|
+
var formSubmitConfigSchema = z6.strictObject({});
|
|
2126
2387
|
|
|
2127
2388
|
// ../tracking-core/src/events/multi-page-session.ts
|
|
2128
|
-
var
|
|
2129
|
-
var multiPageSessionMetadataSchema =
|
|
2130
|
-
page_count:
|
|
2131
|
-
page:
|
|
2132
|
-
path:
|
|
2133
|
-
})
|
|
2134
|
-
})
|
|
2135
|
-
var multiPageSessionConfigSchema =
|
|
2136
|
-
pageThreshold:
|
|
2137
|
-
})
|
|
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()
|
|
2394
|
+
})
|
|
2395
|
+
});
|
|
2396
|
+
var multiPageSessionConfigSchema = z7.strictObject({
|
|
2397
|
+
pageThreshold: z7.int().check(z7.gte(2))
|
|
2398
|
+
});
|
|
2138
2399
|
|
|
2139
2400
|
// ../tracking-core/src/events/page-exit.ts
|
|
2140
|
-
var
|
|
2141
|
-
var pageExitMetadataSchema =
|
|
2142
|
-
dwell_ms:
|
|
2401
|
+
var z8 = __toESM(require("zod/mini"));
|
|
2402
|
+
var pageExitMetadataSchema = z8.strictObject({
|
|
2403
|
+
dwell_ms: z8.int().check(z8.gte(0)),
|
|
2143
2404
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
2144
2405
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
2145
|
-
max_scroll_percent:
|
|
2406
|
+
max_scroll_percent: z8.nullable(z8.int().check(z8.gte(0), z8.lte(100))),
|
|
2146
2407
|
// The gating baseline: the fraction of the page visible at load with
|
|
2147
2408
|
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
2148
2409
|
// (skeleton/streaming renders), the first-scroll position that
|
|
2149
2410
|
// established it. null = page had no scrollable range, or the segment
|
|
2150
|
-
// ended before the snapshot.
|
|
2411
|
+
// ended before the snapshot. Optionality is load-bearing: SDK builds
|
|
2151
2412
|
// predating this field keep POSTing page_exit without the key —
|
|
2152
2413
|
// requiring it would 422 whole keepalive beacon batches.
|
|
2153
|
-
scroll_baseline_percent:
|
|
2154
|
-
page:
|
|
2155
|
-
path:
|
|
2156
|
-
})
|
|
2157
|
-
})
|
|
2158
|
-
var pageExitConfigSchema =
|
|
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()
|
|
2417
|
+
})
|
|
2418
|
+
});
|
|
2419
|
+
var pageExitConfigSchema = z8.strictObject({});
|
|
2159
2420
|
|
|
2160
2421
|
// ../tracking-core/src/events/phone-click.ts
|
|
2161
|
-
var
|
|
2162
|
-
var phoneClickMetadataSchema =
|
|
2163
|
-
phone_number:
|
|
2164
|
-
page:
|
|
2165
|
-
path:
|
|
2166
|
-
})
|
|
2167
|
-
section:
|
|
2168
|
-
})
|
|
2169
|
-
var phoneClickConfigSchema =
|
|
2170
|
-
autoCapture:
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
})
|
|
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()
|
|
2427
|
+
}),
|
|
2428
|
+
section: z9.optional(z9.nullable(z9.string()))
|
|
2429
|
+
});
|
|
2430
|
+
var phoneClickConfigSchema = z9.strictObject({
|
|
2431
|
+
autoCapture: z9.optional(
|
|
2432
|
+
z9.strictObject({
|
|
2433
|
+
selector: z9.optional(z9.string())
|
|
2434
|
+
})
|
|
2435
|
+
)
|
|
2436
|
+
});
|
|
2174
2437
|
|
|
2175
2438
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
2176
|
-
var
|
|
2177
|
-
var scrollDepthMetadataSchema =
|
|
2178
|
-
depth_percent:
|
|
2179
|
-
page:
|
|
2180
|
-
path:
|
|
2181
|
-
})
|
|
2182
|
-
})
|
|
2183
|
-
var scrollDepthConfigSchema =
|
|
2184
|
-
thresholds:
|
|
2185
|
-
})
|
|
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()
|
|
2444
|
+
})
|
|
2445
|
+
});
|
|
2446
|
+
var scrollDepthConfigSchema = z10.strictObject({
|
|
2447
|
+
thresholds: z10.array(z10.int().check(z10.gte(1), z10.lte(100))).check(z10.minLength(1))
|
|
2448
|
+
});
|
|
2186
2449
|
|
|
2187
2450
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
2188
|
-
var
|
|
2451
|
+
var z11 = __toESM(require("zod/mini"));
|
|
2189
2452
|
var PAGE_IDENTITY_MAX_LENGTH = 64;
|
|
2190
2453
|
var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
|
|
2191
|
-
var pageIdentitySchema =
|
|
2192
|
-
|
|
2193
|
-
|
|
2454
|
+
var pageIdentitySchema = z11.string().check(
|
|
2455
|
+
z11.maxLength(PAGE_IDENTITY_MAX_LENGTH),
|
|
2456
|
+
z11.regex(PAGE_IDENTITY_PATTERN, {
|
|
2457
|
+
message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
|
|
2458
|
+
})
|
|
2459
|
+
);
|
|
2194
2460
|
var specificPageNameSchema = pageIdentitySchema;
|
|
2195
|
-
var specificPageVisitMetadataSchema =
|
|
2461
|
+
var specificPageVisitMetadataSchema = z11.strictObject({
|
|
2196
2462
|
page_name: specificPageNameSchema,
|
|
2197
|
-
page:
|
|
2198
|
-
path:
|
|
2199
|
-
})
|
|
2200
|
-
})
|
|
2201
|
-
var specificPageVisitConfigSchema =
|
|
2202
|
-
pages:
|
|
2203
|
-
|
|
2463
|
+
page: z11.strictObject({
|
|
2464
|
+
path: z11.string()
|
|
2465
|
+
})
|
|
2466
|
+
});
|
|
2467
|
+
var specificPageVisitConfigSchema = z11.strictObject({
|
|
2468
|
+
pages: z11.array(
|
|
2469
|
+
z11.strictObject({
|
|
2204
2470
|
name: specificPageNameSchema,
|
|
2205
|
-
pathPattern:
|
|
2471
|
+
pathPattern: z11.custom((value) => value instanceof RegExp, {
|
|
2206
2472
|
message: "pathPattern must be a RegExp"
|
|
2207
2473
|
})
|
|
2208
|
-
})
|
|
2209
|
-
).
|
|
2210
|
-
})
|
|
2474
|
+
})
|
|
2475
|
+
).check(z11.minLength(1))
|
|
2476
|
+
});
|
|
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({});
|
|
2211
2501
|
|
|
2212
2502
|
// ../tracking-core/src/events/time-on-site.ts
|
|
2213
|
-
var
|
|
2214
|
-
var timeOnSiteMetadataSchema =
|
|
2215
|
-
duration_ms:
|
|
2216
|
-
page:
|
|
2217
|
-
path:
|
|
2218
|
-
})
|
|
2219
|
-
})
|
|
2220
|
-
var timeOnSiteConfigSchema =
|
|
2221
|
-
thresholdSeconds:
|
|
2222
|
-
})
|
|
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()
|
|
2508
|
+
})
|
|
2509
|
+
});
|
|
2510
|
+
var timeOnSiteConfigSchema = z13.strictObject({
|
|
2511
|
+
thresholdSeconds: z13.int().check(z13.positive())
|
|
2512
|
+
});
|
|
2223
2513
|
|
|
2224
2514
|
// ../tracking-core/src/events/semantics.ts
|
|
2225
2515
|
var EVENT_SEMANTICS = {
|
|
@@ -2288,6 +2578,18 @@ var EVENT_SEMANTICS = {
|
|
|
2288
2578
|
category: "engagement",
|
|
2289
2579
|
outcomeRole: "engagement",
|
|
2290
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"
|
|
2291
2593
|
}
|
|
2292
2594
|
};
|
|
2293
2595
|
|
|
@@ -2343,6 +2645,20 @@ var EVENT_REGISTRY = {
|
|
|
2343
2645
|
metadataSchema: pageExitMetadataSchema,
|
|
2344
2646
|
configSchema: pageExitConfigSchema
|
|
2345
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
|
+
},
|
|
2346
2662
|
// --- manual triggers ---
|
|
2347
2663
|
form_submit: {
|
|
2348
2664
|
kind: "manual",
|
|
@@ -2378,7 +2694,7 @@ function createTypedClient(raw, registry, options = {}) {
|
|
|
2378
2694
|
trackEvent(eventType, metadata, opts) {
|
|
2379
2695
|
if (debug) {
|
|
2380
2696
|
const def = getEventDefinition(eventType);
|
|
2381
|
-
def.metadataSchema
|
|
2697
|
+
(0, import_mini2.parse)(def.metadataSchema, metadata);
|
|
2382
2698
|
}
|
|
2383
2699
|
raw.trackEvent({
|
|
2384
2700
|
eventType,
|
|
@@ -2948,6 +3264,57 @@ function attachCtaClickCapture(client, config) {
|
|
|
2948
3264
|
};
|
|
2949
3265
|
}
|
|
2950
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
|
+
|
|
2951
3318
|
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2952
3319
|
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2953
3320
|
function safeDecodeURIComponent(value) {
|
|
@@ -3002,117 +3369,6 @@ function attachPhoneClickCapture(client, config) {
|
|
|
3002
3369
|
};
|
|
3003
3370
|
}
|
|
3004
3371
|
|
|
3005
|
-
// ../tracking-core/src/resources/sales/schema.ts
|
|
3006
|
-
var import_zod12 = require("zod");
|
|
3007
|
-
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
3008
|
-
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
3009
|
-
var currencySchema = import_zod12.z.enum(SUPPORTED_CURRENCIES);
|
|
3010
|
-
var centsSchema = import_zod12.z.number().int().nonnegative();
|
|
3011
|
-
var quantitySchema = import_zod12.z.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
3012
|
-
var metadataSchema = import_zod12.z.record(import_zod12.z.unknown());
|
|
3013
|
-
var saleItemSchema = import_zod12.z.object({
|
|
3014
|
-
external_item_id: import_zod12.z.string().nullable().optional(),
|
|
3015
|
-
name: import_zod12.z.string().nullable().optional(),
|
|
3016
|
-
category: import_zod12.z.string().nullable().optional(),
|
|
3017
|
-
quantity: quantitySchema,
|
|
3018
|
-
unit_price_cents: centsSchema,
|
|
3019
|
-
// Non-negativity validated on the wire — same contract as the other cents
|
|
3020
|
-
// fields — and backstopped by the DB CHECK.
|
|
3021
|
-
unit_cost_cents: centsSchema.nullable().optional()
|
|
3022
|
-
}).strict();
|
|
3023
|
-
var saleServiceSchema = import_zod12.z.object({
|
|
3024
|
-
service: import_zod12.z.string(),
|
|
3025
|
-
amount_cents: centsSchema
|
|
3026
|
-
}).strict();
|
|
3027
|
-
var customerNameSchema = import_zod12.z.string().max(200);
|
|
3028
|
-
var customerPhoneSchema = import_zod12.z.string().max(64);
|
|
3029
|
-
var customerEmailSchema = import_zod12.z.string().max(320).email();
|
|
3030
|
-
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
3031
|
-
if (val.services != null) {
|
|
3032
|
-
if (val.service != null) {
|
|
3033
|
-
ctx.addIssue({
|
|
3034
|
-
code: import_zod12.z.ZodIssueCode.custom,
|
|
3035
|
-
message: "pass either `service` or `services`, not both",
|
|
3036
|
-
path: ["services"]
|
|
3037
|
-
});
|
|
3038
|
-
}
|
|
3039
|
-
if (val.services.length === 0) {
|
|
3040
|
-
ctx.addIssue({
|
|
3041
|
-
code: import_zod12.z.ZodIssueCode.custom,
|
|
3042
|
-
message: "`services` must not be empty",
|
|
3043
|
-
path: ["services"]
|
|
3044
|
-
});
|
|
3045
|
-
}
|
|
3046
|
-
const keys = val.services.map((s) => s.service);
|
|
3047
|
-
if (new Set(keys).size !== keys.length) {
|
|
3048
|
-
ctx.addIssue({
|
|
3049
|
-
code: import_zod12.z.ZodIssueCode.custom,
|
|
3050
|
-
message: "`services` must not list the same service more than once",
|
|
3051
|
-
path: ["services"]
|
|
3052
|
-
});
|
|
3053
|
-
}
|
|
3054
|
-
if (val.amount_total_cents != null) {
|
|
3055
|
-
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
3056
|
-
if (val.amount_total_cents !== sum) {
|
|
3057
|
-
ctx.addIssue({
|
|
3058
|
-
code: import_zod12.z.ZodIssueCode.custom,
|
|
3059
|
-
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
3060
|
-
path: ["amount_total_cents"]
|
|
3061
|
-
});
|
|
3062
|
-
}
|
|
3063
|
-
}
|
|
3064
|
-
} else if (requireAmount && val.amount_total_cents == null) {
|
|
3065
|
-
ctx.addIssue({
|
|
3066
|
-
code: import_zod12.z.ZodIssueCode.custom,
|
|
3067
|
-
message: "amount_total_cents is required unless `services` is provided",
|
|
3068
|
-
path: ["amount_total_cents"]
|
|
3069
|
-
});
|
|
3070
|
-
}
|
|
3071
|
-
}
|
|
3072
|
-
var saleCreateSchema = import_zod12.z.object({
|
|
3073
|
-
external_id: import_zod12.z.string().nullable().optional(),
|
|
3074
|
-
description: import_zod12.z.string().nullable().optional(),
|
|
3075
|
-
service: import_zod12.z.string().nullable().optional(),
|
|
3076
|
-
services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
|
|
3077
|
-
currency: currencySchema,
|
|
3078
|
-
// Optional only because the plural `services` form derives it from the sum
|
|
3079
|
-
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
3080
|
-
amount_total_cents: centsSchema.nullable().optional(),
|
|
3081
|
-
occurred_at: import_zod12.z.string().datetime(),
|
|
3082
|
-
environment: import_zod12.z.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
3083
|
-
items: import_zod12.z.array(saleItemSchema).default([]),
|
|
3084
|
-
metadata: metadataSchema.nullable().optional(),
|
|
3085
|
-
customer_name: customerNameSchema.nullable().optional(),
|
|
3086
|
-
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
3087
|
-
customer_email: customerEmailSchema.nullable().optional(),
|
|
3088
|
-
// CASL consent attestation: the customer agreed to receive SMS. Recorded
|
|
3089
|
-
// with a timestamp server-side; every SMS send path gates on it.
|
|
3090
|
-
//
|
|
3091
|
-
// Tri-state: omit it (or send null) to let the server apply the business's
|
|
3092
|
-
// configured default-opt-in policy, honouring a returning customer's
|
|
3093
|
-
// remembered preference. Send an explicit boolean to assert consent state
|
|
3094
|
-
// yourself — `false` records a deliberate opt-out.
|
|
3095
|
-
sms_consent: import_zod12.z.boolean().nullable().optional()
|
|
3096
|
-
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
3097
|
-
var saleUpdateSchema = import_zod12.z.object({
|
|
3098
|
-
description: import_zod12.z.string().nullable().optional(),
|
|
3099
|
-
service: import_zod12.z.string().nullable().optional(),
|
|
3100
|
-
services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
|
|
3101
|
-
currency: currencySchema.optional(),
|
|
3102
|
-
amount_total_cents: centsSchema.optional(),
|
|
3103
|
-
occurred_at: import_zod12.z.string().datetime().optional(),
|
|
3104
|
-
items: import_zod12.z.array(saleItemSchema).optional(),
|
|
3105
|
-
metadata: metadataSchema.nullable().optional(),
|
|
3106
|
-
customer_name: customerNameSchema.nullable().optional(),
|
|
3107
|
-
// Re-attest when changing a filler-looking name; the server clears the
|
|
3108
|
-
// prior attestation whenever `customer_name` changes.
|
|
3109
|
-
customer_name_placeholder_confirmed: import_zod12.z.boolean().optional(),
|
|
3110
|
-
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
3111
|
-
customer_email: customerEmailSchema.nullable().optional(),
|
|
3112
|
-
// NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
|
|
3113
|
-
sms_consent: import_zod12.z.boolean().optional()
|
|
3114
|
-
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
|
|
3115
|
-
|
|
3116
3372
|
// src/hooks.ts
|
|
3117
3373
|
function useGclid() {
|
|
3118
3374
|
const [gclid, setGclid] = (0, import_react.useState)(null);
|
|
@@ -3444,7 +3700,7 @@ function GoogleAdsTracking(props) {
|
|
|
3444
3700
|
var import_react6 = require("react");
|
|
3445
3701
|
|
|
3446
3702
|
// package.json
|
|
3447
|
-
var version = "
|
|
3703
|
+
var version = "1.1.0";
|
|
3448
3704
|
|
|
3449
3705
|
// ../tracking-core/src/phone-react.tsx
|
|
3450
3706
|
var import_react5 = require("react");
|
|
@@ -3567,7 +3823,8 @@ function createTracking(options) {
|
|
|
3567
3823
|
// Still publish phone config so usePhoneField/<PhoneField> work even when
|
|
3568
3824
|
// tracking is disabled (missing apiKey/endpoint).
|
|
3569
3825
|
TrackingProvider: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneConfigProvider, { value: phone ?? null, children }),
|
|
3570
|
-
useTracking: () => noopTyped
|
|
3826
|
+
useTracking: () => noopTyped,
|
|
3827
|
+
decorateUrl: (url) => url
|
|
3571
3828
|
};
|
|
3572
3829
|
}
|
|
3573
3830
|
const TrackingContext = (0, import_react6.createContext)(null);
|
|
@@ -3586,8 +3843,8 @@ function createTracking(options) {
|
|
|
3586
3843
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- gtagIdsKey is stable proxy
|
|
3587
3844
|
[gtagId, gtagIdsKey]
|
|
3588
3845
|
);
|
|
3589
|
-
const rawClient = (0, import_react6.useMemo)(
|
|
3590
|
-
|
|
3846
|
+
const rawClient = (0, import_react6.useMemo)(() => {
|
|
3847
|
+
const created = getOrCreateTrackingClient({
|
|
3591
3848
|
apiKey,
|
|
3592
3849
|
endpoint,
|
|
3593
3850
|
surface: "react",
|
|
@@ -3598,9 +3855,10 @@ function createTracking(options) {
|
|
|
3598
3855
|
activeGtagIds: resolvedGtagIds,
|
|
3599
3856
|
configSiteId: trackingConfig?.siteId ?? null,
|
|
3600
3857
|
debug
|
|
3601
|
-
})
|
|
3602
|
-
|
|
3603
|
-
|
|
3858
|
+
});
|
|
3859
|
+
stripLinkParamFromLocation();
|
|
3860
|
+
return created;
|
|
3861
|
+
}, [resolvedGtagIds]);
|
|
3604
3862
|
const conversionStore = (0, import_react6.useMemo)(
|
|
3605
3863
|
() => trackingConfig ? getTrackingConfigRuntime(trackingConfig) : conversionConfig ? resolveConversionConfig({
|
|
3606
3864
|
cdnUrl: conversionConfig.cdnUrl,
|
|
@@ -3654,6 +3912,11 @@ function createTracking(options) {
|
|
|
3654
3912
|
if (timeOnSite) {
|
|
3655
3913
|
detachers.push(attachTimeOnSite(detectorClient, timeOnSite));
|
|
3656
3914
|
}
|
|
3915
|
+
detachers.push(
|
|
3916
|
+
attachSiteLinkCapture(detectorClient, {
|
|
3917
|
+
linkedHostnames: () => conversionStore?.linkedHostnames() ?? []
|
|
3918
|
+
})
|
|
3919
|
+
);
|
|
3657
3920
|
const specificPageVisit = triggers.automatic.specific_page_visit;
|
|
3658
3921
|
if (specificPageVisit) {
|
|
3659
3922
|
detachers.push(attachSpecificPageVisit(detectorClient, specificPageVisit));
|
|
@@ -3696,7 +3959,14 @@ function createTracking(options) {
|
|
|
3696
3959
|
}
|
|
3697
3960
|
return client;
|
|
3698
3961
|
}
|
|
3699
|
-
return {
|
|
3962
|
+
return {
|
|
3963
|
+
TrackingProvider,
|
|
3964
|
+
useTracking,
|
|
3965
|
+
decorateUrl: (url) => decorateCrossSiteUrl(
|
|
3966
|
+
url,
|
|
3967
|
+
trackingConfig ? getTrackingConfigRuntime(trackingConfig).linkedHostnames() : []
|
|
3968
|
+
)
|
|
3969
|
+
};
|
|
3700
3970
|
}
|
|
3701
3971
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3702
3972
|
0 && (module.exports = {
|