@lyleunderwood/filereader-polyfill
v1.0.0
Published
W3C File API specification compliant FileReader polyfill for Node.js environments
Maintainers
Readme
FileReader Polyfill
A comprehensive FileReader API polyfill for Node.js environments that provides 100% W3C File API specification compliance with full compatibility with the Web FileReader API, including support for both File and Blob objects.
Features
- ✅ W3C File API Specification Compliant - Passes comprehensive spec compliance tests
- ✅ Complete FileReader API implementation
- ✅ Support for all read methods:
readAsText,readAsDataURL,readAsArrayBuffer,readAsBinaryString - ✅ Full event support:
loadstart,progress,load,error,abort,loadend - ✅ Proper error handling with DOMException types (
InvalidStateError,NotReadableError,AbortError) - ✅ Works with both File and Blob objects
- ✅ Stream-based reading with progress events
- ✅ Proper abort functionality
- ✅ File path support for Node.js environments
- ✅ TypeScript support with full type definitions
- ✅ Event-driven architecture with EventTarget inheritance
Requirements
- Node.js 16.7.0 or higher (required for native
BlobandEventTargetsupport)
Installation
npm install @lyleunderwood/filereader-polyfillUsage
Basic Usage
import { FileReader, File } from '@lyleunderwood/filereader-polyfill';
// Reading from a Blob
const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
const reader = new FileReader();
reader.onload = (event) => {
console.log('Result:', reader.result);
};
reader.readAsText(blob);Reading from File Paths (Node.js specific)
import { FileReader, File } from '@lyleunderwood/filereader-polyfill';
// Create File from file path
const file = new File('/path/to/your/file.txt');
const reader = new FileReader();
reader.onload = () => {
console.log('File content:', reader.result);
};
reader.readAsText(file);Global Polyfill
The polyfill automatically installs itself globally if FileReader or File don't exist:
import '@lyleunderwood/filereader-polyfill';
// Now you can use FileReader and File globally
const reader = new FileReader();
const file = new File(['data'], 'example.txt');Event Handling
const reader = new FileReader();
reader.onloadstart = () => console.log('Started reading');
reader.onprogress = (event) => {
if (event.lengthComputable) {
const progress = (event.loaded / event.total) * 100;
console.log(`Progress: ${progress}%`);
}
};
reader.onload = () => console.log('Reading completed');
reader.onerror = () => console.error('Error occurred:', reader.error);
reader.onabort = () => console.log('Reading aborted');
reader.onloadend = () => console.log('Reading finished');
// You can also use addEventListener
reader.addEventListener('load', (event) => {
console.log('Load event:', event);
});Reading Different Formats
const reader = new FileReader();
const blob = new Blob(['Hello, World!']);
// Read as text
reader.readAsText(blob);
// Read as ArrayBuffer
reader.readAsArrayBuffer(blob);
// Read as Data URL
reader.readAsDataURL(blob);
// Read as binary string
reader.readAsBinaryString(blob);Abort Reading
const reader = new FileReader();
const blob = new Blob(['Large file content...']);
reader.readAsText(blob);
// Abort the reading operation
setTimeout(() => {
reader.abort();
}, 100);Error Handling
The polyfill provides W3C-compliant error handling with proper DOMException types:
const reader = new FileReader();
// Handle different error scenarios
reader.onerror = (event) => {
console.log('Error name:', reader.error.name);
console.log('Error message:', reader.error.message);
};
reader.onabort = (event) => {
console.log('Operation was aborted');
// reader.error will be AbortError
};
// Reading from non-existent file (Node.js path constructor)
try {
const file = new File('/path/to/nonexistent/file.txt');
reader.readAsText(file); // Will trigger error event with NotReadableError
} catch (error) {
// File constructor errors are deferred to read operations
}
// Attempting to read while already reading
try {
reader.readAsText(blob);
reader.readAsText(blob); // Throws InvalidStateError
} catch (error) {
console.log(error.name); // "InvalidStateError"
}API Reference
FileReader Class
Extends EventTarget and implements the complete Web FileReader API.
Properties
readyState: Current state (EMPTY,LOADING,DONE)result: The file's contents (available after successful read)error: Error information if reading failed
Methods
readAsText(blob, encoding?): Read as text with optional encodingreadAsDataURL(blob): Read as Data URLreadAsArrayBuffer(blob): Read as ArrayBufferreadAsBinaryString(blob): Read as binary stringabort(): Abort the current reading operation
Events
loadstart: Reading startedprogress: Reading progress (includesloadedandtotalproperties)load: Reading completed successfullyerror: Error occurred during readingabort: Reading was abortedloadend: Reading finished (success, error, or abort)
File Class
Extends native Blob and supports both Web API and Node.js file path constructors.
Constructors
// Web API style
new File(fileBits, fileName, options)
// Node.js file path style
new File(filePath)Properties
name: File namelastModified: Last modification timestampsize: File size in bytestype: MIME typepath: File path (Node.js specific, when created from path)
TypeScript Support
Full W3C specification-compliant TypeScript definitions are included:
import {
FileReader,
File,
type IFileReader,
type IFile,
type NodeFile,
type EventHandler,
type ProgressEvent,
type FileReaderState,
type BlobPart,
type FilePropertyBag
} from '@lyleunderwood/filereader-polyfill';
// W3C compliant usage
const reader: FileReader = new FileReader();
const file: File = new File(['content'], 'example.txt');
// Type-safe event handlers
reader.onload = (event: Event) => {
console.log(reader.result);
};
reader.onprogress = (event: Event) => {
const progressEvent = event as ProgressEvent;
if (progressEvent.lengthComputable) {
const progress = progressEvent.loaded / progressEvent.total;
console.log(`Progress: ${Math.round(progress * 100)}%`);
}
};
// File constructor with proper types
const fileFromBits: File = new File(
['Hello, World!'] as BlobPart[],
'hello.txt',
{ type: 'text/plain', lastModified: Date.now() } as FilePropertyBag
);
// Node.js specific file path constructor
const fileFromPath: NodeFile = new File('/path/to/file.txt');
console.log(fileFromPath.path); // string | undefinedAvailable Types
IFileReader: W3C specification compliant FileReader interfaceIFile: W3C specification compliant File interfaceNodeFile: Extended File interface with Node.js specificpathpropertyEventHandler: W3C compliant event handler function typeProgressEvent: Progress event interface withlengthComputable,loaded, andtotalFileReaderState: Enum for FileReader states (EMPTY, LOADING, DONE)BlobPart: Union type for valid Blob constructor partsFilePropertyBag: Options interface for File constructor
W3C Specification Compliance
This polyfill implements the W3C File API specification with 100% compliance for Node.js environments. It includes comprehensive test coverage that verifies:
- ✅ All FileReader interface requirements (constants, attributes, methods, events)
- ✅ All File interface requirements (constructor, properties, Blob inheritance)
- ✅ Proper error handling with correct DOMException types
- ✅ Event firing order and timing per specification
- ✅ State management and concurrent operation prevention
- ✅ Progress events with proper
lengthComputable,loaded, andtotalproperties
Known Limitations
Due to the Node.js environment, some aspects cannot be implemented with 100% browser fidelity:
- File system access: Cannot detect file changes after File creation (deferred to read operations)
- Event objects: Uses generic Event instead of native ProgressEvent (properties are preserved)
- Microtask timing: Event firing may differ slightly from browser microtask scheduling
- Memory management: Cannot replicate exact browser garbage collection behavior
- Security restrictions: Cannot enforce same-origin policies or file access permissions
These limitations do not affect functional compatibility with the W3C specification.
Browser Compatibility
This polyfill is designed for Node.js environments. For browser usage, use the native FileReader API which is widely supported.
Testing
Run the comprehensive test suite including W3C specification compliance tests:
npm testThe test suite includes:
- Unit tests for all functionality
- W3C File API specification compliance tests
- Error handling and edge case coverage
- Integration tests between File and FileReader
Contributing
Contributions are welcome! Please ensure all tests pass and maintain W3C specification compliance when making changes.
License
MIT License - see LICENSE file for details.
