@aranova/tracking-react 0.17.1 → 0.17.3
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 +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +192 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +192 -98
- package/dist/index.mjs.map +1 -1
- package/dist/phone.js +8 -0
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +8 -0
- 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
|
@@ -654,9 +654,9 @@ function resolveConversionConfig(options) {
|
|
|
654
654
|
}
|
|
655
655
|
}
|
|
656
656
|
function notifyResolved() {
|
|
657
|
-
const
|
|
657
|
+
const listeners2 = [...resolveListeners];
|
|
658
658
|
resolveListeners.clear();
|
|
659
|
-
for (const listener of
|
|
659
|
+
for (const listener of listeners2) {
|
|
660
660
|
try {
|
|
661
661
|
listener();
|
|
662
662
|
} catch {
|
|
@@ -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);
|
|
@@ -1403,6 +1424,14 @@ var pageExitMetadataSchema = z7.object({
|
|
|
1403
1424
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1404
1425
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1405
1426
|
max_scroll_percent: z7.number().int().min(0).max(100).nullable(),
|
|
1427
|
+
// The gating baseline: the fraction of the page visible at load with
|
|
1428
|
+
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
1429
|
+
// (skeleton/streaming renders), the first-scroll position that
|
|
1430
|
+
// established it. null = page had no scrollable range, or the segment
|
|
1431
|
+
// ended before the snapshot. `.optional()` is load-bearing: SDK builds
|
|
1432
|
+
// predating this field keep POSTing page_exit without the key —
|
|
1433
|
+
// requiring it would 422 whole keepalive beacon batches.
|
|
1434
|
+
scroll_baseline_percent: z7.number().int().min(0).max(100).nullable().optional(),
|
|
1406
1435
|
page: z7.object({
|
|
1407
1436
|
path: z7.string()
|
|
1408
1437
|
}).strict()
|
|
@@ -1672,6 +1701,97 @@ function attachSpecificPageVisit(client, config) {
|
|
|
1672
1701
|
};
|
|
1673
1702
|
}
|
|
1674
1703
|
|
|
1704
|
+
// ../tracking-core/src/triggers/navigation.ts
|
|
1705
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1706
|
+
var restorePatch = null;
|
|
1707
|
+
function notify() {
|
|
1708
|
+
for (const listener of listeners) listener();
|
|
1709
|
+
}
|
|
1710
|
+
function notifyDeferred() {
|
|
1711
|
+
setTimeout(notify, 0);
|
|
1712
|
+
}
|
|
1713
|
+
function installPatch() {
|
|
1714
|
+
const originalPushState = history.pushState;
|
|
1715
|
+
const originalReplaceState = history.replaceState;
|
|
1716
|
+
function patchedPushState(...args) {
|
|
1717
|
+
originalPushState.apply(this, args);
|
|
1718
|
+
notifyDeferred();
|
|
1719
|
+
}
|
|
1720
|
+
function patchedReplaceState(...args) {
|
|
1721
|
+
originalReplaceState.apply(this, args);
|
|
1722
|
+
notifyDeferred();
|
|
1723
|
+
}
|
|
1724
|
+
history.pushState = patchedPushState;
|
|
1725
|
+
history.replaceState = patchedReplaceState;
|
|
1726
|
+
window.addEventListener("popstate", notify);
|
|
1727
|
+
restorePatch = () => {
|
|
1728
|
+
history.pushState = originalPushState;
|
|
1729
|
+
history.replaceState = originalReplaceState;
|
|
1730
|
+
window.removeEventListener("popstate", notify);
|
|
1731
|
+
restorePatch = null;
|
|
1732
|
+
};
|
|
1733
|
+
}
|
|
1734
|
+
function onHistoryChange(listener) {
|
|
1735
|
+
if (listeners.size === 0) installPatch();
|
|
1736
|
+
listeners.add(listener);
|
|
1737
|
+
return () => {
|
|
1738
|
+
if (!listeners.delete(listener)) return;
|
|
1739
|
+
if (listeners.size === 0) restorePatch?.();
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
// ../tracking-core/src/triggers/scroll-measurement.ts
|
|
1744
|
+
var BOTTOM_EPSILON_PX = 2;
|
|
1745
|
+
function measureScrollPercent() {
|
|
1746
|
+
const root = document.scrollingElement ?? document.documentElement;
|
|
1747
|
+
const scrollHeight = root.scrollHeight;
|
|
1748
|
+
const clientHeight = root.clientHeight;
|
|
1749
|
+
if (scrollHeight <= 0 || clientHeight <= 0) return null;
|
|
1750
|
+
if (scrollHeight <= clientHeight + BOTTOM_EPSILON_PX) return null;
|
|
1751
|
+
const maxTop = scrollHeight - clientHeight;
|
|
1752
|
+
const scrollTop = Math.min(Math.max(root.scrollTop, 0), maxTop);
|
|
1753
|
+
if (scrollTop + clientHeight >= scrollHeight - BOTTOM_EPSILON_PX) return 100;
|
|
1754
|
+
return Math.max(1, Math.min(100, Math.round((scrollTop + clientHeight) / scrollHeight * 100)));
|
|
1755
|
+
}
|
|
1756
|
+
function scheduleBaselineSnapshot(onSnapshot) {
|
|
1757
|
+
let rafId = requestAnimationFrame(() => {
|
|
1758
|
+
rafId = requestAnimationFrame(() => {
|
|
1759
|
+
onSnapshot(measureScrollPercent());
|
|
1760
|
+
});
|
|
1761
|
+
});
|
|
1762
|
+
return () => cancelAnimationFrame(rafId);
|
|
1763
|
+
}
|
|
1764
|
+
function createBaselineGate() {
|
|
1765
|
+
let baselinePercent = null;
|
|
1766
|
+
let ready = false;
|
|
1767
|
+
let cancelSnapshot = null;
|
|
1768
|
+
return {
|
|
1769
|
+
rebaseline() {
|
|
1770
|
+
cancelSnapshot?.();
|
|
1771
|
+
ready = false;
|
|
1772
|
+
baselinePercent = null;
|
|
1773
|
+
cancelSnapshot = scheduleBaselineSnapshot((b) => {
|
|
1774
|
+
baselinePercent = b;
|
|
1775
|
+
ready = true;
|
|
1776
|
+
});
|
|
1777
|
+
},
|
|
1778
|
+
cancel() {
|
|
1779
|
+
cancelSnapshot?.();
|
|
1780
|
+
},
|
|
1781
|
+
baseline() {
|
|
1782
|
+
return ready ? baselinePercent : null;
|
|
1783
|
+
},
|
|
1784
|
+
sample() {
|
|
1785
|
+
if (!ready) return null;
|
|
1786
|
+
if (baselinePercent === null) {
|
|
1787
|
+
baselinePercent = measureScrollPercent();
|
|
1788
|
+
return null;
|
|
1789
|
+
}
|
|
1790
|
+
return measureScrollPercent();
|
|
1791
|
+
}
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1675
1795
|
// ../tracking-core/src/triggers/scroll-depth.ts
|
|
1676
1796
|
function attachScrollDepth(client, config) {
|
|
1677
1797
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
@@ -1682,17 +1802,14 @@ function attachScrollDepth(client, config) {
|
|
|
1682
1802
|
let firedForPath = /* @__PURE__ */ new Set();
|
|
1683
1803
|
let currentPath2 = window.location.pathname;
|
|
1684
1804
|
let rafId = null;
|
|
1685
|
-
|
|
1686
|
-
const doc = document.documentElement;
|
|
1687
|
-
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1688
|
-
const scrollHeight = doc.scrollHeight;
|
|
1689
|
-
const clientHeight = doc.clientHeight;
|
|
1690
|
-
if (scrollHeight <= clientHeight) return 100;
|
|
1691
|
-
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1692
|
-
}
|
|
1805
|
+
const gate = createBaselineGate();
|
|
1693
1806
|
function checkThresholds() {
|
|
1694
|
-
const percent =
|
|
1807
|
+
const percent = gate.sample();
|
|
1808
|
+
if (percent === null) return;
|
|
1809
|
+
const baseline = gate.baseline();
|
|
1810
|
+
if (baseline === null) return;
|
|
1695
1811
|
for (const threshold of thresholds) {
|
|
1812
|
+
if (threshold <= baseline) continue;
|
|
1696
1813
|
if (percent >= threshold && !firedForPath.has(threshold)) {
|
|
1697
1814
|
firedForPath.add(threshold);
|
|
1698
1815
|
client.trackEvent({
|
|
@@ -1719,28 +1836,15 @@ function attachScrollDepth(client, config) {
|
|
|
1719
1836
|
if (newPath === currentPath2) return;
|
|
1720
1837
|
currentPath2 = newPath;
|
|
1721
1838
|
firedForPath = /* @__PURE__ */ new Set();
|
|
1722
|
-
|
|
1723
|
-
}
|
|
1724
|
-
const originalPushState = history.pushState.bind(history);
|
|
1725
|
-
const originalReplaceState = history.replaceState.bind(history);
|
|
1726
|
-
function patchedPushState(...args) {
|
|
1727
|
-
originalPushState(...args);
|
|
1728
|
-
setTimeout(resetIfPathChanged, 0);
|
|
1839
|
+
gate.rebaseline();
|
|
1729
1840
|
}
|
|
1730
|
-
|
|
1731
|
-
originalReplaceState(...args);
|
|
1732
|
-
setTimeout(resetIfPathChanged, 0);
|
|
1733
|
-
}
|
|
1734
|
-
history.pushState = patchedPushState;
|
|
1735
|
-
history.replaceState = patchedReplaceState;
|
|
1736
|
-
window.addEventListener("popstate", resetIfPathChanged);
|
|
1841
|
+
const unsubscribeNav = onHistoryChange(resetIfPathChanged);
|
|
1737
1842
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1738
|
-
|
|
1843
|
+
gate.rebaseline();
|
|
1739
1844
|
return () => {
|
|
1740
1845
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
window.removeEventListener("popstate", resetIfPathChanged);
|
|
1846
|
+
gate.cancel();
|
|
1847
|
+
unsubscribeNav();
|
|
1744
1848
|
window.removeEventListener("scroll", onScroll);
|
|
1745
1849
|
};
|
|
1746
1850
|
}
|
|
@@ -1912,21 +2016,14 @@ function attachPageExit(client) {
|
|
|
1912
2016
|
let accumulatedMs = 0;
|
|
1913
2017
|
let maxScrollPercent = null;
|
|
1914
2018
|
let rafId = null;
|
|
1915
|
-
|
|
1916
|
-
const doc = document.documentElement;
|
|
1917
|
-
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1918
|
-
const scrollHeight = doc.scrollHeight;
|
|
1919
|
-
const clientHeight = doc.clientHeight;
|
|
1920
|
-
if (scrollHeight <= clientHeight) return 100;
|
|
1921
|
-
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1922
|
-
}
|
|
2019
|
+
const gate = createBaselineGate();
|
|
1923
2020
|
function onScroll() {
|
|
1924
2021
|
if (rafId !== null) return;
|
|
1925
2022
|
rafId = requestAnimationFrame(() => {
|
|
1926
2023
|
rafId = null;
|
|
1927
|
-
const percent =
|
|
1928
|
-
if (percent
|
|
1929
|
-
maxScrollPercent =
|
|
2024
|
+
const percent = gate.sample();
|
|
2025
|
+
if (percent !== null && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
2026
|
+
maxScrollPercent = percent;
|
|
1930
2027
|
}
|
|
1931
2028
|
});
|
|
1932
2029
|
}
|
|
@@ -1945,6 +2042,12 @@ function attachPageExit(client) {
|
|
|
1945
2042
|
metadata: {
|
|
1946
2043
|
dwell_ms: dwell,
|
|
1947
2044
|
max_scroll_percent: maxScrollPercent,
|
|
2045
|
+
// Lets the backend tell "scrolled to the bottom" apart from "the page
|
|
2046
|
+
// was barely scrollable". null = unscrollable page or the segment
|
|
2047
|
+
// ended before the post-paint snapshot landed. For pages that grew
|
|
2048
|
+
// after the snapshot this is the first-scroll position, not the
|
|
2049
|
+
// at-load fraction (see BaselineGate.baseline).
|
|
2050
|
+
scroll_baseline_percent: gate.baseline(),
|
|
1948
2051
|
page: { path }
|
|
1949
2052
|
},
|
|
1950
2053
|
pageUrl: window.location.href,
|
|
@@ -1962,6 +2065,7 @@ function attachPageExit(client) {
|
|
|
1962
2065
|
emitSegment(currentPath2, false);
|
|
1963
2066
|
currentPath2 = newPath;
|
|
1964
2067
|
maxScrollPercent = null;
|
|
2068
|
+
gate.rebaseline();
|
|
1965
2069
|
accumulatedMs = 0;
|
|
1966
2070
|
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1967
2071
|
}
|
|
@@ -1975,27 +2079,15 @@ function attachPageExit(client) {
|
|
|
1975
2079
|
function onPageHide() {
|
|
1976
2080
|
emitSegment(currentPath2, true);
|
|
1977
2081
|
}
|
|
1978
|
-
const
|
|
1979
|
-
const originalReplaceState = history.replaceState.bind(history);
|
|
1980
|
-
function patchedPushState(...args) {
|
|
1981
|
-
originalPushState(...args);
|
|
1982
|
-
setTimeout(onNavigate, 0);
|
|
1983
|
-
}
|
|
1984
|
-
function patchedReplaceState(...args) {
|
|
1985
|
-
originalReplaceState(...args);
|
|
1986
|
-
setTimeout(onNavigate, 0);
|
|
1987
|
-
}
|
|
1988
|
-
history.pushState = patchedPushState;
|
|
1989
|
-
history.replaceState = patchedReplaceState;
|
|
1990
|
-
window.addEventListener("popstate", onNavigate);
|
|
2082
|
+
const unsubscribeNav = onHistoryChange(onNavigate);
|
|
1991
2083
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1992
2084
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1993
2085
|
window.addEventListener("pagehide", onPageHide);
|
|
2086
|
+
gate.rebaseline();
|
|
1994
2087
|
return () => {
|
|
1995
2088
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
window.removeEventListener("popstate", onNavigate);
|
|
2089
|
+
gate.cancel();
|
|
2090
|
+
unsubscribeNav();
|
|
1999
2091
|
window.removeEventListener("scroll", onScroll);
|
|
2000
2092
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
2001
2093
|
window.removeEventListener("pagehide", onPageHide);
|
|
@@ -2800,7 +2892,7 @@ function GoogleAdsTracking(props) {
|
|
|
2800
2892
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
2801
2893
|
|
|
2802
2894
|
// package.json
|
|
2803
|
-
var version = "0.17.
|
|
2895
|
+
var version = "0.17.3";
|
|
2804
2896
|
|
|
2805
2897
|
// ../tracking-core/src/phone-react.tsx
|
|
2806
2898
|
import {
|
|
@@ -2970,7 +3062,6 @@ function createTracking(options) {
|
|
|
2970
3062
|
}
|
|
2971
3063
|
}, [metaPixelId, metaPixelIdsKey]);
|
|
2972
3064
|
useEffect5(() => {
|
|
2973
|
-
const detachers = [];
|
|
2974
3065
|
const rawClient = getOrCreateTrackingClient({
|
|
2975
3066
|
apiKey,
|
|
2976
3067
|
endpoint,
|
|
@@ -2981,47 +3072,50 @@ function createTracking(options) {
|
|
|
2981
3072
|
activeGtagIds: resolvedGtagIds,
|
|
2982
3073
|
debug
|
|
2983
3074
|
});
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
if (specificPageVisit) {
|
|
2998
|
-
detachers.push(attachSpecificPageVisit(detectorClient, specificPageVisit));
|
|
2999
|
-
}
|
|
3000
|
-
const scrollDepth = triggers.automatic.scroll_depth;
|
|
3001
|
-
if (scrollDepth) {
|
|
3002
|
-
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
3003
|
-
}
|
|
3004
|
-
const multiPageSession = triggers.automatic.multi_page_session;
|
|
3005
|
-
if (multiPageSession) {
|
|
3006
|
-
detachers.push(attachMultiPageSession(detectorClient, multiPageSession));
|
|
3007
|
-
}
|
|
3008
|
-
const formStart = triggers.automatic.form_start;
|
|
3009
|
-
if (formStart) {
|
|
3010
|
-
detachers.push(attachFormStart(detectorClient, formStart));
|
|
3011
|
-
}
|
|
3012
|
-
const ctaClick = triggers.manual?.cta_click;
|
|
3013
|
-
if (ctaClick) {
|
|
3014
|
-
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
3015
|
-
}
|
|
3016
|
-
const phoneClick = triggers.manual?.phone_click;
|
|
3017
|
-
if (phoneClick) {
|
|
3018
|
-
detachers.push(attachPhoneClickCapture(detectorClient, phoneClick));
|
|
3019
|
-
}
|
|
3020
|
-
return () => {
|
|
3021
|
-
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
3022
|
-
detachers[i]();
|
|
3075
|
+
return attachClientCapturesOnce(rawClient, () => {
|
|
3076
|
+
const detachers = [];
|
|
3077
|
+
const conversionStore = conversionConfig ? resolveConversionConfig({
|
|
3078
|
+
cdnUrl: conversionConfig.cdnUrl,
|
|
3079
|
+
baked: conversionConfig.baked
|
|
3080
|
+
}) : null;
|
|
3081
|
+
const detectorClient = conversionStore ? withConversionAutoFire(rawClient, createConversionAutoFire(conversionStore)) : rawClient;
|
|
3082
|
+
detachers.push(attachAutoPageView(detectorClient));
|
|
3083
|
+
detachers.push(attachBfcacheRestore(detectorClient));
|
|
3084
|
+
detachers.push(attachPageExit(detectorClient));
|
|
3085
|
+
const timeOnSite = triggers.automatic.time_on_site;
|
|
3086
|
+
if (timeOnSite) {
|
|
3087
|
+
detachers.push(attachTimeOnSite(detectorClient, timeOnSite));
|
|
3023
3088
|
}
|
|
3024
|
-
|
|
3089
|
+
const specificPageVisit = triggers.automatic.specific_page_visit;
|
|
3090
|
+
if (specificPageVisit) {
|
|
3091
|
+
detachers.push(attachSpecificPageVisit(detectorClient, specificPageVisit));
|
|
3092
|
+
}
|
|
3093
|
+
const scrollDepth = triggers.automatic.scroll_depth;
|
|
3094
|
+
if (scrollDepth) {
|
|
3095
|
+
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
3096
|
+
}
|
|
3097
|
+
const multiPageSession = triggers.automatic.multi_page_session;
|
|
3098
|
+
if (multiPageSession) {
|
|
3099
|
+
detachers.push(attachMultiPageSession(detectorClient, multiPageSession));
|
|
3100
|
+
}
|
|
3101
|
+
const formStart = triggers.automatic.form_start;
|
|
3102
|
+
if (formStart) {
|
|
3103
|
+
detachers.push(attachFormStart(detectorClient, formStart));
|
|
3104
|
+
}
|
|
3105
|
+
const ctaClick = triggers.manual?.cta_click;
|
|
3106
|
+
if (ctaClick) {
|
|
3107
|
+
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
3108
|
+
}
|
|
3109
|
+
const phoneClick = triggers.manual?.phone_click;
|
|
3110
|
+
if (phoneClick) {
|
|
3111
|
+
detachers.push(attachPhoneClickCapture(detectorClient, phoneClick));
|
|
3112
|
+
}
|
|
3113
|
+
return () => {
|
|
3114
|
+
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
3115
|
+
detachers[i]();
|
|
3116
|
+
}
|
|
3117
|
+
};
|
|
3118
|
+
});
|
|
3025
3119
|
}, []);
|
|
3026
3120
|
return /* @__PURE__ */ jsx3(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ jsx3(PhoneConfigProvider, { value: phone ?? null, children }) });
|
|
3027
3121
|
}
|