taglib-wasm
Version:
TagLib for TypeScript platforms: Deno, Node.js, Bun, Electron, browsers, and Cloudflare Workers
250 lines (249 loc) • 6.51 kB
JavaScript
import {
decodeAudioProperties,
decodeFastTagData,
decodeMessagePack,
decodeMessagePackAuto,
decodePicture,
decodePictureArray,
decodePropertyMap,
decodeTagData,
getMessagePackInfo,
isValidMessagePack
} from "./decoder.js";
import {
canEncodeToMessagePack,
compareEncodingEfficiency,
encodeAudioProperties,
encodeBatchTagData,
encodeFastTagData,
encodeMessagePack,
encodeMessagePackCompact,
encodeMessagePackStream,
encodePicture,
encodePictureArray,
encodePropertyMap,
encodeTagData,
estimateMessagePackSize
} from "./encoder.js";
import { TAGLIB_MSGPACK_MARKERS } from "./types.js";
import {
decodeAudioProperties as decodeAudioProperties2,
decodeMessagePackAuto as decodeMessagePackAuto2,
decodePicture as decodePicture2,
decodeTagData as decodeTagData2,
isValidMessagePack as isValidMessagePack2
} from "./decoder.js";
import { compareEncodingEfficiency as compareEncodingEfficiency2, encodeTagData as encodeTagData2 } from "./encoder.js";
class MessagePackUtils {
/**
* Smart decode that automatically detects the data type
*/
static decode(buffer) {
return decodeMessagePackAuto2(buffer);
}
/**
* Validate and decode tag data with error handling
*/
static safeDecodeTagData(buffer) {
try {
if (!isValidMessagePack2(buffer)) {
return null;
}
return decodeTagData2(buffer);
} catch {
return null;
}
}
/**
* Validate and decode audio properties with error handling
*/
static safeDecodeAudioProperties(buffer) {
try {
if (!isValidMessagePack2(buffer)) {
return null;
}
return decodeAudioProperties2(buffer);
} catch {
return null;
}
}
/**
* Validate and decode picture data with error handling
*/
static safeDecodePicture(buffer) {
try {
if (!isValidMessagePack2(buffer)) {
return null;
}
return decodePicture2(buffer);
} catch {
return null;
}
}
/**
* Get performance metrics for MessagePack vs JSON
*/
static getPerformanceComparison(data) {
const comparison = compareEncodingEfficiency2(data);
return {
messagePackSize: comparison.messagePackSize,
jsonSize: comparison.jsonSize,
sizeReduction: comparison.sizeReduction,
estimatedSpeedImprovement: comparison.speedImprovement
};
}
/**
* Convert between MessagePack and JSON for debugging/comparison
*/
static toJson(buffer) {
try {
const decoded = decodeMessagePackAuto2(buffer);
return JSON.stringify(decoded, null, 2);
} catch (error) {
throw new Error(`Failed to convert MessagePack to JSON: ${error}`);
}
}
/**
* Convert JSON back to MessagePack (for testing/migration)
*/
static fromJson(jsonString) {
try {
const data = JSON.parse(jsonString);
return encodeTagData2(data);
} catch (error) {
throw new Error(`Failed to convert JSON to MessagePack: ${error}`);
}
}
/**
* Batch process multiple MessagePack buffers
*/
static batchDecode(buffers) {
return buffers.map((buffer) => {
try {
const data = decodeMessagePackAuto2(buffer);
return { success: true, data };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : "Unknown error"
};
}
});
}
/**
* Check if data is compatible with TagLib MessagePack format
*/
static isTagLibCompatible(data) {
if (typeof data !== "object" || data === null) {
return false;
}
const obj = data;
if ("title" in obj || "artist" in obj || "album" in obj) {
return true;
}
if ("bitrate" in obj && "sampleRate" in obj) {
return true;
}
if ("mimeType" in obj && "data" in obj) {
return true;
}
return false;
}
}
function createMessagePackProcessor(options = {}) {
const {
validateInput = true,
enableMetrics = false,
maxBufferSize = 50 * 1024 * 1024
// 50MB
} = options;
return {
/**
* Decode with optional validation and metrics
*/
decode(buffer) {
if (buffer.length > maxBufferSize) {
throw new Error(
`Buffer too large: ${buffer.length} bytes (max: ${maxBufferSize})`
);
}
if (validateInput && !isValidMessagePack2(buffer)) {
throw new Error("Invalid MessagePack data");
}
const startTime = enableMetrics ? performance.now() : 0;
const result = decodeMessagePackAuto2(buffer);
const endTime = enableMetrics ? performance.now() : 0;
if (enableMetrics) {
console.log(`MessagePack decode took ${endTime - startTime}ms`);
}
return result;
},
/**
* Encode with optional metrics
*/
encode(data) {
const startTime = enableMetrics ? performance.now() : 0;
const result = encodeTagData2(data);
const endTime = enableMetrics ? performance.now() : 0;
if (result.length > maxBufferSize) {
throw new Error(
`Encoded data too large: ${result.length} bytes (max: ${maxBufferSize})`
);
}
if (enableMetrics) {
console.log(`MessagePack encode took ${endTime - startTime}ms`);
}
return result;
}
};
}
const defaultMessagePackProcessor = createMessagePackProcessor({
validateInput: true,
enableMetrics: false,
maxBufferSize: 50 * 1024 * 1024
// 50MB
});
const performanceMessagePackProcessor = createMessagePackProcessor({
validateInput: false,
// Skip validation for speed
enableMetrics: false,
maxBufferSize: 100 * 1024 * 1024
// 100MB
});
const debugMessagePackProcessor = createMessagePackProcessor({
validateInput: true,
enableMetrics: true,
maxBufferSize: 10 * 1024 * 1024
// 10MB
});
export {
MessagePackUtils,
TAGLIB_MSGPACK_MARKERS,
canEncodeToMessagePack,
compareEncodingEfficiency,
createMessagePackProcessor,
debugMessagePackProcessor,
decodeAudioProperties,
decodeFastTagData,
decodeMessagePack,
decodeMessagePackAuto,
decodePicture,
decodePictureArray,
decodePropertyMap,
decodeTagData,
defaultMessagePackProcessor,
encodeAudioProperties,
encodeBatchTagData,
encodeFastTagData,
encodeMessagePack,
encodeMessagePackCompact,
encodeMessagePackStream,
encodePicture,
encodePictureArray,
encodePropertyMap,
encodeTagData,
estimateMessagePackSize,
getMessagePackInfo,
isValidMessagePack,
performanceMessagePackProcessor
};