UNPKG

tianji-client-sdk

Version:

186 lines (185 loc) 5.63 kB
"use strict"; /** * Pure Website Tracking SDK for Tianji * Simple event tracking without DOM manipulation or auto-tracking */ Object.defineProperty(exports, "__esModule", { value: true }); exports.initWebsiteTracking = initWebsiteTracking; exports.trackPageView = trackPageView; exports.reportWebsiteEvent = reportWebsiteEvent; exports.identifyWebsiteUser = identifyWebsiteUser; exports.flushBatchQueue = flushBatchQueue; const batch_manager_1 = require("../utils/batch-manager"); let options; let batchManager = null; /** * Initialize website tracking */ function initWebsiteTracking(_options) { options = _options; // Initialize batch manager batchManager = new batch_manager_1.BatchManager({ batchDelay: _options.batchDelay, disableBatch: _options.disableBatch, onBatchSend: async (items) => { await sendBatchRequest(_options.serverUrl, items); }, onSingleSend: async (item) => { await sendSingleRequest(_options.serverUrl, item.type, item.payload); }, }); } /** * Get basic browser information if available */ function getBrowserInfo() { if (typeof window === 'undefined') { return {}; } const { screen: { width, height }, navigator: { language }, location: { hostname, pathname, search }, document: { title, referrer }, } = window; return { hostname, screen: `${width}x${height}`, language, title, url: `${pathname}${search}`, referrer: referrer || undefined, }; } /** * Send website page view event to Tianji server */ async function trackPageView(url, title) { if (!options) { console.warn('Website tracking is not initialized'); return; } const browserInfo = getBrowserInfo(); const payload = { website: options.websiteId, ...browserInfo, ...(url && { url }), ...(title && { title }), }; sendWebsiteRequest(options.serverUrl, 'event', payload); } /** * Send custom website event to Tianji server * * @param eventName - Name of the event * @param eventData - Event data */ async function reportWebsiteEvent(eventName, eventData = {}) { if (!options) { console.warn('Website tracking is not initialized'); return; } const browserInfo = getBrowserInfo(); const payload = { website: options.websiteId, ...browserInfo, name: eventName, data: eventData, }; sendWebsiteRequest(options.serverUrl, 'event', payload); } /** * Identify user for website tracking * * @param userData - User identification data */ async function identifyWebsiteUser(userInfo) { if (!options) { console.warn('Website tracking is not initialized'); return; } if (!userInfo || Object.keys(userInfo).length === 0) { console.warn('User data is required for identification'); return; } const browserInfo = getBrowserInfo(); const payload = { website: options.websiteId, ...browserInfo, data: userInfo, }; sendWebsiteRequest(options.serverUrl, 'identify', payload); } /** * Send website request with automatic batching * Events are automatically queued and sent together at fixed intervals (throttling) * If queue reaches 100 events, it will be sent immediately * * @param serverUrl - Tianji server URL * @param type - Request type ('event' or 'identify') * @param payload - Request payload */ function sendWebsiteRequest(serverUrl, type, payload) { if (!batchManager) { console.warn('Website tracking is not initialized'); return; } batchManager.add(type, payload); } /** * Send single request to Tianji website API (fallback when batch is disabled) * * @param serverUrl - Tianji server URL * @param type - Request type ('event' or 'identify') * @param payload - Request payload */ async function sendSingleRequest(serverUrl, type, payload) { try { const response = await fetch(`${serverUrl}/api/website/send`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type, payload, }), }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Failed to send website ${type}: ${errorText}`); } } catch (error) { console.error(`Error sending website ${type}:`, error); return; // As event tracking SDK, should not throw error which maybe cause crash } } /** * Send batch request to Tianji website API */ async function sendBatchRequest(serverUrl, items) { try { const response = await fetch(`${serverUrl}/api/website/batch`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ events: items, }), }); if (!response.ok) { const errorText = await response.text(); throw new Error(`Failed to send batch request: ${errorText}`); } } catch (error) { console.error('Error sending batch request:', error); return; // As event tracking SDK, should not throw error which maybe cause crash } } /** * Flush batch queue manually (send all pending requests immediately) * Useful for ensuring events are sent before page unload */ async function flushBatchQueue() { if (batchManager) { await batchManager.flush(); } }