UNPKG

@wavetrace/client

Version:

Lightweight web analytics client with TypeScript support

442 lines (344 loc) 11.2 kB
# WaveTrace Client A lightweight, TypeScript-first web analytics client for tracking user behavior, page views, clicks, and custom events. The primary goal for this client is to provide analytics on a specific user by tracking his/her activity on a DApp. Some tracking are automated while some could be manually tracked. So, it provides: - Both automated and manual tracking for users - Connect annoymous/signed out user tracking linked to existing/future wallet/user login ## Features - **Lightweight**: Only 4.8KB minified - **TypeScript Support**: Full type definitions included - **Zero Dependencies**: No external dependencies - **DApp Ready**: Built-in wallet tracking for Web3 applications - **Auto-Detect Wallets**: Automatically detect and track MetaMask, Coinbase, and other wallet connections - **Transaction Tracking**: Complete lifecycle tracking for blockchain transactions (initiated → pending → executed/failed) - **Offline Queue**: localStorage persistence - events are saved and sent when back online - **Retry Logic**: Exponential backoff for failed requests with configurable retries - **Smart Click Tracking**: Intelligent filtering - track only buttons, links, and important interactions - **Automatic Tracking**: Auto-track page views and clicks with configurable modes - **Event Batching**: Efficient event batching with configurable batch size and timeout - **User Identification**: Track user ID, username, wallet addresses, and custom properties - **Anonymous-to-Wallet Linking**: Seamlessly connect anonymous activity to wallet addresses - **Session Management**: Automatic session tracking with 30-minute timeout - **Privacy-Conscious**: Configurable data collection - **Multiple Formats**: ESM, CommonJS, and browser IIFE builds ## Installation ```bash npm install @wavetrace/client ``` ## Usage ### Basic Setup (Browser) ```html <script src="https://unpkg.com/@wavetrace/client/dist/wavetrace.min.js"></script> <script> const tracker = new WaveTrace.WaveTracker({ endpoint: "https://your-api.com/track", autoTrackPageViews: true, autoTrackClicks: true, }); </script> ``` ### ES Modules ```typescript import { WaveTracker } from "@wavetrace/client"; const tracker = new WaveTracker({ endpoint: "https://your-api.com/track", autoTrackPageViews: true, autoTrackClicks: true, batchSize: 10, batchTimeout: 5000, debug: false, }); ``` ### DApp Wallet Tracking For Web3/DApp applications, track wallet connections with automatic detection or manual tracking: #### Automatic Wallet Detection (Recommended) ```typescript const tracker = new WaveTracker({ endpoint: "https://your-api.com/track", autoDetectWallet: true, // Automatically detect wallet connections autoTrackPageViews: true, }); // That's it! Wallet connections are automatically tracked // No need to manually call connectWallet() or disconnectWallet() ``` The tracker automatically: - Detects when users connect wallets (MetaMask, Coinbase, etc.) - Tracks `wallet_connected` event with wallet address and chain ID - Links anonymous activity to wallet address - Detects account switches - Detects disconnections - Handles network changes #### Manual Wallet Tracking ```typescript // When user connects wallet (if not using auto-detection) await tracker.connectWallet("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", { properties: { chainId: 1, walletType: "metamask", }, }); // Track DApp events tracker.track("swap_executed", { fromToken: "ETH", toToken: "USDC", amount: "1.5", txHash: "0x...", }); // When user disconnects await tracker.disconnectWallet(); ``` **How it works:** 1. User browses your DApp anonymously → tracked with anonymous ID 2. User connects wallet → automatically linked to wallet address 3. All future events include wallet address 4. Backend receives `wallet_connected` event with `previousAnonymousId` for user merging See [DAPP-INTEGRATION.md](./DAPP-INTEGRATION.md) for complete DApp integration guide. ### Smart Click Tracking WaveTrace includes intelligent click filtering to reduce noise and focus on meaningful interactions. **Default behavior** (tracks only important elements): ```typescript const tracker = new WaveTracker({ endpoint: "...", autoTrackClicks: true, // Uses 'important' mode - tracks buttons, links, data-track elements }); ``` **Track specific elements with data-track:** ```html <button data-track="connect-wallet">Connect Wallet</button> <button data-track="execute-swap">Swap</button> <div data-track="feature-card"> <!-- Entire card is trackable --> </div> ``` **Advanced configuration:** ```typescript const tracker = new WaveTracker({ endpoint: "...", autoTrackClicks: { mode: "important", // 'all' | 'important' | 'data-attribute' | 'custom' ignoreSelectors: ["[data-track-ignore]", ".no-track"], customSelectors: [".my-button", "[data-action]"], // For 'custom' mode }, }); ``` **Tracking modes:** - `important` (default): Buttons, links, and `data-track` elements - `all`: Every click on the page - `data-attribute`: Only elements with `data-track` - `custom`: Use your own CSS selectors See [CLICK-TRACKING.md](./CLICK-TRACKING.md) for complete guide and examples. ### User Identification Track user information with your events: ```typescript tracker.identify({ userId: "12345", username: "john_doe", wallet: "0x1234567890abcdef", email: "john@example.com", properties: { plan: "premium", signupDate: "2024-01-01", }, }); ``` ### Transaction Tracking (DApps) Automatically track the complete lifecycle of blockchain transactions: ```typescript // Track a swap transaction with automatic lifecycle tracking const tx = await tracker.trackTransaction( "swap", async () => { // Your transaction logic return await contract.swap(fromToken, toToken, amount); }, { fromToken: "ETH", toToken: "USDC", amount: "1.5", } ); // Automatically tracks: // 1. swap_initiated - When transaction starts // 2. swap_pending - Transaction submitted with txHash // 3. swap_executed - Transaction confirmed with gasUsed, blockNumber // 4. swap_failed - If transaction fails (with error details) ``` The transaction helper captures: - Transaction hash - Gas used - Block number - Confirmation time - Error messages (if failed) This eliminates the need to manually track each transaction state. ### Track Custom Events ```typescript // Simple event tracker.track("button_click"); // Event with properties tracker.track("purchase", { productId: "prod_123", amount: 99.99, currency: "USD", }); ``` ### Manual Page View Tracking ```typescript // Track page view with custom properties tracker.trackPageView({ campaign: "summer_sale", source: "email", }); ``` ### Configuration Options ```typescript interface TrackerConfig { // Required: Your tracking endpoint URL endpoint: string; // Auto-detect wallet connections (MetaMask, Coinbase, etc.) // Automatically tracks wallet_connected events and links anonymous activity // (default: false) autoDetectWallet?: boolean; // Enable offline queue with localStorage persistence // Events are saved locally and sent when back online // (default: true) offlineQueue?: boolean; // Maximum number of events to store offline // (default: 100) maxOfflineEvents?: number; // Retry configuration for failed requests retry?: { enabled?: boolean; // Enable retry logic (default: true) maxRetries?: number; // Max retry attempts (default: 3) initialDelay?: number; // Initial delay in ms (default: 1000) backoffMultiplier?: number; // Exponential backoff multiplier (default: 2) }; // Auto-track page views (default: true) autoTrackPageViews?: boolean; // Auto-track link clicks (default: true) autoTrackClicks?: boolean; // Batch size for sending events (0 = send immediately, default: 10) batchSize?: number; // Max time in ms to wait before sending batch (default: 5000) batchTimeout?: number; // Include referrer information (default: true) includeReferrer?: boolean; // Include user agent (default: true) includeUserAgent?: boolean; // Custom headers for tracking requests customHeaders?: Record<string, string>; // Enable debug logging (default: false) debug?: boolean; } ``` ## Event Structure All events sent to your endpoint follow this structure: ```typescript { events: [ { type: "pageview" | "click" | "custom_event_name", timestamp: "2024-01-15T10:30:00.000Z", url: "https://example.com/page", title: "Page Title", referrer: "https://google.com", userAgent: "Mozilla/5.0...", screen: { width: 1920, height: 1080 }, viewport: { width: 1200, height: 800 }, sessionId: "1234567890-abcdef", user: { userId: "12345", username: "john_doe", wallet: "0x1234...", properties: { /* custom user properties */ }, }, properties: { /* event-specific properties */ }, }, ]; } ``` ### Click Events Click events include additional properties: ```typescript { type: 'click', properties: { tagName: 'button', id: 'submit-btn', className: 'btn btn-primary', href: 'https://example.com/link', // for anchor tags text: 'Click Me', x: 450, // click coordinates y: 200 } } ``` ## Advanced Usage ### Manual Event Flushing ```typescript // Flush all queued events immediately await tracker.flush(); ``` ### Disable Click Tracking ```typescript tracker.disableClickTracking(); ``` ### Cleanup ```typescript // Clean up resources and flush remaining events tracker.destroy(); ``` ## Server-Side Endpoint Your tracking endpoint should accept POST requests with JSON payloads. Here's a simple example using Express: ```typescript app.post("/track", express.json(), (req, res) => { const { events } = req.body; // Store events in your database events.forEach((event) => { // Add IP address from request event.ip = req.ip; // Save to database db.events.insert(event); }); res.json({ success: true }); }); ``` ## Building from Source ```bash # Install dependencies npm install # Build all formats npm run build # Build and watch for changes npm run dev ``` ## Browser Support - Modern browsers (Chrome, Firefox, Safari, Edge) - ES2020+ features required - LocalStorage required for session management ## Privacy Considerations - IP addresses are captured server-side (from request headers) - User agent strings are optional (configurable) - No cookies are used - Session data stored in localStorage only - All tracking is explicit and configurable ## License MIT ## Roadmap ### Completed ✅ - ✅ Auto-detect wallet connections (MetaMask, Coinbase, etc.) - ✅ Offline queue persistence with localStorage - ✅ Retry logic with exponential backoff - ✅ Transaction lifecycle tracking helper ### Planned - React integration with hooks - Next.js plugin - Vue integration - Server-side tracking - Custom storage adapters - Event validation and schemas - Performance monitoring - Multi-wallet management - GDPR compliance helpers