UNPKG

taglib-wasm

Version:

TagLib-Wasm is the universal tagging library for TypeScript/JavaScript platforms: Browsers, Node.js, Deno, Bun, Cloudflare Workers, and Electron apps

111 lines (110 loc) 3.75 kB
import { EnvironmentError, errorMessage, TagLibInitializationError } from "../errors/classes.js"; import { isDenoCompiled } from "./deno-detect.js"; import { checkNodeVersion } from "./detector.js"; async function loadTagLibModule(options) { const g = globalThis; const nodeVersion = g.process?.versions?.node; const versionError = checkNodeVersion(nodeVersion); if (versionError) { throw new EnvironmentError("Node.js", versionError, "WASI support"); } if (options?.forceWasmType === "wasi" && options?.wasmBinary) { throw new TagLibInitializationError( "wasmBinary is not supported by the WASI backend: it loads from a filesystem path or URL. Use wasmUrl, or omit forceWasmType to use the Emscripten backend", { forceWasmType: "wasi" } ); } if (!options?.wasmBinary && !options?.wasmUrl && !options?.forceWasmType && isDenoCompiled()) { const wasmBinary = await tryLoadEmbeddedWasm(); if (!wasmBinary) { console.warn( "[TagLib] Deno compile detected but embedded Wasm not found. Include taglib-web.wasm with: deno compile --include taglib-web.wasm" ); } return loadBufferModeTagLibModule({ ...options, forceWasmType: "emscripten", ...wasmBinary ? { wasmBinary } : {} }); } if (options?.forceWasmType === "emscripten") { return loadBufferModeTagLibModule(options); } try { const { loadUnifiedTagLibModule } = await import("./unified-loader/index.js"); return await loadUnifiedTagLibModule({ wasmBinary: options?.wasmBinary, wasmUrl: options?.wasmUrl, forceWasmType: options?.forceWasmType, debug: false }); } catch (error) { if (options?.forceWasmType === "wasi") { throw new TagLibInitializationError( `WASI backend failed to load: ${errorMessage(error)}. forceWasmType is "wasi", so the Emscripten fallback was not attempted`, { cause: error, forceWasmType: "wasi" } ); } console.warn( `[TagLib] Unified loader failed, falling back to buffer mode: ${errorMessage(error)}` ); return loadBufferModeTagLibModule(options || {}); } } async function loadBufferModeTagLibModule(options) { let createTagLibModule; try { const module2 = await import("../../taglib-wrapper.js"); createTagLibModule = module2.default; } catch { try { const module2 = await import("../../taglib-wrapper.js"); createTagLibModule = module2.default; } catch { throw new TagLibInitializationError( "Could not load taglib-wrapper.js from either ./build or ./dist" ); } } const moduleConfig = {}; if (options?.wasmBinary) { moduleConfig.wasmBinary = options.wasmBinary; } if (options?.wasmUrl) { moduleConfig.locateFile = (path) => { if (path.endsWith(".wasm")) { return options.wasmUrl; } return path; }; } else if (!options?.wasmBinary) { const wasmUrl = new URL("../../taglib-web.wasm", import.meta.url); moduleConfig.locateFile = (path) => path.endsWith(".wasm") ? wasmUrl.href : path; } const module = await createTagLibModule(moduleConfig); return module; } async function tryLoadEmbeddedWasm() { const strategies = [ // Relative to user's entry point (where --include embeds files) () => Deno.readFile(new URL("./taglib-web.wasm", Deno.mainModule)), // Relative to this library module () => Deno.readFile(new URL("./taglib-web.wasm", import.meta.url)), // CWD fallback (last resort — depends on where the binary is invoked) () => Deno.readFile("taglib-web.wasm") ]; for (const strategy of strategies) { try { return await strategy(); } catch { } } return null; } export { loadTagLibModule };