@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.
@@ -26,7 +26,7 @@ var Loamly = (() => {
26
26
  });
27
27
 
28
28
  // src/config.ts
29
- var VERSION = "2.0.2";
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
- eventQueue = new EventQueue(endpoint(DEFAULT_CONFIG.endpoints.behavioral), {
1784
- batchSize: DEFAULT_CONFIG.batchSize,
1785
- batchTimeout: DEFAULT_CONFIG.batchTimeout
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
- behavioralClassifier = new BehavioralClassifier(1e4);
1801
- behavioralClassifier.setOnClassify(handleBehavioralClassification);
1802
- setupBehavioralMLTracking();
1803
- focusBlurAnalyzer = new FocusBlurAnalyzer();
1804
- focusBlurAnalyzer.initTracking();
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
- scrollTracker = new ScrollTracker({
1829
- chunks: [30, 60, 90, 100],
1830
- onChunkReached: (event) => {
1831
- log("Scroll chunk:", event.chunk);
1832
- queueEvent("scroll_depth", {
1833
- depth: event.depth,
1834
- chunk: event.chunk,
1835
- time_to_reach_ms: event.time_to_reach_ms
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
- timeTracker.start();
1855
- formTracker = new FormTracker({
1856
- onFormEvent: (event) => {
1857
- log("Form event:", event.event_type, event.form_id);
1858
- queueEvent(event.event_type, {
1859
- form_id: event.form_id,
1860
- form_type: event.form_type,
1861
- field_name: event.field_name,
1862
- field_type: event.field_type,
1863
- time_to_submit_ms: event.time_to_submit_ms,
1864
- is_conversion: event.is_conversion
1865
- });
1866
- }
1867
- });
1868
- formTracker.start();
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");