@aranova/tracking-react 0.17.2 → 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 +128 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +128 -57
- 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/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 {
|
|
@@ -1424,6 +1424,14 @@ var pageExitMetadataSchema = z7.object({
|
|
|
1424
1424
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1425
1425
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1426
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(),
|
|
1427
1435
|
page: z7.object({
|
|
1428
1436
|
path: z7.string()
|
|
1429
1437
|
}).strict()
|
|
@@ -1693,6 +1701,97 @@ function attachSpecificPageVisit(client, config) {
|
|
|
1693
1701
|
};
|
|
1694
1702
|
}
|
|
1695
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
|
+
|
|
1696
1795
|
// ../tracking-core/src/triggers/scroll-depth.ts
|
|
1697
1796
|
function attachScrollDepth(client, config) {
|
|
1698
1797
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
@@ -1703,17 +1802,14 @@ function attachScrollDepth(client, config) {
|
|
|
1703
1802
|
let firedForPath = /* @__PURE__ */ new Set();
|
|
1704
1803
|
let currentPath2 = window.location.pathname;
|
|
1705
1804
|
let rafId = null;
|
|
1706
|
-
|
|
1707
|
-
const doc = document.documentElement;
|
|
1708
|
-
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1709
|
-
const scrollHeight = doc.scrollHeight;
|
|
1710
|
-
const clientHeight = doc.clientHeight;
|
|
1711
|
-
if (scrollHeight <= clientHeight) return 100;
|
|
1712
|
-
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1713
|
-
}
|
|
1805
|
+
const gate = createBaselineGate();
|
|
1714
1806
|
function checkThresholds() {
|
|
1715
|
-
const percent =
|
|
1807
|
+
const percent = gate.sample();
|
|
1808
|
+
if (percent === null) return;
|
|
1809
|
+
const baseline = gate.baseline();
|
|
1810
|
+
if (baseline === null) return;
|
|
1716
1811
|
for (const threshold of thresholds) {
|
|
1812
|
+
if (threshold <= baseline) continue;
|
|
1717
1813
|
if (percent >= threshold && !firedForPath.has(threshold)) {
|
|
1718
1814
|
firedForPath.add(threshold);
|
|
1719
1815
|
client.trackEvent({
|
|
@@ -1740,28 +1836,15 @@ function attachScrollDepth(client, config) {
|
|
|
1740
1836
|
if (newPath === currentPath2) return;
|
|
1741
1837
|
currentPath2 = newPath;
|
|
1742
1838
|
firedForPath = /* @__PURE__ */ new Set();
|
|
1743
|
-
|
|
1839
|
+
gate.rebaseline();
|
|
1744
1840
|
}
|
|
1745
|
-
const
|
|
1746
|
-
const originalReplaceState = history.replaceState.bind(history);
|
|
1747
|
-
function patchedPushState(...args) {
|
|
1748
|
-
originalPushState(...args);
|
|
1749
|
-
setTimeout(resetIfPathChanged, 0);
|
|
1750
|
-
}
|
|
1751
|
-
function patchedReplaceState(...args) {
|
|
1752
|
-
originalReplaceState(...args);
|
|
1753
|
-
setTimeout(resetIfPathChanged, 0);
|
|
1754
|
-
}
|
|
1755
|
-
history.pushState = patchedPushState;
|
|
1756
|
-
history.replaceState = patchedReplaceState;
|
|
1757
|
-
window.addEventListener("popstate", resetIfPathChanged);
|
|
1841
|
+
const unsubscribeNav = onHistoryChange(resetIfPathChanged);
|
|
1758
1842
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1759
|
-
|
|
1843
|
+
gate.rebaseline();
|
|
1760
1844
|
return () => {
|
|
1761
1845
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
window.removeEventListener("popstate", resetIfPathChanged);
|
|
1846
|
+
gate.cancel();
|
|
1847
|
+
unsubscribeNav();
|
|
1765
1848
|
window.removeEventListener("scroll", onScroll);
|
|
1766
1849
|
};
|
|
1767
1850
|
}
|
|
@@ -1933,21 +2016,14 @@ function attachPageExit(client) {
|
|
|
1933
2016
|
let accumulatedMs = 0;
|
|
1934
2017
|
let maxScrollPercent = null;
|
|
1935
2018
|
let rafId = null;
|
|
1936
|
-
|
|
1937
|
-
const doc = document.documentElement;
|
|
1938
|
-
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1939
|
-
const scrollHeight = doc.scrollHeight;
|
|
1940
|
-
const clientHeight = doc.clientHeight;
|
|
1941
|
-
if (scrollHeight <= clientHeight) return 100;
|
|
1942
|
-
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1943
|
-
}
|
|
2019
|
+
const gate = createBaselineGate();
|
|
1944
2020
|
function onScroll() {
|
|
1945
2021
|
if (rafId !== null) return;
|
|
1946
2022
|
rafId = requestAnimationFrame(() => {
|
|
1947
2023
|
rafId = null;
|
|
1948
|
-
const percent =
|
|
1949
|
-
if (percent
|
|
1950
|
-
maxScrollPercent =
|
|
2024
|
+
const percent = gate.sample();
|
|
2025
|
+
if (percent !== null && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
2026
|
+
maxScrollPercent = percent;
|
|
1951
2027
|
}
|
|
1952
2028
|
});
|
|
1953
2029
|
}
|
|
@@ -1966,6 +2042,12 @@ function attachPageExit(client) {
|
|
|
1966
2042
|
metadata: {
|
|
1967
2043
|
dwell_ms: dwell,
|
|
1968
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(),
|
|
1969
2051
|
page: { path }
|
|
1970
2052
|
},
|
|
1971
2053
|
pageUrl: window.location.href,
|
|
@@ -1983,6 +2065,7 @@ function attachPageExit(client) {
|
|
|
1983
2065
|
emitSegment(currentPath2, false);
|
|
1984
2066
|
currentPath2 = newPath;
|
|
1985
2067
|
maxScrollPercent = null;
|
|
2068
|
+
gate.rebaseline();
|
|
1986
2069
|
accumulatedMs = 0;
|
|
1987
2070
|
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1988
2071
|
}
|
|
@@ -1996,27 +2079,15 @@ function attachPageExit(client) {
|
|
|
1996
2079
|
function onPageHide() {
|
|
1997
2080
|
emitSegment(currentPath2, true);
|
|
1998
2081
|
}
|
|
1999
|
-
const
|
|
2000
|
-
const originalReplaceState = history.replaceState.bind(history);
|
|
2001
|
-
function patchedPushState(...args) {
|
|
2002
|
-
originalPushState(...args);
|
|
2003
|
-
setTimeout(onNavigate, 0);
|
|
2004
|
-
}
|
|
2005
|
-
function patchedReplaceState(...args) {
|
|
2006
|
-
originalReplaceState(...args);
|
|
2007
|
-
setTimeout(onNavigate, 0);
|
|
2008
|
-
}
|
|
2009
|
-
history.pushState = patchedPushState;
|
|
2010
|
-
history.replaceState = patchedReplaceState;
|
|
2011
|
-
window.addEventListener("popstate", onNavigate);
|
|
2082
|
+
const unsubscribeNav = onHistoryChange(onNavigate);
|
|
2012
2083
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
2013
2084
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
2014
2085
|
window.addEventListener("pagehide", onPageHide);
|
|
2086
|
+
gate.rebaseline();
|
|
2015
2087
|
return () => {
|
|
2016
2088
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
window.removeEventListener("popstate", onNavigate);
|
|
2089
|
+
gate.cancel();
|
|
2090
|
+
unsubscribeNav();
|
|
2020
2091
|
window.removeEventListener("scroll", onScroll);
|
|
2021
2092
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
2022
2093
|
window.removeEventListener("pagehide", onPageHide);
|
|
@@ -2821,7 +2892,7 @@ function GoogleAdsTracking(props) {
|
|
|
2821
2892
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
2822
2893
|
|
|
2823
2894
|
// package.json
|
|
2824
|
-
var version = "0.17.
|
|
2895
|
+
var version = "0.17.3";
|
|
2825
2896
|
|
|
2826
2897
|
// ../tracking-core/src/phone-react.tsx
|
|
2827
2898
|
import {
|