UNPKG

@chaseleto/sessions-sdk

Version:

Privacy-conscious session recording SDK for self-hosted session tracking

450 lines (334 loc) 10.4 kB
# Session SDK A privacy-conscious, self-hosted session recording SDK for capturing user sessions with essential metadata, network requests, console logs, and session replays. ## Features - 🎥 **Session Recording**: Full session replay using rrweb - 📝 **Console Logging**: Capture console.log, warn, error, info, debug - 🌐 **Network Monitoring**: Track fetch and XHR requests - 🔒 **Privacy First**: Respects Do Not Track headers - 📊 **Sampling**: Configurable sampling rates - 🚀 **Lightweight**: Minimal bundle size with tree-shaking - 🔄 **Reliable Upload**: Retry queue with exponential backoff - 📱 **Cross-Platform**: Works in all modern browsers ## Installation ### NPM ```bash npm install client-sdk ``` ### CDN ```html <script src="https://unpkg.com/client-sdk@latest/dist/index.umd.min.js"></script> ``` ## Development ### Prerequisites - Node.js 16+ - npm or yarn ### Setup ```bash # Install dependencies npm install # Run tests npm test # Run tests with coverage npm run test:coverage # Run tests in watch mode npm run test:watch # Type checking npm run type-check # Build (includes tests and type checking) npm run build # Full CI process (tests + type check + build) npm run ci ``` ### Build Process The build process automatically runs: 1. **Tests** - Ensures all functionality works correctly 2. **Type checking** - Validates TypeScript types 3. **Build** - Creates distribution files This ensures that any published version has passed all quality checks. ## Quick Start ### Basic Usage ```javascript import { init } from 'client-sdk'; // Initialize with your API key init('your-api-key-here', { projectId: 'your-project-id', userId: 'user-123', attributes: { plan: 'premium', environment: 'production' } }); ``` ### Next.js Usage (Recommended - Like HyperDX) ```tsx // pages/_app.tsx or app/layout.tsx import { initSessionRecording } from '@chaseleto/sessions-sdk'; // Initialize session recording (runs once on app load) initSessionRecording(process.env.NEXT_PUBLIC_SESSION_API_KEY!, { projectId: 'my-nextjs-app', userId: 'user-123', attributes: { environment: process.env.NODE_ENV, framework: 'nextjs', }, }); export default function App({ Component, pageProps }) { return <Component {...pageProps} />; } ``` ### Next.js with React Hooks (Alternative) ```tsx // pages/_app.tsx or app/layout.tsx import { useSessionRecording } from '@chaseleto/sessions-sdk'; export default function App({ Component, pageProps }) { const { sessionId, isActive } = useSessionRecording( process.env.NEXT_PUBLIC_SESSION_API_KEY!, { projectId: 'my-nextjs-app', userId: 'user-123', attributes: { environment: process.env.NODE_ENV, framework: 'nextjs', }, } ); return <Component {...pageProps} />; } ``` ### CDN Usage ```html <script> // Initialize with your API key SessionSDK.init('your-api-key-here', { projectId: 'your-project-id' }); </script> ``` ## Configuration Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `endpoint` | string | `'https://api.sessions.chxse.dev/api/v1/sessions'` | API endpoint for sending session data | | `projectId` | string | `''` | Project ID for the session | | `userId` | string | `''` | User ID to associate with sessions | | `attributes` | object | `{}` | Custom attributes to attach to all sessions | | `captureConsole` | boolean | `true` | Whether to capture console logs | | `captureNetwork` | boolean | `true` | Whether to capture network requests | | `samplingRate` | number | `1.0` | Sampling rate (0-1) for session recording | | `maxSessionDuration` | number | `1800000` | Maximum session duration in milliseconds (30 min) | | `uploadInterval` | number | `10000` | Upload interval in milliseconds (10 sec) | | `respectDNT` | boolean | `true` | Whether to respect Do Not Track headers | | `headers` | object | `{}` | Custom headers to include in requests | ## API Reference ### Core Functions #### `init(apiKey, options?)` Initialize the session SDK. ```javascript const sdk = init('your-api-key', { endpoint: 'https://your-backend.com/sessions', projectId: 'project-123' }); ``` ### Next.js Integration The SDK includes Next.js-specific utilities for easy integration: #### `useSessionRecording(apiKey, options?)` React hook for Next.js applications: ```tsx import { useSessionRecording } from '@chaseleto/sessions-sdk'; function MyComponent() { const { sessionId, isActive, setUserId, setAttributes } = useSessionRecording( 'your-api-key', { projectId: 'my-app', userId: 'user-123', enabled: process.env.NODE_ENV === 'production', } ); return <div>Session ID: {sessionId}</div>; } ``` #### `SessionRecorder` Component Invisible component for easy integration: ```tsx import { SessionRecorder } from '@chaseleto/sessions-sdk'; export default function App({ Component, pageProps }) { return ( <> <SessionRecorder apiKey={process.env.NEXT_PUBLIC_SESSION_API_KEY!} projectId="my-app" userId="user-123" /> <Component {...pageProps} /> </> ); } ``` #### `withSessionRecording(Component, apiKey, options?)` HOC for wrapping components: ```tsx import { withSessionRecording } from '@chaseleto/sessions-sdk'; const MyComponent = () => <div>My App</div>; export default withSessionRecording(MyComponent, 'your-api-key', { projectId: 'my-app', }); ``` #### `destroy()` Stop recording and destroy the SDK instance. ```javascript destroy(); ``` #### `setAttributes(attributes)` Add custom attributes to the current session. ```javascript setAttributes({ plan: 'premium', userType: 'admin', page: 'checkout' }); ``` #### `setUserId(userId)` Set the user ID for the current session. ```javascript setUserId('user-123'); ``` #### `getSessionId()` Get the current session ID. ```javascript const sessionId = getSessionId(); console.log('Current session:', sessionId); ``` #### `isActive()` Check if recording is currently active. ```javascript if (isActive()) { console.log('Session recording is active'); } ``` ### Advanced Usage #### Using the SessionSDK Class For more control, you can use the SessionSDK class directly: ```javascript import { SessionSDK } from 'client-sdk'; const sdk = new SessionSDK('your-api-key', { endpoint: 'https://your-backend.com/sessions', projectId: 'project-123' }); // Start recording sdk.init(); // Add attributes sdk.setAttributes({ plan: 'premium' }); // Stop recording sdk.stop(); // Destroy instance sdk.destroy(); ``` ## Data Structure The SDK sends session data in the following format: ```typescript interface SessionData { sessionId: string; projectId: string; userId?: string; attributes: Record<string, any>; metadata: { userAgent: string; url: string; referrer: string; viewport: { width: number; height: number }; timestamp: number; timezone: string; language: string; }; events: Array<{ type: 'rrweb'; data: any; timestamp: number; }>; consoleLogs: Array<{ level: 'log' | 'warn' | 'error' | 'info' | 'debug'; message: string; args: any[]; timestamp: number; stack?: string; }>; networkRequests: Array<{ method: string; url: string; status?: number; statusText?: string; requestHeaders?: Record<string, string>; responseHeaders?: Record<string, string>; requestBody?: any; responseBody?: any; duration: number; timestamp: number; error?: string; }>; timestamp: number; duration: number; } ``` ## Privacy & Compliance ### Do Not Track The SDK respects the Do Not Track (DNT) header by default. When DNT is enabled, no session data is recorded. ### Data Minimization - Only essential metadata is collected - Sensitive input fields (passwords) are automatically masked - Console logs and network requests are truncated to prevent data bloat - Session data is automatically cleaned up after upload ## Data Size Limits & Memory Management The SDK implements comprehensive size limits to prevent memory issues and ensure reliable uploads: ### Individual Item Limits | Item Type | Size Limit | Description | |-----------|------------|-------------| | Console Logs | 5KB per log | Large console objects are truncated | | Network Requests | 10KB per request | Large request/response data is limited | | Request Bodies | 1KB | Request payloads are truncated | | Console Arguments | 1KB per argument | Large objects in console calls are limited | ### Total Collection Limits | Data Type | Maximum Items | Server Validation | |-----------|---------------|-------------------| | Events (rrweb) | 10,000 | 10,000 | | Console Logs | 1,000 | 1,000 | | Network Requests | 1,000 | 1,000 | ### Memory Management Features - **Preventive Filtering**: Items that would exceed size limits are skipped entirely - **Frequent Cleanup**: Data is cleaned up every 5 seconds to prevent accumulation - **Progressive Truncation**: If upload data is too large, items are progressively reduced - **Automatic Cleanup**: Old data is automatically removed after successful uploads - **Size Validation**: Data is validated before upload to prevent server rejections ### Upload Limits - **Client-side limit**: 25MB per upload - **Server-side limit**: 50MB per upload - **Automatic retry**: Failed uploads are retried with exponential backoff - **Graceful degradation**: If data is still too large after truncation, upload is skipped ### Best Practices 1. **Avoid large objects in console logs**: The SDK will truncate them, but it's better to log smaller, focused data 2. **Monitor network requests**: Large API responses will be limited to metadata only 3. **Use sampling for high-traffic sites**: Reduce the sampling rate to limit data collection 4. **Set appropriate session durations**: Long sessions accumulate more data ### GDPR Compliance - No personally identifiable information is collected by default - Users can opt-out by setting DNT headers - Session data can be easily deleted by session ID ## Browser Support - Chrome 60+ - Firefox 55+ - Safari 12+ - Edge 79+ ## Development ### Building ```bash npm install npm run build ``` ### Development Mode ```bash npm run dev ``` ### Testing ```bash npm test ``` ## License MIT License - see LICENSE file for details.