@loamly/tracker 2.0.2 → 2.1.0
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 +23 -0
- package/dist/index.cjs +96 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.mjs +96 -59
- package/dist/index.mjs.map +1 -1
- package/dist/loamly.iife.global.js +96 -59
- package/dist/loamly.iife.global.js.map +1 -1
- package/dist/loamly.iife.min.global.js +1 -1
- package/dist/loamly.iife.min.global.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +1 -1
- package/src/core.ts +125 -73
- package/src/types.ts +25 -0
|
@@ -26,7 +26,7 @@ var Loamly = (() => {
|
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
// src/config.ts
|
|
29
|
-
var VERSION = "2.0
|
|
29
|
+
var VERSION = "2.1.0";
|
|
30
30
|
var DEFAULT_CONFIG = {
|
|
31
31
|
apiHost: "https://app.loamly.ai",
|
|
32
32
|
endpoints: {
|
|
@@ -1774,16 +1774,32 @@ var Loamly = (() => {
|
|
|
1774
1774
|
apiHost: userConfig.apiHost || DEFAULT_CONFIG.apiHost
|
|
1775
1775
|
};
|
|
1776
1776
|
debugMode = userConfig.debug ?? false;
|
|
1777
|
+
const features = {
|
|
1778
|
+
scroll: true,
|
|
1779
|
+
time: true,
|
|
1780
|
+
forms: true,
|
|
1781
|
+
spa: true,
|
|
1782
|
+
behavioralML: true,
|
|
1783
|
+
focusBlur: true,
|
|
1784
|
+
agentic: true,
|
|
1785
|
+
eventQueue: true,
|
|
1786
|
+
ping: false,
|
|
1787
|
+
// Opt-in only
|
|
1788
|
+
...userConfig.features
|
|
1789
|
+
};
|
|
1777
1790
|
log("Initializing Loamly Tracker v" + VERSION);
|
|
1791
|
+
log("Features:", features);
|
|
1778
1792
|
visitorId = getVisitorId();
|
|
1779
1793
|
log("Visitor ID:", visitorId);
|
|
1780
1794
|
const session = getSessionId();
|
|
1781
1795
|
sessionId = session.sessionId;
|
|
1782
1796
|
log("Session ID:", sessionId, session.isNew ? "(new)" : "(existing)");
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1797
|
+
if (features.eventQueue) {
|
|
1798
|
+
eventQueue = new EventQueue(endpoint(DEFAULT_CONFIG.endpoints.behavioral), {
|
|
1799
|
+
batchSize: DEFAULT_CONFIG.batchSize,
|
|
1800
|
+
batchTimeout: DEFAULT_CONFIG.batchTimeout
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1787
1803
|
navigationTiming = detectNavigationType();
|
|
1788
1804
|
log("Navigation timing:", navigationTiming);
|
|
1789
1805
|
aiDetection = detectAIFromReferrer(document.referrer) || detectAIFromUTM(window.location.href);
|
|
@@ -1795,21 +1811,27 @@ var Loamly = (() => {
|
|
|
1795
1811
|
pageview();
|
|
1796
1812
|
}
|
|
1797
1813
|
if (!userConfig.disableBehavioral) {
|
|
1798
|
-
setupAdvancedBehavioralTracking();
|
|
1814
|
+
setupAdvancedBehavioralTracking(features);
|
|
1815
|
+
}
|
|
1816
|
+
if (features.behavioralML) {
|
|
1817
|
+
behavioralClassifier = new BehavioralClassifier(1e4);
|
|
1818
|
+
behavioralClassifier.setOnClassify(handleBehavioralClassification);
|
|
1819
|
+
setupBehavioralMLTracking();
|
|
1820
|
+
}
|
|
1821
|
+
if (features.focusBlur) {
|
|
1822
|
+
focusBlurAnalyzer = new FocusBlurAnalyzer();
|
|
1823
|
+
focusBlurAnalyzer.initTracking();
|
|
1824
|
+
setTimeout(() => {
|
|
1825
|
+
if (focusBlurAnalyzer) {
|
|
1826
|
+
handleFocusBlurAnalysis(focusBlurAnalyzer.analyze());
|
|
1827
|
+
}
|
|
1828
|
+
}, 5e3);
|
|
1799
1829
|
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
setTimeout(() => {
|
|
1806
|
-
if (focusBlurAnalyzer) {
|
|
1807
|
-
handleFocusBlurAnalysis(focusBlurAnalyzer.analyze());
|
|
1808
|
-
}
|
|
1809
|
-
}, 5e3);
|
|
1810
|
-
agenticAnalyzer = new AgenticBrowserAnalyzer();
|
|
1811
|
-
agenticAnalyzer.init();
|
|
1812
|
-
if (visitorId && sessionId) {
|
|
1830
|
+
if (features.agentic) {
|
|
1831
|
+
agenticAnalyzer = new AgenticBrowserAnalyzer();
|
|
1832
|
+
agenticAnalyzer.init();
|
|
1833
|
+
}
|
|
1834
|
+
if (features.ping && visitorId && sessionId) {
|
|
1813
1835
|
pingService = new PingService(sessionId, visitorId, VERSION, {
|
|
1814
1836
|
interval: DEFAULT_CONFIG.pingInterval,
|
|
1815
1837
|
endpoint: endpoint(DEFAULT_CONFIG.endpoints.ping)
|
|
@@ -1824,48 +1846,63 @@ var Loamly = (() => {
|
|
|
1824
1846
|
reportHealth("initialized");
|
|
1825
1847
|
log("Initialization complete");
|
|
1826
1848
|
}
|
|
1827
|
-
function setupAdvancedBehavioralTracking() {
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
}
|
|
1838
|
-
});
|
|
1839
|
-
scrollTracker.start();
|
|
1840
|
-
timeTracker = new TimeTracker({
|
|
1841
|
-
updateIntervalMs: 1e4,
|
|
1842
|
-
// Report every 10 seconds
|
|
1843
|
-
onUpdate: (event) => {
|
|
1844
|
-
if (event.active_time_ms >= DEFAULT_CONFIG.timeSpentThresholdMs) {
|
|
1845
|
-
queueEvent("time_spent", {
|
|
1846
|
-
active_time_ms: event.active_time_ms,
|
|
1847
|
-
total_time_ms: event.total_time_ms,
|
|
1848
|
-
idle_time_ms: event.idle_time_ms,
|
|
1849
|
-
is_engaged: event.is_engaged
|
|
1849
|
+
function setupAdvancedBehavioralTracking(features) {
|
|
1850
|
+
if (features.scroll) {
|
|
1851
|
+
scrollTracker = new ScrollTracker({
|
|
1852
|
+
chunks: [30, 60, 90, 100],
|
|
1853
|
+
onChunkReached: (event) => {
|
|
1854
|
+
log("Scroll chunk:", event.chunk);
|
|
1855
|
+
queueEvent("scroll_depth", {
|
|
1856
|
+
depth: event.depth,
|
|
1857
|
+
chunk: event.chunk,
|
|
1858
|
+
time_to_reach_ms: event.time_to_reach_ms
|
|
1850
1859
|
});
|
|
1851
1860
|
}
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1861
|
+
});
|
|
1862
|
+
scrollTracker.start();
|
|
1863
|
+
}
|
|
1864
|
+
if (features.time) {
|
|
1865
|
+
timeTracker = new TimeTracker({
|
|
1866
|
+
updateIntervalMs: 1e4,
|
|
1867
|
+
// Report every 10 seconds
|
|
1868
|
+
onUpdate: (event) => {
|
|
1869
|
+
if (event.active_time_ms >= DEFAULT_CONFIG.timeSpentThresholdMs) {
|
|
1870
|
+
queueEvent("time_spent", {
|
|
1871
|
+
active_time_ms: event.active_time_ms,
|
|
1872
|
+
total_time_ms: event.total_time_ms,
|
|
1873
|
+
idle_time_ms: event.idle_time_ms,
|
|
1874
|
+
is_engaged: event.is_engaged
|
|
1875
|
+
});
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
});
|
|
1879
|
+
timeTracker.start();
|
|
1880
|
+
}
|
|
1881
|
+
if (features.forms) {
|
|
1882
|
+
formTracker = new FormTracker({
|
|
1883
|
+
onFormEvent: (event) => {
|
|
1884
|
+
log("Form event:", event.event_type, event.form_id);
|
|
1885
|
+
queueEvent(event.event_type, {
|
|
1886
|
+
form_id: event.form_id,
|
|
1887
|
+
form_type: event.form_type,
|
|
1888
|
+
field_name: event.field_name,
|
|
1889
|
+
field_type: event.field_type,
|
|
1890
|
+
time_to_submit_ms: event.time_to_submit_ms,
|
|
1891
|
+
is_conversion: event.is_conversion
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1894
|
+
});
|
|
1895
|
+
formTracker.start();
|
|
1896
|
+
}
|
|
1897
|
+
if (features.spa) {
|
|
1898
|
+
spaRouter = new SPARouter({
|
|
1899
|
+
onNavigate: (event) => {
|
|
1900
|
+
log("SPA navigation:", event.navigation_type);
|
|
1901
|
+
pageview(event.to_url);
|
|
1902
|
+
}
|
|
1903
|
+
});
|
|
1904
|
+
spaRouter.start();
|
|
1905
|
+
}
|
|
1869
1906
|
document.addEventListener("click", (e) => {
|
|
1870
1907
|
const target = e.target;
|
|
1871
1908
|
const link = target.closest("a");
|