UNPKG

taglib-wasm

Version:

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

203 lines (202 loc) 5.67 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import { detectRuntime } from "./detector.js"; import { initializeWasmer, isWasmerAvailable, loadWasmerWasi } from "./wasmer-sdk-loader.js"; class UnifiedLoaderError extends Error { constructor(message, cause) { super(message); __publicField(this, "code", "UNIFIED_LOADER_ERROR"); this.name = "UnifiedLoaderError"; this.cause = cause; } } class ModuleLoadError extends Error { constructor(message, wasmType, cause) { super(message); this.wasmType = wasmType; __publicField(this, "code", "MODULE_LOAD_ERROR"); this.name = "ModuleLoadError"; this.cause = cause; } } async function loadUnifiedTagLibModule(options = {}) { const startTime = performance.now(); const runtime = detectRuntime(); if (options.debug) { console.log(`[UnifiedLoader] Detected runtime: ${runtime.environment}`); } const wasmType = await selectWasmType(runtime, options); if (options.debug) { console.log( `[UnifiedLoader] Selected ${wasmType} for ${runtime.environment}` ); } const { module, actualWasmType } = await loadModule( wasmType, runtime, options ); const unifiedModule = await createUnifiedModule( module, runtime, actualWasmType, startTime ); if (options.debug) { const initTime = performance.now() - startTime; console.log(`[UnifiedLoader] Initialized in ${initTime.toFixed(2)}ms`); } return unifiedModule; } async function selectWasmType(runtime, options) { if (options.forceWasmType) { return options.forceWasmType; } if (options.disableOptimizations) { return "emscripten"; } if (runtime.supportsFilesystem && await isWasmerAvailable()) { return "wasi"; } return "emscripten"; } async function loadModule(wasmType, _runtime, options) { if (wasmType === "wasi") { return await loadWasiModuleWithFallback(options); } else { return { module: await loadEmscriptenModule(options), actualWasmType: "emscripten" }; } } async function loadWasiModuleWithFallback(options) { try { await initializeWasmer(options.useInlineWasm); const wasiModule = await loadWasmerWasi({ wasmPath: options.wasmUrl || "./dist/taglib-wasi.wasm", useInlineWasm: options.useInlineWasm, debug: options.debug }); return { module: wasiModule, actualWasmType: "wasi" }; } catch (error) { if (options.debug) { console.warn( `[UnifiedLoader] WASI loading failed, falling back to Emscripten:`, error ); } return { module: await loadEmscriptenModule(options), actualWasmType: "emscripten" }; } } async function loadEmscriptenModule(options) { try { let createModule; try { const module2 = await import("../../build/taglib-wrapper.js"); createModule = module2.default; } catch { try { const module2 = await import("../../dist/taglib-wrapper.js"); createModule = module2.default; } catch { throw new ModuleLoadError( "Could not load Emscripten module from build or dist", "emscripten" ); } } const moduleConfig = {}; if (options.wasmBinary) { moduleConfig.wasmBinary = options.wasmBinary; } if (options.wasmUrl) { moduleConfig.locateFile = (path) => { return path.endsWith(".wasm") ? options.wasmUrl : path; }; } const module = await createModule(moduleConfig); return module; } catch (error) { throw new ModuleLoadError( `Failed to load Emscripten module: ${error}`, "emscripten", error ); } } async function createUnifiedModule(module, runtime, wasmType, startTime) { const isWasi = wasmType === "wasi"; const initTime = performance.now() - startTime; if (isWasi) { const wasiModule = module; const adapter = await createWasiAdapter(wasiModule); return Object.assign(adapter, { runtime, isWasi: true, isEmscripten: false, getPerformanceMetrics: () => ({ initTime, wasmType: "wasi", environment: runtime.environment, memoryUsage: wasiModule.memory.buffer.byteLength }) }); } else { const emscriptenModule = module; return { ...emscriptenModule, runtime, isWasi: false, isEmscripten: true, getPerformanceMetrics: () => ({ initTime, wasmType: "emscripten", environment: runtime.environment, memoryUsage: emscriptenModule.HEAP8?.buffer.byteLength }) }; } } async function createWasiAdapter(wasiModule) { const { WasiToTagLibAdapter } = await import("./wasi-adapter.js"); return new WasiToTagLibAdapter(wasiModule); } function isWasiAvailable() { const runtime = detectRuntime(); return runtime.wasmType === "wasi" && runtime.supportsFilesystem; } function getRecommendedConfig() { const runtime = detectRuntime(); if (runtime.environment === "browser") { return { forceWasmType: "emscripten", disableOptimizations: false }; } if (runtime.supportsFilesystem) { return { forceWasmType: "wasi", useInlineWasm: false, disableOptimizations: false }; } return { disableOptimizations: false }; } export { ModuleLoadError, UnifiedLoaderError, getRecommendedConfig, isWasiAvailable, loadUnifiedTagLibModule };