All files / client compression.js

100% Statements 38/38
100% Branches 14/14
100% Functions 5/5
100% Lines 34/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89          4x         15x 2x     13x 13x 13x   13x 175023x 170823x   4200x 4200x 4200x         13x     13x 5x     8x             5x 2x     3x 3x   3x 7x 7x   7x 1160x       3x             5x 5x   64x                 2x 2x   2x 32x     2x      
/**
 * Simple compression utilities for localStorage
 * Using a lightweight implementation that doesn't require external dependencies
 */
 
export const Compression = {
	/**
	 * Simple RLE compression for Uint16Array data
	 */
	compressUint16Array(array) {
		if (!array || !array.length) {
			return null;
		}
 
		const result = [];
		let currentValue = array[0];
		let count = 1;
 
		for (let i = 1; i < array.length; i++) {
			if (array[i] === currentValue && count < 65535) {
				count++;
			} else {
				result.push(count, currentValue);
				currentValue = array[i];
				count = 1;
			}
		}
 
		// Don't forget the last run
		result.push(count, currentValue);
 
		// If compression isn't effective, return null
		if (result.length >= array.length) {
			return null; // Indicate no compression benefit
		}
 
		return new Uint32Array(result);
	},
 
	/**
	 * Decompress RLE data back to Uint16Array
	 */
	decompressToUint16Array(compressed, outputLength) {
		if (!compressed || !compressed.length) {
			return null;
		}
 
		const result = new Uint16Array(outputLength);
		let outputIndex = 0;
 
		for (let i = 0; i < compressed.length; i += 2) {
			const count = compressed[i];
			const value = compressed[i + 1];
 
			for (let j = 0; j < count; j++) {
				result[outputIndex++] = value;
			}
		}
 
		return result;
	},
 
	/**
	 * Convert compressed data to base64 for storage
	 */
	compressedToBase64(compressed) {
		const bytes = new Uint8Array(compressed.buffer);
		return btoa(
			Array.from(bytes)
				.map(byte => String.fromCharCode(byte))
				.join(''),
		);
	},
 
	/**
	 * Convert base64 back to compressed data
	 */
	base64ToCompressed(base64) {
		const binaryString = atob(base64);
		const bytes = new Uint8Array(binaryString.length);
 
		for (let i = 0; i < bytes.length; i++) {
			bytes[i] = binaryString.charCodeAt(i);
		}
 
		return new Uint32Array(bytes.buffer);
	},
};