UNPKG

@trynova-ai/shadow-js

Version:

A TypeScript library for user session tracking.

125 lines (124 loc) 4.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Shadow = void 0; const uuid_1 = require("uuid"); const browser_1 = require("./plugins/browser"); class Shadow { constructor(options) { var _a; this.eventBuffer = []; this.url = options.url; this.headers = options.headers || {}; this.sessionId = options.sessionProvider ? options.sessionProvider() : this.getStoredSessionId(); this.plugins = options.plugins || [new browser_1.BrowserPlugin()]; this.bufferConfig = options.buffer || { enabled: false }; const sampleRate = (_a = options.sampleRate) !== null && _a !== void 0 ? _a : 0.1; // Default to 10% if not provided this.isClientEnabled = Math.random() < sampleRate; if (this.isClientEnabled && this.bufferConfig.enabled) { try { this.startFlushInterval(); } catch (error) { console.error('Error starting flush interval:', error); } } if (this.isClientEnabled) { try { this.setupPlugins(); } catch (error) { console.error('Error setting up plugins:', error); } } } static init(options) { try { return new Shadow(options); } catch (error) { console.error('Error initializing Shadow:', error); throw error; // re-throw if needed } } getStoredSessionId() { try { let sessionId = localStorage.getItem('session-id'); if (!sessionId) { sessionId = (0, uuid_1.v4)(); localStorage.setItem('session-id', sessionId); } return sessionId; } catch (error) { console.error('Error getting or storing session ID:', error); return (0, uuid_1.v4)(); // fallback to a new UUID if there's an issue } } setupPlugins() { this.plugins.forEach(plugin => plugin.setup(this)); } capture(event) { if (!this.isClientEnabled) return; try { const payload = Object.assign(Object.assign({}, event), { sessionId: this.sessionId }); if (this.bufferConfig.enabled) { this.eventBuffer.push(payload); if (this.eventBuffer.length >= (this.bufferConfig.maxEvents || 10)) { this.flushEvents(); } } else { this.sendEvent(this.url + '/session', payload); } } catch (error) { console.error('Error capturing event:', error); } } flushEvents() { try { if (this.eventBuffer.length > 0) { const bulkPayload = [...this.eventBuffer]; this.eventBuffer = []; this.sendEvent(this.url + '/sessions', bulkPayload); } } catch (error) { console.error('Error flushing events:', error); } } startFlushInterval() { try { this.flushTimeout = setInterval(() => { this.flushEvents(); }, this.bufferConfig.flushInterval || 5000); } catch (error) { console.error('Error starting flush interval:', error); } } sendEvent(endpoint, payload) { try { const headers = Object.assign(Object.assign({}, this.headers), { 'Content-Type': 'application/json' }); fetch(endpoint, { method: 'POST', headers: headers, body: JSON.stringify(payload), keepalive: true }).catch(error => console.error('Error sending session events:', error)); } catch (error) { console.error('Error in sendEvent:', error); } } stopFlushInterval() { try { clearInterval(this.flushTimeout); } catch (error) { console.error('Error stopping flush interval:', error); } } } exports.Shadow = Shadow;