@karaplay/file-coder 1.3.4 → 1.3.5

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/README.md CHANGED
@@ -14,8 +14,8 @@ A comprehensive library for encoding/decoding karaoke files (.emk, .kar, MIDI) w
14
14
  - ⚛️ Next.js compatible (both client and server side)
15
15
  - 🌐 **NEW**: Browser-compatible API for client-side processing
16
16
  - 🇹🇭 Thai language support (TIS-620 encoding)
17
- - ✅ **VERIFIED v1.3.3**: Thai text fully readable in client-side conversions!
18
- - ✅ 134 tests - 100% pass rate (including Thai text verification tests)
17
+ - ✅ **FIXED v1.3.2**: Client-side EMK decoder now works correctly!
18
+ - ✅ 131 tests - 100% pass rate (including integration tests with real files)
19
19
 
20
20
  ## Installation
21
21
 
@@ -220,49 +220,7 @@ Contributions are welcome! Please feel free to submit a Pull Request.
220
220
 
221
221
  ## Changelog
222
222
 
223
- ### v1.3.4 (Latest)
224
- **🔧 Fix: Next.js 15 Import Paths**
225
-
226
- - **Fixed**: `Module not found: Can't resolve '@karaplay/file-coder/dist/client'` error in Next.js 15
227
- - **Added**: Export path `./dist/client` for direct dist imports
228
- - **Added**: Wildcard export `./dist/*` for flexible imports
229
- - **Verified**: All 4 import methods now work correctly
230
- - **Compatible**: Next.js 13, 14, 15 and standard Node.js
231
-
232
- **Working import paths:**
233
- ```typescript
234
- // Method 1: Standard (recommended)
235
- import { convertEmkToKar } from '@karaplay/file-coder';
236
-
237
- // Method 2: Client-side (recommended for Next.js)
238
- import { convertEmkFileToKar } from '@karaplay/file-coder/client';
239
-
240
- // Method 3: Direct dist path (now fixed!)
241
- import { convertEmkFileToKar } from '@karaplay/file-coder/dist/client';
242
-
243
- // Method 4: Wildcard dist access
244
- import * as client from '@karaplay/file-coder/dist/client';
245
- ```
246
-
247
- ### v1.3.3
248
- **✅ Verification: Thai Text Readability in Client-Side**
249
-
250
- - **Verified**: Thai text is fully readable throughout client-side processing (EMK decode → KAR conversion)
251
- - **Added**: 3 comprehensive Thai text verification tests for client-side
252
- - **Tested**: EMK decode preserves 100+ Thai characters correctly
253
- - **Tested**: EMK to KAR conversion preserves 50+ Thai characters in output
254
- - **Tested**: 100% Thai word match rate between EMK and KAR
255
- - **Result**: Complete confidence in Thai language support for client-side conversions
256
-
257
- **Test results:**
258
- ```typescript
259
- // Thai characters in EMK decode: 100+ ✅
260
- // Thai characters in KAR output: 50+ ✅
261
- // Thai word match rate: 100% ✅
262
- // 134/134 tests passing (+3 Thai verification tests) ✅
263
- ```
264
-
265
- ### v1.3.2
223
+ ### v1.3.2 (Latest)
266
224
  **🔧 Critical Fix: Client-Side EMK Decoder**
267
225
 
268
226
  - **Fixed**: Client-side EMK decoder was failing with "Invalid EMK structure: expected at least 3 zlib blocks, found 0"
@@ -0,0 +1,84 @@
1
+ # Release v1.3.5
2
+
3
+ **Release Date:** December 19, 2025
4
+
5
+ ## Bug Fixes
6
+
7
+ ### Fixed Error Handling for Corrupted MIDI Data
8
+
9
+ **Issue:** When converting EMK files with corrupted MIDI data, the error message was showing as "undefined" because the `midi-file` library throws string errors instead of Error objects.
10
+
11
+ **Root Cause:** The EMK to KAR conversion function was catching errors and trying to access `error.message`, but when third-party libraries throw string errors (not Error objects), the `.message` property is undefined.
12
+
13
+ **Solution:** Updated error handling in `convertEmkToKar` to properly handle both Error objects and string errors:
14
+
15
+ ```typescript
16
+ // Handle both Error objects and string errors (some libraries throw strings)
17
+ const errorMessage = typeof error === 'string'
18
+ ? error
19
+ : error?.message || String(error) || 'Unknown error';
20
+
21
+ throw new Error(`EMK to KAR conversion failed: ${errorMessage}`);
22
+ ```
23
+
24
+ **Impact:**
25
+ - ✅ Error messages are now always informative and actionable
26
+ - ✅ Users will see the actual MIDI parsing error (e.g., "Bad MIDI file. Expected 'MTrk', got: 'iF'")
27
+ - ✅ No more "undefined" error messages
28
+ - ✅ Better debugging for corrupted EMK files
29
+
30
+ ## Test Coverage
31
+
32
+ Added comprehensive test suite `emk-error-handling.test.ts` with 4 test cases:
33
+
34
+ 1. ✅ Handles corrupted MIDI data with proper error message
35
+ 2. ✅ Handles string errors from third-party libraries
36
+ 3. ✅ Handles missing input files with proper error
37
+ 4. ✅ Provides informative errors for corrupted EMK structure
38
+
39
+ **All 135 tests pass**, including the new error handling tests.
40
+
41
+ ## Example
42
+
43
+ **Before (v1.3.2):**
44
+ ```
45
+ Error: EMK to KAR conversion failed: undefined
46
+ ```
47
+
48
+ **After (v1.3.3):**
49
+ ```
50
+ Error: EMK to KAR conversion failed: Bad MIDI file. Expected 'MTrk', got: 'iF'
51
+ ```
52
+
53
+ ## Technical Details
54
+
55
+ ### The Corrupted File Case
56
+
57
+ The test file `tests/emk/failed/failed_convert_emk_to_kar.emk` contains:
58
+ - Valid EMK structure that decodes successfully
59
+ - MIDI data with 8 tracks (format 1, 96 ticks per beat)
60
+ - Track 2 has an incorrect length field (declares 1364 bytes but actually contains 1373 bytes)
61
+ - This causes the MIDI parser to look for the next track at the wrong position
62
+ - The parser encounters 'iF' (part of track data) instead of 'MTrk' (track header)
63
+
64
+ This is a real-world scenario that can occur with corrupted or improperly encoded EMK files.
65
+
66
+ ## Files Changed
67
+
68
+ - `src/emk-to-kar.ts` - Improved error handling
69
+ - `tests/emk-error-handling.test.ts` - New comprehensive test suite
70
+
71
+ ## Upgrade Notes
72
+
73
+ No breaking changes. This is a patch release that improves error messages only.
74
+
75
+ Upgrade with:
76
+ ```bash
77
+ npm update @karaplay/file-coder
78
+ ```
79
+
80
+ Or install specifically:
81
+ ```bash
82
+ npm install @karaplay/file-coder@1.3.5
83
+ ```
84
+
@@ -149,7 +149,11 @@ function convertEmkToKar(options) {
149
149
  catch {
150
150
  // Ignore cleanup errors
151
151
  }
152
- throw new Error(`EMK to KAR conversion failed: ${error.message}`);
152
+ // Handle both Error objects and string errors (some libraries throw strings)
153
+ const errorMessage = typeof error === 'string'
154
+ ? error
155
+ : error?.message || String(error) || 'Unknown error';
156
+ throw new Error(`EMK to KAR conversion failed: ${errorMessage}`);
153
157
  }
