These are blocking issues that prevent the library from working properly.
- Priority: CRITICAL
- Issue: Files exceed the 250-line limit per CLAUDE.md guidelines
- Files:
src/taglib.ts(1229 lines) - Exceeds limit by 979 linessrc/types.ts(639 lines) - Exceeds limit by 389 linessrc/errors.ts(264 lines) - Slightly over by 14 lines
- Tasks:
- Extract interface definitions from
taglib.tsinto separate files - Move metadata mapping logic from
types.tsto a dedicated module - Consider splitting error classes into separate files by category
- Extract interface definitions from
- Impact: Compliance with SonarQube metrics, better maintainability
-
Priority: CRITICAL
-
Issue: Missing try-finally blocks for WebAssembly memory cleanup
-
Current Pattern (incorrect):
dataPtr = this.module._malloc(buffer.length); this.module.HEAPU8.set(buffer, dataPtr); // ... operations ... // No explicit _free() call found
-
Required Pattern:
const ptr = module._malloc(data.length); try { module.HEAPU8.set(data, ptr); // Process data return result; } finally { module._free(ptr); }
-
Tasks:
- Audit all
_malloc()usage in the codebase - Add try-finally blocks to ensure
_free()is always called - Update workers.ts, taglib.ts, and any other files using direct memory allocation
- Audit all
-
Impact: Prevent memory leaks, better resource management
These should be addressed before widespread adoption to improve developer experience.
- Problem: RESOLVED - Test suite now runs successfully in Deno
- Solution: Added sed patch in build script to convert
import("module")toimport("node:module") - Tests Status:
- 25/25 tests passing
- Test coverage includes: Core API, Simple API, Workers API, Performance, Format tests, Integration tests
- All audio formats (WAV, MP3, FLAC, OGG, M4A) working correctly
- Priority: MEDIUM
- Tasks:
- Document what happens without
dispose() - Add best practices for long-running applications
- Document memory usage patterns with large files
- Add memory leak detection examples
- Document what happens without
- Priority: MEDIUM
- Tasks:
- Document 370KB WASM file impact
- Add lazy loading strategies
- Provide CDN hosting recommendations
- Show code splitting examples
- Priority: MEDIUM
- Issue: package.json has placeholder author info
- Tasks:
- Update author field in package.json
- Ensure consistent author info across all package files
-
Priority: HIGH
-
Issue: Workers fail type checking in Deno because they're checked in window/DOM context instead of worker context
-
Root Cause Analysis:
- Type Context Mismatch: Worker files are type-checked as window scripts, not worker scripts
self.onmessageandself.postMessagedon't exist onWindow & typeof globalThis- Worker-specific globals are not available during type checking
- Import Chain Contamination: Workers import modules that reference DOM APIs
src/workers/taglib-worker.tsimports from../simple.tssimple.tsimports from modules that use DOM APIs (e.g.,web-utils.tswithHTMLCanvasElement)- These DOM types are incompatible with worker context
- Configuration Issues:
deno.jsonspecifies"lib": ["deno.window", "dom"]globally- This sets up window/DOM context for all files
- No separate configuration for worker files
- Worker Creation Method: Using
new Worker(new URL(...))works at runtime but not for static analysis
- Type Context Mismatch: Worker files are type-checked as window scripts, not worker scripts
-
Why It Only Fails During Type Checking:
- At runtime, workers execute in correct context with proper globals
- During
deno check, all files are analyzed in the default (window) context - Tests pass without
--checkflag but fail with it - The issue is purely about static type analysis, not runtime behavior
-
Solutions:
- Isolate Worker Code:
- Create worker-specific modules that don't import DOM-dependent code
- Move shared logic to DOM-free utility modules
- Use dependency injection or configuration to avoid direct imports
- Configure Worker Type Context:
- Add triple-slash directives to worker files:
/// <reference lib="webworker" /> - Consider separate
tsconfig.jsonfor workers with"lib": ["webworker"] - Use
.d.tsfiles to declare worker-specific globals
- Add triple-slash directives to worker files:
- Refactor Import Structure:
- Extract pure functions from
simple.tsthat don't depend on DOM - Create a
worker-safemodule that workers can import - Use dynamic imports with type guards for DOM-specific code
- Extract pure functions from
- Build Process Changes:
- Compile workers separately with worker-specific type context
- Use build tools that understand worker context
- Consider using Web Workers API type definitions
- Isolate Worker Code:
-
Impact:
- Fixes test failures with type checking enabled
- Enables proper type safety for worker code
- Improves developer experience with correct IntelliSense
- Makes workers more reliable across different environments
- Priority: LOW
- Tasks:
- Create migration guide from node-taglib
- Create migration guide from music-metadata
- Add comparison table with other libraries
- Priority: LOW
- Tasks:
- Benchmark processing time for different file sizes
- Compare with native libraries
- Document memory usage patterns
- Test performance across runtimes
- Priority: FUTURE - Research/Planning
- Concept: Integrate ReplayGain analysis with Web Audio API's native decoders for efficient client-side loudness calculation
- Architecture:
- Web Audio API handles audio decoding (MP3, AAC, FLAC, etc.) using browser's optimized native decoders
- Pass decoded PCM data (Float32Array) from AudioBuffer to TagLib-Wasm
- TagLib-Wasm performs ReplayGain calculations (K-weighting, RMS, LUFS gating)
- Return calculated gain/peak values to JavaScript for tag writing
- Implementation Plan:
- Audio Decoding Layer:
- Use
AudioContext.decodeAudioData()for format-agnostic decoding - Leverage
OfflineAudioContextfor faster-than-realtime processing - Extract channel data as Float32Arrays from AudioBuffer
- Use
- Wasm Analysis Module:
- Implement ITU-R BS.1770 algorithm in C++ (K-weighting filter, gating, integration)
- Export
analyzeReplayGain(channel1Data, channel2Data, sampleRate)function - Calculate track gain (dB) and peak amplitude values
- JavaScript Integration:
- Create high-level API:
await calculateReplayGain(file) - Handle file → ArrayBuffer → AudioBuffer → analysis pipeline
- Write calculated values back to file metadata
- Create high-level API:
- Audio Decoding Layer:
- Benefits:
- Eliminates need for bundling audio decoders (libavcodec, FFmpeg) in Wasm
- Leverages browser's hardware-accelerated, optimized decoders
- Smaller Wasm bundle size (analysis code only, not decoders)
- Clean separation of concerns (browser: I/O & decoding, Wasm: computation)
- Works with any format the browser can decode
- Technical Requirements:
- Expose raw PCM data interface in TagLib-Wasm
- Implement ReplayGain 2.0 algorithm (EBU R128 based)
- Support both track and album gain calculations
- Handle mono/stereo/multichannel audio
- Efficient memory transfer between JavaScript and Wasm
- Use Cases:
- Web-based music players with client-side normalization
- Online mastering tools and DAWs
- Batch processing tools for music libraries
- Privacy-preserving audio analysis (no server upload needed)
- Challenges:
- Memory constraints for very large files (may need streaming approach)
- Cross-browser AudioContext compatibility
- Performance optimization for batch processing
- Estimated Effort: Medium-High (requires ReplayGain algorithm implementation)
- Priority: FUTURE - Research/Experiment
- Concept: Port rsgain (ReplayGain 2.0 scanner) to WebAssembly for client-side loudness analysis
- Benefits:
- Enable ReplayGain analysis directly in browsers without server infrastructure
- Privacy-preserving (audio never leaves user's device)
- Direct integration with web audio applications and DAWs
- Universal deployment without platform-specific binaries
- Challenges:
- Performance would be 2-4x slower than native (but likely acceptable)
- Would need to replace FFmpeg with lightweight decoders (e.g., dr_libs, minimp3)
- Memory constraints for very large files
- No effective multithreading compared to native rsgain
- Use Cases:
- Web-based music players wanting client-side normalization
- Online audio editors/DAWs
- Educational tools demonstrating loudness concepts
- Processing small to medium files (< 100MB)
- Technical Requirements:
- Implement ITU-R BS.1770 algorithm (K-weighting, gating, integration)
- Support basic ReplayGain tags (track/album gain and peak)
- Make computationally expensive features (true peak) optional
- Target bundle size < 1MB
- Impact: Would fill a gap in the web audio ecosystem - currently no browser-based ReplayGain analysis exists
Add ReplayGain 2.0 calculation capabilities to taglib-wasm, enabling loudness normalization analysis directly in JavaScript environments. ReplayGain 2.0 uses the EBU R128/ITU BS.1770 standard for perceptual loudness measurement, providing more accurate results than the original ReplayGain specification.
Key Benefits:
- Client-side loudness analysis without server infrastructure
- Privacy-preserving (audio never leaves user's device)
- Consistent loudness across music libraries
- Support for both track and album normalization
ReplayGain 2.0 measures audio loudness using:
- ITU-R BS.1770-4: Defines the K-weighting filter and loudness measurement algorithm
- EBU R128: Specifies -23 LUFS as the target loudness level
- Gating: Excludes silence (< -70 LUFS) and quiet passages (< -10 LU relative)
- True Peak: Prevents clipping by measuring inter-sample peaks
Approach: Use the existing ebur128-wasm npm package, which provides a Rust-based EBU R128 implementation compiled to WebAssembly.
Pros:
- Immediate availability - can be integrated quickly
- Well-tested Rust implementation
- Small footprint (~200KB)
- Handles the complex loudness algorithm correctly
Cons:
- Additional dependency
- Limited customization options
- Requires audio to be decoded first
Implementation Steps:
- Add
ebur128-wasmas a dependency - Create adapter layer to bridge with taglib-wasm's API
- Handle audio decoding before analysis
- Write calculated values back to file metadata
Example Integration:
import { analyzeReplayGain } from './replaygain';
// Add to AudioFile class
async calculateReplayGain(): Promise<ReplayGainInfo> {
const pcmData = await this.decodeToPCM();
return analyzeReplayGain(pcmData, this.sampleRate);
}
// Add to Simple API
export async function calculateAndWriteReplayGain(
path: string | Uint8Array
): Promise<void> {
const file = await taglib.open(path);
try {
const replayGain = await file.calculateReplayGain();
await file.tag.setReplayGainTrackGain(replayGain.trackGain);
await file.tag.setReplayGainTrackPeak(replayGain.trackPeak);
await file.save();
} finally {
file.dispose();
}
}Approach: Compile the C library libebur128 to WebAssembly and integrate directly into taglib-wasm.
Pros:
- Full control over implementation
- Can optimize for taglib-wasm's architecture
- No external dependencies
- Can be customized for specific needs
Cons:
- More development effort required
- Need to maintain the port
- Larger initial time investment
Implementation Steps:
- Add libebur128 as a git submodule
- Modify build-wasm.sh to compile libebur128
- Create C++ wrapper functions for Emscripten
- Expose through taglib-wasm's existing API
Build Integration:
# In build-wasm.sh
echo "Building libebur128..."
emcc -O3 -s WASM=1 \
lib/libebur128/ebur128/ebur128.c \
-I lib/libebur128/ebur128 \
-c -o build/ebur128.o
# Link with taglib
emcc ... build/ebur128.o ...Approach: Leverage the Web Audio API for audio decoding in browsers, passing decoded PCM to a custom WebAssembly analysis module.
Pros:
- Uses browser's optimized, hardware-accelerated decoders
- No need to bundle audio decoders in Wasm
- Smaller Wasm footprint
- Works with any format the browser supports
Cons:
- Browser-only solution
- Requires fallback for Node.js/Deno
- More complex implementation
Architecture:
// Browser implementation
class BrowserReplayGainAnalyzer {
private audioContext: OfflineAudioContext;
async analyze(file: File | Blob): Promise<ReplayGainInfo> {
// 1. Decode audio using Web Audio API
const arrayBuffer = await file.arrayBuffer();
const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
// 2. Extract PCM data
const channelData = [];
for (let i = 0; i < audioBuffer.numberOfChannels; i++) {
channelData.push(audioBuffer.getChannelData(i));
}
// 3. Pass to Wasm analyzer
return this.wasmAnalyzer.calculateLoudness(
channelData,
audioBuffer.sampleRate,
);
}
}
// Server implementation (Node.js/Deno)
class ServerReplayGainAnalyzer {
async analyze(buffer: Uint8Array): Promise<ReplayGainInfo> {
// Use taglib to decode audio
const pcmData = await this.decodeWithTagLib(buffer);
return this.wasmAnalyzer.calculateLoudness(
pcmData.channels,
pcmData.sampleRate,
);
}
}// In AudioFile class
interface AudioFile {
// ... existing methods ...
/**
* Calculate ReplayGain values for this audio file
* @returns Promise resolving to track gain and peak values
*/
calculateReplayGain(): Promise<ReplayGainInfo>;
/**
* Decode audio to PCM for analysis
* @returns Promise resolving to PCM data
*/
decodeToPCM(): Promise<PCMData>;
}
interface ReplayGainInfo {
/** Track gain in dB (typically negative) */
trackGain: number;
/** Track peak value (0.0 to 1.0) */
trackPeak: number;
/** LUFS loudness value */
loudness: number;
}
interface PCMData {
/** Audio channels as Float32Arrays */
channels: Float32Array[];
/** Sample rate in Hz */
sampleRate: number;
/** Number of samples per channel */
length: number;
}/**
* Calculate and write ReplayGain tags to an audio file
* @param path Path to audio file or buffer
* @param options Analysis options
*/
export async function calculateReplayGain(
path: string | Uint8Array,
options?: ReplayGainOptions,
): Promise<ReplayGainInfo>;
/**
* Calculate album ReplayGain for multiple tracks
* @param paths Array of file paths or buffers
* @param options Analysis options
*/
export async function calculateAlbumReplayGain(
paths: (string | Uint8Array)[],
options?: ReplayGainOptions,
): Promise<AlbumReplayGainInfo>;
interface ReplayGainOptions {
/** Write calculated values to file (default: true) */
writeTags?: boolean;
/** Calculate true peak (slower but more accurate) */
calculateTruePeak?: boolean;
/** Target loudness in LUFS (default: -18 for ReplayGain 2.0) */
targetLoudness?: number;
}
interface AlbumReplayGainInfo {
/** Individual track results */
tracks: ReplayGainInfo[];
/** Album gain in dB */
albumGain: number;
/** Album peak (max of all track peaks) */
albumPeak: number;
}-
K-weighting Filter:
- Stage 1: High-frequency shelf filter (4.0 dB boost above 1500 Hz)
- Stage 2: High-pass filter (RLB weighting curve)
-
Loudness Calculation:
- Mean square of filtered samples over blocks
- 400ms blocks for momentary loudness
- 3-second blocks for short-term loudness
- Gated integration for overall loudness
-
Gating:
- Absolute gate: -70 LUFS (silence removal)
- Relative gate: -10 LU below ungated loudness
-
True Peak Detection (optional):
- 4x oversampling
- Measure inter-sample peaks
- Prevent digital clipping
- Process audio in chunks for large files
- Reuse buffers where possible
- Clear intermediate data promptly
- Provide streaming API for very large files
- Integrate ebur128-wasm for proof of concept
- Add basic ReplayGain calculation to Core API
- Implement Simple API wrappers
- Add tests for accuracy
- Port libebur128 to WebAssembly
- Integrate with build system
- Replace ebur128-wasm with native implementation
- Optimize performance
- Implement Web Audio API decoder integration
- Add OfflineAudioContext for faster processing
- Create unified API across environments
- Add progress callbacks for long operations
- Album gain calculation
- Batch processing optimization
- Streaming analysis for large files
- True peak detection option
-
Accuracy Tests:
- Compare with reference implementations (ffmpeg, rsgain)
- Test with EBU test vectors
- Verify gating behavior
-
Performance Tests:
- Benchmark against native tools
- Memory usage profiling
- Large file handling
-
Integration Tests:
- Test with all supported audio formats
- Verify tag writing correctness
- Cross-runtime compatibility
- Browser: Use Web Audio API
- Node.js/Deno: Need separate decoder
- Solution: Abstract decoder interface with runtime-specific implementations
- Issue: JavaScript processing can be slow
- Solution: Move heavy computation to WebAssembly
- Optimization: Process in chunks, use Web Workers
- Issue: Large files may exceed memory
- Solution: Implement streaming analysis
- Fallback: Provide file size warnings
- Issue: Floating-point differences between implementations
- Solution: Use reference test vectors
- Tolerance: Allow small variations (< 0.1 dB)
- Calculation accuracy within 0.1 dB of reference
- Performance within 2-4x of native implementation
- Memory usage under 50MB for typical files
- Support for 95% of common audio formats
- Zero crashes on invalid input
- Pure JavaScript Implementation: Too slow for practical use
- Server-Side Only: Defeats purpose of client-side library
- FFmpeg Integration: Too large, licensing concerns
- External Service: Privacy concerns, requires internet
This document tracks potential improvements to make the project more native to the Deno 2 ecosystem.
- Goal: Eliminate the NPM/JSR dual distribution complexity
- Tasks:
- Keep only JSR distribution with a single implementation
- Remove duplicate files (
taglib.ts/taglib-jsr.ts,simple.ts/simple-jsr.ts) - Remove
index.tsand keep onlymod.ts - Node.js users can use
npx jsr add @charleswiltgen/taglib-wasm
- Impact: Major simplification of codebase and maintenance
- Goal: Replace Emscripten's JavaScript wrapper with native WebAssembly APIs
- Tasks:
- Implement direct
WebAssembly.instantiate()for Wasm loading - Load the .wasm file as a static asset using Deno's file APIs
- Remove dependency on generated JavaScript (
taglib.js) - Update
taglib-jsr.tsto actually work instead of throwing error
- Implement direct
- Impact: Remove ~500KB of generated JavaScript, more idiomatic Deno code
- Goal: Leverage Deno's native TypeScript support
- Tasks:
- Delete
tsconfig.json - Remove the
build:tsnpm script - Let Deno handle TypeScript natively
- Use
deno checkfor type checking
- Delete
- Impact: Simpler build process, faster development
- Goal: Single implementation that works everywhere
- Tasks:
- Merge all duplicate implementations
- Create unified API that works across all runtimes
- Use feature detection instead of separate builds
- Impact: Easier maintenance, less code duplication
- Goal: Fully leverage Deno's built-in test framework
- Tasks:
- Refactor tests to use
Deno.test()with proper test steps and sub-tests - Add test coverage with
deno test --coverage - Use built-in assertions like
assertSnapshot()for output comparison - Add granular permissions per test
- Consider using Deno's benchmark tool for performance testing
- Refactor tests to use
- Impact: Better test organization, coverage tracking
- Goal: Replace shell scripts with Deno-native tooling
- Tasks:
- Convert
build-wasm.shto a Deno TypeScript script - Use Deno's subprocess API for Emscripten compilation
- Make builds cross-platform without shell dependencies
- Use Deno scripts for build orchestration
- Convert
- Impact: Cross-platform builds, better error handling
- Goal: Use Deno's built-in documentation tools
- Tasks:
- Use
deno docfor API documentation generation - Host documentation on deno.land/x or similar Deno-native platforms
- Remove external documentation tooling
- Use
- Impact: Automatic API docs, better integration with Deno ecosystem
- Goal: Eliminate Node.js-specific code and dependencies
- Tasks:
- Delete
package.json(keep minimal version only for NPM publish if needed) - Remove
@types/nodedependency - Use
deno taskexclusively instead of npm scripts - Remove Node.js-specific test runners
- Delete
- Impact: Cleaner dependency tree, more idiomatic Deno project
- Expand import maps beyond standard library
- Map internal imports for cleaner paths
- Use import maps for version management
- Consider workspace features for monorepo management
- Add granular permissions in
deno.json - Use permission queries in code for better error messages
- Document required permissions for different use cases
- Ensure Wasm module works with Deno Deploy constraints
- Add deployment examples
- Consider using Deno KV for caching processed metadata
- Use
https://imports for external dependencies where appropriate - Consider using
npm:specifiers for NPM compatibility - Use
node:specifiers for Node.js built-in compatibility
- Phase 1: Implement native Wasm loading (Priority 2)
- Phase 2: Consolidate to single distribution (Priority 1)
- Phase 3: Remove TypeScript compilation and simplify modules (Priorities 3 & 4)
- Phase 4: Implement remaining improvements incrementally
- Each change should maintain backward compatibility where possible
- Consider deprecation periods for breaking changes
- Prioritize changes that reduce complexity while maintaining functionality
- The goal is to make the project feel native to Deno while keeping it accessible
- Overall Compliance: 33% of critical items completed
- Last Review: CLAUDE_REVIEW_REPORT.md (2025-06-23)
-
Enum Replacement (2025-06-23)
- Replaced all enums with union types
- Updated
TagLibErrorCodeandPictureType - Fixed all imports and type references
-
Error Message Style Guide
- Already compliant with colon usage
- Proper context inclusion
- Consistent formatting
- Split Large Files - See Critical Issues #1
- Memory Management - See Critical Issues #2
- SonarQube Metrics - Need to run analysis for exact complexity scores
- Test Coverage - Target: 80% minimum
- Function Complexity - Some functions may exceed cognitive complexity limits
- Completed: 2025-01-14
- Issue: The generated
taglib.jsfile contained Node.js-specific imports that broke in Deno - Error:
TypeError: Relative import path "module" not prefixed with / or ./ or ../ - Implementation:
- Added sed patch in
build-wasm.shto convertimport("module")to conditional import - Patch changes to:
import(typeof Deno!=="undefined"?"node:module":"module") - Removed unused
deno-compat.jspre-js file
- Added sed patch in
- Result: All 25 tests now pass successfully in Deno without module loading errors
- Completed: 2025-01-14
- Implementation:
- Consolidated
test-systematic.tsandtest-integration.tsinto singletaglib.test.ts - Updated test commands in package.json
- Fixed import paths and TypeScript issues
- Consolidated
- Result: Single comprehensive test file following KISS principle
- Issue Discovered: Tests cannot run in Deno due to module loading compatibility issue
- Completed: 2025-01-14
- Implementation:
- Reorganized BACKLOG.md with clear priority sections
- Added critical Deno compatibility issue as top priority
- Documented current test infrastructure status
- Result: Clearer task prioritization and tracking
- Completed: 2025-01-14
- Implementation: Updated
writeTags()insimple.tsto callaudioFile.getFileBuffer()after saving - Result: Now correctly returns the modified buffer instead of the original
- Completed: 2025-01-14
- Implementation:
- Added
getBuffer()method to C++ FileHandle class intaglib_embind.cpp - Exposed via Embind bindings
- Added
getFileBuffer()method to TypeScript AudioFile class - Converts C++ string buffer to Uint8Array for JavaScript consumption
- Added
- Result: Core API now provides access to modified file data after save operations
- Completed: 2025-01-15
- Implementation:
- Added JSDoc comments to all public APIs in Core API (taglib.ts)
- Enhanced documentation in Simple API (simple.ts)
- Added comprehensive JSDoc to Workers API (workers.ts)
- Documented all type definitions (types.ts)
- Added module-level documentation to main entry point (index.ts)
- Details:
- Included
@param,@returns,@throws,@exampletags - Documented error conditions and edge cases
- Added usage examples for all major functions
- Enhanced type documentation with examples
- Included
- Result: All public APIs now have comprehensive JSDoc documentation for better developer experience
- Completed: 2025-01-15
- Implementation:
- Created custom error types in
src/errors.tswith specific error codes - Added error types: InvalidFormatError, UnsupportedFormatError, FileOperationError, MetadataError, etc.
- Each error includes contextual information like file size, format, operation type
- Error messages now provide helpful hints and debugging information
- Added type guards for programmatic error handling
- Created custom error types in
- Updates:
- Updated all core APIs (taglib.ts, simple.ts, workers.ts) to use new error types
- Added comprehensive error handling tests
- Updated README with error handling documentation and examples
- Result: Developers now get detailed, actionable error messages that help them quickly identify and fix issues
- Completed: 2025-01-16
- Issue: Writing non-ASCII Unicode characters (emoji, CJK, RTL text) corrupted audio files
- Root Cause: The C++ wrapper was using
to8Bit(true)which is lossy for Unicode characters - Solution:
- Changed all string conversions from
to8Bit(true)totoCString(true)in taglib_embind.cpp toCString(true)properly handles UTF-8 encoding for all Unicode characters- Wrapped results in
std::string()to satisfy Emscripten's type requirements
- Changed all string conversions from
- Result: All Unicode tests now pass - emoji, CJK characters, RTL text, and mixed scripts work correctly
- Impact: Critical fix for international users - the library now fully supports Unicode metadata
- Completed: 2025-01-15
- Issue: Tests only covered happy path scenarios
- Implementation:
- Created
tests/edge-cases.test.tswith comprehensive edge case coverage - Added Unicode handling tests (emoji, CJK, RTL text, special characters)
- Added input validation tests (null/undefined, wrong types, empty buffers)
- Added tests for non-audio data and corrupted files
- Added illegal audio properties tests
- Fixed buffer handling issue in
simple.tswhere.bufferproperty could reference larger ArrayBuffer
- Created
- Known Limitations Discovered:
- Writing non-ASCII Unicode characters (emoji, CJK, RTL) to tags currently causes file corruption
- This appears to be a limitation in the TagLib Wasm implementation's string handling
- Tests document this behavior and will need updating when Unicode support is fixed
- Result: 14 new edge case tests added, all passing; edge cases are now properly handled with appropriate errors
This section captures improvement opportunities identified during a comprehensive project review.
- Priority: MEDIUM
- Issue: Multiple README.md files scattered across subdirectories create confusion
- Current State:
/README.md(main project readme)/docs/README.md/docs/guide/README.md/examples/README.md/examples/workers/README.md/tests/README.md/tests/test-files/README.md
- Tasks:
- Keep only the main README.md
- Convert subdirectory READMEs to appropriately named files (e.g.,
docs/index.md) - Update navigation and links accordingly
- Impact: Clearer documentation hierarchy, easier navigation
- Priority: MEDIUM
- Issue: Generated files and build artifacts in version control
- Tasks:
- Add
dist/directory to.gitignore - Consider whether
build/taglib.jsandbuild/taglib.wasmshould be in git - Clean up
node_modulesreferences in subdirectories
- Add
- Impact: Cleaner repository, smaller clone size
- Priority: MEDIUM
- Issue: Test files mixed with documentation and utilities
- Current State:
- Test files at multiple levels
IMPROVEMENTS.mdmixed with test files- Utility scripts mixed with tests
- Tasks:
- Move
tests/IMPROVEMENTS.mdtodocs/or BACKLOG - Create clear separation between test files and test utilities
- Consider grouping tests by type (unit, integration, edge-cases)
- Move
- Impact: Clearer test structure, easier to find specific tests
- Priority: LOW
- Issue: Examples split between runtime-specific and common directories
- Tasks:
- Consider whether runtime-specific examples are necessary
- Consolidate common patterns
- Add clear index of examples in main README
- Impact: Easier to find relevant examples
- Priority: HIGH
- Issue: Inconsistent error handling between Core, Simple, and Workers APIs
- Tasks:
- Ensure all APIs use the custom error types consistently
- Add error code constants for programmatic handling
- Consider adding error recovery suggestions in error messages
- Impact: Better developer experience, easier debugging
- Priority: MEDIUM
- Issue: Mix of sync and async APIs can be confusing
- Tasks:
- Document clearly which operations are sync vs async
- Consider making all file operations consistently async
- Add sync versions where performance critical
- Impact: More predictable API behavior
- Priority: MEDIUM
- Issue: Not all useful types are exported from main entry points
- Tasks:
- Audit all internal types and interfaces
- Export commonly needed types
- Add type-only exports for better tree shaking
- Impact: Better TypeScript experience
- Priority: MEDIUM
- Tasks:
- Add debug logging that can be enabled via environment variable
- Add performance timing for operations in debug mode
- Add validation mode that checks all inputs thoroughly
- Impact: Easier debugging and development
- Priority: HIGH
- Tasks:
- Add a quick start guide in the main README
- Create a simple "Hello World" example as the first example
- Add troubleshooting for common issues
- Consider adding a CLI tool for testing
- Impact: Lower barrier to entry for new users
- Priority: LOW
- Tasks:
- Consider adding a playground/demo site
- Add runnable examples in documentation
- Create video tutorials for common use cases
- Impact: Better learning experience
- Priority: MEDIUM
- Tasks:
- Consider using a build tool like Vite or esbuild
- Add watch mode for development
- Improve build error messages
- Add build performance metrics
- Impact: Faster development cycle
- Priority: HIGH
- Tasks:
- Add GitHub Actions for automated testing
- Add automated build verification
- Add size tracking for the Wasm bundle
- Consider adding automated benchmarks
- Impact: Higher reliability, catch issues early
- Priority: MEDIUM
- Tasks:
- Add ESM and CJS builds for better compatibility
- Consider CDN distribution for browser usage
- Add Deno.land/x distribution
- Improve package.json exports field
- Impact: Easier adoption across different environments
- Priority: HIGH
- Tasks:
- Add code coverage reporting
- Add mutation testing
- Add property-based testing for edge cases
- Add stress tests for memory management
- Add cross-browser testing
- Impact: Higher reliability, fewer bugs
- Priority: MEDIUM
- Tasks:
- Test with real-world audio files
- Test with very large files (>100MB)
- Test batch processing scenarios
- Test error recovery scenarios
- Impact: Better real-world reliability
- Priority: MEDIUM
- Tasks:
- Add automated performance benchmarks
- Track performance over time
- Add memory usage benchmarks
- Compare with native implementations
- Impact: Maintain and improve performance
- Priority: MEDIUM
- Tasks:
- Add ESLint with strict rules
- Add Prettier for consistent formatting
- Add pre-commit hooks
- Consider adding SonarQube or similar
- Impact: More maintainable code
- Priority: MEDIUM
- Tasks:
- Add inline comments for complex algorithms
- Document architectural decisions
- Add diagrams for data flow
- Create contributor guidelines
- Impact: Easier for contributors to understand and modify
- Priority: LOW
- Tasks:
- Extract common patterns into utilities
- Reduce code duplication
- Improve naming consistency
- Consider splitting large files
- Impact: Easier long-term maintenance
- Priority: MEDIUM
- Tasks:
- Add configurable retry for transient failures
- Add exponential backoff
- Add circuit breaker pattern for repeated failures
- Impact: Better reliability in production
- Priority: HIGH
- Feedback: User requested improvements to error handling
- Tasks:
- Add retry logic for file access issues
- Better validation of tag data before writing
- Atomic operations with rollback on failure
- Use Cases:
- Handling temporary file locks or access issues
- Preventing partial writes that corrupt files
- Ensuring data integrity during batch operations
- Implementation Ideas:
- Add transaction-like API for batch operations
- Validate tag data against format-specific constraints
- Create backup before modifications with automatic rollback
- Impact: More robust file operations, reduced risk of data loss
- Priority: HIGH
- Tasks:
- Add automatic cleanup on errors
- Add memory pressure detection
- Add configurable memory limits
- Improve documentation on memory patterns
- Impact: Prevent memory leaks, better resource usage
- Priority: LOW
- Tasks:
- Add optional telemetry for usage patterns
- Add performance metrics collection
- Add error reporting integration
- Ensure privacy-preserving implementation
- Impact: Better understanding of real-world usage