or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-linebyline

Simple streaming readline module for Node.js that enables memory-efficient line-by-line file reading

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/linebyline@1.3.x

To install, run

npx @tessl/cli install tessl/npm-linebyline@1.3.0

index.mddocs/

LineByLine

LineByLine is a simple streaming readline module for Node.js that enables memory-efficient line-by-line file reading. It creates a readable stream from a file and emits line events for each line of text, making it ideal for processing large files without loading them entirely into memory.

Package Information

  • Package Name: linebyline
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install linebyline

Core Imports

const readLine = require('linebyline');

Basic Usage

const readLine = require('linebyline');

// Read a file line by line
const rl = readLine('./somefile.txt');

rl.on('line', function(line, lineCount, byteCount) {
  console.log('Line ' + lineCount + ': ' + line);
})
.on('error', function(e) {
  console.error('Error reading file:', e);
})
.on('end', function() {
  console.log('Finished reading file');
});

Architecture

LineByLine is built around a simple streaming architecture:

  • EventEmitter Pattern: The main class extends EventEmitter to provide event-based line processing
  • Stream Integration: Works with both file paths and existing readable streams
  • Memory Efficiency: Uses a configurable buffer size to read files without loading them entirely into memory
  • Line Detection: Processes data byte-by-byte to detect line endings (LF and CR)
  • Error Handling: Comprehensive error propagation through the event system

Capabilities

Constructor Function

Creates a new ReadLine instance for reading files line by line.

/**
 * Creates a new ReadLine instance for reading files line by line
 * @param {string|Stream} file - File path string or readable stream object
 * @param {Object} [opts] - Configuration options
 * @param {number} [opts.maxLineLength=4096] - Maximum line length in bytes
 * @param {boolean} [opts.retainBuffer=false] - If true, emits raw Buffer objects instead of strings
 * @returns {ReadLine} ReadLine instance (EventEmitter)
 */
function readLine(file, opts);

Usage Examples:

// Basic usage with file path
const rl = readLine('./data.txt');

// With options
const rl = readLine('./large-file.txt', {
  maxLineLength: 8192,  // 8K buffer
  retainBuffer: false   // Convert to strings
});

// With existing stream
const fs = require('fs');
const stream = fs.createReadStream('./file.txt');
const rl = readLine(stream);

// Can be called with or without 'new'
const rl1 = readLine('./file.txt');
const rl2 = new readLine('./file.txt');

Events

The ReadLine instance emits several events during file processing.

Line Event

Emitted for each line read from the file.

/**
 * Emitted for each line read from the file
 * @param {string|Buffer} line - Line content (string by default, Buffer if retainBuffer=true)
 * @param {number} lineCount - Current line number (1-based)
 * @param {number} byteCount - Total bytes processed so far
 */
rl.on('line', function(line, lineCount, byteCount) {
  // Process line
});

Usage Examples:

// Standard string processing
rl.on('line', function(line, lineCount, byteCount) {
  console.log(`Line ${lineCount} (${byteCount} bytes): ${line}`);
});

// Custom encoding with retainBuffer
const iconv = require('iconv-lite');
const rl = readLine('./file-in-win1251.txt', { retainBuffer: true });

rl.on('line', function(buffer, lineCount, byteCount) {
  const line = iconv.decode(buffer, 'win1251');
  console.log(`Decoded line ${lineCount}: ${line}`);
});

Open Event

Emitted when the underlying file stream opens.

/**
 * Emitted when the underlying file stream opens
 * @param {number} fd - File descriptor
 */
rl.on('open', function(fd) {
  // File opened successfully
});

Error Event

Emitted when an error occurs during reading or processing.

/**
 * Emitted when an error occurs during reading or processing
 * @param {Error} error - Error object
 */
rl.on('error', function(error) {
  // Handle error
});

Usage Examples:

rl.on('error', function(err) {
  if (err.code === 'ENOENT') {
    console.error('File not found:', err.path);
  } else {
    console.error('Reading error:', err.message);
  }
});

End Event

Emitted when the file has been completely read.

/**
 * Emitted when the file has been completely read
 */
rl.on('end', function() {
  // File reading completed
});

Close Event

Emitted when the underlying stream closes.

/**
 * Emitted when the underlying stream closes
 */
rl.on('close', function() {
  // Stream closed
});

Configuration Options

maxLineLength

Controls the maximum buffer size for a single line.

/**
 * Maximum buffer size for a single line
 * @type {number}
 * @default 4096
 */
opts.maxLineLength

Lines longer than this limit will not be read properly and may cause data loss.

retainBuffer

Controls whether to emit raw Buffer objects instead of converted strings.

/**
 * When true, the 'line' event receives raw Buffer objects instead of strings
 * @type {boolean} 
 * @default false
 */
opts.retainBuffer

Useful for custom encoding scenarios where you need to decode the buffer manually.

Usage Examples:

// High precision for large lines
const rl = readLine('./big-data.txt', {
  maxLineLength: 16384  // 16K buffer
});

// Custom encoding handling
const rl = readLine('./encoded-file.txt', {
  retainBuffer: true
});

rl.on('line', function(buffer, lineCount, byteCount) {
  // Custom decoding logic here
  const line = buffer.toString('utf16le');
  console.log(line);
});

Types

/**
 * ReadLine class - extends EventEmitter
 */
class ReadLine extends EventEmitter {
  constructor(file, opts);
  
  /** The underlying readable stream */
  input: ReadableStream;
}

/**
 * Configuration options for ReadLine constructor
 */
interface ReadLineOptions {
  /** Maximum line length in bytes (default: 4096) */
  maxLineLength?: number;
  /** If true, emits raw Buffer objects instead of strings (default: false) */
  retainBuffer?: boolean;
}

Error Handling

LineByLine provides comprehensive error handling through the event system:

  • File System Errors: File not found, permission errors, etc. are emitted as 'error' events
  • Processing Errors: Errors during line emission are caught and emitted as 'error' events
  • Stream Errors: Underlying stream errors are propagated through the 'error' event
  • Buffer Overflow: Lines exceeding maxLineLength may cause data loss but don't emit errors

Best Practices:

const rl = readLine('./file.txt');

// Always handle errors
rl.on('error', function(err) {
  console.error('Error:', err.message);
  // Handle error appropriately
});

// Ensure proper cleanup
rl.on('end', function() {
  console.log('Processing completed');
});

rl.on('close', function() {
  console.log('Stream closed');
});

Line Ending Support

LineByLine handles different line ending formats:

  • LF (Line Feed - ASCII 10): Standard Unix/Linux line endings - triggers line emission
  • CR (Carriage Return - ASCII 13): Classic Mac line endings - ignored but processed
  • CRLF: Windows line endings work correctly (CR is ignored, LF triggers emission)
  • EOF: Final line is emitted even without trailing line ending

Performance Characteristics

  • Memory Efficient: Streaming implementation processes files without loading them entirely into memory
  • Configurable Buffer: Default 4K line buffer, adjustable via maxLineLength option
  • Byte-by-byte Processing: Processes data one byte at a time for accurate line detection
  • Event-driven: Non-blocking, event-based processing suitable for large files
  • Lazy Evaluation: Lines are processed as they are read from the stream