UNPKG

@codeankitanime/eventlogger

Version:

A lightweight JavaScript event tracker that logs user interactions (clicks, inputs, scrolls, etc.) along with browser, OS, and optional geolocation/IP metadata. Ideal for building custom front-end analytics.

113 lines (91 loc) 3.42 kB
import { collectUserMeta } from './meta'; let eventBuffer = []; let config = {}; let meta = {}; let sessionStart = Date.now(); let visitorId = ''; let debounceTimeout; let currentPage = window.location.pathname; let pageEnterTime = Date.now(); // Utilities function generateVisitorId() { return '_' + Math.random().toString(36).substr(2, 9); } function getBufferedEvents() { return [...eventBuffer]; } function clearBufferedEvents() { eventBuffer = []; } function flushEvents() { if (config.onFlush && typeof config.onFlush === 'function' && eventBuffer.length > 0) { const now = Date.now(); const sessionDuration = Math.round((now - sessionStart) / 1000); // seconds const pageDuration = Math.round((now - pageEnterTime) / 1000); config.onFlush({ visitorId, sessionStart, sessionDuration, meta, events: getBufferedEvents(), page: { path: currentPage, duration: pageDuration } }); clearBufferedEvents(); currentPage = window.location.pathname; pageEnterTime = Date.now(); } } function debounceFlush() { clearTimeout(debounceTimeout); debounceTimeout = setTimeout(flushEvents, config.flushDelay || 4000); } function pushEvent(evt) { eventBuffer.push({ ...evt, timestamp: Date.now() }); debounceFlush(); } // ------ Event Handlers ------ function trackClick(e) { pushEvent({ type: 'click', x: e.clientX, y: e.clientY, tag: e.target.tagName, id: e.target.id, class: e.target.className }); } function trackScroll() { pushEvent({ type: 'scroll', scrollY: window.scrollY }); } function trackInput(e) { pushEvent({ type: 'input', tag: e.target.tagName, name: e.target.name || '', value: e.target.value || '' }); } function trackMouseMove(e) { if (Math.random() < 0.05) { pushEvent({ type: 'mousemove', x: e.clientX, y: e.clientY }); } } function trackKeyDown(e) { pushEvent({ type: 'keydown', key: e.key, code: e.code, target: e.target.tagName }); } function trackFocus(e) { pushEvent({ type: 'focus', tag: e.target.tagName, id: e.target.id }); } function trackBlur(e) { pushEvent({ type: 'blur', tag: e.target.tagName, id: e.target.id }); } // ------ Main Tracking Start ------ export async function startTracking(userConfig) { config = userConfig; meta = await collectUserMeta(); visitorId = localStorage.getItem('visitorId') || generateVisitorId(); localStorage.setItem('visitorId', visitorId); const storedSessionStart = sessionStorage.getItem('sessionStart'); if (storedSessionStart) sessionStart = parseInt(storedSessionStart, 10); else sessionStorage.setItem('sessionStart', sessionStart); const evs = config.events || []; if (evs.includes('click')) window.addEventListener('click', trackClick); if (evs.includes('scroll')) window.addEventListener('scroll', trackScroll); if (evs.includes('input')) document.addEventListener('input', trackInput); if (evs.includes('mousemove')) window.addEventListener('mousemove', trackMouseMove); if (evs.includes('keydown')) window.addEventListener('keydown', trackKeyDown); if (evs.includes('focus')) window.addEventListener('focus', trackFocus, true); if (evs.includes('blur')) window.addEventListener('blur', trackBlur, true); window.addEventListener('beforeunload', flushEvents); }