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

198 lines (197 loc) 6.64 kB
var __defProp = Object.defineProperty; var __typeError = (msg) => { throw TypeError(msg); }; 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); var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var _wasm, _ptr, _size, _wasm2, _allocs; import { MemoryError } from "../errors/classes.js"; import { TagLibError } from "../errors/base.js"; const heapViews = (mem) => ({ u8: new Uint8Array(mem.buffer), i8: new Int8Array(mem.buffer), u16: new Uint16Array(mem.buffer), i16: new Int16Array(mem.buffer), u32: new Uint32Array(mem.buffer), dv: new DataView(mem.buffer) }); class WasmAlloc { constructor(wasm, size) { __privateAdd(this, _wasm); __privateAdd(this, _ptr); __privateAdd(this, _size); __privateSet(this, _wasm, wasm); __privateSet(this, _ptr, wasm.malloc(size)); if (__privateGet(this, _ptr) === 0) { throw new MemoryError( `malloc returned null. Requested size: ${size} bytes` ); } __privateSet(this, _size, size); } get ptr() { return __privateGet(this, _ptr); } get size() { return __privateGet(this, _size); } /** * Write bytes to allocation */ write(bytes, offset = 0) { if (offset + bytes.length > __privateGet(this, _size)) { throw new MemoryError( `Write exceeds allocation bounds. Offset: ${offset}, size: ${bytes.byteLength}, allocated: ${__privateGet(this, _size)}` ); } const { u8 } = heapViews(__privateGet(this, _wasm).memory); u8.set(bytes, __privateGet(this, _ptr) + offset); } /** * Read bytes from allocation (zero-copy view) */ read(len = __privateGet(this, _size), offset = 0) { if (offset + len > __privateGet(this, _size)) { throw new MemoryError( `Read exceeds allocation bounds. Offset: ${offset}, size: ${len}, allocated: ${__privateGet(this, _size)}` ); } const { u8 } = heapViews(__privateGet(this, _wasm).memory); return u8.subarray(__privateGet(this, _ptr) + offset, __privateGet(this, _ptr) + offset + len); } /** * Write C string with null terminator. * Accepts a string or pre-encoded UTF-8 bytes (avoids double-encoding). */ writeCString(input) { const bytes = typeof input === "string" ? new TextEncoder().encode(input) : input; if (bytes.length >= __privateGet(this, _size)) { throw new MemoryError( `String too long for allocation. String: ${bytes.byteLength} bytes, allocated: ${__privateGet(this, _size)}` ); } const { u8 } = heapViews(__privateGet(this, _wasm).memory); u8.set(bytes, __privateGet(this, _ptr)); u8[__privateGet(this, _ptr) + bytes.length] = 0; } /** * Read C string (null-terminated) */ readCString() { const { u8 } = heapViews(__privateGet(this, _wasm).memory); let end = __privateGet(this, _ptr); while (end < __privateGet(this, _ptr) + __privateGet(this, _size) && u8[end] !== 0) { end++; } return new TextDecoder().decode(u8.subarray(__privateGet(this, _ptr), end)); } /** * Write 32-bit integer (little-endian) */ writeUint32(value, offset = 0) { if (offset + 4 > __privateGet(this, _size)) { throw new MemoryError( `Write exceeds allocation bounds. Offset: ${offset}, size: 4, allocated: ${__privateGet(this, _size)}` ); } const { dv } = heapViews(__privateGet(this, _wasm).memory); dv.setUint32(__privateGet(this, _ptr) + offset, value, true); } /** * Read 32-bit integer (little-endian) */ readUint32(offset = 0) { if (offset + 4 > __privateGet(this, _size)) { throw new MemoryError( `Read exceeds allocation bounds. Offset: ${offset}, size: 4, allocated: ${__privateGet(this, _size)}` ); } const { dv } = heapViews(__privateGet(this, _wasm).memory); return dv.getUint32(__privateGet(this, _ptr) + offset, true); } /** * Automatic cleanup via Symbol.dispose */ [Symbol.dispose]() { if (__privateGet(this, _ptr) !== 0) { __privateGet(this, _wasm).free(__privateGet(this, _ptr)); __privateSet(this, _ptr, 0); } } } _wasm = new WeakMap(); _ptr = new WeakMap(); _size = new WeakMap(); class WasmArena { constructor(wasm) { __privateAdd(this, _wasm2); __privateAdd(this, _allocs, []); __privateSet(this, _wasm2, wasm); } /** * Allocate memory within this arena */ alloc(size) { const allocation = new WasmAlloc(__privateGet(this, _wasm2), size); __privateGet(this, _allocs).push(allocation); return allocation; } /** * Allocate and write string (encodes once) */ allocString(str) { const bytes = new TextEncoder().encode(str); const allocation = this.alloc(bytes.length + 1); allocation.writeCString(bytes); return allocation; } /** * Allocate and write buffer */ allocBuffer(buffer) { const allocation = this.alloc(buffer.length); allocation.write(buffer); return allocation; } /** * Allocate 32-bit integer */ allocUint32(value = 0) { const allocation = this.alloc(4); allocation.writeUint32(value); return allocation; } /** * Automatic cleanup of all allocations */ [Symbol.dispose]() { for (const alloc of __privateGet(this, _allocs)) { alloc[Symbol.dispose](); } __privateGet(this, _allocs).length = 0; } } _wasm2 = new WeakMap(); _allocs = new WeakMap(); class WasmMemoryError extends TagLibError { constructor(message, operation, errorCode) { super( "WASM_MEMORY", `${operation}: ${message}${errorCode === void 0 ? "" : ` (code ${errorCode})`}` ); __publicField(this, "operation", operation); __publicField(this, "errorCode", errorCode); this.name = "WasmMemoryError"; Object.setPrototypeOf(this, WasmMemoryError.prototype); } } export { WasmAlloc, WasmArena, WasmMemoryError, heapViews };