@chaseleto/sessions-sdk
Version:
Privacy-conscious session recording SDK for self-hosted session tracking
450 lines (334 loc) • 10.4 kB
Markdown
# 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.