@bugspotter/sdk
Version:
Professional bug reporting SDK with screenshots, session replay, and automatic error capture for web applications
80 lines (79 loc) • 2.98 kB
JavaScript
;
/**
* Upload Helpers
* Utilities for preparing data for presigned URL uploads
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.compressReplayEvents = compressReplayEvents;
exports.canvasToBlob = canvasToBlob;
exports.estimateCompressedReplaySize = estimateCompressedReplaySize;
exports.isWithinSizeLimit = isWithinSizeLimit;
/**
* Compress replay events using CompressionStream API (browser native)
* Falls back to no compression if API not available
* @param events - Session replay events array
* @returns Compressed Blob (gzip)
*/
async function compressReplayEvents(events) {
// Convert events to JSON string
const jsonString = JSON.stringify(events);
const textEncoder = new TextEncoder();
const data = textEncoder.encode(jsonString);
// Check if CompressionStream is supported (Chrome 80+, Firefox 113+, Safari 16.4+)
if (typeof CompressionStream === 'undefined') {
console.warn('CompressionStream not supported, uploading uncompressed replay data');
return new Blob([data], { type: 'application/json' });
}
try {
// Use modern streaming API: Blob → ReadableStream → CompressionStream → Response → Blob
const blob = new Blob([data]);
const compressedStream = blob.stream().pipeThrough(new CompressionStream('gzip'));
return await new Response(compressedStream, {
headers: { 'Content-Type': 'application/gzip' },
}).blob();
}
catch (error) {
console.error('Compression failed, uploading uncompressed:', error);
return new Blob([data], { type: 'application/json' });
}
}
/**
* Convert screenshot canvas to Blob
* @param canvas - HTML Canvas element with screenshot
* @param quality - JPEG quality (0-1), default 0.9
* @returns Screenshot Blob
*/
async function canvasToBlob(canvas, quality = 0.9) {
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => {
if (blob) {
resolve(blob);
}
else {
reject(new Error('Failed to convert canvas to Blob'));
}
}, 'image/png', quality);
});
}
/**
* Estimate compressed size of replay events
* Uses rough heuristic: gzip typically achieves 80-90% compression for JSON
* @param events - Replay events array
* @returns Estimated compressed size in bytes
*/
function estimateCompressedReplaySize(events) {
const jsonString = JSON.stringify(events);
const uncompressedSize = new TextEncoder().encode(jsonString).length;
// Assume 85% compression ratio (conservative estimate)
return Math.round(uncompressedSize * 0.15);
}
/**
* Check if file size is within upload limits
* @param blob - File or Blob to check
* @param maxSizeMB - Maximum size in megabytes
* @returns True if within limit
*/
function isWithinSizeLimit(blob, maxSizeMB) {
const maxBytes = maxSizeMB * 1024 * 1024;
return blob.size <= maxBytes;
}