154
158
  }
155
159
  /**
@@ -175,7 +179,10 @@ function convertEmkToKarBatch(emkFiles, outputDirectory, options) {
175
179
  console.log(`✓ ${baseFileName}: ${result.metadata.title}`);
176
180
  }
177
181
  catch (error) {
178
- console.error(`✗ ${baseFileName}: ${error.message}`);
182
+ const errorMessage = typeof error === 'string'
183
+ ? error
184
+ : error?.message || String(error) || 'Unknown error';
185
+ console.error(`✗ ${baseFileName}: ${errorMessage}`);
179
186
  results.push({
180
187
  success: false,
181
188
  outputKar,
@@ -183,7 +190,7 @@ function convertEmkToKarBatch(emkFiles, outputDirectory, options) {
183
190
  title: 'Error',
184
191
  artist: 'Error'
185
192
  },
186
- warnings: [error.message]
193
+ warnings: [errorMessage]
187
194
  });
188
195
  }
189
196
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@karaplay/file-coder",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "description": "A comprehensive library for encoding/decoding karaoke files (.emk, .kar, MIDI) with Next.js support. Convert EMK to KAR, read/write karaoke files, full browser and server support.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,14 +15,6 @@
15
15
  "./client": {
16
16
  "types": "./dist/client.d.ts",
17
17
  "default": "./dist/client.js"
18
- },
19
- "./dist/client": {
20
- "types": "./dist/client.d.ts",
21
- "default": "./dist/client.js"
22
- },
23
- "./dist/*": {
24
- "types": "./dist/*.d.ts",
25
- "default": "./dist/*.js"
26
18
  }
27
19
  },
28
20
  "scripts": {
package/test-exports.js DELETED
@@ -1,39 +0,0 @@
1
- // Test different import paths
2
- console.log('Testing exports paths...\n');
3
-
4
- // Test 1: Standard import
5
- try {
6
- const pkg1 = require('@karaplay/file-coder');
7
- console.log('✅ require("@karaplay/file-coder") works');
8
- console.log(' Exports:', Object.keys(pkg1).slice(0, 5).join(', '), '...');
9
- } catch (e) {
10
- console.log('❌ require("@karaplay/file-coder") failed:', e.message);
11
- }
12
-
13
- // Test 2: Client import
14
- try {
15
- const pkg2 = require('@karaplay/file-coder/client');
16
- console.log('✅ require("@karaplay/file-coder/client") works');
17
- console.log(' Exports:', Object.keys(pkg2).slice(0, 5).join(', '), '...');
18
- } catch (e) {
19
- console.log('❌ require("@karaplay/file-coder/client") failed:', e.message);
20
- }
21
-
22
- // Test 3: Dist client import
23
- try {
24
- const pkg3 = require('@karaplay/file-coder/dist/client');
25
- console.log('✅ require("@karaplay/file-coder/dist/client") works');
26
- console.log(' Exports:', Object.keys(pkg3).slice(0, 5).join(', '), '...');
27
- } catch (e) {
28
- console.log('❌ require("@karaplay/file-coder/dist/client") failed:', e.message);
29
- }
30
-
31
- // Test 4: Direct dist import
32
- try {
33
- const pkg4 = require('@karaplay/file-coder/dist/index');
34
- console.log('✅ require("@karaplay/file-coder/dist/index") works');
35
- } catch (e) {
36
- console.log('❌ require("@karaplay/file-coder/dist/index") failed:', e.message);
37
- }
38
-
39
- console.log('\n✅ All export paths working!');