taglib-wasm 0.2.7 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.ts CHANGED
@@ -3,9 +3,14 @@
3
3
  */
4
4
 
5
5
  // Re-export commonly used classes from other modules
6
- export type { TagLibModule } from "./wasm-jsr.ts";
6
+ export type { TagLibModule } from "./wasm.ts";
7
7
  // Note: AudioFile is not needed for JSR exports
8
8
 
9
+ /**
10
+ * Supported file types
11
+ */
12
+ export type FileType = "MP3" | "MP4" | "FLAC" | "OGG" | "OPUS" | "WAV" | "AIFF" | "UNKNOWN";
13
+
9
14
  /**
10
15
  * Audio format types supported by TagLib
11
16
  */
@@ -40,8 +45,6 @@ export interface AudioProperties {
40
45
  readonly sampleRate: number;
41
46
  /** Number of audio channels */
42
47
  readonly channels: number;
43
- /** Audio format */
44
- readonly format: AudioFormat;
45
48
  }
46
49
 
47
50
  /**
package/src/wasm-jsr.ts CHANGED
@@ -1,280 +1,13 @@
1
1
  /**
2
- * @fileoverview JSR-compatible WASM loading for TagLib
3
- *
4
- * This version loads the WASM file directly without relying on Emscripten's JS file,
5
- * making it compatible with JSR publishing requirements.
6
- */
7
-
8
- import type { TagLibConfig } from "./types.ts";
9
-
10
- /**
11
- * JSR-compatible TagLib module interface
12
- */
13
- export interface TagLibModule {
14
- // Standard Emscripten memory arrays
15
- HEAPU8: Uint8Array;
16
- HEAP8: Int8Array;
17
- HEAP16: Int16Array;
18
- HEAP32: Int32Array;
19
- HEAPU16: Uint16Array;
20
- HEAPU32: Uint32Array;
21
- HEAPF32: Float32Array;
22
- HEAPF64: Float64Array;
23
-
24
- // Standard functions
25
- _malloc: (size: number) => number;
26
- _free: (ptr: number) => void;
27
- allocate: (array: Uint8Array, type: number) => number;
28
-
29
- // Allocation constants
30
- ALLOC_NORMAL: number;
31
- ALLOC_STACK: number;
32
- ALLOC_STATIC: number;
33
- ALLOC_DYNAMIC: number;
34
- ALLOC_NONE: number;
35
-
36
- // TagLib-specific functions
37
- _taglib_file_new_from_buffer: (data: number, size: number) => number;
38
- _taglib_file_delete: (fileId: number) => void;
39
- _taglib_file_save: (fileId: number) => number;
40
- _taglib_file_is_valid: (fileId: number) => number;
41
- _taglib_file_format: (fileId: number) => number;
42
- _taglib_file_tag: (fileId: number) => number;
43
- _taglib_tag_title: (tag: number) => number;
44
- _taglib_tag_artist: (tag: number) => number;
45
- _taglib_tag_album: (tag: number) => number;
46
- _taglib_tag_comment: (tag: number) => number;
47
- _taglib_tag_genre: (tag: number) => number;
48
- _taglib_tag_year: (tag: number) => number;
49
- _taglib_tag_track: (tag: number) => number;
50
- _taglib_tag_set_title: (tag: number, title: number) => void;
51
- _taglib_tag_set_artist: (tag: number, artist: number) => void;
52
- _taglib_tag_set_album: (tag: number, album: number) => void;
53
- _taglib_tag_set_comment: (tag: number, comment: number) => void;
54
- _taglib_tag_set_genre: (tag: number, genre: number) => void;
55
- _taglib_tag_set_year: (tag: number, year: number) => void;
56
- _taglib_tag_set_track: (tag: number, track: number) => void;
57
- _taglib_file_audioproperties: (fileId: number) => number;
58
- _taglib_audioproperties_length: (props: number) => number;
59
- _taglib_audioproperties_bitrate: (props: number) => number;
60
- _taglib_audioproperties_samplerate: (props: number) => number;
61
- _taglib_audioproperties_channels: (props: number) => number;
62
-
63
- // PropertyMap operations
64
- _taglib_file_properties_json: (fileId: number) => number;
65
- _taglib_file_set_properties_json: (fileId: number, json: number) => number;
66
- _taglib_file_get_property: (fileId: number, key: number) => number;
67
- _taglib_file_set_property: (fileId: number, key: number, value: number) => number;
68
-
69
- // MP4-specific operations
70
- _taglib_file_is_mp4: (fileId: number) => number;
71
- _taglib_mp4_get_item: (fileId: number, key: number) => number;
72
- _taglib_mp4_set_item: (fileId: number, key: number, value: number) => number;
73
- _taglib_mp4_remove_item: (fileId: number, key: number) => number;
74
- }
75
-
76
- /**
77
- * Load taglib-wasm module for JSR
78
- */
79
- export async function loadTagLibModuleJSR(
80
- config?: TagLibConfig,
81
- ): Promise<TagLibModule> {
82
- // Load WASM file as bytes (same file for all platforms)
83
- const wasmUrl = new URL("../build/taglib.wasm", import.meta.url);
84
- const wasmBytes = await fetch(wasmUrl).then((r) => r.arrayBuffer());
85
-
86
- // Create memory
87
- const memory = new WebAssembly.Memory({ initial: 256, maximum: 4096 });
88
-
89
- // Create heap views (initialized after memory is created)
90
- let HEAP8!: Int8Array;
91
- let HEAPU8!: Uint8Array;
92
- let HEAP16!: Int16Array;
93
- let HEAPU16!: Uint16Array;
94
- let HEAP32!: Int32Array;
95
- let HEAPU32!: Uint32Array;
96
- let HEAPF32!: Float32Array;
97
- let HEAPF64!: Float64Array;
98
-
99
- function updateMemoryViews() {
100
- const buffer = memory.buffer;
101
- HEAP8 = new Int8Array(buffer);
102
- HEAPU8 = new Uint8Array(buffer);
103
- HEAP16 = new Int16Array(buffer);
104
- HEAPU16 = new Uint16Array(buffer);
105
- HEAP32 = new Int32Array(buffer);
106
- HEAPU32 = new Uint32Array(buffer);
107
- HEAPF32 = new Float32Array(buffer);
108
- HEAPF64 = new Float64Array(buffer);
109
- }
110
-
111
- updateMemoryViews();
112
-
113
- // Import functions expected by the WASM module (still minified with -O3)
114
- const wasmImports = {
115
- a: {
116
- // a: ___cxa_throw
117
- a: (ptr: number, type: number, destructor: number) => {
118
- throw new Error('Exception thrown from WASM');
119
- },
120
- // e: __abort_js
121
- e: () => {
122
- throw new Error('Abort called from WASM');
123
- },
124
- // b: __tzset_js
125
- b: (timezone: number, daylight: number, std_name: number, dst_name: number) => {
126
- // Minimal timezone implementation
127
- },
128
- // f: _emscripten_resize_heap
129
- f: (requestedSize: number) => {
130
- const oldSize = HEAPU8.length;
131
- const newSize = Math.max(oldSize, requestedSize);
132
- const pages = Math.ceil((newSize - memory.buffer.byteLength) / 65536);
133
- try {
134
- memory.grow(pages);
135
- updateMemoryViews();
136
- return 1;
137
- } catch (e) {
138
- return 0;
139
- }
140
- },
141
- // c: _environ_get
142
- c: (__environ: number, environ_buf: number) => 0,
143
- // d: _environ_sizes_get
144
- d: (penviron_count: number, penviron_buf_size: number) => {
145
- HEAPU32[penviron_count >> 2] = 0;
146
- HEAPU32[penviron_buf_size >> 2] = 0;
147
- return 0;
148
- },
149
- // g: memory
150
- g: memory,
151
- },
152
- };
153
-
154
- // Instantiate WASM with the expected imports
155
- const wasmModule = await WebAssembly.instantiate(wasmBytes, wasmImports);
156
-
157
- const exports = wasmModule.instance.exports as any;
158
-
159
- // Update memory reference from exports (g is memory in minified version)
160
- if (exports.g) {
161
- updateMemoryViews();
162
- }
163
-
164
- // Initialize runtime (h is the init function in minified version)
165
- if (exports.h) {
166
- exports.h();
167
- }
168
-
169
- // Build the module interface
170
- const module: TagLibModule = {
171
- // Memory arrays
172
- HEAPU8,
173
- HEAP8,
174
- HEAP16,
175
- HEAP32,
176
- HEAPU16,
177
- HEAPU32,
178
- HEAPF32,
179
- HEAPF64,
180
-
181
- // Standard functions (minified with -O3)
182
- _malloc: exports.P || (() => {
183
- throw new Error("malloc not available");
184
- }),
185
- _free: exports.Q || (() => {}),
186
- allocate: (array: Uint8Array, type: number) => {
187
- const ptr = module._malloc(array.length);
188
- // Ensure we have the latest memory view
189
- if (memory.buffer !== module.HEAPU8.buffer) {
190
- updateMemoryViews();
191
- module.HEAPU8 = HEAPU8;
192
- module.HEAP8 = HEAP8;
193
- module.HEAP16 = HEAP16;
194
- module.HEAP32 = HEAP32;
195
- module.HEAPU16 = HEAPU16;
196
- module.HEAPU32 = HEAPU32;
197
- module.HEAPF32 = HEAPF32;
198
- module.HEAPF64 = HEAPF64;
199
- }
200
- module.HEAPU8.set(array, ptr);
201
- return ptr;
202
- },
203
-
204
- // Allocation constants
205
- ALLOC_NORMAL: 0,
206
- ALLOC_STACK: 1,
207
- ALLOC_STATIC: 2,
208
- ALLOC_DYNAMIC: 3,
209
- ALLOC_NONE: 4,
210
-
211
- // TagLib functions - map from minified WASM exports (with -O3)
212
- _taglib_file_new_from_buffer: exports.i,
213
- _taglib_file_delete: exports.j,
214
- _taglib_file_save: exports.k,
215
- _taglib_file_is_valid: exports.l,
216
- _taglib_file_format: exports.m,
217
- _taglib_file_tag: exports.n,
218
- _taglib_tag_title: exports.o,
219
- _taglib_tag_artist: exports.p,
220
- _taglib_tag_album: exports.q,
221
- _taglib_tag_comment: exports.r,
222
- _taglib_tag_genre: exports.s,
223
- _taglib_tag_year: exports.t,
224
- _taglib_tag_track: exports.u,
225
- _taglib_tag_set_title: exports.v,
226
- _taglib_tag_set_artist: exports.w,
227
- _taglib_tag_set_album: exports.x,
228
- _taglib_tag_set_comment: exports.y,
229
- _taglib_tag_set_genre: exports.z,
230
- _taglib_tag_set_year: exports.A,
231
- _taglib_tag_set_track: exports.B,
232
- _taglib_file_audioproperties: exports.C,
233
- _taglib_audioproperties_length: exports.D,
234
- _taglib_audioproperties_bitrate: exports.E,
235
- _taglib_audioproperties_samplerate: exports.F,
236
- _taglib_audioproperties_channels: exports.G,
237
-
238
- // PropertyMap operations
239
- _taglib_file_properties_json: exports.H,
240
- _taglib_file_set_properties_json: exports.I,
241
- _taglib_file_get_property: exports.J,
242
- _taglib_file_set_property: exports.K,
243
-
244
- // MP4-specific operations
245
- _taglib_file_is_mp4: exports.L,
246
- _taglib_mp4_get_item: exports.M,
247
- _taglib_mp4_set_item: exports.N,
248
- _taglib_mp4_remove_item: exports.O,
249
- };
250
-
251
- return module;
252
- }
253
-
254
- /**
255
- * Convert JavaScript string to C string pointer
256
- */
257
- export function jsToCStringJSR(module: TagLibModule, str: string): number {
258
- const encoder = new TextEncoder();
259
- const bytes = encoder.encode(str + "\0");
260
- return module.allocate(bytes, module.ALLOC_NORMAL);
261
- }
262
-
263
- /**
264
- * Convert C string pointer to JavaScript string
265
- */
266
- export function cStringToJSJSR(module: TagLibModule, ptr: number): string {
267
- if (ptr === 0) return "";
268
-
269
- const bytes: number[] = [];
270
- let i = 0;
271
- while (true) {
272
- const byte = module.HEAPU8[ptr + i];
273
- if (byte === undefined || byte === 0) break;
274
- bytes.push(byte);
275
- i++;
276
- }
277
-
278
- const decoder = new TextDecoder();
279
- return decoder.decode(new Uint8Array(bytes));
280
- }
2
+ * @fileoverview JSR-compatible WASM module interface (no Node.js dependencies)
3
+ */
4
+
5
+ // Re-export types only (no implementation imports)
6
+ export type {
7
+ EmscriptenModule,
8
+ FileHandle,
9
+ TagWrapper,
10
+ AudioPropertiesWrapper,
11
+ TagLibModule,
12
+ WasmModule,
13
+ } from "./wasm.ts";
package/src/wasm.ts CHANGED
@@ -1,263 +1,94 @@
1
1
  /**
2
- * @fileoverview WebAssembly module interface and loading utilities
2
+ * @fileoverview WebAssembly module interface types for Emscripten
3
3
  */
