agentic-qe
Version: 
Agentic Quality Engineering Fleet System - AI-driven quality management platform
227 lines • 8.57 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompressionManager = void 0;
const zlib = __importStar(require("zlib"));
const util_1 = require("util");
const gzipAsync = (0, util_1.promisify)(zlib.gzip);
const gunzipAsync = (0, util_1.promisify)(zlib.gunzip);
const deflateAsync = (0, util_1.promisify)(zlib.deflate);
const inflateAsync = (0, util_1.promisify)(zlib.inflate);
/**
 * CompressionManager - Handles compression and decompression of large data
 *
 * Features:
 * - Gzip and Deflate compression
 * - Automatic compression for large values
 * - Compression ratio tracking
 * - Base64 encoding for storage
 * - Configurable compression thresholds
 */
class CompressionManager {
    /**
     * Compress data using specified algorithm
     */
    async compress(data, algorithm = CompressionManager.DEFAULT_ALGORITHM) {
        try {
            const buffer = Buffer.from(data, 'utf8');
            let compressed;
            if (algorithm === 'gzip') {
                compressed = await gzipAsync(buffer);
            }
            else if (algorithm === 'deflate') {
                compressed = await deflateAsync(buffer);
            }
            else {
                throw new Error(`Unsupported compression algorithm: ${algorithm}`);
            }
            // Format: COMPRESSED:algorithm:base64data
            return `${CompressionManager.COMPRESSION_PREFIX}${algorithm}:${compressed.toString('base64')}`;
        }
        catch (error) {
            throw new Error(`Compression failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
        }
    }
    /**
     * Decompress data
     */
    async decompress(compressedData, algorithm) {
        try {
            // Parse compressed format
            if (!compressedData.startsWith(CompressionManager.COMPRESSION_PREFIX)) {
                throw new Error('Invalid compressed data format');
            }
            const withoutPrefix = compressedData.substring(CompressionManager.COMPRESSION_PREFIX.length);
            const parts = withoutPrefix.split(':');
            if (parts.length !== 2) {
                throw new Error('Invalid compressed data format');
            }
            const detectedAlgorithm = parts[0];
            const base64Data = parts[1];
            const compressionAlgorithm = algorithm || detectedAlgorithm;
            const buffer = Buffer.from(base64Data, 'base64');
            let decompressed;
            if (compressionAlgorithm === 'gzip') {
                decompressed = await gunzipAsync(buffer);
            }
            else if (compressionAlgorithm === 'deflate') {
                decompressed = await inflateAsync(buffer);
            }
            else {
                throw new Error(`Unsupported compression algorithm: ${compressionAlgorithm}`);
            }
            return decompressed.toString('utf8');
        }
        catch (error) {
            throw new Error(`Decompression failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
        }
    }
    /**
     * Check if data should be compressed based on size threshold
     */
    shouldCompress(data, threshold = CompressionManager.DEFAULT_THRESHOLD) {
        const size = Buffer.byteLength(data, 'utf8');
        return size > threshold;
    }
    /**
     * Check if data is compressed
     */
    isCompressed(data) {
        return data.startsWith(CompressionManager.COMPRESSION_PREFIX);
    }
    /**
     * Get compression metadata from compressed data
     */
    getCompressionMetadata(compressedData) {
        if (!this.isCompressed(compressedData)) {
            return { compressed: false };
        }
        const withoutPrefix = compressedData.substring(CompressionManager.COMPRESSION_PREFIX.length);
        const parts = withoutPrefix.split(':');
        if (parts.length !== 2) {
            return { compressed: false };
        }
        return {
            algorithm: parts[0],
            compressed: true,
            compressedSize: Buffer.byteLength(compressedData, 'utf8'),
            timestamp: Date.now()
        };
    }
    /**
     * Calculate compression ratio
     */
    getCompressionRatio(originalData, compressedData) {
        const originalSize = Buffer.byteLength(originalData, 'utf8');
        const compressedSize = Buffer.byteLength(compressedData, 'utf8');
        if (originalSize === 0) {
            return 0;
        }
        return compressedSize / originalSize;
    }
    /**
     * Compress with automatic algorithm selection
     */
    async compressAuto(data) {
        // Try both algorithms and use the one with better compression
        const gzipped = await this.compress(data, 'gzip');
        const deflated = await this.compress(data, 'deflate');
        return gzipped.length < deflated.length ? gzipped : deflated;
    }
    /**
     * Compress only if beneficial (size reduction)
     */
    async compressIfBeneficial(data, minCompressionRatio = 0.9) {
        const compressed = await this.compress(data);
        const ratio = this.getCompressionRatio(data, compressed);
        if (ratio < minCompressionRatio) {
            return { compressed: true, data: compressed, ratio };
        }
        return { compressed: false, data };
    }
    /**
     * Compress object to string
     */
    async compressObject(obj, algorithm) {
        const jsonString = JSON.stringify(obj);
        return this.compress(jsonString, algorithm);
    }
    /**
     * Decompress to object
     */
    async decompressObject(compressedData, algorithm) {
        const decompressed = await this.decompress(compressedData, algorithm);
        return JSON.parse(decompressed);
    }
    /**
     * Get compression statistics for data
     */
    async getCompressionStats(data, algorithm) {
        const originalSize = Buffer.byteLength(data, 'utf8');
        const compressed = await this.compress(data, algorithm);
        const compressedSize = Buffer.byteLength(compressed, 'utf8');
        const compressionRatio = compressedSize / originalSize;
        const metadata = this.getCompressionMetadata(compressed);
        return {
            algorithm: metadata.algorithm || CompressionManager.DEFAULT_ALGORITHM,
            compressed: true,
            originalSize,
            compressedSize,
            compressionRatio,
            timestamp: Date.now()
        };
    }
    /**
     * Estimate compression ratio without actually compressing
     */
    estimateCompressionRatio(data) {
        // Simple heuristic: count repeated patterns
        const uniqueChars = new Set(data).size;
        const totalChars = data.length;
        if (totalChars === 0) {
            return 1;
        }
        // More repeated characters = better compression
        const entropy = uniqueChars / totalChars;
        return Math.max(0.1, Math.min(1, entropy));
    }
    /**
     * Batch compress multiple values
     */
    async compressBatch(values, algorithm) {
        return Promise.all(values.map(value => this.compress(value, algorithm)));
    }
    /**
     * Batch decompress multiple values
     */
    async decompressBatch(compressedValues, algorithm) {
        return Promise.all(compressedValues.map(value => this.decompress(value, algorithm)));
    }
}
exports.CompressionManager = CompressionManager;
CompressionManager.DEFAULT_ALGORITHM = 'gzip';
CompressionManager.DEFAULT_THRESHOLD = 1024; // 1KB
CompressionManager.COMPRESSION_PREFIX = 'COMPRESSED:';
//# sourceMappingURL=CompressionManager.js.map