UNPKG

taglib-wasm

Version:

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

116 lines (115 loc) 3.98 kB
import { TagLibInitializationError } from "./errors.js"; const DEFAULT_WORKERS_CONFIG = { memory: { initial: 8 * 1024 * 1024, // 8MB (reduced from 16MB) maximum: 64 * 1024 * 1024 // 64MB (reduced from 256MB) }, debug: false }; function createModuleConfig(wasmBinary, config) { const mergedConfig = { ...DEFAULT_WORKERS_CONFIG, ...config }; return { wasmBinary, wasmMemory: new WebAssembly.Memory({ initial: (mergedConfig.memory?.initial ?? 8 * 1024 * 1024) / (64 * 1024), maximum: (mergedConfig.memory?.maximum ?? 64 * 1024 * 1024) / (64 * 1024) }), print: mergedConfig.debug ? console.log : () => { }, printErr: mergedConfig.debug ? console.error : () => { }, onRuntimeInitialized: () => { if (mergedConfig.debug) { console.log("taglib-wasm module initialized in Workers"); } }, // Workers-specific settings locateFile: () => "", // Empty string since we're providing wasmBinary directly noFSInit: true, // Disable file system access noExitRuntime: true }; } function setupMemoryArrays(wasmInstance) { if (!wasmInstance.HEAPU8) { const buffer = wasmInstance.buffer ?? wasmInstance.wasmMemory?.buffer; if (buffer) { wasmInstance.HEAPU8 = new Uint8Array(buffer); wasmInstance.HEAP8 = new Int8Array(buffer); wasmInstance.HEAP16 = new Int16Array(buffer); wasmInstance.HEAP32 = new Int32Array(buffer); wasmInstance.HEAPU16 = new Uint16Array(buffer); wasmInstance.HEAPU32 = new Uint32Array(buffer); wasmInstance.HEAPF32 = new Float32Array(buffer); wasmInstance.HEAPF64 = new Float64Array(buffer); } } } async function loadTagLibModuleForWorkers(wasmBinary, config = {}) { const moduleConfig = createModuleConfig(wasmBinary, config); try { const TagLibWasm = await createWorkersCompatibleModule(); if (typeof TagLibWasm !== "function") { throw new TagLibInitializationError( "Failed to load taglib-wasm module for Workers. The module may not be properly bundled for the Workers environment." ); } const wasmInstance = await TagLibWasm(moduleConfig); setupMemoryArrays(wasmInstance); return wasmInstance; } catch (error) { if (error instanceof TagLibInitializationError) { throw error; } throw new TagLibInitializationError( `Failed to load taglib-wasm for Workers: ${error.message}`, { error: error.message } ); } } async function createWorkersCompatibleModule() { try { const wasmModule = await import("../taglib-wrapper.js"); return wasmModule.default ?? wasmModule; } catch (error) { throw new TagLibInitializationError( `Workers-compatible Wasm module not available. Please build with Workers target or use a bundler that supports Wasm modules. Original error: ${error.message}`, { error: error.message } ); } } function cStringToJS(module, ptr) { if (ptr === 0) return ""; const view = new Uint8Array(module.HEAPU8.buffer, ptr); let length = 0; while (view[length] !== 0) length++; return new TextDecoder().decode(view.subarray(0, length)); } function jsToCString(module, str) { const encoder = new TextEncoder(); const bytes = encoder.encode(str + "\0"); if (module.allocate && module.ALLOC_NORMAL !== void 0) { return module.allocate(bytes, module.ALLOC_NORMAL); } else { const ptr = module._malloc(bytes.length); try { module.HEAPU8.set(bytes, ptr); return ptr; } catch (error) { module._free(ptr); throw error; } } } function isCloudflareWorkers() { return typeof globalThis !== "undefined" && typeof globalThis.caches !== "undefined" && typeof globalThis.Request !== "undefined" && typeof globalThis.Response !== "undefined" && typeof globalThis.process === "undefined" && typeof globalThis.Deno === "undefined"; } export { cStringToJS, isCloudflareWorkers, jsToCString, loadTagLibModuleForWorkers };