@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.d.mts
CHANGED
|
@@ -349,6 +349,7 @@ type MultiPageSessionConfig = z.infer<typeof multiPageSessionConfigSchema>;
|
|
|
349
349
|
declare const pageExitMetadataSchema: z.ZodObject<{
|
|
350
350
|
dwell_ms: z.ZodNumber;
|
|
351
351
|
max_scroll_percent: z.ZodNullable<z.ZodNumber>;
|
|
352
|
+
scroll_baseline_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
352
353
|
page: z.ZodObject<{
|
|
353
354
|
path: z.ZodString;
|
|
354
355
|
}, "strict", z.ZodTypeAny, {
|
|
@@ -362,12 +363,14 @@ declare const pageExitMetadataSchema: z.ZodObject<{
|
|
|
362
363
|
};
|
|
363
364
|
dwell_ms: number;
|
|
364
365
|
max_scroll_percent: number | null;
|
|
366
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
365
367
|
}, {
|
|
366
368
|
page: {
|
|
367
369
|
path: string;
|
|
368
370
|
};
|
|
369
371
|
dwell_ms: number;
|
|
370
372
|
max_scroll_percent: number | null;
|
|
373
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
371
374
|
}>;
|
|
372
375
|
type PageExitMetadata = z.infer<typeof pageExitMetadataSchema>;
|
|
373
376
|
/**
|
|
@@ -934,6 +937,7 @@ declare const EVENT_REGISTRY: {
|
|
|
934
937
|
readonly metadataSchema: z.ZodObject<{
|
|
935
938
|
dwell_ms: z.ZodNumber;
|
|
936
939
|
max_scroll_percent: z.ZodNullable<z.ZodNumber>;
|
|
940
|
+
scroll_baseline_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
937
941
|
page: z.ZodObject<{
|
|
938
942
|
path: z.ZodString;
|
|
939
943
|
}, "strict", z.ZodTypeAny, {
|
|
@@ -947,12 +951,14 @@ declare const EVENT_REGISTRY: {
|
|
|
947
951
|
};
|
|
948
952
|
dwell_ms: number;
|
|
949
953
|
max_scroll_percent: number | null;
|
|
954
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
950
955
|
}, {
|
|
951
956
|
page: {
|
|
952
957
|
path: string;
|
|
953
958
|
};
|
|
954
959
|
dwell_ms: number;
|
|
955
960
|
max_scroll_percent: number | null;
|
|
961
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
956
962
|
}>;
|
|
957
963
|
readonly configSchema: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
|
|
958
964
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -349,6 +349,7 @@ type MultiPageSessionConfig = z.infer<typeof multiPageSessionConfigSchema>;
|
|
|
349
349
|
declare const pageExitMetadataSchema: z.ZodObject<{
|
|
350
350
|
dwell_ms: z.ZodNumber;
|
|
351
351
|
max_scroll_percent: z.ZodNullable<z.ZodNumber>;
|
|
352
|
+
scroll_baseline_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
352
353
|
page: z.ZodObject<{
|
|
353
354
|
path: z.ZodString;
|
|
354
355
|
}, "strict", z.ZodTypeAny, {
|
|
@@ -362,12 +363,14 @@ declare const pageExitMetadataSchema: z.ZodObject<{
|
|
|
362
363
|
};
|
|
363
364
|
dwell_ms: number;
|
|
364
365
|
max_scroll_percent: number | null;
|
|
366
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
365
367
|
}, {
|
|
366
368
|
page: {
|
|
367
369
|
path: string;
|
|
368
370
|
};
|
|
369
371
|
dwell_ms: number;
|
|
370
372
|
max_scroll_percent: number | null;
|
|
373
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
371
374
|
}>;
|
|
372
375
|
type PageExitMetadata = z.infer<typeof pageExitMetadataSchema>;
|
|
373
376
|
/**
|
|
@@ -934,6 +937,7 @@ declare const EVENT_REGISTRY: {
|
|
|
934
937
|
readonly metadataSchema: z.ZodObject<{
|
|
935
938
|
dwell_ms: z.ZodNumber;
|
|
936
939
|
max_scroll_percent: z.ZodNullable<z.ZodNumber>;
|
|
940
|
+
scroll_baseline_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
937
941
|
page: z.ZodObject<{
|
|
938
942
|
path: z.ZodString;
|
|
939
943
|
}, "strict", z.ZodTypeAny, {
|
|
@@ -947,12 +951,14 @@ declare const EVENT_REGISTRY: {
|
|
|
947
951
|
};
|
|
948
952
|
dwell_ms: number;
|
|
949
953
|
max_scroll_percent: number | null;
|
|
954
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
950
955
|
}, {
|
|
951
956
|
page: {
|
|
952
957
|
path: string;
|
|
953
958
|
};
|
|
954
959
|
dwell_ms: number;
|
|
955
960
|
max_scroll_percent: number | null;
|
|
961
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
956
962
|
}>;
|
|
957
963
|
readonly configSchema: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
|
|
958
964
|
};
|
package/dist/index.js
CHANGED
|
@@ -726,9 +726,9 @@ function resolveConversionConfig(options) {
|
|
|
726
726
|
}
|
|
727
727
|
}
|
|
728
728
|
function notifyResolved() {
|
|
729
|
-
const
|
|
729
|
+
const listeners2 = [...resolveListeners];
|
|
730
730
|
resolveListeners.clear();
|
|
731
|
-
for (const listener of
|
|
731
|
+
for (const listener of listeners2) {
|
|
732
732
|
try {
|
|
733
733
|
listener();
|
|
734
734
|
} catch {
|
|
@@ -1496,6 +1496,14 @@ var pageExitMetadataSchema = import_zod7.z.object({
|
|
|
1496
1496
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1497
1497
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1498
1498
|
max_scroll_percent: import_zod7.z.number().int().min(0).max(100).nullable(),
|
|
1499
|
+
// The gating baseline: the fraction of the page visible at load with
|
|
1500
|
+
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
1501
|
+
// (skeleton/streaming renders), the first-scroll position that
|
|
1502
|
+
// established it. null = page had no scrollable range, or the segment
|
|
1503
|
+
// ended before the snapshot. `.optional()` is load-bearing: SDK builds
|
|
1504
|
+
// predating this field keep POSTing page_exit without the key —
|
|
1505
|
+
// requiring it would 422 whole keepalive beacon batches.
|
|
1506
|
+
scroll_baseline_percent: import_zod7.z.number().int().min(0).max(100).nullable().optional(),
|
|
1499
1507
|
page: import_zod7.z.object({
|
|
1500
1508
|
path: import_zod7.z.string()
|
|
1501
1509
|
}).strict()
|
|
@@ -1765,6 +1773,97 @@ function attachSpecificPageVisit(client, config) {
|
|
|
1765
1773
|
};
|
|
1766
1774
|
}
|
|
1767
1775
|
|
|
1776
|
+
// ../tracking-core/src/triggers/navigation.ts
|
|
1777
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1778
|
+
var restorePatch = null;
|
|
1779
|
+
function notify() {
|
|
1780
|
+
for (const listener of listeners) listener();
|
|
1781
|
+
}
|
|
1782
|
+
function notifyDeferred() {
|
|
1783
|
+
setTimeout(notify, 0);
|
|
1784
|
+
}
|
|
1785
|
+
function installPatch() {
|
|
1786
|
+
const originalPushState = history.pushState;
|
|
1787
|
+
const originalReplaceState = history.replaceState;
|
|
1788
|
+
function patchedPushState(...args) {
|
|
1789
|
+
originalPushState.apply(this, args);
|
|
1790
|
+
notifyDeferred();
|
|
1791
|
+
}
|
|
1792
|
+
function patchedReplaceState(...args) {
|
|
1793
|
+
originalReplaceState.apply(this, args);
|
|
1794
|
+
notifyDeferred();
|
|
1795
|
+
}
|
|
1796
|
+
history.pushState = patchedPushState;
|
|
1797
|
+
history.replaceState = patchedReplaceState;
|
|
1798
|
+
window.addEventListener("popstate", notify);
|
|
1799
|
+
restorePatch = () => {
|
|
1800
|
+
history.pushState = originalPushState;
|
|
1801
|
+
history.replaceState = originalReplaceState;
|
|
1802
|
+
window.removeEventListener("popstate", notify);
|
|
1803
|
+
restorePatch = null;
|
|
1804
|
+
};
|
|
1805
|
+
}
|
|
1806
|
+
function onHistoryChange(listener) {
|
|
1807
|
+
if (listeners.size === 0) installPatch();
|
|
1808
|
+
listeners.add(listener);
|
|
1809
|
+
return () => {
|
|
1810
|
+
if (!listeners.delete(listener)) return;
|
|
1811
|
+
if (listeners.size === 0) restorePatch?.();
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
// ../tracking-core/src/triggers/scroll-measurement.ts
|
|
1816
|
+
var BOTTOM_EPSILON_PX = 2;
|
|
1817
|
+
function measureScrollPercent() {
|
|
1818
|
+
const root = document.scrollingElement ?? document.documentElement;
|
|
1819
|
+
const scrollHeight = root.scrollHeight;
|
|
1820
|
+
const clientHeight = root.clientHeight;
|
|
1821
|
+
if (scrollHeight <= 0 || clientHeight <= 0) return null;
|
|
1822
|
+
if (scrollHeight <= clientHeight + BOTTOM_EPSILON_PX) return null;
|
|
1823
|
+
const maxTop = scrollHeight - clientHeight;
|
|
1824
|
+
const scrollTop = Math.min(Math.max(root.scrollTop, 0), maxTop);
|
|
1825
|
+
if (scrollTop + clientHeight >= scrollHeight - BOTTOM_EPSILON_PX) return 100;
|
|
1826
|
+
return Math.max(1, Math.min(100, Math.round((scrollTop + clientHeight) / scrollHeight * 100)));
|
|
1827
|
+
}
|
|
1828
|
+
function scheduleBaselineSnapshot(onSnapshot) {
|
|
1829
|
+
let rafId = requestAnimationFrame(() => {
|
|
1830
|
+
rafId = requestAnimationFrame(() => {
|
|
1831
|
+
onSnapshot(measureScrollPercent());
|
|
1832
|
+
});
|
|
1833
|
+
});
|
|
1834
|
+
return () => cancelAnimationFrame(rafId);
|
|
1835
|
+
}
|
|
1836
|
+
function createBaselineGate() {
|
|
1837
|
+
let baselinePercent = null;
|
|
1838
|
+
let ready = false;
|
|
1839
|
+
let cancelSnapshot = null;
|
|
1840
|
+
return {
|
|
1841
|
+
rebaseline() {
|
|
1842
|
+
cancelSnapshot?.();
|
|
1843
|
+
ready = false;
|
|
1844
|
+
baselinePercent = null;
|
|
1845
|
+
cancelSnapshot = scheduleBaselineSnapshot((b) => {
|
|
1846
|
+
baselinePercent = b;
|
|
1847
|
+
ready = true;
|
|
1848
|
+
});
|
|
1849
|
+
},
|
|
1850
|
+
cancel() {
|
|
1851
|
+
cancelSnapshot?.();
|
|
1852
|
+
},
|
|
1853
|
+
baseline() {
|
|
1854
|
+
return ready ? baselinePercent : null;
|
|
1855
|
+
},
|
|
1856
|
+
sample() {
|
|
1857
|
+
if (!ready) return null;
|
|
1858
|
+
if (baselinePercent === null) {
|
|
1859
|
+
baselinePercent = measureScrollPercent();
|
|
1860
|
+
return null;
|
|
1861
|
+
}
|
|
1862
|
+
return measureScrollPercent();
|
|
1863
|
+
}
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1768
1867
|
// ../tracking-core/src/triggers/scroll-depth.ts
|
|
1769
1868
|
function attachScrollDepth(client, config) {
|
|
1770
1869
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
@@ -1775,17 +1874,14 @@ function attachScrollDepth(client, config) {
|
|
|
1775
1874
|
let firedForPath = /* @__PURE__ */ new Set();
|
|
1776
1875
|
let currentPath2 = window.location.pathname;
|
|
1777
1876
|
let rafId = null;
|
|
1778
|
-
|
|
1779
|
-
const doc = document.documentElement;
|
|
1780
|
-
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1781
|
-
const scrollHeight = doc.scrollHeight;
|
|
1782
|
-
const clientHeight = doc.clientHeight;
|
|
1783
|
-
if (scrollHeight <= clientHeight) return 100;
|
|
1784
|
-
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1785
|
-
}
|
|
1877
|
+
const gate = createBaselineGate();
|
|
1786
1878
|
function checkThresholds() {
|
|
1787
|
-
const percent =
|
|
1879
|
+
const percent = gate.sample();
|
|
1880
|
+
if (percent === null) return;
|
|
1881
|
+
const baseline = gate.baseline();
|
|
1882
|
+
if (baseline === null) return;
|
|
1788
1883
|
for (const threshold of thresholds) {
|
|
1884
|
+
if (threshold <= baseline) continue;
|
|
1789
1885
|
if (percent >= threshold && !firedForPath.has(threshold)) {
|
|
1790
1886
|
firedForPath.add(threshold);
|
|
1791
1887
|
client.trackEvent({
|
|
@@ -1812,28 +1908,15 @@ function attachScrollDepth(client, config) {
|
|
|
1812
1908
|
if (newPath === currentPath2) return;
|
|
1813
1909
|
currentPath2 = newPath;
|
|
1814
1910
|
firedForPath = /* @__PURE__ */ new Set();
|
|
1815
|
-
|
|
1911
|
+
gate.rebaseline();
|
|
1816
1912
|
}
|
|
1817
|
-
const
|
|
1818
|
-
const originalReplaceState = history.replaceState.bind(history);
|
|
1819
|
-
function patchedPushState(...args) {
|
|
1820
|
-
originalPushState(...args);
|
|
1821
|
-
setTimeout(resetIfPathChanged, 0);
|
|
1822
|
-
}
|
|
1823
|
-
function patchedReplaceState(...args) {
|
|
1824
|
-
originalReplaceState(...args);
|
|
1825
|
-
setTimeout(resetIfPathChanged, 0);
|
|
1826
|
-
}
|
|
1827
|
-
history.pushState = patchedPushState;
|
|
1828
|
-
history.replaceState = patchedReplaceState;
|
|
1829
|
-
window.addEventListener("popstate", resetIfPathChanged);
|
|
1913
|
+
const unsubscribeNav = onHistoryChange(resetIfPathChanged);
|
|
1830
1914
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1831
|
-
|
|
1915
|
+
gate.rebaseline();
|
|
1832
1916
|
return () => {
|
|
1833
1917
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
window.removeEventListener("popstate", resetIfPathChanged);
|
|
1918
|
+
gate.cancel();
|
|
1919
|
+
unsubscribeNav();
|
|
1837
1920
|
window.removeEventListener("scroll", onScroll);
|
|
1838
1921
|
};
|
|
1839
1922
|
}
|
|
@@ -2005,21 +2088,14 @@ function attachPageExit(client) {
|
|
|
2005
2088
|
let accumulatedMs = 0;
|
|
2006
2089
|
let maxScrollPercent = null;
|
|
2007
2090
|
let rafId = null;
|
|
2008
|
-
|
|
2009
|
-
const doc = document.documentElement;
|
|
2010
|
-
const scrollTop = window.scrollY || doc.scrollTop;
|
|
2011
|
-
const scrollHeight = doc.scrollHeight;
|
|
2012
|
-
const clientHeight = doc.clientHeight;
|
|
2013
|
-
if (scrollHeight <= clientHeight) return 100;
|
|
2014
|
-
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
2015
|
-
}
|
|
2091
|
+
const gate = createBaselineGate();
|
|
2016
2092
|
function onScroll() {
|
|
2017
2093
|
if (rafId !== null) return;
|
|
2018
2094
|
rafId = requestAnimationFrame(() => {
|
|
2019
2095
|
rafId = null;
|
|
2020
|
-
const percent =
|
|
2021
|
-
if (percent
|
|
2022
|
-
maxScrollPercent =
|
|
2096
|
+
const percent = gate.sample();
|
|
2097
|
+
if (percent !== null && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
2098
|
+
maxScrollPercent = percent;
|
|
2023
2099
|
}
|
|
2024
2100
|
});
|
|
2025
2101
|
}
|
|
@@ -2038,6 +2114,12 @@ function attachPageExit(client) {
|
|
|
2038
2114
|
metadata: {
|
|
2039
2115
|
dwell_ms: dwell,
|
|
2040
2116
|
max_scroll_percent: maxScrollPercent,
|
|
2117
|
+
// Lets the backend tell "scrolled to the bottom" apart from "the page
|
|
2118
|
+
// was barely scrollable". null = unscrollable page or the segment
|
|
2119
|
+
// ended before the post-paint snapshot landed. For pages that grew
|
|
2120
|
+
// after the snapshot this is the first-scroll position, not the
|
|
2121
|
+
// at-load fraction (see BaselineGate.baseline).
|
|
2122
|
+
scroll_baseline_percent: gate.baseline(),
|
|
2041
2123
|
page: { path }
|
|
2042
2124
|
},
|
|
2043
2125
|
pageUrl: window.location.href,
|
|
@@ -2055,6 +2137,7 @@ function attachPageExit(client) {
|
|
|
2055
2137
|
emitSegment(currentPath2, false);
|
|
2056
2138
|
currentPath2 = newPath;
|
|
2057
2139
|
maxScrollPercent = null;
|
|
2140
|
+
gate.rebaseline();
|
|
2058
2141
|
accumulatedMs = 0;
|
|
2059
2142
|
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
2060
2143
|
}
|
|
@@ -2068,27 +2151,15 @@ function attachPageExit(client) {
|
|
|
2068
2151
|
function onPageHide() {
|
|
2069
2152
|
emitSegment(currentPath2, true);
|
|
2070
2153
|
}
|
|
2071
|
-
const
|
|
2072
|
-
const originalReplaceState = history.replaceState.bind(history);
|
|
2073
|
-
function patchedPushState(...args) {
|
|
2074
|
-
originalPushState(...args);
|
|
2075
|
-
setTimeout(onNavigate, 0);
|
|
2076
|
-
}
|
|
2077
|
-
function patchedReplaceState(...args) {
|
|
2078
|
-
originalReplaceState(...args);
|
|
2079
|
-
setTimeout(onNavigate, 0);
|
|
2080
|
-
}
|
|
2081
|
-
history.pushState = patchedPushState;
|
|
2082
|
-
history.replaceState = patchedReplaceState;
|
|
2083
|
-
window.addEventListener("popstate", onNavigate);
|
|
2154
|
+
const unsubscribeNav = onHistoryChange(onNavigate);
|
|
2084
2155
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
2085
2156
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
2086
2157
|
window.addEventListener("pagehide", onPageHide);
|
|
2158
|
+
gate.rebaseline();
|
|
2087
2159
|
return () => {
|
|
2088
2160
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
window.removeEventListener("popstate", onNavigate);
|
|
2161
|
+
gate.cancel();
|
|
2162
|
+
unsubscribeNav();
|
|
2092
2163
|
window.removeEventListener("scroll", onScroll);
|
|
2093
2164
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
2094
2165
|
window.removeEventListener("pagehide", onPageHide);
|
|
@@ -2893,7 +2964,7 @@ function GoogleAdsTracking(props) {
|
|
|
2893
2964
|
var import_react6 = require("react");
|
|
2894
2965
|
|
|
2895
2966
|
// package.json
|
|
2896
|
-
var version = "0.17.
|
|
2967
|
+
var version = "0.17.3";
|
|
2897
2968
|
|
|
2898
2969
|
// ../tracking-core/src/phone-react.tsx
|
|
2899
2970
|
var import_react5 = require("react");
|