@aranova/tracking-react 0.18.1 → 0.19.1
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/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +461 -184
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +459 -184
- package/dist/index.mjs.map +1 -1
- package/dist/{phone-utils-CVCzW04Z.d.mts → phone-utils-B2vHJkNz.d.mts} +10 -0
- package/dist/{phone-utils-CVCzW04Z.d.ts → phone-utils-B2vHJkNz.d.ts} +10 -0
- package/dist/phone.d.mts +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/phone.js +40 -40
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +40 -40
- package/dist/phone.mjs.map +1 -1
- package/dist/{sales-QqKh6_iy.d.mts → sales-DrH6dY5F.d.mts} +34 -2
- package/dist/{sales-QqKh6_iy.d.ts → sales-DrH6dY5F.d.ts} +34 -2
- package/dist/sales.d.mts +2 -1
- package/dist/sales.d.ts +2 -1
- package/dist/sales.js +106 -19
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +106 -19
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4,6 +4,140 @@ import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
|
4
4
|
// src/hooks.ts
|
|
5
5
|
import { useCallback, useEffect, useState } from "react";
|
|
6
6
|
|
|
7
|
+
// ../tracking-core/src/phone.ts
|
|
8
|
+
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
9
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
10
|
+
function parsePhone(raw, country) {
|
|
11
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
12
|
+
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
13
|
+
if (!parsed) {
|
|
14
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
15
|
+
}
|
|
16
|
+
const isValid = parsed.isValid();
|
|
17
|
+
return {
|
|
18
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
19
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
20
|
+
e164: isValid ? parsed.number : null,
|
|
21
|
+
national: parsed.formatNational(),
|
|
22
|
+
international: parsed.formatInternational(),
|
|
23
|
+
country: parsed.country ?? region,
|
|
24
|
+
isValid
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function toE164(raw, country) {
|
|
28
|
+
return parsePhone(raw, country).e164;
|
|
29
|
+
}
|
|
30
|
+
function formatPhone(value, format = "national", country) {
|
|
31
|
+
const parsed = parsePhone(value, country);
|
|
32
|
+
if (typeof format === "function") return format(parsed);
|
|
33
|
+
switch (format) {
|
|
34
|
+
case "international":
|
|
35
|
+
return parsed.international || value;
|
|
36
|
+
case "e164":
|
|
37
|
+
return parsed.e164 ?? value;
|
|
38
|
+
case "national":
|
|
39
|
+
default:
|
|
40
|
+
return parsed.national || value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function formatPhoneAsTyped(raw, country) {
|
|
44
|
+
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ../tracking-core/src/user-data.ts
|
|
48
|
+
var EMAIL_SHAPE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
|
|
49
|
+
var EMAIL_NAME_HINT = /e[-_]?mail/i;
|
|
50
|
+
var PHONE_NAME_HINT = /(^|[^a-z])(phone|tel|mobile|cell)/i;
|
|
51
|
+
var stash = { email: null, phoneNumber: null };
|
|
52
|
+
function normalizeEmail(raw) {
|
|
53
|
+
if (typeof raw !== "string") return null;
|
|
54
|
+
const cleaned = raw.trim().toLowerCase();
|
|
55
|
+
return EMAIL_SHAPE.test(cleaned) ? cleaned : null;
|
|
56
|
+
}
|
|
57
|
+
function fieldText(field, key) {
|
|
58
|
+
const value = field[key];
|
|
59
|
+
return typeof value === "string" ? value : "";
|
|
60
|
+
}
|
|
61
|
+
function extractUserDataFromFormFields(fields, country) {
|
|
62
|
+
const result = { email: null, phoneNumber: null };
|
|
63
|
+
if (!Array.isArray(fields)) return result;
|
|
64
|
+
const passes = [
|
|
65
|
+
(field, _hint, type) => fieldText(field, "type").toLowerCase() === type,
|
|
66
|
+
(field, hint) => hint.test(fieldText(field, "name")) || hint.test(fieldText(field, "label"))
|
|
67
|
+
];
|
|
68
|
+
for (const matches of passes) {
|
|
69
|
+
for (const raw of fields) {
|
|
70
|
+
if (raw === null || typeof raw !== "object") continue;
|
|
71
|
+
const field = raw;
|
|
72
|
+
if (typeof field.value !== "string" || field.value.length === 0) continue;
|
|
73
|
+
if (result.email === null && matches(field, EMAIL_NAME_HINT, "email")) {
|
|
74
|
+
result.email = normalizeEmail(field.value);
|
|
75
|
+
}
|
|
76
|
+
if (result.phoneNumber === null && matches(field, PHONE_NAME_HINT, "tel")) {
|
|
77
|
+
try {
|
|
78
|
+
result.phoneNumber = toE164(field.value, country);
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (result.email !== null && result.phoneNumber !== null) break;
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
function stashUserData(data, country) {
|
|
88
|
+
const email = normalizeEmail(data.email);
|
|
89
|
+
let phoneNumber = null;
|
|
90
|
+
if (typeof data.phone === "string" && data.phone.length > 0) {
|
|
91
|
+
try {
|
|
92
|
+
phoneNumber = toE164(data.phone, country);
|
|
93
|
+
} catch {
|
|
94
|
+
phoneNumber = null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
stash = {
|
|
98
|
+
email: email ?? stash.email,
|
|
99
|
+
phoneNumber: phoneNumber ?? stash.phoneNumber
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function stashUserDataFromFormFields(fields, country) {
|
|
103
|
+
try {
|
|
104
|
+
const extracted = extractUserDataFromFormFields(fields, country);
|
|
105
|
+
stash = {
|
|
106
|
+
email: extracted.email ?? stash.email,
|
|
107
|
+
phoneNumber: extracted.phoneNumber ?? stash.phoneNumber
|
|
108
|
+
};
|
|
109
|
+
} catch {
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function clearStashedUserData() {
|
|
113
|
+
stash = { email: null, phoneNumber: null };
|
|
114
|
+
}
|
|
115
|
+
function applyUserDataForConversion(explicit, country) {
|
|
116
|
+
if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
|
|
117
|
+
let email = stash.email;
|
|
118
|
+
let phoneNumber = stash.phoneNumber;
|
|
119
|
+
if (explicit) {
|
|
120
|
+
const normalizedEmail = normalizeEmail(explicit.email);
|
|
121
|
+
if (normalizedEmail) email = normalizedEmail;
|
|
122
|
+
if (typeof explicit.phone === "string" && explicit.phone.length > 0) {
|
|
123
|
+
try {
|
|
124
|
+
phoneNumber = toE164(explicit.phone, country) ?? phoneNumber;
|
|
125
|
+
} catch {
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (email === null && phoneNumber === null) return false;
|
|
130
|
+
try {
|
|
131
|
+
window.gtag("set", "user_data", {
|
|
132
|
+
...email !== null ? { email } : {},
|
|
133
|
+
...phoneNumber !== null ? { phone_number: phoneNumber } : {}
|
|
134
|
+
});
|
|
135
|
+
return true;
|
|
136
|
+
} catch {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
7
141
|
// ../tracking-core/src/consent.ts
|
|
8
142
|
var CONSENT_STATE_KEY = "consent_state";
|
|
9
143
|
var CONSENT_TIMESTAMP_KEY = "consent_timestamp";
|
|
@@ -89,6 +223,13 @@ function setConsentState(state, options) {
|
|
|
89
223
|
} catch {
|
|
90
224
|
}
|
|
91
225
|
pushConsentToPlatforms(state);
|
|
226
|
+
if (state === "denied") {
|
|
227
|
+
clearStashedUserData();
|
|
228
|
+
try {
|
|
229
|
+
if (typeof window.gtag === "function") window.gtag("set", "user_data", null);
|
|
230
|
+
} catch {
|
|
231
|
+
}
|
|
232
|
+
}
|
|
92
233
|
notifyConsentChanged({ state, source: "explicit", updatedAt, expiresAt });
|
|
93
234
|
}
|
|
94
235
|
function optIn() {
|
|
@@ -113,6 +254,11 @@ function resetConsent() {
|
|
|
113
254
|
var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
|
|
114
255
|
var TRACKING_PARAM_KEYS = [
|
|
115
256
|
"gclid",
|
|
257
|
+
// Google's iOS/Safari replacement click IDs — issued when privacy features
|
|
258
|
+
// withhold gclid (wbraid: web-to-web, gbraid: app-to-web). First-class
|
|
259
|
+
// citizens: captured, persisted, and attributed exactly like gclid.
|
|
260
|
+
"wbraid",
|
|
261
|
+
"gbraid",
|
|
116
262
|
"fbclid",
|
|
117
263
|
"utm_source",
|
|
118
264
|
"utm_medium",
|
|
@@ -123,6 +269,8 @@ var TRACKING_PARAM_KEYS = [
|
|
|
123
269
|
function createEmptyTrackingParams() {
|
|
124
270
|
return {
|
|
125
271
|
gclid: null,
|
|
272
|
+
wbraid: null,
|
|
273
|
+
gbraid: null,
|
|
126
274
|
fbclid: null,
|
|
127
275
|
utm_source: null,
|
|
128
276
|
utm_medium: null,
|
|
@@ -454,6 +602,8 @@ function buildLandingPayloadFields(sessionId, override) {
|
|
|
454
602
|
if (params === null) return {};
|
|
455
603
|
return {
|
|
456
604
|
landing_gclid: params.gclid ?? null,
|
|
605
|
+
landing_wbraid: params.wbraid ?? null,
|
|
606
|
+
landing_gbraid: params.gbraid ?? null,
|
|
457
607
|
landing_fbclid: params.fbclid ?? null,
|
|
458
608
|
landing_utm_source: params.utm_source ?? null,
|
|
459
609
|
landing_utm_medium: params.utm_medium ?? null,
|
|
@@ -481,6 +631,8 @@ function createTrackingSessionUpsertPayload(trackingParams, input, context) {
|
|
|
481
631
|
session_id: input.sessionId,
|
|
482
632
|
visitor_id: input.visitorId ?? null,
|
|
483
633
|
gclid: trackingParams.gclid,
|
|
634
|
+
wbraid: trackingParams.wbraid,
|
|
635
|
+
gbraid: trackingParams.gbraid,
|
|
484
636
|
fbclid: trackingParams.fbclid,
|
|
485
637
|
fbc: getFbcCookie(),
|
|
486
638
|
fbp: getFbpCookie(),
|
|
@@ -502,6 +654,8 @@ function createTrackingEventCreatePayload(trackingParams, input, context) {
|
|
|
502
654
|
session_id: input.sessionId,
|
|
503
655
|
event_type: input.eventType,
|
|
504
656
|
gclid: trackingParams.gclid,
|
|
657
|
+
wbraid: trackingParams.wbraid,
|
|
658
|
+
gbraid: trackingParams.gbraid,
|
|
505
659
|
fbclid: trackingParams.fbclid,
|
|
506
660
|
fbc: getFbcCookie(),
|
|
507
661
|
fbp: getFbpCookie(),
|
|
@@ -531,13 +685,18 @@ function markFired(input) {
|
|
|
531
685
|
} catch {
|
|
532
686
|
}
|
|
533
687
|
}
|
|
534
|
-
function
|
|
535
|
-
if (
|
|
536
|
-
if (
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
688
|
+
function fireConversionWithConsent(input, options) {
|
|
689
|
+
if (getConsentState() === "denied") return "denied";
|
|
690
|
+
if (alreadyFired(input)) return "duplicate";
|
|
691
|
+
if (!isValidSendTo(input.sendTo)) return "invalid";
|
|
692
|
+
try {
|
|
693
|
+
applyUserDataForConversion(options?.userData);
|
|
694
|
+
if (!fireGtagConversion(input)) return "retryable";
|
|
695
|
+
markFired(input);
|
|
696
|
+
return "fired";
|
|
697
|
+
} catch {
|
|
698
|
+
return "retryable";
|
|
699
|
+
}
|
|
541
700
|
}
|
|
542
701
|
|
|
543
702
|
// ../tracking-core/src/resources/conversion-config.ts
|
|
@@ -711,6 +870,103 @@ function resolveConversionConfig(options) {
|
|
|
711
870
|
};
|
|
712
871
|
}
|
|
713
872
|
|
|
873
|
+
// ../tracking-core/src/resources/automatic-transaction.ts
|
|
874
|
+
var STORAGE_KEY = "_aranova_auto_txn_map";
|
|
875
|
+
var transactionIds = /* @__PURE__ */ new Map();
|
|
876
|
+
var legacyCounter = 0;
|
|
877
|
+
function scopeKey(sessionId, goalKey, path) {
|
|
878
|
+
return JSON.stringify([sessionId, goalKey, path]);
|
|
879
|
+
}
|
|
880
|
+
function randomId() {
|
|
881
|
+
const cryptoApi = globalThis.crypto;
|
|
882
|
+
if (typeof cryptoApi?.randomUUID === "function") return cryptoApi.randomUUID();
|
|
883
|
+
if (typeof cryptoApi?.getRandomValues === "function") {
|
|
884
|
+
const bytes = cryptoApi.getRandomValues(new Uint8Array(16));
|
|
885
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
886
|
+
}
|
|
887
|
+
legacyCounter = (legacyCounter + 1) % 4294967296;
|
|
888
|
+
const timestamp = Date.now().toString(16).padStart(12, "0");
|
|
889
|
+
const counter = legacyCounter.toString(16).padStart(8, "0");
|
|
890
|
+
const random = Math.floor(Math.random() * 281474976710655).toString(16).padStart(12, "0");
|
|
891
|
+
return `${timestamp}${counter}${random}`.slice(0, 32);
|
|
892
|
+
}
|
|
893
|
+
function isValidTransactionId(value) {
|
|
894
|
+
return typeof value === "string" && /^auto:(?:[0-9a-f]{32}|[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})$/i.test(
|
|
895
|
+
value
|
|
896
|
+
) && value.length <= 64;
|
|
897
|
+
}
|
|
898
|
+
function readStoredMap(sessionId) {
|
|
899
|
+
if (typeof window === "undefined") return { sessionId, entries: {} };
|
|
900
|
+
try {
|
|
901
|
+
const raw = window.localStorage.getItem(STORAGE_KEY);
|
|
902
|
+
if (!raw) return { sessionId, entries: {} };
|
|
903
|
+
const parsed = JSON.parse(raw);
|
|
904
|
+
if (parsed.sessionId !== sessionId || !parsed.entries || typeof parsed.entries !== "object" || Array.isArray(parsed.entries)) {
|
|
905
|
+
return { sessionId, entries: {} };
|
|
906
|
+
}
|
|
907
|
+
return { sessionId, entries: parsed.entries };
|
|
908
|
+
} catch {
|
|
909
|
+
return { sessionId, entries: {} };
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
function writeStoredMap(stored) {
|
|
913
|
+
if (typeof window === "undefined") return;
|
|
914
|
+
try {
|
|
915
|
+
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(stored));
|
|
916
|
+
} catch {
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
function getAutomaticTransactionId(sessionId, goalKey, path) {
|
|
920
|
+
const key = scopeKey(sessionId, goalKey, path);
|
|
921
|
+
const existing = transactionIds.get(key);
|
|
922
|
+
if (existing) return existing;
|
|
923
|
+
const stored = readStoredMap(sessionId);
|
|
924
|
+
const storedId = stored.entries[key];
|
|
925
|
+
if (isValidTransactionId(storedId)) {
|
|
926
|
+
transactionIds.set(key, storedId);
|
|
927
|
+
return storedId;
|
|
928
|
+
}
|
|
929
|
+
const transactionId = `auto:${randomId()}`;
|
|
930
|
+
transactionIds.set(key, transactionId);
|
|
931
|
+
const latest = readStoredMap(sessionId);
|
|
932
|
+
const concurrentId = latest.entries[key];
|
|
933
|
+
if (isValidTransactionId(concurrentId)) {
|
|
934
|
+
transactionIds.set(key, concurrentId);
|
|
935
|
+
return concurrentId;
|
|
936
|
+
}
|
|
937
|
+
latest.entries[key] = transactionId;
|
|
938
|
+
writeStoredMap(latest);
|
|
939
|
+
return transactionId;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// ../tracking-core/src/resources/automatic-trigger.ts
|
|
943
|
+
function hasNumberField(metadata, key) {
|
|
944
|
+
return typeof metadata[key] === "number";
|
|
945
|
+
}
|
|
946
|
+
function hasStringField(metadata, key) {
|
|
947
|
+
return typeof metadata[key] === "string";
|
|
948
|
+
}
|
|
949
|
+
function automaticThresholdMet(goal, eventType, metadata) {
|
|
950
|
+
const trigger = goal.trigger;
|
|
951
|
+
if (!trigger || trigger.event_type !== eventType) return false;
|
|
952
|
+
switch (eventType) {
|
|
953
|
+
case "scroll_depth":
|
|
954
|
+
return hasNumberField(metadata, "depth_percent") && trigger.threshold_percent != null && metadata.depth_percent >= trigger.threshold_percent;
|
|
955
|
+
case "time_on_site":
|
|
956
|
+
return hasNumberField(metadata, "duration_ms") && trigger.threshold_seconds != null && metadata.duration_ms >= trigger.threshold_seconds * 1e3;
|
|
957
|
+
case "multi_page_session":
|
|
958
|
+
return hasNumberField(metadata, "page_count") && trigger.page_threshold != null && metadata.page_count >= trigger.page_threshold;
|
|
959
|
+
case "specific_page_visit":
|
|
960
|
+
return hasStringField(metadata, "page_name") && metadata.page_name === trigger.page_name;
|
|
961
|
+
case "page_view":
|
|
962
|
+
case "form_start":
|
|
963
|
+
case "phone_click":
|
|
964
|
+
return true;
|
|
965
|
+
default:
|
|
966
|
+
return false;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
714
970
|
// ../tracking-core/src/resources/sales/money.ts
|
|
715
971
|
var MINOR_UNIT_EXPONENT = {
|
|
716
972
|
USD: 2,
|
|
@@ -829,7 +1085,12 @@ var TrackingConfigRuntime = class {
|
|
|
829
1085
|
this.etag = null;
|
|
830
1086
|
this.stateValue = "unconfirmed";
|
|
831
1087
|
this.confirmedAt = 0;
|
|
1088
|
+
this.authorityGeneration = 0;
|
|
832
1089
|
this.inFlight = null;
|
|
1090
|
+
this.flushInFlight = null;
|
|
1091
|
+
this.flushRequested = false;
|
|
1092
|
+
this.retryTimer = null;
|
|
1093
|
+
this.started = false;
|
|
833
1094
|
this.conversionQueue = [];
|
|
834
1095
|
this.automaticQueue = [];
|
|
835
1096
|
this.pageQueue = [];
|
|
@@ -837,6 +1098,20 @@ var TrackingConfigRuntime = class {
|
|
|
837
1098
|
const cached = readCache2(ref.cdnUrl);
|
|
838
1099
|
this.current = cached?.config ?? null;
|
|
839
1100
|
this.etag = cached?.etag ?? null;
|
|
1101
|
+
this.start();
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Explicitly start authority resolution and Google-tag bootstrap.
|
|
1105
|
+
*
|
|
1106
|
+
* Idempotent so framework effects can call it after hydration without
|
|
1107
|
+
* depending on constructor timing.
|
|
1108
|
+
*/
|
|
1109
|
+
start() {
|
|
1110
|
+
if (this.started) {
|
|
1111
|
+
void this.flush();
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
this.started = true;
|
|
840
1115
|
void this.revalidate();
|
|
841
1116
|
if (typeof window !== "undefined") {
|
|
842
1117
|
window.addEventListener("visibilitychange", () => {
|
|
@@ -852,7 +1127,7 @@ var TrackingConfigRuntime = class {
|
|
|
852
1127
|
return this.stateValue === "active" || this.stateValue === "tombstone" ? this.current : null;
|
|
853
1128
|
}
|
|
854
1129
|
__unsafeExpireAuthorityForTests() {
|
|
855
|
-
this.confirmedAt =
|
|
1130
|
+
this.confirmedAt = Number.NEGATIVE_INFINITY;
|
|
856
1131
|
}
|
|
857
1132
|
subscribe(listener) {
|
|
858
1133
|
this.listeners.add(listener);
|
|
@@ -862,10 +1137,14 @@ var TrackingConfigRuntime = class {
|
|
|
862
1137
|
if (this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS) {
|
|
863
1138
|
return true;
|
|
864
1139
|
}
|
|
865
|
-
await this.
|
|
1140
|
+
await this.revalidateAuthority();
|
|
866
1141
|
return this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS;
|
|
867
1142
|
}
|
|
868
1143
|
async revalidate() {
|
|
1144
|
+
await this.revalidateAuthority();
|
|
1145
|
+
await this.flush();
|
|
1146
|
+
}
|
|
1147
|
+
async revalidateAuthority() {
|
|
869
1148
|
if (typeof window === "undefined" || !this.fetchImpl) return;
|
|
870
1149
|
if (this.inFlight) return this.inFlight;
|
|
871
1150
|
this.inFlight = this.revalidateNow().finally(() => {
|
|
@@ -882,8 +1161,8 @@ var TrackingConfigRuntime = class {
|
|
|
882
1161
|
this.conversionQueue.push({ key, ...options });
|
|
883
1162
|
void this.flush();
|
|
884
1163
|
}
|
|
885
|
-
queueAutomaticEvent(eventType, metadata, transactionPath) {
|
|
886
|
-
this.automaticQueue.push({ eventType, metadata, transactionPath });
|
|
1164
|
+
queueAutomaticEvent(eventType, metadata, transactionPath, transactionScope) {
|
|
1165
|
+
this.automaticQueue.push({ eventType, metadata, transactionPath, transactionScope });
|
|
887
1166
|
void this.flush();
|
|
888
1167
|
}
|
|
889
1168
|
listGoals() {
|
|
@@ -900,7 +1179,6 @@ var TrackingConfigRuntime = class {
|
|
|
900
1179
|
});
|
|
901
1180
|
if (response.status === 304 && this.current && validateConfig(this.current, this.ref)) {
|
|
902
1181
|
this.confirm(this.current, this.etag);
|
|
903
|
-
await this.flush();
|
|
904
1182
|
return;
|
|
905
1183
|
}
|
|
906
1184
|
if (!response.ok) {
|
|
@@ -917,21 +1195,26 @@ var TrackingConfigRuntime = class {
|
|
|
917
1195
|
return;
|
|
918
1196
|
}
|
|
919
1197
|
this.confirm(next, response.headers.get("ETag"));
|
|
920
|
-
await this.flush();
|
|
921
1198
|
} catch {
|
|
922
1199
|
this.expireAuthority();
|
|
923
1200
|
}
|
|
924
1201
|
}
|
|
925
1202
|
expireAuthority() {
|
|
1203
|
+
this.authorityGeneration += 1;
|
|
926
1204
|
if (this.stateValue !== "unconfirmed") this.stateValue = "unconfirmed";
|
|
927
1205
|
}
|
|
928
1206
|
confirm(config, etag) {
|
|
1207
|
+
this.authorityGeneration += 1;
|
|
929
1208
|
this.current = config;
|
|
930
1209
|
this.etag = etag;
|
|
931
1210
|
this.confirmedAt = Date.now();
|
|
932
1211
|
this.stateValue = isTombstone(config) ? "tombstone" : "active";
|
|
933
1212
|
writeCache2(this.ref.cdnUrl, { etag, config });
|
|
934
1213
|
if (this.stateValue === "tombstone") {
|
|
1214
|
+
if (this.retryTimer !== null) {
|
|
1215
|
+
window.clearTimeout(this.retryTimer);
|
|
1216
|
+
this.retryTimer = null;
|
|
1217
|
+
}
|
|
935
1218
|
this.conversionQueue.length = 0;
|
|
936
1219
|
this.automaticQueue.length = 0;
|
|
937
1220
|
this.pageQueue.length = 0;
|
|
@@ -939,79 +1222,107 @@ var TrackingConfigRuntime = class {
|
|
|
939
1222
|
for (const listener of this.listeners) listener();
|
|
940
1223
|
}
|
|
941
1224
|
async flush() {
|
|
1225
|
+
if (this.flushInFlight) {
|
|
1226
|
+
this.flushRequested = true;
|
|
1227
|
+
return this.flushInFlight;
|
|
1228
|
+
}
|
|
1229
|
+
this.flushRequested = false;
|
|
1230
|
+
this.flushInFlight = this.flushNow().finally(() => {
|
|
1231
|
+
this.flushInFlight = null;
|
|
1232
|
+
if (this.flushRequested && this.stateValue === "active") void this.flush();
|
|
1233
|
+
});
|
|
1234
|
+
return this.flushInFlight;
|
|
1235
|
+
}
|
|
1236
|
+
scheduleRetry() {
|
|
1237
|
+
if (this.retryTimer !== null || typeof window === "undefined") return;
|
|
1238
|
+
this.retryTimer = window.setTimeout(() => {
|
|
1239
|
+
this.retryTimer = null;
|
|
1240
|
+
void this.flush();
|
|
1241
|
+
}, 1e3);
|
|
1242
|
+
}
|
|
1243
|
+
async flushNow() {
|
|
942
1244
|
if (!await this.ensureAuthority()) return;
|
|
943
1245
|
if (this.stateValue !== "active" || !this.current) return;
|
|
944
|
-
const
|
|
1246
|
+
const config = this.current;
|
|
1247
|
+
const generation = this.authorityGeneration;
|
|
1248
|
+
const ids = Object.values(config.gtag_ids).filter(
|
|
945
1249
|
(id) => typeof id === "string" && isValidGtagId(id)
|
|
946
1250
|
);
|
|
947
1251
|
if (ids.length === 0) return;
|
|
948
1252
|
await ensureScript(ids[0]);
|
|
1253
|
+
if (this.authorityGeneration !== generation || this.stateValue !== "active" || this.current !== config) {
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
949
1256
|
const gtag = window.gtag;
|
|
950
1257
|
if (typeof gtag !== "function") return;
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1258
|
+
try {
|
|
1259
|
+
if (!jsInitialized) {
|
|
1260
|
+
gtag("js", /* @__PURE__ */ new Date());
|
|
1261
|
+
jsInitialized = true;
|
|
1262
|
+
}
|
|
1263
|
+
for (const id of ids) {
|
|
1264
|
+
if (configuredIds.has(id)) continue;
|
|
1265
|
+
gtag("config", id, { send_page_view: false });
|
|
1266
|
+
configuredIds.add(id);
|
|
1267
|
+
}
|
|
1268
|
+
} catch {
|
|
1269
|
+
this.scheduleRetry();
|
|
1270
|
+
return;
|
|
1271
|
+
}
|
|
1272
|
+
while (this.pageQueue.length > 0) {
|
|
1273
|
+
const page = this.pageQueue[0];
|
|
1274
|
+
try {
|
|
1275
|
+
gtag("event", "page_view", {
|
|
1276
|
+
page_location: page.href,
|
|
1277
|
+
page_title: page.title ?? void 0,
|
|
1278
|
+
page_referrer: page.referrer ?? void 0
|
|
1279
|
+
});
|
|
1280
|
+
this.pageQueue.shift();
|
|
1281
|
+
} catch {
|
|
1282
|
+
this.scheduleRetry();
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
967
1285
|
}
|
|
968
|
-
while (this.automaticQueue.length) {
|
|
969
|
-
const event = this.automaticQueue
|
|
970
|
-
for (const goal of
|
|
1286
|
+
while (this.automaticQueue.length > 0) {
|
|
1287
|
+
const event = this.automaticQueue[0];
|
|
1288
|
+
for (const goal of config.goals) {
|
|
971
1289
|
if (goal.kind !== "event" || !goal.firing) continue;
|
|
972
1290
|
if (!automaticThresholdMet(goal, event.eventType, event.metadata)) continue;
|
|
973
1291
|
this.conversionQueue.push({
|
|
974
1292
|
key: goal.key,
|
|
975
|
-
transactionId:
|
|
1293
|
+
transactionId: getAutomaticTransactionId(
|
|
1294
|
+
event.transactionScope,
|
|
1295
|
+
goal.key,
|
|
1296
|
+
event.transactionPath
|
|
1297
|
+
)
|
|
976
1298
|
});
|
|
977
1299
|
}
|
|
1300
|
+
this.automaticQueue.shift();
|
|
978
1301
|
}
|
|
979
|
-
while (this.conversionQueue.length) {
|
|
980
|
-
const item = this.conversionQueue
|
|
981
|
-
const goal =
|
|
1302
|
+
while (this.conversionQueue.length > 0) {
|
|
1303
|
+
const item = this.conversionQueue[0];
|
|
1304
|
+
const goal = config.goals.find((g) => g.key === item.key);
|
|
982
1305
|
const firing = goal?.firing;
|
|
983
|
-
if (!firing
|
|
1306
|
+
if (!firing) {
|
|
1307
|
+
this.conversionQueue.shift();
|
|
1308
|
+
continue;
|
|
1309
|
+
}
|
|
984
1310
|
const currency = item.currency ?? firing.currency ?? null;
|
|
985
1311
|
const value = item.value ?? (firing.value_cents != null && currency ? fromMinor(firing.value_cents, currency) : null);
|
|
986
|
-
|
|
1312
|
+
const outcome = fireConversionWithConsent({
|
|
987
1313
|
sendTo: firing.send_to,
|
|
988
1314
|
value,
|
|
989
1315
|
currency,
|
|
990
1316
|
transactionId: item.transactionId ?? null
|
|
991
1317
|
});
|
|
1318
|
+
if (outcome === "retryable") {
|
|
1319
|
+
this.scheduleRetry();
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
this.conversionQueue.shift();
|
|
992
1323
|
}
|
|
993
1324
|
}
|
|
994
1325
|
};
|
|
995
|
-
function automaticThresholdMet(goal, eventType, metadata) {
|
|
996
|
-
const t = goal.trigger;
|
|
997
|
-
if (!t || t.event_type !== eventType) return false;
|
|
998
|
-
switch (eventType) {
|
|
999
|
-
case "scroll_depth":
|
|
1000
|
-
return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
|
|
1001
|
-
case "time_on_site":
|
|
1002
|
-
return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
|
|
1003
|
-
case "multi_page_session":
|
|
1004
|
-
return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
|
|
1005
|
-
case "specific_page_visit":
|
|
1006
|
-
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
1007
|
-
case "page_view":
|
|
1008
|
-
case "form_start":
|
|
1009
|
-
case "phone_click":
|
|
1010
|
-
return true;
|
|
1011
|
-
default:
|
|
1012
|
-
return false;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
1326
|
function getTrackingConfigRuntime(ref, fetchImpl) {
|
|
1016
1327
|
const key = `${ref.cdnUrl}|${ref.businessId}|${ref.environment}`;
|
|
1017
1328
|
const existing = runtimes.get(key);
|
|
@@ -1022,26 +1333,6 @@ function getTrackingConfigRuntime(ref, fetchImpl) {
|
|
|
1022
1333
|
}
|
|
1023
1334
|
|
|
1024
1335
|
// ../tracking-core/src/resources/conversion-autofire.ts
|
|
1025
|
-
function thresholdMet(goal, eventType, metadata) {
|
|
1026
|
-
const t = goal.trigger;
|
|
1027
|
-
if (!t || t.event_type !== eventType) return false;
|
|
1028
|
-
switch (eventType) {
|
|
1029
|
-
case "scroll_depth":
|
|
1030
|
-
return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
|
|
1031
|
-
case "time_on_site":
|
|
1032
|
-
return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
|
|
1033
|
-
case "multi_page_session":
|
|
1034
|
-
return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
|
|
1035
|
-
case "specific_page_visit":
|
|
1036
|
-
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
1037
|
-
case "page_view":
|
|
1038
|
-
case "form_start":
|
|
1039
|
-
case "phone_click":
|
|
1040
|
-
return true;
|
|
1041
|
-
default:
|
|
1042
|
-
return false;
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
1336
|
function currentPath() {
|
|
1046
1337
|
return typeof window === "undefined" ? "" : window.location.pathname;
|
|
1047
1338
|
}
|
|
@@ -1049,13 +1340,14 @@ var MAX_BUFFERED_EVENTS = 50;
|
|
|
1049
1340
|
function createConversionAutoFire(store) {
|
|
1050
1341
|
const pending = [];
|
|
1051
1342
|
let subscribed = false;
|
|
1052
|
-
function fireMatching(eventType, metadata) {
|
|
1343
|
+
function fireMatching(eventType, metadata, transactionScope) {
|
|
1053
1344
|
for (const goal of store.listGoals()) {
|
|
1054
1345
|
if (goal.kind !== "event" || !goal.firing) continue;
|
|
1055
|
-
if (!
|
|
1346
|
+
if (!automaticThresholdMet(goal, eventType, metadata)) continue;
|
|
1347
|
+
const transactionId = getAutomaticTransactionId(transactionScope, goal.key, currentPath());
|
|
1056
1348
|
if ("queueAutomaticEvent" in store) {
|
|
1057
1349
|
store.fireConversion(goal.key, {
|
|
1058
|
-
transactionId
|
|
1350
|
+
transactionId
|
|
1059
1351
|
});
|
|
1060
1352
|
continue;
|
|
1061
1353
|
}
|
|
@@ -1066,28 +1358,30 @@ function createConversionAutoFire(store) {
|
|
|
1066
1358
|
sendTo: firing.send_to,
|
|
1067
1359
|
value: cents != null && currency ? fromMinor(cents, currency) : null,
|
|
1068
1360
|
currency,
|
|
1069
|
-
|
|
1070
|
-
// shouldn't re-fire as the visitor scrolls back and forth or re-enters a page.
|
|
1071
|
-
transactionId: `auto:${goal.key}:${currentPath()}`
|
|
1361
|
+
transactionId
|
|
1072
1362
|
});
|
|
1073
1363
|
}
|
|
1074
1364
|
}
|
|
1075
1365
|
return {
|
|
1076
|
-
onAutomaticEvent(eventType, metadata) {
|
|
1366
|
+
onAutomaticEvent(eventType, metadata, transactionScope) {
|
|
1077
1367
|
if ("queueAutomaticEvent" in store) {
|
|
1078
|
-
store.queueAutomaticEvent(eventType, metadata, currentPath());
|
|
1368
|
+
store.queueAutomaticEvent(eventType, metadata, currentPath(), transactionScope);
|
|
1079
1369
|
return;
|
|
1080
1370
|
}
|
|
1081
1371
|
if (store.isReady()) {
|
|
1082
|
-
fireMatching(eventType, metadata);
|
|
1372
|
+
fireMatching(eventType, metadata, transactionScope);
|
|
1083
1373
|
return;
|
|
1084
1374
|
}
|
|
1085
|
-
if (pending.length < MAX_BUFFERED_EVENTS)
|
|
1375
|
+
if (pending.length < MAX_BUFFERED_EVENTS) {
|
|
1376
|
+
pending.push({ eventType, metadata, transactionScope });
|
|
1377
|
+
}
|
|
1086
1378
|
if (!subscribed) {
|
|
1087
1379
|
subscribed = true;
|
|
1088
1380
|
store.onResolve(() => {
|
|
1089
1381
|
const buffered = pending.splice(0);
|
|
1090
|
-
for (const event of buffered)
|
|
1382
|
+
for (const event of buffered) {
|
|
1383
|
+
fireMatching(event.eventType, event.metadata, event.transactionScope);
|
|
1384
|
+
}
|
|
1091
1385
|
});
|
|
1092
1386
|
}
|
|
1093
1387
|
}
|
|
@@ -1099,7 +1393,7 @@ function withConversionAutoFire(client, autoFire) {
|
|
|
1099
1393
|
trackEvent: (input) => {
|
|
1100
1394
|
client.trackEvent(input);
|
|
1101
1395
|
try {
|
|
1102
|
-
autoFire.onAutomaticEvent(input.eventType, input.metadata ?? {});
|
|
1396
|
+
autoFire.onAutomaticEvent(input.eventType, input.metadata ?? {}, client.getSessionId());
|
|
1103
1397
|
} catch {
|
|
1104
1398
|
}
|
|
1105
1399
|
}
|
|
@@ -1514,6 +1808,8 @@ function createTrackingClient(config) {
|
|
|
1514
1808
|
session_id: sessionId,
|
|
1515
1809
|
visitor_id: visitorId,
|
|
1516
1810
|
gclid: params.gclid,
|
|
1811
|
+
wbraid: params.wbraid,
|
|
1812
|
+
gbraid: params.gbraid,
|
|
1517
1813
|
fbclid: params.fbclid,
|
|
1518
1814
|
fbc: getFbcCookie(),
|
|
1519
1815
|
fbp: getFbpCookie(),
|
|
@@ -1560,6 +1856,13 @@ function createTrackingClient(config) {
|
|
|
1560
1856
|
function trackEvent(input) {
|
|
1561
1857
|
if (destroyed) return;
|
|
1562
1858
|
if (!input || typeof input.eventType !== "string" || input.eventType.length === 0) return;
|
|
1859
|
+
if (input.eventType === "form_submit" && getConsentState() !== "denied") {
|
|
1860
|
+
try {
|
|
1861
|
+
const fields = input.metadata?.form?.fields;
|
|
1862
|
+
if (fields) stashUserDataFromFormFields(fields, config.phone?.defaultCountry);
|
|
1863
|
+
} catch {
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1563
1866
|
const occurredAt = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : typeof input.occurredAt === "string" ? input.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
1564
1867
|
queue.push({
|
|
1565
1868
|
event_type: input.eventType,
|
|
@@ -2223,7 +2526,7 @@ function attachScrollDepth(client, config) {
|
|
|
2223
2526
|
}
|
|
2224
2527
|
|
|
2225
2528
|
// ../tracking-core/src/triggers/multi-page-session.ts
|
|
2226
|
-
var
|
|
2529
|
+
var STORAGE_KEY2 = "aranova_tracking_mps_paths";
|
|
2227
2530
|
var SESSION_KEY = "aranova_tracking_mps_session";
|
|
2228
2531
|
var FIRED_KEY = "aranova_tracking_mps_fired";
|
|
2229
2532
|
function getSessionStorage() {
|
|
@@ -2245,7 +2548,7 @@ function attachMultiPageSession(client, config) {
|
|
|
2245
2548
|
let lastCheckedPath = "";
|
|
2246
2549
|
function getDistinctPaths() {
|
|
2247
2550
|
try {
|
|
2248
|
-
const raw = storage.getItem(
|
|
2551
|
+
const raw = storage.getItem(STORAGE_KEY2);
|
|
2249
2552
|
return raw ? new Set(JSON.parse(raw)) : /* @__PURE__ */ new Set();
|
|
2250
2553
|
} catch {
|
|
2251
2554
|
return /* @__PURE__ */ new Set();
|
|
@@ -2253,7 +2556,7 @@ function attachMultiPageSession(client, config) {
|
|
|
2253
2556
|
}
|
|
2254
2557
|
function saveDistinctPaths(paths) {
|
|
2255
2558
|
try {
|
|
2256
|
-
storage.setItem(
|
|
2559
|
+
storage.setItem(STORAGE_KEY2, JSON.stringify([...paths]));
|
|
2257
2560
|
} catch {
|
|
2258
2561
|
}
|
|
2259
2562
|
}
|
|
@@ -2262,7 +2565,7 @@ function attachMultiPageSession(client, config) {
|
|
|
2262
2565
|
const storedSession = storage.getItem(SESSION_KEY);
|
|
2263
2566
|
if (storedSession !== currentSession) {
|
|
2264
2567
|
storage.setItem(SESSION_KEY, currentSession);
|
|
2265
|
-
storage.removeItem(
|
|
2568
|
+
storage.removeItem(STORAGE_KEY2);
|
|
2266
2569
|
storage.removeItem(FIRED_KEY);
|
|
2267
2570
|
}
|
|
2268
2571
|
}
|
|
@@ -2523,46 +2826,6 @@ function attachCtaClickCapture(client, config) {
|
|
|
2523
2826
|
};
|
|
2524
2827
|
}
|
|
2525
2828
|
|
|
2526
|
-
// ../tracking-core/src/phone.ts
|
|
2527
|
-
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
2528
|
-
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2529
|
-
function parsePhone(raw, country) {
|
|
2530
|
-
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2531
|
-
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
2532
|
-
if (!parsed) {
|
|
2533
|
-
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2534
|
-
}
|
|
2535
|
-
const isValid = parsed.isValid();
|
|
2536
|
-
return {
|
|
2537
|
-
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2538
|
-
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2539
|
-
e164: isValid ? parsed.number : null,
|
|
2540
|
-
national: parsed.formatNational(),
|
|
2541
|
-
international: parsed.formatInternational(),
|
|
2542
|
-
country: parsed.country ?? region,
|
|
2543
|
-
isValid
|
|
2544
|
-
};
|
|
2545
|
-
}
|
|
2546
|
-
function toE164(raw, country) {
|
|
2547
|
-
return parsePhone(raw, country).e164;
|
|
2548
|
-
}
|
|
2549
|
-
function formatPhone(value, format = "national", country) {
|
|
2550
|
-
const parsed = parsePhone(value, country);
|
|
2551
|
-
if (typeof format === "function") return format(parsed);
|
|
2552
|
-
switch (format) {
|
|
2553
|
-
case "international":
|
|
2554
|
-
return parsed.international || value;
|
|
2555
|
-
case "e164":
|
|
2556
|
-
return parsed.e164 ?? value;
|
|
2557
|
-
case "national":
|
|
2558
|
-
default:
|
|
2559
|
-
return parsed.national || value;
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2562
|
-
function formatPhoneAsTyped(raw, country) {
|
|
2563
|
-
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2564
|
-
}
|
|
2565
|
-
|
|
2566
2829
|
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2567
2830
|
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2568
2831
|
function safeDecodeURIComponent(value) {
|
|
@@ -2672,6 +2935,8 @@ async function salesRequest(config, method, path, body) {
|
|
|
2672
2935
|
// ../tracking-core/src/resources/sales/client.ts
|
|
2673
2936
|
function fireRecordedConversions(firing, input, recorded, sale, currency) {
|
|
2674
2937
|
if (!firing) return;
|
|
2938
|
+
const userData = input.customer_email || input.customer_phone ? { email: input.customer_email ?? null, phone: input.customer_phone ?? null } : null;
|
|
2939
|
+
if (userData && getConsentState() !== "denied") stashUserData(userData);
|
|
2675
2940
|
const txnBase = input.external_id ?? sale.id;
|
|
2676
2941
|
for (const item of recorded) {
|
|
2677
2942
|
if (!item.service) continue;
|
|
@@ -2686,12 +2951,15 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
|
|
|
2686
2951
|
const config = firing.getFiring(item.service);
|
|
2687
2952
|
if (!config) continue;
|
|
2688
2953
|
const cents = item.amount_cents ?? config.value_cents ?? null;
|
|
2689
|
-
fireConversionWithConsent(
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2954
|
+
fireConversionWithConsent(
|
|
2955
|
+
{
|
|
2956
|
+
sendTo: config.send_to,
|
|
2957
|
+
value: cents != null ? fromMinor(cents, currency) : null,
|
|
2958
|
+
currency: config.currency ?? currency,
|
|
2959
|
+
transactionId: `${txnBase}:${item.service}`
|
|
2960
|
+
},
|
|
2961
|
+
{ userData }
|
|
2962
|
+
);
|
|
2695
2963
|
}
|
|
2696
2964
|
}
|
|
2697
2965
|
function createSalesClient(config) {
|
|
@@ -2726,6 +2994,7 @@ function createSalesClient(config) {
|
|
|
2726
2994
|
recordSale: record,
|
|
2727
2995
|
trackConversion(key, options) {
|
|
2728
2996
|
if (config.firing && "fireConversion" in config.firing) {
|
|
2997
|
+
if (options?.userData && getConsentState() !== "denied") stashUserData(options.userData);
|
|
2729
2998
|
config.firing.fireConversion(key, {
|
|
2730
2999
|
value: options?.value ?? void 0,
|
|
2731
3000
|
currency: options?.currency ?? config.defaultCurrency ?? void 0,
|
|
@@ -2738,12 +3007,15 @@ function createSalesClient(config) {
|
|
|
2738
3007
|
const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
|
|
2739
3008
|
const cents = firing.value_cents ?? null;
|
|
2740
3009
|
const value = options?.value ?? (cents != null && currency ? fromMinor(cents, currency) : null);
|
|
2741
|
-
fireConversionWithConsent(
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
3010
|
+
fireConversionWithConsent(
|
|
3011
|
+
{
|
|
3012
|
+
sendTo: firing.send_to,
|
|
3013
|
+
value,
|
|
3014
|
+
currency,
|
|
3015
|
+
transactionId: options?.transactionId ?? null
|
|
3016
|
+
},
|
|
3017
|
+
{ userData: options?.userData }
|
|
3018
|
+
);
|
|
2747
3019
|
},
|
|
2748
3020
|
async list(query) {
|
|
2749
3021
|
const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
|
|
@@ -3288,7 +3560,7 @@ function GoogleAdsTracking(props) {
|
|
|
3288
3560
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
3289
3561
|
|
|
3290
3562
|
// package.json
|
|
3291
|
-
var version = "0.
|
|
3563
|
+
var version = "0.19.1";
|
|
3292
3564
|
|
|
3293
3565
|
// ../tracking-core/src/phone-react.tsx
|
|
3294
3566
|
import {
|
|
@@ -3426,31 +3698,46 @@ function createTracking(options) {
|
|
|
3426
3698
|
metaPixelIds,
|
|
3427
3699
|
children
|
|
3428
3700
|
}) {
|
|
3429
|
-
const
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
}),
|
|
3701
|
+
const gtagIdsKey = useMemo4(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
|
|
3702
|
+
const resolvedGtagIds = useMemo4(
|
|
3703
|
+
() => gtagIds ? Object.fromEntries(
|
|
3704
|
+
Object.entries(gtagIds).filter((e) => e[1] != null)
|
|
3705
|
+
) : gtagId ? { default: gtagId } : void 0,
|
|
3706
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- gtagIdsKey is stable proxy
|
|
3707
|
+
[gtagId, gtagIdsKey]
|
|
3708
|
+
);
|
|
3709
|
+
const rawClient = useMemo4(
|
|
3710
|
+
() => getOrCreateTrackingClient({
|
|
3711
|
+
apiKey,
|
|
3712
|
+
endpoint,
|
|
3713
|
+
surface: "react",
|
|
3714
|
+
packageName: "@aranova/tracking-react",
|
|
3715
|
+
sdkVersion: version,
|
|
3445
3716
|
triggers,
|
|
3446
|
-
|
|
3447
|
-
|
|
3717
|
+
environment,
|
|
3718
|
+
activeGtagIds: resolvedGtagIds,
|
|
3719
|
+
debug
|
|
3720
|
+
}),
|
|
3721
|
+
[resolvedGtagIds]
|
|
3722
|
+
);
|
|
3723
|
+
const conversionStore = useMemo4(
|
|
3724
|
+
() => trackingConfig ? getTrackingConfigRuntime(trackingConfig) : conversionConfig ? resolveConversionConfig({
|
|
3725
|
+
cdnUrl: conversionConfig.cdnUrl,
|
|
3726
|
+
baked: conversionConfig.baked
|
|
3727
|
+
}) : null,
|
|
3448
3728
|
[]
|
|
3449
3729
|
);
|
|
3450
|
-
const
|
|
3730
|
+
const conversionClient = useMemo4(
|
|
3731
|
+
() => conversionStore ? withConversionAutoFire(rawClient, createConversionAutoFire(conversionStore)) : rawClient,
|
|
3732
|
+
[rawClient, conversionStore]
|
|
3733
|
+
);
|
|
3734
|
+
const client = useMemo4(
|
|
3735
|
+
() => createTypedClient(conversionClient, triggers, { debug }),
|
|
3736
|
+
[conversionClient]
|
|
3737
|
+
);
|
|
3451
3738
|
useEffect5(() => {
|
|
3452
3739
|
if (trackingConfig) {
|
|
3453
|
-
|
|
3740
|
+
getTrackingConfigRuntime(trackingConfig).start();
|
|
3454
3741
|
} else if (gtagIds && Object.keys(gtagIds).length > 0) {
|
|
3455
3742
|
bootstrapMultipleGtags(gtagIds);
|
|
3456
3743
|
} else if (gtagId) {
|
|
@@ -3469,23 +3756,9 @@ function createTracking(options) {
|
|
|
3469
3756
|
}
|
|
3470
3757
|
}, [metaPixelId, metaPixelIdsKey]);
|
|
3471
3758
|
useEffect5(() => {
|
|
3472
|
-
const rawClient = getOrCreateTrackingClient({
|
|
3473
|
-
apiKey,
|
|
3474
|
-
endpoint,
|
|
3475
|
-
surface: "react",
|
|
3476
|
-
packageName: "@aranova/tracking-react",
|
|
3477
|
-
triggers,
|
|
3478
|
-
environment,
|
|
3479
|
-
activeGtagIds: resolvedGtagIds,
|
|
3480
|
-
debug
|
|
3481
|
-
});
|
|
3482
3759
|
return attachClientCapturesOnce(rawClient, () => {
|
|
3483
3760
|
const detachers = [];
|
|
3484
|
-
const
|
|
3485
|
-
cdnUrl: conversionConfig.cdnUrl,
|
|
3486
|
-
baked: conversionConfig.baked
|
|
3487
|
-
}) : null;
|
|
3488
|
-
const detectorClient = conversionStore ? withConversionAutoFire(rawClient, createConversionAutoFire(conversionStore)) : rawClient;
|
|
3761
|
+
const detectorClient = conversionStore ? conversionClient : rawClient;
|
|
3489
3762
|
const pageClient = trackingConfig && conversionStore && "queuePageView" in conversionStore ? {
|
|
3490
3763
|
...detectorClient,
|
|
3491
3764
|
trackEvent: (input) => {
|
|
@@ -3530,7 +3803,7 @@ function createTracking(options) {
|
|
|
3530
3803
|
}
|
|
3531
3804
|
};
|
|
3532
3805
|
});
|
|
3533
|
-
}, []);
|
|
3806
|
+
}, [conversionClient, conversionStore, rawClient]);
|
|
3534
3807
|
return /* @__PURE__ */ jsx3(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ jsx3(PhoneConfigProvider, { value: phone ?? null, children }) });
|
|
3535
3808
|
}
|
|
3536
3809
|
function useTracking() {
|
|
@@ -3558,6 +3831,7 @@ export {
|
|
|
3558
3831
|
TRACKING_PARAM_KEYS,
|
|
3559
3832
|
TRACKING_RANGES,
|
|
3560
3833
|
captureTrackingParamsFromLocation,
|
|
3834
|
+
clearStashedUserData,
|
|
3561
3835
|
createSalesClient,
|
|
3562
3836
|
createTracking,
|
|
3563
3837
|
createTrackingClientContext,
|
|
@@ -3586,6 +3860,7 @@ export {
|
|
|
3586
3860
|
saleUpdateSchema,
|
|
3587
3861
|
salesRequest,
|
|
3588
3862
|
setConsentState,
|
|
3863
|
+
stashUserData,
|
|
3589
3864
|
toE164,
|
|
3590
3865
|
toMinor,
|
|
3591
3866
|
useConsent,
|