4
4
 
5
- import type { TagLibConfig } from "./types.ts";
6
-
7
- /**
8
- * Emscripten module interface for taglib-wasm
9
- */
10
- export interface TagLibModule {
11
- // Emscripten standard properties
12
- HEAPU8: Uint8Array;
5
+ // Basic Emscripten module interface
6
+ export interface EmscriptenModule {
7
+ // Memory
13
8
  HEAP8: Int8Array;
14
9
  HEAP16: Int16Array;
15
10
  HEAP32: Int32Array;
11
+ HEAPU8: Uint8Array;
16
12
  HEAPU16: Uint16Array;
17
13
  HEAPU32: Uint32Array;
18
14
  HEAPF32: Float32Array;
19
15
  HEAPF64: Float64Array;
20
-
21
- // Standard Emscripten functions
22
- cwrap: (ident: string, returnType: string, argTypes: string[]) => any;
23
- ccall: (
24
- ident: string,
25
- returnType: string,
26
- argTypes: string[],
27
- args: any[],
28
- ) => any;
29
- getValue: (ptr: number, type: string) => number;
30
- setValue: (ptr: number, value: number, type: string) => void;
31
- addFunction: (func: Function, signature: string) => number;
32
- removeFunction: (funcPtr: number) => void;
33
-
34
- // Memory allocation functions
35
- _malloc: (size: number) => number;
36
- _free: (ptr: number) => void;
37
- allocate: (array: Uint8Array, type: number) => number;
38
-
39
- // Allocation types
40
- ALLOC_NORMAL: number;
41
- ALLOC_STACK: number;
42
- ALLOC_STATIC: number;
43
- ALLOC_DYNAMIC: number;
44
- ALLOC_NONE: number;
45
-
46
- // File operations
47
- _taglib_file_new_from_buffer: (data: number, size: number) => number;
48
- _taglib_file_delete: (fileId: number) => void;
49
- _taglib_file_save: (fileId: number) => number;
50
- _taglib_file_is_valid: (fileId: number) => number;
51
- _taglib_file_format: (fileId: number) => number;
52
-
53
- // Tag operations
54
- _taglib_file_tag: (fileId: number) => number;
55
- _taglib_tag_title: (tag: number) => number;
56
- _taglib_tag_artist: (tag: number) => number;
57
- _taglib_tag_album: (tag: number) => number;
58
- _taglib_tag_comment: (tag: number) => number;
59
- _taglib_tag_genre: (tag: number) => number;
60
- _taglib_tag_year: (tag: number) => number;
61
- _taglib_tag_track: (tag: number) => number;
62
-
63
- _taglib_tag_set_title: (tag: number, title: number) => void;
64
- _taglib_tag_set_artist: (tag: number, artist: number) => void;
65
- _taglib_tag_set_album: (tag: number, album: number) => void;
66
- _taglib_tag_set_comment: (tag: number, comment: number) => void;
67
- _taglib_tag_set_genre: (tag: number, genre: number) => void;
68
- _taglib_tag_set_year: (tag: number, year: number) => void;
69
- _taglib_tag_set_track: (tag: number, track: number) => void;
70
-
71
- // Audio properties
72
- _taglib_file_audioproperties: (fileId: number) => number;
73
- _taglib_audioproperties_length: (props: number) => number;
74
- _taglib_audioproperties_bitrate: (props: number) => number;
75
- _taglib_audioproperties_samplerate: (props: number) => number;
76
- _taglib_audioproperties_channels: (props: number) => number;
77
-
78
- // PropertyMap operations
79
- _taglib_file_properties_json: (fileId: number) => number;
80
- _taglib_file_set_properties_json: (fileId: number, json: number) => number;
81
- _taglib_file_get_property: (fileId: number, key: number) => number;
82
- _taglib_file_set_property: (fileId: number, key: number, value: number) => number;
83
-
84
- // MP4-specific operations
85
- _taglib_file_is_mp4: (fileId: number) => number;
86
- _taglib_mp4_get_item: (fileId: number, key: number) => number;
87
- _taglib_mp4_set_item: (fileId: number, key: number, value: number) => number;
88
- _taglib_mp4_remove_item: (fileId: number, key: number) => number;
89
-
90
- // String utilities
91
- _taglib_string_new: (str: number) => number;
92
- _taglib_string_delete: (str: number) => void;
93
- _taglib_string_to_cstring: (str: number) => number;
94
-
95
- // Memory management functions already defined above
16
+
17
+ // Memory management
18
+ _malloc(size: number): number;
19
+ _free(ptr: number): void;
20
+ allocate?(data: number[] | Uint8Array, allocator: number): number;
21
+ ALLOC_NORMAL?: number;
22
+
23
+ // String conversion
24
+ ccall?(ident: string, returnType: string, argTypes: string[], args: any[]): any;
25
+ cwrap?(ident: string, returnType: string, argTypes: string[]): (...args: any[]) => any;
26
+
27
+ // File system (if enabled)
28
+ FS?: any;
29
+
30
+ // Runtime
31
+ then?(callback: (module: EmscriptenModule) => void): void;
32
+ onRuntimeInitialized?: () => void;
96
33
  }
97
34
 
98
- /**
99
- * Default configuration for taglib-wasm module
100
- */
101
- const DEFAULT_CONFIG: Required<TagLibConfig> = {
102
- memory: {
103
- initial: 16 * 1024 * 1024, // 16MB
104
- maximum: 256 * 1024 * 1024, // 256MB
105
- },
106
- debug: false,
107
- };
108
-
109
- /**
110
- * Load and initialize the TagLib WebAssembly module
111
- */
112
- export async function loadTagLibModule(
113
- config: TagLibConfig = {},
114
- ): Promise<TagLibModule> {
115
- const mergedConfig = { ...DEFAULT_CONFIG, ...config };
116
-
117
- // Detect runtime environment
118
- const isNode = typeof (globalThis as any).process !== "undefined" && (globalThis as any).process.versions?.node;
119
- const isDeno = typeof (globalThis as any).Deno !== "undefined";
120
-
121
- let wasmPath: string;
122
-
123
- if (isDeno) {
124
- // Deno: Use file system path
125
- wasmPath = new URL("../build/taglib.wasm", import.meta.url).pathname;
126
- } else if (isNode) {
127
- // Node.js: Use require.resolve or fs path
128
- wasmPath = new URL("../build/taglib.wasm", import.meta.url).pathname;
129
- } else {
130
- // Browser: Relative path
131
- wasmPath = "./taglib.wasm";
132
- }
133
-
134
- // Load WASM binary
135
- let wasmBinary: Uint8Array;
136
-
137
- if (isDeno) {
138
- wasmBinary = await (globalThis as any).Deno.readFile(wasmPath);
139
- } else if (isNode) {
140
- const fs = await import("node:fs");
141
- wasmBinary = await fs.promises.readFile(wasmPath);
142
- } else {
143
- // Browser
144
- const response = await fetch(wasmPath);
145
- wasmBinary = new Uint8Array(await response.arrayBuffer());
146
- }
147
-
148
- // Create Emscripten module configuration
149
- const moduleConfig = {
150
- wasmBinary,
151
- wasmMemory: new WebAssembly.Memory({
152
- initial: mergedConfig.memory.initial! / (64 * 1024),
153
- maximum: mergedConfig.memory.maximum! / (64 * 1024),
154
- }),
155
- print: mergedConfig.debug ? console.log : () => {},
156
- printErr: mergedConfig.debug ? console.error : () => {},
157
- onRuntimeInitialized: () => {
158
- if (mergedConfig.debug) {
159
- console.log("taglib-wasm module initialized");
160
- }
161
- },
162
- };
163
-
164
- // Load the Emscripten-generated module
165
- try {
166
- // For Deno, we need to handle the CommonJS-style export
167
- let TagLibWASM: any;
168
-
169
- if (isDeno) {
170
- // In Deno, read and evaluate the JS file
171
- const jsContent = await (globalThis as any).Deno.readTextFile(
172
- new URL("../build/taglib.js", import.meta.url).pathname,
173
- );
174
-
175
- // Create a minimal CommonJS environment
176
- const exports = {} as any;
177
- const module = { exports } as any;
178
- const define = undefined;
179
- const require = (name: string) => {
180
- if (name === "fs") {
181
- return {
182
- readFileSync: (path: string) => (globalThis as any).Deno.readFileSync(path),
183
- };
184
- }
185
- throw new Error(`Module ${name} not found`);
186
- };
187
-
188
- // Add a minimal process object for Node.js compatibility
189
- const process = {
190
- versions: {},
191
- argv: [],
192
- type: "deno",
193
- };
194
-
195
- // Execute the WASM JS with the proper context
196
- const func = new Function(
197
- "exports",
198
- "module",
199
- "define",
200
- "require",
201
- "process",
202
- "__dirname",
203
- "__filename",
204
- jsContent +
205
- '\nreturn typeof TagLibWASM !== "undefined" ? TagLibWASM : module.exports;',
206
- );
207
-
208
- TagLibWASM = func(exports, module, define, require, process, "", "");
209
- } else {
210
- // For Node.js and browsers, use normal import
211
- const wasmModule = await import("../build/taglib.js");
212
- TagLibWASM = wasmModule.default || wasmModule;
213
- }
214
-
215
- if (typeof TagLibWASM !== "function") {
216
- throw new Error("Failed to load taglib-wasm module");
217
- }
218
-
219
- const wasmInstance = await TagLibWASM(moduleConfig);
220
-
221
- // Ensure proper memory arrays are set up
222
- if (!wasmInstance.HEAPU8) {
223
- // Manual setup if not automatically created
224
- const buffer = wasmInstance.buffer || wasmInstance.wasmMemory?.buffer;
225
- if (buffer) {
226
- wasmInstance.HEAPU8 = new Uint8Array(buffer);
227
- wasmInstance.HEAP8 = new Int8Array(buffer);
228
- wasmInstance.HEAP16 = new Int16Array(buffer);
229
- wasmInstance.HEAP32 = new Int32Array(buffer);
230
- wasmInstance.HEAPU16 = new Uint16Array(buffer);
231
- wasmInstance.HEAPU32 = new Uint32Array(buffer);
232
- wasmInstance.HEAPF32 = new Float32Array(buffer);
233
- wasmInstance.HEAPF64 = new Float64Array(buffer);
234
- }
235
- }
236
-
237
- return wasmInstance as TagLibModule;
238
- } catch (error) {
239
- throw new Error(`Failed to load taglib-wasm: ${(error as Error).message}`);
240
- }
35
+ // Embind class interfaces
36
+ export interface FileHandle {
37
+ loadFromBuffer(data: Uint8Array): boolean;
38
+ isValid(): boolean;
39
+ save(): boolean;
40
+ getFormat(): string;
41
+ getProperties(): any;
42
+ setProperties(props: any): void;
43
+ getProperty(key: string): string;
44
+ setProperty(key: string, value: string): void;
45
+ isMP4(): boolean;
46
+ getMP4Item(key: string): string;
47
+ setMP4Item(key: string, value: string): void;
48
+ removeMP4Item(key: string): void;
49
+ getTag(): TagWrapper;
50
+ getAudioProperties(): AudioPropertiesWrapper;
241
51
  }
242
52
 
243
- /**
244
- * Convert a C string pointer to JavaScript string
245
- */
246
- export function cStringToJS(module: TagLibModule, ptr: number): string {
247
- if (ptr === 0) return "";
53
+ export interface TagWrapper {
54
+ title(): string;
55
+ artist(): string;
56
+ album(): string;
57
+ comment(): string;
58
+ genre(): string;
59
+ year(): number;
60
+ track(): number;
61
+ setTitle(value: string): void;
62
+ setArtist(value: string): void;
63
+ setAlbum(value: string): void;
64
+ setComment(value: string): void;
65
+ setGenre(value: string): void;
66
+ setYear(value: number): void;
67
+ setTrack(value: number): void;
68
+ }
248
69
 
249
- const view = new Uint8Array(module.HEAPU8.buffer, ptr);
250
- let length = 0;
251
- while (view[length] !== 0) length++;
70
+ export interface AudioPropertiesWrapper {
71
+ lengthInSeconds(): number;
72
+ lengthInMilliseconds(): number;
73
+ bitrate(): number;
74
+ sampleRate(): number;
75
+ channels(): number;
76
+ }
252
77
 
253
- return new TextDecoder().decode(view.subarray(0, length));
78
+ export interface TagLibModule extends EmscriptenModule {
79
+ // Embind classes
80
+ FileHandle: new () => FileHandle;
81
+ TagWrapper: new () => TagWrapper;
82
+ AudioPropertiesWrapper: new () => AudioPropertiesWrapper;
83
+
84
+ // Embind functions
85
+ createFileHandle(): FileHandle;
254
86
  }
255
87
 
256
- /**
257
- * Convert JavaScript string to C string
258
- */
259
- export function jsToCString(module: TagLibModule, str: string): number {
260
- const encoder = new TextEncoder();
261
- const bytes = encoder.encode(str + "\0");
262
- return module.allocate(bytes, module.ALLOC_NORMAL);
88
+ export interface WasmModule extends EmscriptenModule {
89
+ // Alias for compatibility
90
+ FileHandle?: new () => FileHandle;
91
+ createFileHandle?(): FileHandle;
263
92
  }
93
+
94
+ // Module loading function removed for modular imports