UNPKG

taglib-wasm

Version:

TagLib for TypeScript platforms: Deno, Node.js, Bun, Electron, browsers, and Cloudflare Workers

220 lines (219 loc) 6.1 kB
import { encode } from "@msgpack/msgpack"; const MSGPACK_ENCODE_OPTIONS = { // Use the most compact representation sortKeys: false, // Maintain field order for consistency forceFloat32: false, // Use optimal precision ignoreUndefined: true, // Skip undefined fields initialBufferSize: 2048, // Start with reasonable buffer size maxDepth: 32, // Reasonable nesting limit // Extension codec for custom types (if needed) extensionCodec: void 0 }; function encodeTagData(tagData) { try { const cleanedData = cleanObject(tagData); return encode(cleanedData, MSGPACK_ENCODE_OPTIONS); } catch (error) { throw new Error(`Failed to encode tag data to MessagePack: ${error}`); } } function encodeAudioProperties(audioProps) { try { const cleanedData = cleanObject(audioProps); return encode(cleanedData, MSGPACK_ENCODE_OPTIONS); } catch (error) { throw new Error( `Failed to encode audio properties to MessagePack: ${error}` ); } } function encodePropertyMap(propertyMap) { try { return encode(propertyMap, MSGPACK_ENCODE_OPTIONS); } catch (error) { throw new Error(`Failed to encode property map to MessagePack: ${error}`); } } function encodePicture(picture) { try { const cleanedPicture = { ...picture, data: picture.data instanceof Uint8Array ? picture.data : new Uint8Array(picture.data) }; return encode(cleanedPicture, MSGPACK_ENCODE_OPTIONS); } catch (error) { throw new Error(`Failed to encode picture to MessagePack: ${error}`); } } function encodePictureArray(pictures) { try { const cleanedPictures = pictures.map((picture) => ({ ...picture, data: picture.data instanceof Uint8Array ? picture.data : new Uint8Array(picture.data) })); return encode(cleanedPictures, MSGPACK_ENCODE_OPTIONS); } catch (error) { throw new Error(`Failed to encode picture array to MessagePack: ${error}`); } } function encodeMessagePack(data, options = {}) { try { const mergedOptions = { ...MSGPACK_ENCODE_OPTIONS, ...options }; const cleanedData = cleanObject(data); return encode(cleanedData, mergedOptions); } catch (error) { throw new Error(`Failed to encode data to MessagePack: ${error}`); } } function encodeMessagePackCompact(data) { try { const compactOptions = { ...MSGPACK_ENCODE_OPTIONS, sortKeys: true, // Sort keys for better compression initialBufferSize: 512, // Start smaller for compact data forceFloat32: true // Use smaller floats when possible }; const cleanedData = cleanObject(data); return encode(cleanedData, compactOptions); } catch (error) { throw new Error(`Failed to encode data to compact MessagePack: ${error}`); } } function cleanObject(obj) { if (obj === null || obj === void 0) { return null; } if (typeof obj !== "object") { return obj; } if (obj instanceof Uint8Array || obj instanceof Array) { return obj; } if (obj instanceof Date) { return obj; } const cleaned = {}; for (const [key, value] of Object.entries(obj)) { if (value === void 0) { continue; } if (value === null) { cleaned[key] = null; continue; } if (typeof value === "string" && value === "") { continue; } if (typeof value === "object") { cleaned[key] = cleanObject(value); } else { cleaned[key] = value; } } return cleaned; } function encodeBatchTagData(tagDataArray) { try { const cleanedArray = tagDataArray.map((tagData) => cleanObject(tagData)); return encode(cleanedArray, { ...MSGPACK_ENCODE_OPTIONS, initialBufferSize: 8192, // Larger buffer for batch data maxDepth: 16 // Simpler structure for batch }); } catch (error) { throw new Error(`Failed to encode batch tag data to MessagePack: ${error}`); } } function* encodeMessagePackStream(dataIterator) { try { for (const item of dataIterator) { const cleanedItem = cleanObject(item); yield encode(cleanedItem, { ...MSGPACK_ENCODE_OPTIONS, initialBufferSize: 1024 // Smaller buffer for streaming }); } } catch (error) { throw new Error(`Failed to encode streaming data to MessagePack: ${error}`); } } function estimateMessagePackSize(data) { try { const encoded = encode(cleanObject(data), { ...MSGPACK_ENCODE_OPTIONS, initialBufferSize: 512 }); return encoded.length; } catch (error) { const jsonSize = JSON.stringify(data).length; return Math.floor(jsonSize * 0.75); } } function encodeFastTagData(tagData) { try { const fastOptions = { sortKeys: false, ignoreUndefined: true, initialBufferSize: 256, // Small buffer for essential fields maxDepth: 8 // Simple structure }; const cleanedData = cleanObject(tagData); return encode(cleanedData, fastOptions); } catch (error) { throw new Error(`Failed to encode fast tag data to MessagePack: ${error}`); } } function canEncodeToMessagePack(data) { try { encode(cleanObject(data), { ...MSGPACK_ENCODE_OPTIONS, maxDepth: 16, initialBufferSize: 256 }); return true; } catch { return false; } } function compareEncodingEfficiency(data) { const jsonString = JSON.stringify(data); const jsonSize = new TextEncoder().encode(jsonString).length; const messagePackData = encode(cleanObject(data), MSGPACK_ENCODE_OPTIONS); const messagePackSize = messagePackData.length; const sizeReduction = (jsonSize - messagePackSize) / jsonSize * 100; const speedImprovement = 10; return { messagePackSize, jsonSize, sizeReduction: Math.max(0, sizeReduction), speedImprovement }; } export { canEncodeToMessagePack, compareEncodingEfficiency, encodeAudioProperties, encodeBatchTagData, encodeFastTagData, encodeMessagePack, encodeMessagePackCompact, encodeMessagePackStream, encodePicture, encodePictureArray, encodePropertyMap, encodeTagData, estimateMessagePackSize };