@aranova/tracking-react 0.17.3 → 0.18.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 +39 -20
- package/dist/index.d.mts +169 -12
- package/dist/index.d.ts +169 -12
- package/dist/index.js +428 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +425 -8
- package/dist/index.mjs.map +1 -1
- package/dist/phone.js +82 -0
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +82 -0
- package/dist/phone.mjs.map +1 -1
- package/dist/{sales-C3jFBx08.d.mts → sales-QqKh6_iy.d.mts} +55 -2
- package/dist/{sales-C3jFBx08.d.ts → sales-QqKh6_iy.d.ts} +55 -2
- package/dist/sales.d.mts +1 -1
- package/dist/sales.d.ts +1 -1
- package/dist/sales.js +16 -0
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +16 -0
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(src_exports, {
|
|
|
25
25
|
ConsentBanner: () => ConsentBanner,
|
|
26
26
|
DEFAULT_DECLINE_TTL_DAYS: () => DEFAULT_DECLINE_TTL_DAYS,
|
|
27
27
|
DEFAULT_PHONE_COUNTRY: () => DEFAULT_PHONE_COUNTRY,
|
|
28
|
+
EVENT_SEMANTICS: () => EVENT_SEMANTICS,
|
|
28
29
|
GoogleAdsTracking: () => GoogleAdsTracking,
|
|
29
30
|
NAMED_RANGES: () => NAMED_RANGES,
|
|
30
31
|
PhoneField: () => PhoneField,
|
|
@@ -45,6 +46,8 @@ __export(src_exports, {
|
|
|
45
46
|
fromMinor: () => fromMinor,
|
|
46
47
|
getConsentChoice: () => getConsentChoice,
|
|
47
48
|
getConsentState: () => getConsentState,
|
|
49
|
+
getEventSemantics: () => getEventSemantics,
|
|
50
|
+
getTrackingConfigRuntime: () => getTrackingConfigRuntime,
|
|
48
51
|
onConsentChange: () => onConsentChange,
|
|
49
52
|
optIn: () => optIn,
|
|
50
53
|
optOut: () => optOut,
|
|
@@ -680,6 +683,7 @@ function parseConversionConfig(raw) {
|
|
|
680
683
|
business_id: typeof obj.business_id === "string" ? obj.business_id : void 0,
|
|
681
684
|
customer_id: typeof obj.customer_id === "string" ? obj.customer_id : null,
|
|
682
685
|
environment: typeof obj.environment === "string" ? obj.environment : void 0,
|
|
686
|
+
google_tracking_state: obj.google_tracking_state === "active" ? "active" : "disabled",
|
|
683
687
|
gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
|
|
684
688
|
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
685
689
|
services,
|
|
@@ -815,6 +819,283 @@ function formatDateInTz(iso, timeZone, opts, locale) {
|
|
|
815
819
|
}).format(date);
|
|
816
820
|
}
|
|
817
821
|
|
|
822
|
+
// ../tracking-core/src/resources/tracking-config-runtime.ts
|
|
823
|
+
var CACHE_PREFIX2 = "_aranova_cfg_runtime_";
|
|
824
|
+
var AUTHORITY_TTL_MS = 6e4;
|
|
825
|
+
var runtimes = /* @__PURE__ */ new Map();
|
|
826
|
+
var configuredIds = /* @__PURE__ */ new Set();
|
|
827
|
+
var scriptLoad = null;
|
|
828
|
+
var jsInitialized = false;
|
|
829
|
+
function cacheKey2(url) {
|
|
830
|
+
return `${CACHE_PREFIX2}${url}`;
|
|
831
|
+
}
|
|
832
|
+
function readCache2(url) {
|
|
833
|
+
if (typeof window === "undefined") return null;
|
|
834
|
+
try {
|
|
835
|
+
const raw = window.sessionStorage.getItem(cacheKey2(url));
|
|
836
|
+
if (!raw) return null;
|
|
837
|
+
const parsed = JSON.parse(raw);
|
|
838
|
+
const config = parseConversionConfig(parsed.config);
|
|
839
|
+
if (!config) return null;
|
|
840
|
+
return {
|
|
841
|
+
etag: typeof parsed.etag === "string" ? parsed.etag : null,
|
|
842
|
+
config
|
|
843
|
+
};
|
|
844
|
+
} catch {
|
|
845
|
+
return null;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
function writeCache2(url, entry) {
|
|
849
|
+
if (typeof window === "undefined") return;
|
|
850
|
+
try {
|
|
851
|
+
window.sessionStorage.setItem(cacheKey2(url), JSON.stringify(entry));
|
|
852
|
+
} catch {
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
function isTombstone(config) {
|
|
856
|
+
return config.google_tracking_state === "disabled" || Object.keys(config.gtag_ids).length === 0;
|
|
857
|
+
}
|
|
858
|
+
function validateConfig(config, ref) {
|
|
859
|
+
return config.business_id === ref.businessId && config.environment === ref.environment && (config.google_tracking_state === "active" || config.google_tracking_state === "disabled");
|
|
860
|
+
}
|
|
861
|
+
function pageViewSnapshot() {
|
|
862
|
+
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
863
|
+
return {
|
|
864
|
+
href: window.location.href,
|
|
865
|
+
title: document.title || null,
|
|
866
|
+
referrer: document.referrer || null
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
function ensureScript(gtagId) {
|
|
870
|
+
if (typeof window === "undefined" || typeof document === "undefined") return Promise.resolve();
|
|
871
|
+
applyDefaultConsentState();
|
|
872
|
+
loadGtagScript(gtagId);
|
|
873
|
+
if (scriptLoad) return scriptLoad;
|
|
874
|
+
scriptLoad = new Promise((resolve) => {
|
|
875
|
+
const script = document.querySelector(
|
|
876
|
+
'script[data-aranova-tracking="aranova-gtag-loader"]'
|
|
877
|
+
);
|
|
878
|
+
if (!script) {
|
|
879
|
+
resolve();
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
if (script.dataset.loaded === "true") {
|
|
883
|
+
resolve();
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
window.setTimeout(resolve, 0);
|
|
887
|
+
script.addEventListener(
|
|
888
|
+
"load",
|
|
889
|
+
() => {
|
|
890
|
+
script.dataset.loaded = "true";
|
|
891
|
+
resolve();
|
|
892
|
+
},
|
|
893
|
+
{ once: true }
|
|
894
|
+
);
|
|
895
|
+
script.addEventListener("error", () => resolve(), { once: true });
|
|
896
|
+
});
|
|
897
|
+
return scriptLoad;
|
|
898
|
+
}
|
|
899
|
+
var TrackingConfigRuntime = class {
|
|
900
|
+
constructor(ref, fetchImpl = globalThis.fetch) {
|
|
901
|
+
this.ref = ref;
|
|
902
|
+
this.fetchImpl = fetchImpl;
|
|
903
|
+
this.current = null;
|
|
904
|
+
this.etag = null;
|
|
905
|
+
this.stateValue = "unconfirmed";
|
|
906
|
+
this.confirmedAt = 0;
|
|
907
|
+
this.inFlight = null;
|
|
908
|
+
this.conversionQueue = [];
|
|
909
|
+
this.automaticQueue = [];
|
|
910
|
+
this.pageQueue = [];
|
|
911
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
912
|
+
const cached = readCache2(ref.cdnUrl);
|
|
913
|
+
this.current = cached?.config ?? null;
|
|
914
|
+
this.etag = cached?.etag ?? null;
|
|
915
|
+
void this.revalidate();
|
|
916
|
+
if (typeof window !== "undefined") {
|
|
917
|
+
window.addEventListener("visibilitychange", () => {
|
|
918
|
+
if (document.visibilityState === "visible") void this.revalidate();
|
|
919
|
+
});
|
|
920
|
+
window.addEventListener("focus", () => void this.revalidate());
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
state() {
|
|
924
|
+
return this.stateValue;
|
|
925
|
+
}
|
|
926
|
+
config() {
|
|
927
|
+
return this.stateValue === "active" || this.stateValue === "tombstone" ? this.current : null;
|
|
928
|
+
}
|
|
929
|
+
__unsafeExpireAuthorityForTests() {
|
|
930
|
+
this.confirmedAt = 0;
|
|
931
|
+
}
|
|
932
|
+
subscribe(listener) {
|
|
933
|
+
this.listeners.add(listener);
|
|
934
|
+
return () => this.listeners.delete(listener);
|
|
935
|
+
}
|
|
936
|
+
async ensureAuthority() {
|
|
937
|
+
if (this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS) {
|
|
938
|
+
return true;
|
|
939
|
+
}
|
|
940
|
+
await this.revalidate();
|
|
941
|
+
return this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS;
|
|
942
|
+
}
|
|
943
|
+
async revalidate() {
|
|
944
|
+
if (typeof window === "undefined" || !this.fetchImpl) return;
|
|
945
|
+
if (this.inFlight) return this.inFlight;
|
|
946
|
+
this.inFlight = this.revalidateNow().finally(() => {
|
|
947
|
+
this.inFlight = null;
|
|
948
|
+
});
|
|
949
|
+
return this.inFlight;
|
|
950
|
+
}
|
|
951
|
+
queuePageView(snapshot = pageViewSnapshot()) {
|
|
952
|
+
if (!snapshot) return;
|
|
953
|
+
this.pageQueue.push(snapshot);
|
|
954
|
+
void this.flush();
|
|
955
|
+
}
|
|
956
|
+
fireConversion(key, options) {
|
|
957
|
+
this.conversionQueue.push({ key, ...options });
|
|
958
|
+
void this.flush();
|
|
959
|
+
}
|
|
960
|
+
queueAutomaticEvent(eventType, metadata, transactionPath) {
|
|
961
|
+
this.automaticQueue.push({ eventType, metadata, transactionPath });
|
|
962
|
+
void this.flush();
|
|
963
|
+
}
|
|
964
|
+
listGoals() {
|
|
965
|
+
return this.current?.goals ?? [];
|
|
966
|
+
}
|
|
967
|
+
async revalidateNow() {
|
|
968
|
+
try {
|
|
969
|
+
const headers = {};
|
|
970
|
+
if (this.etag) headers["If-None-Match"] = this.etag;
|
|
971
|
+
const response = await this.fetchImpl(this.ref.cdnUrl, {
|
|
972
|
+
method: "GET",
|
|
973
|
+
headers,
|
|
974
|
+
cache: "no-cache"
|
|
975
|
+
});
|
|
976
|
+
if (response.status === 304 && this.current && validateConfig(this.current, this.ref)) {
|
|
977
|
+
this.confirm(this.current, this.etag);
|
|
978
|
+
await this.flush();
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
if (!response.ok) {
|
|
982
|
+
this.expireAuthority();
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
const next = parseConversionConfig(await response.json());
|
|
986
|
+
if (!next || !validateConfig(next, this.ref)) {
|
|
987
|
+
this.expireAuthority();
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
if (this.current && next.config_version < this.current.config_version) {
|
|
991
|
+
this.expireAuthority();
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
this.confirm(next, response.headers.get("ETag"));
|
|
995
|
+
await this.flush();
|
|
996
|
+
} catch {
|
|
997
|
+
this.expireAuthority();
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
expireAuthority() {
|
|
1001
|
+
if (this.stateValue !== "unconfirmed") this.stateValue = "unconfirmed";
|
|
1002
|
+
}
|
|
1003
|
+
confirm(config, etag) {
|
|
1004
|
+
this.current = config;
|
|
1005
|
+
this.etag = etag;
|
|
1006
|
+
this.confirmedAt = Date.now();
|
|
1007
|
+
this.stateValue = isTombstone(config) ? "tombstone" : "active";
|
|
1008
|
+
writeCache2(this.ref.cdnUrl, { etag, config });
|
|
1009
|
+
if (this.stateValue === "tombstone") {
|
|
1010
|
+
this.conversionQueue.length = 0;
|
|
1011
|
+
this.automaticQueue.length = 0;
|
|
1012
|
+
this.pageQueue.length = 0;
|
|
1013
|
+
}
|
|
1014
|
+
for (const listener of this.listeners) listener();
|
|
1015
|
+
}
|
|
1016
|
+
async flush() {
|
|
1017
|
+
if (!await this.ensureAuthority()) return;
|
|
1018
|
+
if (this.stateValue !== "active" || !this.current) return;
|
|
1019
|
+
const ids = Object.values(this.current.gtag_ids).filter(
|
|
1020
|
+
(id) => typeof id === "string" && isValidGtagId(id)
|
|
1021
|
+
);
|
|
1022
|
+
if (ids.length === 0) return;
|
|
1023
|
+
await ensureScript(ids[0]);
|
|
1024
|
+
const gtag = window.gtag;
|
|
1025
|
+
if (typeof gtag !== "function") return;
|
|
1026
|
+
if (!jsInitialized) {
|
|
1027
|
+
gtag("js", /* @__PURE__ */ new Date());
|
|
1028
|
+
jsInitialized = true;
|
|
1029
|
+
}
|
|
1030
|
+
for (const id of ids) {
|
|
1031
|
+
if (configuredIds.has(id)) continue;
|
|
1032
|
+
gtag("config", id, { send_page_view: false });
|
|
1033
|
+
configuredIds.add(id);
|
|
1034
|
+
}
|
|
1035
|
+
while (this.pageQueue.length) {
|
|
1036
|
+
const page = this.pageQueue.shift();
|
|
1037
|
+
gtag("event", "page_view", {
|
|
1038
|
+
page_location: page.href,
|
|
1039
|
+
page_title: page.title ?? void 0,
|
|
1040
|
+
page_referrer: page.referrer ?? void 0
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
while (this.automaticQueue.length) {
|
|
1044
|
+
const event = this.automaticQueue.shift();
|
|
1045
|
+
for (const goal of this.current.goals) {
|
|
1046
|
+
if (goal.kind !== "event" || !goal.firing) continue;
|
|
1047
|
+
if (!automaticThresholdMet(goal, event.eventType, event.metadata)) continue;
|
|
1048
|
+
this.conversionQueue.push({
|
|
1049
|
+
key: goal.key,
|
|
1050
|
+
transactionId: `auto:${goal.key}:${event.transactionPath}`
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
while (this.conversionQueue.length) {
|
|
1055
|
+
const item = this.conversionQueue.shift();
|
|
1056
|
+
const goal = this.current.goals.find((g) => g.key === item.key);
|
|
1057
|
+
const firing = goal?.firing;
|
|
1058
|
+
if (!firing || getConsentState() === "denied") continue;
|
|
1059
|
+
const currency = item.currency ?? firing.currency ?? null;
|
|
1060
|
+
const value = item.value ?? (firing.value_cents != null && currency ? fromMinor(firing.value_cents, currency) : null);
|
|
1061
|
+
fireGtagConversion({
|
|
1062
|
+
sendTo: firing.send_to,
|
|
1063
|
+
value,
|
|
1064
|
+
currency,
|
|
1065
|
+
transactionId: item.transactionId ?? null
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
};
|
|
1070
|
+
function automaticThresholdMet(goal, eventType, metadata) {
|
|
1071
|
+
const t = goal.trigger;
|
|
1072
|
+
if (!t || t.event_type !== eventType) return false;
|
|
1073
|
+
switch (eventType) {
|
|
1074
|
+
case "scroll_depth":
|
|
1075
|
+
return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
|
|
1076
|
+
case "time_on_site":
|
|
1077
|
+
return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
|
|
1078
|
+
case "multi_page_session":
|
|
1079
|
+
return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
|
|
1080
|
+
case "specific_page_visit":
|
|
1081
|
+
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
1082
|
+
case "page_view":
|
|
1083
|
+
case "form_start":
|
|
1084
|
+
case "phone_click":
|
|
1085
|
+
return true;
|
|
1086
|
+
default:
|
|
1087
|
+
return false;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
function getTrackingConfigRuntime(ref, fetchImpl) {
|
|
1091
|
+
const key = `${ref.cdnUrl}|${ref.businessId}|${ref.environment}`;
|
|
1092
|
+
const existing = runtimes.get(key);
|
|
1093
|
+
if (existing) return existing;
|
|
1094
|
+
const runtime = new TrackingConfigRuntime(ref, fetchImpl ?? globalThis.fetch);
|
|
1095
|
+
runtimes.set(key, runtime);
|
|
1096
|
+
return runtime;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
818
1099
|
// ../tracking-core/src/resources/conversion-autofire.ts
|
|
819
1100
|
function thresholdMet(goal, eventType, metadata) {
|
|
820
1101
|
const t = goal.trigger;
|
|
@@ -847,6 +1128,12 @@ function createConversionAutoFire(store) {
|
|
|
847
1128
|
for (const goal of store.listGoals()) {
|
|
848
1129
|
if (goal.kind !== "event" || !goal.firing) continue;
|
|
849
1130
|
if (!thresholdMet(goal, eventType, metadata)) continue;
|
|
1131
|
+
if ("queueAutomaticEvent" in store) {
|
|
1132
|
+
store.fireConversion(goal.key, {
|
|
1133
|
+
transactionId: `auto:${goal.key}:${currentPath()}`
|
|
1134
|
+
});
|
|
1135
|
+
continue;
|
|
1136
|
+
}
|
|
850
1137
|
const firing = goal.firing;
|
|
851
1138
|
const cents = firing.value_cents ?? null;
|
|
852
1139
|
const currency = firing.currency ?? null;
|
|
@@ -862,6 +1149,10 @@ function createConversionAutoFire(store) {
|
|
|
862
1149
|
}
|
|
863
1150
|
return {
|
|
864
1151
|
onAutomaticEvent(eventType, metadata) {
|
|
1152
|
+
if ("queueAutomaticEvent" in store) {
|
|
1153
|
+
store.queueAutomaticEvent(eventType, metadata, currentPath());
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
865
1156
|
if (store.isReady()) {
|
|
866
1157
|
fireMatching(eventType, metadata);
|
|
867
1158
|
return;
|
|
@@ -1579,69 +1870,154 @@ var timeOnSiteConfigSchema = import_zod11.z.object({
|
|
|
1579
1870
|
thresholdSeconds: import_zod11.z.number().int().positive()
|
|
1580
1871
|
}).strict();
|
|
1581
1872
|
|
|
1873
|
+
// ../tracking-core/src/events/semantics.ts
|
|
1874
|
+
var EVENT_SEMANTICS = {
|
|
1875
|
+
page_view: {
|
|
1876
|
+
label: "Page view",
|
|
1877
|
+
category: "page",
|
|
1878
|
+
outcomeRole: "navigation",
|
|
1879
|
+
clientVisibility: "simple"
|
|
1880
|
+
},
|
|
1881
|
+
time_on_site: {
|
|
1882
|
+
label: "Time on site",
|
|
1883
|
+
category: "engagement",
|
|
1884
|
+
outcomeRole: "engagement",
|
|
1885
|
+
clientVisibility: "detailed"
|
|
1886
|
+
},
|
|
1887
|
+
specific_page_visit: {
|
|
1888
|
+
label: "Key page visit",
|
|
1889
|
+
category: "engagement",
|
|
1890
|
+
outcomeRole: "engagement",
|
|
1891
|
+
clientVisibility: "detailed"
|
|
1892
|
+
},
|
|
1893
|
+
scroll_depth: {
|
|
1894
|
+
label: "Scroll depth",
|
|
1895
|
+
category: "engagement",
|
|
1896
|
+
outcomeRole: "engagement",
|
|
1897
|
+
clientVisibility: "detailed"
|
|
1898
|
+
},
|
|
1899
|
+
multi_page_session: {
|
|
1900
|
+
label: "Multi-page session",
|
|
1901
|
+
category: "engagement",
|
|
1902
|
+
outcomeRole: "engagement",
|
|
1903
|
+
clientVisibility: "detailed"
|
|
1904
|
+
},
|
|
1905
|
+
form_start: {
|
|
1906
|
+
label: "Form started",
|
|
1907
|
+
category: "engagement",
|
|
1908
|
+
outcomeRole: "engagement",
|
|
1909
|
+
clientVisibility: "simple"
|
|
1910
|
+
},
|
|
1911
|
+
sdk_heartbeat: {
|
|
1912
|
+
label: "SDK heartbeat",
|
|
1913
|
+
category: "system",
|
|
1914
|
+
outcomeRole: "diagnostic",
|
|
1915
|
+
clientVisibility: "hidden"
|
|
1916
|
+
},
|
|
1917
|
+
page_exit: {
|
|
1918
|
+
label: "Page exit",
|
|
1919
|
+
category: "engagement",
|
|
1920
|
+
outcomeRole: "diagnostic",
|
|
1921
|
+
clientVisibility: "detailed"
|
|
1922
|
+
},
|
|
1923
|
+
form_submit: {
|
|
1924
|
+
label: "Form submitted",
|
|
1925
|
+
category: "lead",
|
|
1926
|
+
outcomeRole: "lead",
|
|
1927
|
+
clientVisibility: "simple"
|
|
1928
|
+
},
|
|
1929
|
+
phone_click: {
|
|
1930
|
+
label: "Phone click",
|
|
1931
|
+
category: "lead",
|
|
1932
|
+
outcomeRole: "lead",
|
|
1933
|
+
clientVisibility: "simple"
|
|
1934
|
+
},
|
|
1935
|
+
cta_click: {
|
|
1936
|
+
label: "CTA click",
|
|
1937
|
+
category: "engagement",
|
|
1938
|
+
outcomeRole: "engagement",
|
|
1939
|
+
clientVisibility: "simple"
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
function getEventSemantics(eventName) {
|
|
1943
|
+
return eventName in EVENT_SEMANTICS ? EVENT_SEMANTICS[eventName] : null;
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1582
1946
|
// ../tracking-core/src/events/registry.ts
|
|
1583
1947
|
var EVENT_REGISTRY = {
|
|
1584
1948
|
// --- automatic triggers ---
|
|
1585
1949
|
page_view: {
|
|
1586
1950
|
kind: "automatic",
|
|
1951
|
+
semantics: EVENT_SEMANTICS.page_view,
|
|
1587
1952
|
metadataSchema: pageViewMetadataSchema,
|
|
1588
1953
|
configSchema: pageViewConfigSchema
|
|
1589
1954
|
},
|
|
1590
1955
|
time_on_site: {
|
|
1591
1956
|
kind: "automatic",
|
|
1957
|
+
semantics: EVENT_SEMANTICS.time_on_site,
|
|
1592
1958
|
metadataSchema: timeOnSiteMetadataSchema,
|
|
1593
1959
|
configSchema: timeOnSiteConfigSchema
|
|
1594
1960
|
},
|
|
1595
1961
|
specific_page_visit: {
|
|
1596
1962
|
kind: "automatic",
|
|
1963
|
+
semantics: EVENT_SEMANTICS.specific_page_visit,
|
|
1597
1964
|
metadataSchema: specificPageVisitMetadataSchema,
|
|
1598
1965
|
configSchema: specificPageVisitConfigSchema
|
|
1599
1966
|
},
|
|
1600
1967
|
scroll_depth: {
|
|
1601
1968
|
kind: "automatic",
|
|
1969
|
+
semantics: EVENT_SEMANTICS.scroll_depth,
|
|
1602
1970
|
metadataSchema: scrollDepthMetadataSchema,
|
|
1603
1971
|
configSchema: scrollDepthConfigSchema
|
|
1604
1972
|
},
|
|
1605
1973
|
multi_page_session: {
|
|
1606
1974
|
kind: "automatic",
|
|
1975
|
+
semantics: EVENT_SEMANTICS.multi_page_session,
|
|
1607
1976
|
metadataSchema: multiPageSessionMetadataSchema,
|
|
1608
1977
|
configSchema: multiPageSessionConfigSchema
|
|
1609
1978
|
},
|
|
1610
1979
|
form_start: {
|
|
1611
1980
|
kind: "automatic",
|
|
1981
|
+
semantics: EVENT_SEMANTICS.form_start,
|
|
1612
1982
|
metadataSchema: formStartMetadataSchema,
|
|
1613
1983
|
configSchema: formStartConfigSchema
|
|
1614
1984
|
},
|
|
1615
1985
|
// --- SDK-internal automatic (not consumer-configurable) ---
|
|
1616
1986
|
sdk_heartbeat: {
|
|
1617
1987
|
kind: "automatic",
|
|
1988
|
+
semantics: EVENT_SEMANTICS.sdk_heartbeat,
|
|
1618
1989
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
1619
1990
|
configSchema: sdkHeartbeatConfigSchema
|
|
1620
1991
|
},
|
|
1621
1992
|
page_exit: {
|
|
1622
1993
|
kind: "automatic",
|
|
1994
|
+
semantics: EVENT_SEMANTICS.page_exit,
|
|
1623
1995
|
metadataSchema: pageExitMetadataSchema,
|
|
1624
1996
|
configSchema: pageExitConfigSchema
|
|
1625
1997
|
},
|
|
1626
1998
|
// --- manual triggers ---
|
|
1627
1999
|
form_submit: {
|
|
1628
2000
|
kind: "manual",
|
|
2001
|
+
semantics: EVENT_SEMANTICS.form_submit,
|
|
1629
2002
|
metadataSchema: formSubmitMetadataSchema,
|
|
1630
2003
|
configSchema: formSubmitConfigSchema
|
|
1631
2004
|
},
|
|
1632
2005
|
phone_click: {
|
|
1633
2006
|
kind: "manual",
|
|
2007
|
+
semantics: EVENT_SEMANTICS.phone_click,
|
|
1634
2008
|
metadataSchema: phoneClickMetadataSchema,
|
|
1635
2009
|
configSchema: phoneClickConfigSchema
|
|
1636
2010
|
},
|
|
1637
2011
|
cta_click: {
|
|
1638
2012
|
kind: "manual",
|
|
2013
|
+
semantics: EVENT_SEMANTICS.cta_click,
|
|
1639
2014
|
metadataSchema: ctaClickMetadataSchema,
|
|
1640
2015
|
configSchema: ctaClickConfigSchema
|
|
1641
2016
|
}
|
|
1642
2017
|
};
|
|
1643
2018
|
var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "automatic").map(([name]) => name);
|
|
1644
2019
|
var ALL_MANUAL_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "manual").map(([name]) => name);
|
|
2020
|
+
var ALL_LEAD_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.semantics.outcomeRole === "lead").map(([name]) => name);
|
|
1645
2021
|
function getEventDefinition(name) {
|
|
1646
2022
|
return EVENT_REGISTRY[name];
|
|
1647
2023
|
}
|
|
@@ -2374,6 +2750,14 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
|
|
|
2374
2750
|
const txnBase = input.external_id ?? sale.id;
|
|
2375
2751
|
for (const item of recorded) {
|
|
2376
2752
|
if (!item.service) continue;
|
|
2753
|
+
if ("fireConversion" in firing) {
|
|
2754
|
+
firing.fireConversion(item.service, {
|
|
2755
|
+
value: item.amount_cents != null ? fromMinor(item.amount_cents, currency) : void 0,
|
|
2756
|
+
currency,
|
|
2757
|
+
transactionId: `${txnBase}:${item.service}`
|
|
2758
|
+
});
|
|
2759
|
+
continue;
|
|
2760
|
+
}
|
|
2377
2761
|
const config = firing.getFiring(item.service);
|
|
2378
2762
|
if (!config) continue;
|
|
2379
2763
|
const cents = item.amount_cents ?? config.value_cents ?? null;
|
|
@@ -2416,6 +2800,14 @@ function createSalesClient(config) {
|
|
|
2416
2800
|
// recordSale is the intent-revealing alias — same behavior, clearer call site.
|
|
2417
2801
|
recordSale: record,
|
|
2418
2802
|
trackConversion(key, options) {
|
|
2803
|
+
if (config.firing && "fireConversion" in config.firing) {
|
|
2804
|
+
config.firing.fireConversion(key, {
|
|
2805
|
+
value: options?.value ?? void 0,
|
|
2806
|
+
currency: options?.currency ?? config.defaultCurrency ?? void 0,
|
|
2807
|
+
transactionId: options?.transactionId ?? null
|
|
2808
|
+
});
|
|
2809
|
+
return;
|
|
2810
|
+
}
|
|
2419
2811
|
const firing = config.firing?.getFiring(key);
|
|
2420
2812
|
if (!firing) return;
|
|
2421
2813
|
const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
|
|
@@ -2920,21 +3312,28 @@ var import_react3 = require("react");
|
|
|
2920
3312
|
function AdPlatformTracking({
|
|
2921
3313
|
gtagId,
|
|
2922
3314
|
gtagIds,
|
|
3315
|
+
trackingConfig,
|
|
3316
|
+
standalonePageView = false,
|
|
2923
3317
|
metaPixelId,
|
|
2924
3318
|
metaPixelIds
|
|
2925
3319
|
}) {
|
|
3320
|
+
const trackingConfigKey = trackingConfig ? `${trackingConfig.cdnUrl}:${trackingConfig.businessId}:${trackingConfig.environment}` : "";
|
|
2926
3321
|
const gtagIdsKey = (0, import_react3.useMemo)(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
|
|
2927
3322
|
const metaPixelIdsKey = (0, import_react3.useMemo)(
|
|
2928
3323
|
() => metaPixelIds ? JSON.stringify(metaPixelIds) : "",
|
|
2929
3324
|
[metaPixelIds]
|
|
2930
3325
|
);
|
|
2931
3326
|
(0, import_react3.useEffect)(() => {
|
|
2932
|
-
if (
|
|
3327
|
+
if (trackingConfig) {
|
|
3328
|
+
const runtime = getTrackingConfigRuntime(trackingConfig);
|
|
3329
|
+
if (standalonePageView) runtime.queuePageView();
|
|
3330
|
+
else void runtime.revalidate();
|
|
3331
|
+
} else if (gtagIds && Object.keys(gtagIds).length > 0) {
|
|
2933
3332
|
bootstrapMultipleGtags(gtagIds);
|
|
2934
3333
|
} else if (gtagId) {
|
|
2935
3334
|
bootstrapGoogleAdsTracking(gtagId);
|
|
2936
3335
|
}
|
|
2937
|
-
}, [gtagId, gtagIdsKey]);
|
|
3336
|
+
}, [gtagId, gtagIdsKey, trackingConfigKey, standalonePageView]);
|
|
2938
3337
|
(0, import_react3.useEffect)(() => {
|
|
2939
3338
|
if (metaPixelIds && Object.keys(metaPixelIds).length > 0) {
|
|
2940
3339
|
bootstrapMultiplePixels(metaPixelIds);
|
|
@@ -2964,7 +3363,7 @@ function GoogleAdsTracking(props) {
|
|
|
2964
3363
|
var import_react6 = require("react");
|
|
2965
3364
|
|
|
2966
3365
|
// package.json
|
|
2967
|
-
var version = "0.
|
|
3366
|
+
var version = "0.18.0";
|
|
2968
3367
|
|
|
2969
3368
|
// ../tracking-core/src/phone-react.tsx
|
|
2970
3369
|
var import_react5 = require("react");
|
|
@@ -3063,7 +3462,16 @@ var NOOP_CLIENT = {
|
|
|
3063
3462
|
getVisitorId: () => ""
|
|
3064
3463
|
};
|
|
3065
3464
|
function createTracking(options) {
|
|
3066
|
-
const {
|
|
3465
|
+
const {
|
|
3466
|
+
apiKey,
|
|
3467
|
+
endpoint,
|
|
3468
|
+
triggers,
|
|
3469
|
+
environment,
|
|
3470
|
+
debug,
|
|
3471
|
+
phone,
|
|
3472
|
+
conversionConfig,
|
|
3473
|
+
trackingConfig
|
|
3474
|
+
} = options;
|
|
3067
3475
|
if (!apiKey || !endpoint) {
|
|
3068
3476
|
if (apiKey || endpoint) {
|
|
3069
3477
|
console.warn(
|
|
@@ -3109,7 +3517,9 @@ function createTracking(options) {
|
|
|
3109
3517
|
);
|
|
3110
3518
|
const gtagIdsKey = (0, import_react6.useMemo)(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
|
|
3111
3519
|
(0, import_react6.useEffect)(() => {
|
|
3112
|
-
if (
|
|
3520
|
+
if (trackingConfig) {
|
|
3521
|
+
void getTrackingConfigRuntime(trackingConfig).revalidate();
|
|
3522
|
+
} else if (gtagIds && Object.keys(gtagIds).length > 0) {
|
|
3113
3523
|
bootstrapMultipleGtags(gtagIds);
|
|
3114
3524
|
} else if (gtagId) {
|
|
3115
3525
|
bootstrapGoogleAdsTracking(gtagId);
|
|
@@ -3139,13 +3549,20 @@ function createTracking(options) {
|
|
|
3139
3549
|
});
|
|
3140
3550
|
return attachClientCapturesOnce(rawClient, () => {
|
|
3141
3551
|
const detachers = [];
|
|
3142
|
-
const conversionStore = conversionConfig ? resolveConversionConfig({
|
|
3552
|
+
const conversionStore = trackingConfig ? getTrackingConfigRuntime(trackingConfig) : conversionConfig ? resolveConversionConfig({
|
|
3143
3553
|
cdnUrl: conversionConfig.cdnUrl,
|
|
3144
3554
|
baked: conversionConfig.baked
|
|
3145
3555
|
}) : null;
|
|
3146
3556
|
const detectorClient = conversionStore ? withConversionAutoFire(rawClient, createConversionAutoFire(conversionStore)) : rawClient;
|
|
3147
|
-
|
|
3148
|
-
|
|
3557
|
+
const pageClient = trackingConfig && conversionStore && "queuePageView" in conversionStore ? {
|
|
3558
|
+
...detectorClient,
|
|
3559
|
+
trackEvent: (input) => {
|
|
3560
|
+
detectorClient.trackEvent(input);
|
|
3561
|
+
if (input.eventType === "page_view") conversionStore.queuePageView();
|
|
3562
|
+
}
|
|
3563
|
+
} : detectorClient;
|
|
3564
|
+
detachers.push(attachAutoPageView(pageClient));
|
|
3565
|
+
detachers.push(attachBfcacheRestore(pageClient));
|
|
3149
3566
|
detachers.push(attachPageExit(detectorClient));
|
|
3150
3567
|
const timeOnSite = triggers.automatic.time_on_site;
|
|
3151
3568
|
if (timeOnSite) {
|
|
@@ -3202,6 +3619,7 @@ function createTracking(options) {
|
|
|
3202
3619
|
ConsentBanner,
|
|
3203
3620
|
DEFAULT_DECLINE_TTL_DAYS,
|
|
3204
3621
|
DEFAULT_PHONE_COUNTRY,
|
|
3622
|
+
EVENT_SEMANTICS,
|
|
3205
3623
|
GoogleAdsTracking,
|
|
3206
3624
|
NAMED_RANGES,
|
|
3207
3625
|
PhoneField,
|
|
@@ -3222,6 +3640,8 @@ function createTracking(options) {
|
|
|
3222
3640
|
fromMinor,
|
|
3223
3641
|
getConsentChoice,
|
|
3224
3642
|
getConsentState,
|
|
3643
|
+
getEventSemantics,
|
|
3644
|
+
getTrackingConfigRuntime,
|
|
3225
3645
|
onConsentChange,
|
|
3226
3646
|
optIn,
|
|
3227
3647
|
optOut,
|