@aranova/tracking-next 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 +132 -61
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +128 -57
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +8 -0
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +8 -0
- package/dist/middleware.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/server.js +8 -0
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +8 -0
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -302,6 +302,7 @@ type MultiPageSessionConfig = z.infer<typeof multiPageSessionConfigSchema>;
|
|
|
302
302
|
declare const pageExitMetadataSchema: z.ZodObject<{
|
|
303
303
|
dwell_ms: z.ZodNumber;
|
|
304
304
|
max_scroll_percent: z.ZodNullable<z.ZodNumber>;
|
|
305
|
+
scroll_baseline_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
305
306
|
page: z.ZodObject<{
|
|
306
307
|
path: z.ZodString;
|
|
307
308
|
}, "strict", z.ZodTypeAny, {
|
|
@@ -315,12 +316,14 @@ declare const pageExitMetadataSchema: z.ZodObject<{
|
|
|
315
316
|
};
|
|
316
317
|
dwell_ms: number;
|
|
317
318
|
max_scroll_percent: number | null;
|
|
319
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
318
320
|
}, {
|
|
319
321
|
page: {
|
|
320
322
|
path: string;
|
|
321
323
|
};
|
|
322
324
|
dwell_ms: number;
|
|
323
325
|
max_scroll_percent: number | null;
|
|
326
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
324
327
|
}>;
|
|
325
328
|
type PageExitMetadata = z.infer<typeof pageExitMetadataSchema>;
|
|
326
329
|
/**
|
|
@@ -887,6 +890,7 @@ declare const EVENT_REGISTRY: {
|
|
|
887
890
|
readonly metadataSchema: z.ZodObject<{
|
|
888
891
|
dwell_ms: z.ZodNumber;
|
|
889
892
|
max_scroll_percent: z.ZodNullable<z.ZodNumber>;
|
|
893
|
+
scroll_baseline_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
890
894
|
page: z.ZodObject<{
|
|
891
895
|
path: z.ZodString;
|
|
892
896
|
}, "strict", z.ZodTypeAny, {
|
|
@@ -900,12 +904,14 @@ declare const EVENT_REGISTRY: {
|
|
|
900
904
|
};
|
|
901
905
|
dwell_ms: number;
|
|
902
906
|
max_scroll_percent: number | null;
|
|
907
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
903
908
|
}, {
|
|
904
909
|
page: {
|
|
905
910
|
path: string;
|
|
906
911
|
};
|
|
907
912
|
dwell_ms: number;
|
|
908
913
|
max_scroll_percent: number | null;
|
|
914
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
909
915
|
}>;
|
|
910
916
|
readonly configSchema: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
|
|
911
917
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -302,6 +302,7 @@ type MultiPageSessionConfig = z.infer<typeof multiPageSessionConfigSchema>;
|
|
|
302
302
|
declare const pageExitMetadataSchema: z.ZodObject<{
|
|
303
303
|
dwell_ms: z.ZodNumber;
|
|
304
304
|
max_scroll_percent: z.ZodNullable<z.ZodNumber>;
|
|
305
|
+
scroll_baseline_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
305
306
|
page: z.ZodObject<{
|
|
306
307
|
path: z.ZodString;
|
|
307
308
|
}, "strict", z.ZodTypeAny, {
|
|
@@ -315,12 +316,14 @@ declare const pageExitMetadataSchema: z.ZodObject<{
|
|
|
315
316
|
};
|
|
316
317
|
dwell_ms: number;
|
|
317
318
|
max_scroll_percent: number | null;
|
|
319
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
318
320
|
}, {
|
|
319
321
|
page: {
|
|
320
322
|
path: string;
|
|
321
323
|
};
|
|
322
324
|
dwell_ms: number;
|
|
323
325
|
max_scroll_percent: number | null;
|
|
326
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
324
327
|
}>;
|
|
325
328
|
type PageExitMetadata = z.infer<typeof pageExitMetadataSchema>;
|
|
326
329
|
/**
|
|
@@ -887,6 +890,7 @@ declare const EVENT_REGISTRY: {
|
|
|
887
890
|
readonly metadataSchema: z.ZodObject<{
|
|
888
891
|
dwell_ms: z.ZodNumber;
|
|
889
892
|
max_scroll_percent: z.ZodNullable<z.ZodNumber>;
|
|
893
|
+
scroll_baseline_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
890
894
|
page: z.ZodObject<{
|
|
891
895
|
path: z.ZodString;
|
|
892
896
|
}, "strict", z.ZodTypeAny, {
|
|
@@ -900,12 +904,14 @@ declare const EVENT_REGISTRY: {
|
|
|
900
904
|
};
|
|
901
905
|
dwell_ms: number;
|
|
902
906
|
max_scroll_percent: number | null;
|
|
907
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
903
908
|
}, {
|
|
904
909
|
page: {
|
|
905
910
|
path: string;
|
|
906
911
|
};
|
|
907
912
|
dwell_ms: number;
|
|
908
913
|
max_scroll_percent: number | null;
|
|
914
|
+
scroll_baseline_percent?: number | null | undefined;
|
|
909
915
|
}>;
|
|
910
916
|
readonly configSchema: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
|
|
911
917
|
};
|
package/dist/index.js
CHANGED
|
@@ -680,9 +680,9 @@ function resolveConversionConfig(options) {
|
|
|
680
680
|
}
|
|
681
681
|
}
|
|
682
682
|
function notifyResolved() {
|
|
683
|
-
const
|
|
683
|
+
const listeners2 = [...resolveListeners];
|
|
684
684
|
resolveListeners.clear();
|
|
685
|
-
for (const listener of
|
|
685
|
+
for (const listener of listeners2) {
|
|
686
686
|
try {
|
|
687
687
|
listener();
|
|
688
688
|
} catch {
|
|
@@ -1412,6 +1412,14 @@ var pageExitMetadataSchema = import_zod7.z.object({
|
|
|
1412
1412
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1413
1413
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1414
1414
|
max_scroll_percent: import_zod7.z.number().int().min(0).max(100).nullable(),
|
|
1415
|
+
// The gating baseline: the fraction of the page visible at load with
|
|
1416
|
+
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
1417
|
+
// (skeleton/streaming renders), the first-scroll position that
|
|
1418
|
+
// established it. null = page had no scrollable range, or the segment
|
|
1419
|
+
// ended before the snapshot. `.optional()` is load-bearing: SDK builds
|
|
1420
|
+
// predating this field keep POSTing page_exit without the key —
|
|
1421
|
+
// requiring it would 422 whole keepalive beacon batches.
|
|
1422
|
+
scroll_baseline_percent: import_zod7.z.number().int().min(0).max(100).nullable().optional(),
|
|
1415
1423
|
page: import_zod7.z.object({
|
|
1416
1424
|
path: import_zod7.z.string()
|
|
1417
1425
|
}).strict()
|
|
@@ -1636,6 +1644,97 @@ function attachTimeOnSite(client, config) {
|
|
|
1636
1644
|
};
|
|
1637
1645
|
}
|
|
1638
1646
|
|
|
1647
|
+
// ../tracking-core/src/triggers/navigation.ts
|
|
1648
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1649
|
+
var restorePatch = null;
|
|
1650
|
+
function notify() {
|
|
1651
|
+
for (const listener of listeners) listener();
|
|
1652
|
+
}
|
|
1653
|
+
function notifyDeferred() {
|
|
1654
|
+
setTimeout(notify, 0);
|
|
1655
|
+
}
|
|
1656
|
+
function installPatch() {
|
|
1657
|
+
const originalPushState = history.pushState;
|
|
1658
|
+
const originalReplaceState = history.replaceState;
|
|
1659
|
+
function patchedPushState(...args) {
|
|
1660
|
+
originalPushState.apply(this, args);
|
|
1661
|
+
notifyDeferred();
|
|
1662
|
+
}
|
|
1663
|
+
function patchedReplaceState(...args) {
|
|
1664
|
+
originalReplaceState.apply(this, args);
|
|
1665
|
+
notifyDeferred();
|
|
1666
|
+
}
|
|
1667
|
+
history.pushState = patchedPushState;
|
|
1668
|
+
history.replaceState = patchedReplaceState;
|
|
1669
|
+
window.addEventListener("popstate", notify);
|
|
1670
|
+
restorePatch = () => {
|
|
1671
|
+
history.pushState = originalPushState;
|
|
1672
|
+
history.replaceState = originalReplaceState;
|
|
1673
|
+
window.removeEventListener("popstate", notify);
|
|
1674
|
+
restorePatch = null;
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
function onHistoryChange(listener) {
|
|
1678
|
+
if (listeners.size === 0) installPatch();
|
|
1679
|
+
listeners.add(listener);
|
|
1680
|
+
return () => {
|
|
1681
|
+
if (!listeners.delete(listener)) return;
|
|
1682
|
+
if (listeners.size === 0) restorePatch?.();
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
// ../tracking-core/src/triggers/scroll-measurement.ts
|
|
1687
|
+
var BOTTOM_EPSILON_PX = 2;
|
|
1688
|
+
function measureScrollPercent() {
|
|
1689
|
+
const root = document.scrollingElement ?? document.documentElement;
|
|
1690
|
+
const scrollHeight = root.scrollHeight;
|
|
1691
|
+
const clientHeight = root.clientHeight;
|
|
1692
|
+
if (scrollHeight <= 0 || clientHeight <= 0) return null;
|
|
1693
|
+
if (scrollHeight <= clientHeight + BOTTOM_EPSILON_PX) return null;
|
|
1694
|
+
const maxTop = scrollHeight - clientHeight;
|
|
1695
|
+
const scrollTop = Math.min(Math.max(root.scrollTop, 0), maxTop);
|
|
1696
|
+
if (scrollTop + clientHeight >= scrollHeight - BOTTOM_EPSILON_PX) return 100;
|
|
1697
|
+
return Math.max(1, Math.min(100, Math.round((scrollTop + clientHeight) / scrollHeight * 100)));
|
|
1698
|
+
}
|
|
1699
|
+
function scheduleBaselineSnapshot(onSnapshot) {
|
|
1700
|
+
let rafId = requestAnimationFrame(() => {
|
|
1701
|
+
rafId = requestAnimationFrame(() => {
|
|
1702
|
+
onSnapshot(measureScrollPercent());
|
|
1703
|
+
});
|
|
1704
|
+
});
|
|
1705
|
+
return () => cancelAnimationFrame(rafId);
|
|
1706
|
+
}
|
|
1707
|
+
function createBaselineGate() {
|
|
1708
|
+
let baselinePercent = null;
|
|
1709
|
+
let ready = false;
|
|
1710
|
+
let cancelSnapshot = null;
|
|
1711
|
+
return {
|
|
1712
|
+
rebaseline() {
|
|
1713
|
+
cancelSnapshot?.();
|
|
1714
|
+
ready = false;
|
|
1715
|
+
baselinePercent = null;
|
|
1716
|
+
cancelSnapshot = scheduleBaselineSnapshot((b) => {
|
|
1717
|
+
baselinePercent = b;
|
|
1718
|
+
ready = true;
|
|
1719
|
+
});
|
|
1720
|
+
},
|
|
1721
|
+
cancel() {
|
|
1722
|
+
cancelSnapshot?.();
|
|
1723
|
+
},
|
|
1724
|
+
baseline() {
|
|
1725
|
+
return ready ? baselinePercent : null;
|
|
1726
|
+
},
|
|
1727
|
+
sample() {
|
|
1728
|
+
if (!ready) return null;
|
|
1729
|
+
if (baselinePercent === null) {
|
|
1730
|
+
baselinePercent = measureScrollPercent();
|
|
1731
|
+
return null;
|
|
1732
|
+
}
|
|
1733
|
+
return measureScrollPercent();
|
|
1734
|
+
}
|
|
1735
|
+
};
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1639
1738
|
// ../tracking-core/src/triggers/scroll-depth.ts
|
|
1640
1739
|
function attachScrollDepth(client, config) {
|
|
1641
1740
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
@@ -1646,17 +1745,14 @@ function attachScrollDepth(client, config) {
|
|
|
1646
1745
|
let firedForPath = /* @__PURE__ */ new Set();
|
|
1647
1746
|
let currentPath2 = window.location.pathname;
|
|
1648
1747
|
let rafId = null;
|
|
1649
|
-
|
|
1650
|
-
const doc = document.documentElement;
|
|
1651
|
-
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1652
|
-
const scrollHeight = doc.scrollHeight;
|
|
1653
|
-
const clientHeight = doc.clientHeight;
|
|
1654
|
-
if (scrollHeight <= clientHeight) return 100;
|
|
1655
|
-
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1656
|
-
}
|
|
1748
|
+
const gate = createBaselineGate();
|
|
1657
1749
|
function checkThresholds() {
|
|
1658
|
-
const percent =
|
|
1750
|
+
const percent = gate.sample();
|
|
1751
|
+
if (percent === null) return;
|
|
1752
|
+
const baseline = gate.baseline();
|
|
1753
|
+
if (baseline === null) return;
|
|
1659
1754
|
for (const threshold of thresholds) {
|
|
1755
|
+
if (threshold <= baseline) continue;
|
|
1660
1756
|
if (percent >= threshold && !firedForPath.has(threshold)) {
|
|
1661
1757
|
firedForPath.add(threshold);
|
|
1662
1758
|
client.trackEvent({
|
|
@@ -1683,28 +1779,15 @@ function attachScrollDepth(client, config) {
|
|
|
1683
1779
|
if (newPath === currentPath2) return;
|
|
1684
1780
|
currentPath2 = newPath;
|
|
1685
1781
|
firedForPath = /* @__PURE__ */ new Set();
|
|
1686
|
-
|
|
1782
|
+
gate.rebaseline();
|
|
1687
1783
|
}
|
|
1688
|
-
const
|
|
1689
|
-
const originalReplaceState = history.replaceState.bind(history);
|
|
1690
|
-
function patchedPushState(...args) {
|
|
1691
|
-
originalPushState(...args);
|
|
1692
|
-
setTimeout(resetIfPathChanged, 0);
|
|
1693
|
-
}
|
|
1694
|
-
function patchedReplaceState(...args) {
|
|
1695
|
-
originalReplaceState(...args);
|
|
1696
|
-
setTimeout(resetIfPathChanged, 0);
|
|
1697
|
-
}
|
|
1698
|
-
history.pushState = patchedPushState;
|
|
1699
|
-
history.replaceState = patchedReplaceState;
|
|
1700
|
-
window.addEventListener("popstate", resetIfPathChanged);
|
|
1784
|
+
const unsubscribeNav = onHistoryChange(resetIfPathChanged);
|
|
1701
1785
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1702
|
-
|
|
1786
|
+
gate.rebaseline();
|
|
1703
1787
|
return () => {
|
|
1704
1788
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
window.removeEventListener("popstate", resetIfPathChanged);
|
|
1789
|
+
gate.cancel();
|
|
1790
|
+
unsubscribeNav();
|
|
1708
1791
|
window.removeEventListener("scroll", onScroll);
|
|
1709
1792
|
};
|
|
1710
1793
|
}
|
|
@@ -1786,21 +1869,14 @@ function attachPageExit(client) {
|
|
|
1786
1869
|
let accumulatedMs = 0;
|
|
1787
1870
|
let maxScrollPercent = null;
|
|
1788
1871
|
let rafId = null;
|
|
1789
|
-
|
|
1790
|
-
const doc = document.documentElement;
|
|
1791
|
-
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1792
|
-
const scrollHeight = doc.scrollHeight;
|
|
1793
|
-
const clientHeight = doc.clientHeight;
|
|
1794
|
-
if (scrollHeight <= clientHeight) return 100;
|
|
1795
|
-
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1796
|
-
}
|
|
1872
|
+
const gate = createBaselineGate();
|
|
1797
1873
|
function onScroll() {
|
|
1798
1874
|
if (rafId !== null) return;
|
|
1799
1875
|
rafId = requestAnimationFrame(() => {
|
|
1800
1876
|
rafId = null;
|
|
1801
|
-
const percent =
|
|
1802
|
-
if (percent
|
|
1803
|
-
maxScrollPercent =
|
|
1877
|
+
const percent = gate.sample();
|
|
1878
|
+
if (percent !== null && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
1879
|
+
maxScrollPercent = percent;
|
|
1804
1880
|
}
|
|
1805
1881
|
});
|
|
1806
1882
|
}
|
|
@@ -1819,6 +1895,12 @@ function attachPageExit(client) {
|
|
|
1819
1895
|
metadata: {
|
|
1820
1896
|
dwell_ms: dwell,
|
|
1821
1897
|
max_scroll_percent: maxScrollPercent,
|
|
1898
|
+
// Lets the backend tell "scrolled to the bottom" apart from "the page
|
|
1899
|
+
// was barely scrollable". null = unscrollable page or the segment
|
|
1900
|
+
// ended before the post-paint snapshot landed. For pages that grew
|
|
1901
|
+
// after the snapshot this is the first-scroll position, not the
|
|
1902
|
+
// at-load fraction (see BaselineGate.baseline).
|
|
1903
|
+
scroll_baseline_percent: gate.baseline(),
|
|
1822
1904
|
page: { path }
|
|
1823
1905
|
},
|
|
1824
1906
|
pageUrl: window.location.href,
|
|
@@ -1836,6 +1918,7 @@ function attachPageExit(client) {
|
|
|
1836
1918
|
emitSegment(currentPath2, false);
|
|
1837
1919
|
currentPath2 = newPath;
|
|
1838
1920
|
maxScrollPercent = null;
|
|
1921
|
+
gate.rebaseline();
|
|
1839
1922
|
accumulatedMs = 0;
|
|
1840
1923
|
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1841
1924
|
}
|
|
@@ -1849,27 +1932,15 @@ function attachPageExit(client) {
|
|
|
1849
1932
|
function onPageHide() {
|
|
1850
1933
|
emitSegment(currentPath2, true);
|
|
1851
1934
|
}
|
|
1852
|
-
const
|
|
1853
|
-
const originalReplaceState = history.replaceState.bind(history);
|
|
1854
|
-
function patchedPushState(...args) {
|
|
1855
|
-
originalPushState(...args);
|
|
1856
|
-
setTimeout(onNavigate, 0);
|
|
1857
|
-
}
|
|
1858
|
-
function patchedReplaceState(...args) {
|
|
1859
|
-
originalReplaceState(...args);
|
|
1860
|
-
setTimeout(onNavigate, 0);
|
|
1861
|
-
}
|
|
1862
|
-
history.pushState = patchedPushState;
|
|
1863
|
-
history.replaceState = patchedReplaceState;
|
|
1864
|
-
window.addEventListener("popstate", onNavigate);
|
|
1935
|
+
const unsubscribeNav = onHistoryChange(onNavigate);
|
|
1865
1936
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1866
1937
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1867
1938
|
window.addEventListener("pagehide", onPageHide);
|
|
1939
|
+
gate.rebaseline();
|
|
1868
1940
|
return () => {
|
|
1869
1941
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
window.removeEventListener("popstate", onNavigate);
|
|
1942
|
+
gate.cancel();
|
|
1943
|
+
unsubscribeNav();
|
|
1873
1944
|
window.removeEventListener("scroll", onScroll);
|
|
1874
1945
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1875
1946
|
window.removeEventListener("pagehide", onPageHide);
|
|
@@ -2685,10 +2756,10 @@ function GoogleAdsTracking(props) {
|
|
|
2685
2756
|
}
|
|
2686
2757
|
|
|
2687
2758
|
// src/factory.tsx
|
|
2688
|
-
var
|
|
2759
|
+
var import_navigation3 = require("next/navigation");
|
|
2689
2760
|
|
|
2690
2761
|
// package.json
|
|
2691
|
-
var version = "0.17.
|
|
2762
|
+
var version = "0.17.3";
|
|
2692
2763
|
|
|
2693
2764
|
// src/factory.tsx
|
|
2694
2765
|
var import_react4 = require("react");
|
|
@@ -2782,8 +2853,8 @@ var PhoneField = (0, import_react3.forwardRef)(function PhoneField2({ country, v
|
|
|
2782
2853
|
// src/factory.tsx
|
|
2783
2854
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
2784
2855
|
function PageViewTracker({ fire }) {
|
|
2785
|
-
const pathname = (0,
|
|
2786
|
-
const searchParams = (0,
|
|
2856
|
+
const pathname = (0, import_navigation3.usePathname)();
|
|
2857
|
+
const searchParams = (0, import_navigation3.useSearchParams)();
|
|
2787
2858
|
(0, import_react4.useEffect)(() => {
|
|
2788
2859
|
fire();
|
|
2789
2860
|
}, [pathname, searchParams, fire]);
|
|
@@ -2814,7 +2885,7 @@ function createTracking(options) {
|
|
|
2814
2885
|
const specificPageVisitConfig = triggers.automatic.specific_page_visit ?? null;
|
|
2815
2886
|
const timeOnSiteConfig = triggers.automatic.time_on_site ?? null;
|
|
2816
2887
|
function TrackingProvider({ children }) {
|
|
2817
|
-
const pathname = (0,
|
|
2888
|
+
const pathname = (0, import_navigation3.usePathname)();
|
|
2818
2889
|
const client = (0, import_react4.useMemo)(
|
|
2819
2890
|
() => createTypedClient(
|
|
2820
2891
|
getOrCreateTrackingClient({
|