@tknf/read-files
TypeScript icon, indicating that this package has built-in type declarations

2.0.0 • Public • Published
Snowflake Logo

@tknf/read-files

Modern, Promise-based utility for reading files in the browser using the FileReader API

Github Workflow Status Github npm npm bundle size npm bundle size Github commit activity GitHub last commit Ask DeepWiki


✨ Features

  • 🎯 Promise-based API - Clean async/await syntax
  • 🛡️ Type Safety - Full TypeScript support with comprehensive types
  • 🔒 Error Handling - Both throwing and safe (non-throwing) variants
  • 📱 Multiple Formats - Support for ArrayBuffer, text, binary string, and data URL
  • 🎚️ Event Callbacks - Optional progress and lifecycle event handlers
  • 🧪 Well Tested - 95%+ test coverage with comprehensive edge case testing
  • 📦 Zero Dependencies - Lightweight with no external dependencies
  • 🌐 Browser Support - Works in all modern browsers supporting FileReader API

📦 Installation

# npm
npm install @tknf/read-files

# yarn
yarn add @tknf/read-files

# pnpm
pnpm add @tknf/read-files

🚀 Quick Start

Basic Usage

import { readAsText, readAsArrayBuffer, readAsDataUrl } from '@tknf/read-files';

// Read file as text
const file = new File(['Hello World'], 'hello.txt', { type: 'text/plain' });
const text = await readAsText(file);
console.log(text); // "Hello World"

// Read file as ArrayBuffer
const buffer = await readAsArrayBuffer(file);
console.log(buffer.byteLength); // 11

// Read file as data URL
const dataUrl = await readAsDataUrl(file);
console.log(dataUrl); // "data:text/plain;base64,SGVsbG8gV29ybGQ="

Safe (Non-throwing) Variants

import { safeReadAsText, safeReadAsArrayBuffer } from '@tknf/read-files';

// Safe reading - returns { result, error } instead of throwing
const { result, error } = await safeReadAsText(file);

if (error) {
  console.error('Failed to read file:', error.message);
} else {
  console.log('File content:', result);
}

📚 API Reference

Reading Functions

readAsText(data, options?)

Reads a File or Blob as text with optional character encoding.

await readAsText(file, { encoding: 'UTF-8' });

readAsArrayBuffer(data, options?)

Reads a File or Blob as an ArrayBuffer for binary data processing.

await readAsArrayBuffer(file);

readAsBinaryString(data, options?)

Reads a File or Blob as a binary string where each byte is represented as a character.

await readAsBinaryString(file);

readAsDataUrl(data, options?)

Reads a File or Blob as a data URL with embedded base64-encoded content.

await readAsDataUrl(file);

Safe Variants

All reading functions have corresponding safe variants that return { result, error } instead of throwing:

  • safeReadAsText(data, options?)
  • safeReadAsArrayBuffer(data, options?)
  • safeReadAsBinaryString(data, options?)
  • safeReadAsDataUrl(data, options?)

Options

interface ReadFilePromiseOptions<ResultType> {
  // Optional pre-configured FileReader instance
  fileReader?: FileReader;
  
  // Event callbacks
  onLoad?(event: ProgressEvent<FileReader>, result: ResultType): void;
  onLoadStart?(event: ProgressEvent<FileReader>): void;
  onLoadEnd?(event: ProgressEvent<FileReader>, result: ResultType): void;
  onProgress?(event: ProgressEvent<FileReader>): void;
  onError?(event: ProgressEvent<FileReader>, error: DOMException): void;
}

// Extended options for text reading
interface ReadAsTextOptions extends ReadFilePromiseOptions<string> {
  encoding?: string; // Character encoding (e.g., "UTF-8", "ISO-8859-1")
}

Utility Functions

isString(value)

Type guard to check if a FileReader result is a string.

import { isString } from '@tknf/read-files';

if (isString(result)) {
  // result is definitely a string
}

isArrayBuffer(value)

Type guard to check if a FileReader result is an ArrayBuffer.

import { isArrayBuffer } from '@tknf/read-files';

if (isArrayBuffer(result)) {
  // result is definitely an ArrayBuffer
}

💡 Examples

File Upload with Progress

import { readAsDataUrl } from '@tknf/read-files';

const handleFileUpload = async (file: File) => {
  try {
    const dataUrl = await readAsDataUrl(file, {
      onLoadStart: () => console.log('Reading started...'),
      onProgress: (event) => {
        if (event.lengthComputable) {
          const progress = (event.loaded / event.total) * 100;
          console.log(`Progress: ${progress.toFixed(2)}%`);
        }
      },
      onLoadEnd: () => console.log('Reading completed'),
    });
    
    // Use the data URL (e.g., for image preview)
    const img = document.createElement('img');
    img.src = dataUrl;
    document.body.appendChild(img);
  } catch (error) {
    console.error('Failed to read file:', error);
  }
};

Processing Binary Data

import { readAsArrayBuffer } from '@tknf/read-files';

const processBinaryFile = async (file: File) => {
  const buffer = await readAsArrayBuffer(file);
  const view = new DataView(buffer);
  
  // Read binary data
  const signature = view.getUint32(0, true);
  console.log('File signature:', signature.toString(16));
  
  // Process the binary data...
};

Error Handling with Safe Variants

import { safeReadAsText } from '@tknf/read-files';

const readFileContent = async (file: File) => {
  const { result, error } = await safeReadAsText(file, {
    encoding: 'UTF-8'
  });
  
  if (error) {
    if (error instanceof DOMException) {
      console.error('FileReader error:', error.message);
    } else {
      console.error('Unexpected error:', error);
    }
    return null;
  }
  
  return result;
};

Custom FileReader Configuration

import { readAsText } from '@tknf/read-files';

// Use a pre-configured FileReader
const customReader = new FileReader();
const text = await readAsText(file, {
  fileReader: customReader,
  onError: (event, error) => {
    console.error('Custom error handler:', error);
  }
});

🛠️ Development

Setup

git clone https://github.com/tknf/read-files.git
cd read-files
pnpm install

Scripts

# Build the library
pnpm run build

# Run tests
pnpm run test

# Run tests with coverage
pnpm run test:coverage

# Lint code
pnpm run lint

# Format code
pnpm run format

# Type check
pnpm run typecheck

Project Structure

src/
├── index.ts                   # Main exports
├── types.ts                   # TypeScript type definitions
├── utils.ts                   # Utility functions and type guards
├── read-as-text.ts            # Text reading implementation
├── read-as-array-buffer.ts    # ArrayBuffer reading implementation
├── read-as-binary-string.ts   # Binary string reading implementation
├── read-as-data-url.ts        # Data URL reading implementation
└── **/*.test.ts               # Comprehensive test suites

🔧 Requirements

  • Browser Environment: Modern browsers with FileReader API support
  • TypeScript: 4.5+ (if using TypeScript)
  • Node.js: 16+ (for development)

📄 License

MIT License - see the LICENSE file for details.

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development Guidelines

  1. Code Style: We use Biome for formatting and linting
  2. Testing: Maintain test coverage above 95%
  3. TypeScript: Ensure full type safety
  4. Documentation: Update README for any API changes

🙏 Acknowledgments

  • Built with TypeScript and modern development tools
  • Tested with Vitest and comprehensive test scenarios
  • Formatted and linted with Biome
  • Bundled with tsup for optimal distribution

Package Sidebar

Install

npm i @tknf/read-files

Weekly Downloads

1

Version

2.0.0

License

MIT

Unpacked Size

54.5 kB

Total Files

8

Last publish

Collaborators

  • mast1ff