@achado/session-replay
v0.0.2
Published
Session replay functionality using rrweb for Achado platform
Downloads
20
Readme
@achado/session-replay
Session recording functionality using rrweb for the Achado platform. Capture complete user sessions with privacy controls and efficient storage.
Installation
npm install @achado/core @achado/session-replayQuick Start
import { AchadoClient } from '@achado/core';
import { SessionReplay } from '@achado/session-replay';
const client = new AchadoClient({ apiKey: 'your-api-key' });
const sessionReplay = new SessionReplay(client, {
enabled: true,
sampleRate: 0.1, // Record 10% of sessions
});
await client.initialize();
await sessionReplay.initialize();
// Sessions are now being recorded automatically!Features
🎥 Complete Session Recording
- Full DOM snapshots and incremental changes
- Mouse movements, clicks, and scrolls
- Keyboard inputs (with privacy controls)
- Window resize and focus events
- Network requests (optional)
🔒 Privacy Controls
- Text input masking
- Sensitive element blocking
- Custom masking rules
- Selective recording areas
- Compliance-ready defaults
⚡ Performance Optimized
- Efficient compression
- Smart segmentation
- Background processing
- Minimal performance impact
- Automatic cleanup
📊 Error Correlation
- Automatic error tracking
- Error replay linking
- Stack trace capture
- Context preservation
Configuration
interface SessionReplayConfig {
enabled?: boolean; // Default: true
sampleRate?: number; // Default: 1.0 (100%)
maxDuration?: number; // Default: 1800000 (30 min)
inactiveThreshold?: number; // Default: 300000 (5 min)
captureConsole?: boolean; // Default: false
captureNetwork?: boolean; // Default: false
maskTextInputs?: boolean; // Default: true
maskAllText?: boolean; // Default: false
maskTextSelector?: string; // Custom mask selector
blockClass?: string; // Default: 'rr-block'
blockSelector?: string; // Custom block selector
ignoreClass?: string; // Default: 'rr-ignore'
checkoutEveryNth?: number; // Default: 200
checkoutEveryNms?: number; // Default: 300000 (5 min)
slimDOMOptions?: SlimDOMOptions;
}Example Configuration
const sessionReplay = new SessionReplay(client, {
enabled: true,
sampleRate: 0.2, // Record 20% of sessions
maxDuration: 900000, // 15 minutes max
maskTextInputs: true,
blockClass: 'no-record',
checkoutEveryNth: 100,
captureConsole: false,
slimDOMOptions: {
script: true,
comment: true,
headFavicon: true,
headWhitespace: true,
},
});API Reference
SessionReplay Class
Constructor
new SessionReplay(client: AchadoClient, config?: SessionReplayConfig)Methods
initialize(): Promise<void>
Start session recording.
startRecording(): Promise<void>
Manually start recording.
stopRecording(): Promise<void>
Manually stop recording.
isRecording(): boolean
Check if currently recording.
getSessionId(): string | undefined
Get the current session ID.
getRecordingDuration(): number
Get recording duration in milliseconds.
getEventCount(): number
Get total recorded events.
getRecordingStats()
Get comprehensive recording statistics.
const stats = sessionReplay.getRecordingStats();
// Returns: { sessionId, isRecording, duration, eventCount }updateConfig(config: Partial<SessionReplayConfig>): void
Update configuration at runtime.
destroy(): Promise<void>
Stop recording and clean up.
Privacy & Masking
Automatic Masking
By default, sensitive inputs are masked:
- Password fields
- Credit card inputs
- Any field with
data-sensitiveattribute
HTML Attributes
<!-- Block entire sections from recording -->
<div class="rr-block">This content will not be recorded</div>
<!-- Ignore elements (still recorded but marked) -->
<div class="rr-ignore">This will be in replay but marked as ignored</div>
<!-- Mask text content -->
<div data-mask-text>This text will be masked in recordings</div>
<!-- Mark sensitive inputs -->
<input type="text" data-sensitive placeholder="SSN" />
<input type="password" />
<!-- Automatically masked -->Custom Masking
const sessionReplay = new SessionReplay(client, {
maskTextInputs: true,
maskTextSelector: '.mask-this, [data-private]',
blockClass: 'no-record',
blockSelector: '.admin-only, .sensitive-area',
});Compliance Options
// GDPR-friendly setup
const sessionReplay = new SessionReplay(client, {
maskAllText: true, // Mask all text content
maskTextInputs: true, // Mask all inputs
captureConsole: false, // Don't capture console logs
captureNetwork: false, // Don't capture network requests
blockClass: 'gdpr-block', // Custom blocking class
});Recording Lifecycle
Session Management
- Session Start: New session begins on page load
- Event Capture: DOM mutations and interactions recorded
- Segmentation: Events split into manageable chunks
- Transmission: Segments sent to API
- Session End: Recording stops on inactivity or max duration
Event Types
- Full Snapshot: Complete DOM state
- Incremental Snapshot: DOM changes
- Mouse Interaction: Clicks, movements, scrolls
- Input: Keyboard and form interactions
- ViewportResize: Window size changes
- Meta: Custom events and errors
Data Structure
Session Metadata
{
sessionId: 'session_1234567890_abc123',
userId: 'user-456',
startTime: 1640995200000,
endTime: 1640998800000,
duration: 3600000,
totalEvents: 1247,
segments: 12,
url: 'https://example.com/app',
userAgent: 'Mozilla/5.0...',
errors: 2,
interactions: 45
}Replay Segment
{
id: 'segment_uuid',
sessionId: 'session_1234567890_abc123',
sequence: 3,
events: [...], // rrweb events
startTime: 1640995800000,
endTime: 1640996100000,
size: 15420 // bytes
}Performance Impact
Benchmarks
- Memory Usage: < 10MB for typical sessions
- CPU Impact: < 1% additional usage
- Network: Compressed segments, < 100KB/minute
- DOM Performance: Negligible impact on interactions
Optimization Features
- Smart Segmentation: Automatic chunking for efficiency
- Compression: Event data compressed before transmission
- Debouncing: Rapid events intelligently merged
- Cleanup: Automatic memory management
Error Integration
Automatic Error Tracking
Errors are automatically correlated with recordings:
// This error will be linked to the current recording
throw new Error('Payment processing failed');Manual Error Tracking
try {
processPayment();
} catch (error) {
// Error automatically tracked and linked to recording
console.error('Payment failed:', error);
}Error Playback
Recordings with errors are automatically flagged and can be filtered for debugging.
Sampling Strategy
Basic Sampling
// Record 10% of all sessions
const sessionReplay = new SessionReplay(client, {
sampleRate: 0.1,
});Conditional Sampling
// Custom sampling logic
const shouldRecord = () => {
// Record all admin users
if (user.role === 'admin') return true;
// Record 5% of regular users
if (Math.random() < 0.05) return true;
return false;
};
const sessionReplay = new SessionReplay(client, {
enabled: shouldRecord(),
});Error-Based Recording
// Start recording when errors occur
window.addEventListener('error', () => {
if (!sessionReplay.isRecording()) {
sessionReplay.startRecording();
}
});Storage & Bandwidth
Local Storage
- Session data temporarily stored locally
- Automatic cleanup after transmission
- Fallback for network failures
Network Optimization
- Gzip compression
- Incremental transmission
- Retry logic with exponential backoff
- Offline support
Browser Support
- Chrome 70+
- Firefox 65+
- Safari 12+
- Edge 79+
Examples
Basic Setup
const sessionReplay = new SessionReplay(client, {
enabled: true,
sampleRate: 1.0, // Record all sessions in development
});Production Setup
const sessionReplay = new SessionReplay(client, {
enabled: process.env.NODE_ENV === 'production',
sampleRate: 0.05, // 5% of production sessions
maxDuration: 1200000, // 20 minutes max
maskTextInputs: true,
blockClass: 'no-record',
});High-Privacy Setup
const sessionReplay = new SessionReplay(client, {
enabled: true,
maskAllText: true,
maskTextInputs: true,
captureConsole: false,
captureNetwork: false,
blockClass: 'sensitive',
slimDOMOptions: {
script: true,
comment: true,
headFavicon: true,
},
});Error-Focused Recording
let hasError = false;
window.addEventListener('error', () => {
hasError = true;
});
const sessionReplay = new SessionReplay(client, {
enabled: () => hasError, // Only record sessions with errors
sampleRate: 1.0,
});