@aranova/tracking-react 0.17.0 → 0.17.2
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 +27 -0
- package/dist/index.d.mts +38 -3
- package/dist/index.d.ts +38 -3
- package/dist/index.js +164 -80
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -80
- package/dist/index.mjs.map +1 -1
- package/dist/phone.js +45 -41
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +45 -41
- package/dist/phone.mjs.map +1 -1
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -758,8 +758,8 @@ function thresholdMet(goal, eventType, metadata) {
|
|
|
758
758
|
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
759
759
|
case "page_view":
|
|
760
760
|
case "form_start":
|
|
761
|
+
case "phone_click":
|
|
761
762
|
return true;
|
|
762
|
-
// no threshold — fire whenever the detector emits
|
|
763
763
|
default:
|
|
764
764
|
return false;
|
|
765
765
|
}
|
|
@@ -1134,6 +1134,27 @@ function getOrCreateTrackingClient(config) {
|
|
|
1134
1134
|
globalClientKey = key;
|
|
1135
1135
|
return globalClient;
|
|
1136
1136
|
}
|
|
1137
|
+
var clientCaptureRegistry = /* @__PURE__ */ new WeakMap();
|
|
1138
|
+
function attachClientCapturesOnce(client, build) {
|
|
1139
|
+
let entry = clientCaptureRegistry.get(client);
|
|
1140
|
+
if (entry === void 0) {
|
|
1141
|
+
entry = { detach: build(), refCount: 0 };
|
|
1142
|
+
clientCaptureRegistry.set(client, entry);
|
|
1143
|
+
}
|
|
1144
|
+
entry.refCount += 1;
|
|
1145
|
+
let released = false;
|
|
1146
|
+
return () => {
|
|
1147
|
+
if (released) return;
|
|
1148
|
+
released = true;
|
|
1149
|
+
const current = clientCaptureRegistry.get(client);
|
|
1150
|
+
if (current === void 0) return;
|
|
1151
|
+
current.refCount -= 1;
|
|
1152
|
+
if (current.refCount <= 0) {
|
|
1153
|
+
current.detach();
|
|
1154
|
+
clientCaptureRegistry.delete(client);
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1137
1158
|
function createTrackingClient(config) {
|
|
1138
1159
|
const flushIntervalMs = config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;
|
|
1139
1160
|
const maxQueueSize = Math.min(config.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE, HARD_MAX_BATCH);
|
|
@@ -1418,7 +1439,11 @@ var phoneClickMetadataSchema = z8.object({
|
|
|
1418
1439
|
}).strict(),
|
|
1419
1440
|
section: z8.string().nullable().optional()
|
|
1420
1441
|
}).strict();
|
|
1421
|
-
var phoneClickConfigSchema = z8.object({
|
|
1442
|
+
var phoneClickConfigSchema = z8.object({
|
|
1443
|
+
autoCapture: z8.object({
|
|
1444
|
+
selector: z8.string().optional()
|
|
1445
|
+
}).strict().optional()
|
|
1446
|
+
}).strict();
|
|
1422
1447
|
|
|
1423
1448
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
1424
1449
|
import { z as z9 } from "zod";
|
|
@@ -2054,6 +2079,99 @@ function attachCtaClickCapture(client, config) {
|
|
|
2054
2079
|
};
|
|
2055
2080
|
}
|
|
2056
2081
|
|
|
2082
|
+
// ../tracking-core/src/phone.ts
|
|
2083
|
+
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
2084
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2085
|
+
function parsePhone(raw, country) {
|
|
2086
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2087
|
+
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
2088
|
+
if (!parsed) {
|
|
2089
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2090
|
+
}
|
|
2091
|
+
const isValid = parsed.isValid();
|
|
2092
|
+
return {
|
|
2093
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2094
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2095
|
+
e164: isValid ? parsed.number : null,
|
|
2096
|
+
national: parsed.formatNational(),
|
|
2097
|
+
international: parsed.formatInternational(),
|
|
2098
|
+
country: parsed.country ?? region,
|
|
2099
|
+
isValid
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
function toE164(raw, country) {
|
|
2103
|
+
return parsePhone(raw, country).e164;
|
|
2104
|
+
}
|
|
2105
|
+
function formatPhone(value, format = "national", country) {
|
|
2106
|
+
const parsed = parsePhone(value, country);
|
|
2107
|
+
if (typeof format === "function") return format(parsed);
|
|
2108
|
+
switch (format) {
|
|
2109
|
+
case "international":
|
|
2110
|
+
return parsed.international || value;
|
|
2111
|
+
case "e164":
|
|
2112
|
+
return parsed.e164 ?? value;
|
|
2113
|
+
case "national":
|
|
2114
|
+
default:
|
|
2115
|
+
return parsed.national || value;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
function formatPhoneAsTyped(raw, country) {
|
|
2119
|
+
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2123
|
+
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2124
|
+
function safeDecodeURIComponent(value) {
|
|
2125
|
+
try {
|
|
2126
|
+
return decodeURIComponent(value);
|
|
2127
|
+
} catch {
|
|
2128
|
+
return value;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
function resolvePhoneNumber(el) {
|
|
2132
|
+
const href = el instanceof HTMLAnchorElement ? el.href : el.getAttribute("href") ?? "";
|
|
2133
|
+
const raw = safeDecodeURIComponent(href.replace(/^tel:/i, "").split(";")[0]).trim();
|
|
2134
|
+
return toE164(raw) ?? raw;
|
|
2135
|
+
}
|
|
2136
|
+
function attachPhoneClickCapture(client, config) {
|
|
2137
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
2138
|
+
return () => {
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2141
|
+
const autoCapture = config.autoCapture;
|
|
2142
|
+
if (!autoCapture) {
|
|
2143
|
+
return () => {
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
const selector = autoCapture.selector ?? DEFAULT_TEL_SELECTOR;
|
|
2147
|
+
function onClick(event) {
|
|
2148
|
+
const target = event.target;
|
|
2149
|
+
if (!(target instanceof Element)) return;
|
|
2150
|
+
let matched = null;
|
|
2151
|
+
try {
|
|
2152
|
+
matched = target.closest(selector);
|
|
2153
|
+
} catch {
|
|
2154
|
+
return;
|
|
2155
|
+
}
|
|
2156
|
+
if (matched === null) return;
|
|
2157
|
+
const metadata = {
|
|
2158
|
+
phone_number: resolvePhoneNumber(matched),
|
|
2159
|
+
page: { path: window.location.pathname },
|
|
2160
|
+
section: matched.getAttribute("data-aranova-section")
|
|
2161
|
+
};
|
|
2162
|
+
client.trackEvent({
|
|
2163
|
+
eventType: "phone_click",
|
|
2164
|
+
metadata,
|
|
2165
|
+
pageUrl: window.location.href,
|
|
2166
|
+
occurredAt: null
|
|
2167
|
+
});
|
|
2168
|
+
}
|
|
2169
|
+
document.addEventListener("click", onClick, true);
|
|
2170
|
+
return () => {
|
|
2171
|
+
document.removeEventListener("click", onClick, true);
|
|
2172
|
+
};
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2057
2175
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
2058
2176
|
var AranovaApiError = class extends Error {
|
|
2059
2177
|
constructor(message, options) {
|
|
@@ -2381,46 +2499,6 @@ async function fetchServices(config) {
|
|
|
2381
2499
|
return salesRequest(config, "GET", "/services");
|
|
2382
2500
|
}
|
|
2383
2501
|
|
|
2384
|
-
// ../tracking-core/src/phone.ts
|
|
2385
|
-
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
2386
|
-
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2387
|
-
function parsePhone(raw, country) {
|
|
2388
|
-
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2389
|
-
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
2390
|
-
if (!parsed) {
|
|
2391
|
-
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2392
|
-
}
|
|
2393
|
-
const isValid = parsed.isValid();
|
|
2394
|
-
return {
|
|
2395
|
-
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2396
|
-
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2397
|
-
e164: isValid ? parsed.number : null,
|
|
2398
|
-
national: parsed.formatNational(),
|
|
2399
|
-
international: parsed.formatInternational(),
|
|
2400
|
-
country: parsed.country ?? region,
|
|
2401
|
-
isValid
|
|
2402
|
-
};
|
|
2403
|
-
}
|
|
2404
|
-
function toE164(raw, country) {
|
|
2405
|
-
return parsePhone(raw, country).e164;
|
|
2406
|
-
}
|
|
2407
|
-
function formatPhone(value, format = "national", country) {
|
|
2408
|
-
const parsed = parsePhone(value, country);
|
|
2409
|
-
if (typeof format === "function") return format(parsed);
|
|
2410
|
-
switch (format) {
|
|
2411
|
-
case "international":
|
|
2412
|
-
return parsed.international || value;
|
|
2413
|
-
case "e164":
|
|
2414
|
-
return parsed.e164 ?? value;
|
|
2415
|
-
case "national":
|
|
2416
|
-
default:
|
|
2417
|
-
return parsed.national || value;
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
function formatPhoneAsTyped(raw, country) {
|
|
2421
|
-
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2422
|
-
}
|
|
2423
|
-
|
|
2424
2502
|
// ../tracking-core/src/phone-field.ts
|
|
2425
2503
|
function phoneField(name, raw, country) {
|
|
2426
2504
|
return { name, type: "phone", value: toE164(raw, country) };
|
|
@@ -2743,7 +2821,7 @@ function GoogleAdsTracking(props) {
|
|
|
2743
2821
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
2744
2822
|
|
|
2745
2823
|
// package.json
|
|
2746
|
-
var version = "0.17.
|
|
2824
|
+
var version = "0.17.2";
|
|
2747
2825
|
|
|
2748
2826
|
// ../tracking-core/src/phone-react.tsx
|
|
2749
2827
|
import {
|
|
@@ -2913,7 +2991,6 @@ function createTracking(options) {
|
|
|
2913
2991
|
}
|
|
2914
2992
|
}, [metaPixelId, metaPixelIdsKey]);
|
|
2915
2993
|
useEffect5(() => {
|
|
2916
|
-
const detachers = [];
|
|
2917
2994
|
const rawClient = getOrCreateTrackingClient({
|
|
2918
2995
|
apiKey,
|
|
2919
2996
|
endpoint,
|
|
@@ -2924,43 +3001,50 @@ function createTracking(options) {
|
|
|
2924
3001
|
activeGtagIds: resolvedGtagIds,
|
|
2925
3002
|
debug
|
|
2926
3003
|
});
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
if (scrollDepth) {
|
|
2945
|
-
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
2946
|
-
}
|
|
2947
|
-
const multiPageSession = triggers.automatic.multi_page_session;
|
|
2948
|
-
if (multiPageSession) {
|
|
2949
|
-
detachers.push(attachMultiPageSession(detectorClient, multiPageSession));
|
|
2950
|
-
}
|
|
2951
|
-
const formStart = triggers.automatic.form_start;
|
|
2952
|
-
if (formStart) {
|
|
2953
|
-
detachers.push(attachFormStart(detectorClient, formStart));
|
|
2954
|
-
}
|
|
2955
|
-
const ctaClick = triggers.manual?.cta_click;
|
|
2956
|
-
if (ctaClick) {
|
|
2957
|
-
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2958
|
-
}
|
|
2959
|
-
return () => {
|
|
2960
|
-
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2961
|
-
detachers[i]();
|
|
3004
|
+
return attachClientCapturesOnce(rawClient, () => {
|
|
3005
|
+
const detachers = [];
|
|
3006
|
+
const conversionStore = conversionConfig ? resolveConversionConfig({
|
|
3007
|
+
cdnUrl: conversionConfig.cdnUrl,
|
|
3008
|
+
baked: conversionConfig.baked
|
|
3009
|
+
}) : null;
|
|
3010
|
+
const detectorClient = conversionStore ? withConversionAutoFire(rawClient, createConversionAutoFire(conversionStore)) : rawClient;
|
|
3011
|
+
detachers.push(attachAutoPageView(detectorClient));
|
|
3012
|
+
detachers.push(attachBfcacheRestore(detectorClient));
|
|
3013
|
+
detachers.push(attachPageExit(detectorClient));
|
|
3014
|
+
const timeOnSite = triggers.automatic.time_on_site;
|
|
3015
|
+
if (timeOnSite) {
|
|
3016
|
+
detachers.push(attachTimeOnSite(detectorClient, timeOnSite));
|
|
3017
|
+
}
|
|
3018
|
+
const specificPageVisit = triggers.automatic.specific_page_visit;
|
|
3019
|
+
if (specificPageVisit) {
|
|
3020
|
+
detachers.push(attachSpecificPageVisit(detectorClient, specificPageVisit));
|
|
2962
3021
|
}
|
|
2963
|
-
|
|
3022
|
+
const scrollDepth = triggers.automatic.scroll_depth;
|
|
3023
|
+
if (scrollDepth) {
|
|
3024
|
+
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
3025
|
+
}
|
|
3026
|
+
const multiPageSession = triggers.automatic.multi_page_session;
|
|
3027
|
+
if (multiPageSession) {
|
|
3028
|
+
detachers.push(attachMultiPageSession(detectorClient, multiPageSession));
|
|
3029
|
+
}
|
|
3030
|
+
const formStart = triggers.automatic.form_start;
|
|
3031
|
+
if (formStart) {
|
|
3032
|
+
detachers.push(attachFormStart(detectorClient, formStart));
|
|
3033
|
+
}
|
|
3034
|
+
const ctaClick = triggers.manual?.cta_click;
|
|
3035
|
+
if (ctaClick) {
|
|
3036
|
+
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
3037
|
+
}
|
|
3038
|
+
const phoneClick = triggers.manual?.phone_click;
|
|
3039
|
+
if (phoneClick) {
|
|
3040
|
+
detachers.push(attachPhoneClickCapture(detectorClient, phoneClick));
|
|
3041
|
+
}
|
|
3042
|
+
return () => {
|
|
3043
|
+
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
3044
|
+
detachers[i]();
|
|
3045
|
+
}
|
|
3046
|
+
};
|
|
3047
|
+
});
|
|
2964
3048
|
}, []);
|
|
2965
3049
|
return /* @__PURE__ */ jsx3(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ jsx3(PhoneConfigProvider, { value: phone ?? null, children }) });
|
|
2966
3050
|
}
|