bare-stream
bare-stream provides a lightweight and performant abstraction for handling streaming data in JavaScript environments, building upon the well-established `streamx` API. It is currently at version 2.13.0, with regular updates indicated by recent minor version bumps, suggesting an active development cadence. The "bare" prefix implies a focus on minimal overhead and core functionality, making it suitable for environments where resource efficiency is critical, such as low-resource servers or specialized applications. Unlike Node.js's built-in streams, bare-stream aims for broader compatibility and a more streamlined API, leveraging the `streamx` pattern. Its primary differentiator is its minimal dependency footprint and its explicit design for efficient data flow, providing a robust foundation for implementing custom streaming logic without the overhead of larger alternatives.
Common errors
-
TypeError: stream.pipe is not a function
cause Attempting to use `.pipe()` on an object that is not a bare-stream (or streamx-compatible) instance, or on an instance that has been incorrectly initialized.fixEnsure that the object you are calling `.pipe()` on is an instance of `bare-stream.Readable` or `bare-stream.Transform`. Verify imports and constructor calls. -
ERR_STREAM_WRITE_AFTER_END: write after end
cause Attempting to write data to a Writable or Transform stream after its `end()` method has been called or a `null` chunk has been pushed, signifying the end of the writable side.fixCheck your logic for when data is being written to the stream. Ensure that no `write()` calls occur after `stream.end()` or after `this.push(null)` in a `Transform` stream, unless specifically designed for that behavior. -
ReferenceError: Readable is not defined
cause The `Readable` class (or Writable, Transform) was not correctly imported or required into the scope before being used.fixAdd `import { Readable } from 'bare-stream'` (for ESM) or `const { Readable } = require('bare-stream')` (for CJS) at the top of your file to make the class available.
Warnings
- gotcha bare-stream's API closely mirrors `streamx` which has subtle differences from Node.js's built-in `stream` module. Developers accustomed to Node.js streams should review `streamx` documentation to understand variations in constructor options, `_read`/`_write` signatures, and backpressure handling.
- breaking While v2.13.0 introduced `Web TransformStream` creation, prior versions might not fully support Web Streams API compatibility. Projects targeting browser environments or Web Streams might encounter unexpected behavior on older versions.
- gotcha Failing to handle stream errors can lead to unhandled promise rejections or silent failures, potentially causing resource leaks or stalled pipelines. Each stream in a pipeline can emit an 'error' event independently.
- gotcha Incorrect backpressure management in stream implementations can lead to memory exhaustion when a producer stream overwhelms a slower consumer. This is especially critical in high-throughput scenarios.
Install
-
npm install bare-stream -
yarn add bare-stream -
pnpm add bare-stream
Imports
- Readable
const Readable = require('bare-stream').Readableimport { Readable } from 'bare-stream' - Writable
import Writable from 'bare-stream/writable'
import { Writable } from 'bare-stream' - Transform
const { Transform } = require('bare-stream'); // Typo or wrong destructuringimport { Transform } from 'bare-stream'
Quickstart
import { Readable, Writable, Transform } from 'bare-stream';
class MyGenerator extends Readable {
constructor(limit) {
super();
this.index = 0;
this.limit = limit;
}
_read(size) {
if (this.index < this.limit) {
const chunk = `Data chunk ${this.index++}\n`;
this.push(Buffer.from(chunk));
} else {
this.push(null); // Signal end of stream
}
}
}
class MyProcessor extends Transform {
_transform(chunk, encoding, callback) {
// Convert to uppercase and add a prefix
this.push(Buffer.from(`PROCESSED: ${chunk.toString().toUpperCase()}`));
callback();
}
}
class MyConsumer extends Writable {
_write(chunk, encoding, callback) {
console.log(chunk.toString().trim());
callback();
}
}
const generator = new MyGenerator(3);
const processor = new MyProcessor();
const consumer = new MyConsumer();
generator.pipe(processor).pipe(consumer);
// Error handling is crucial for streams
generator.on('error', (err) => console.error('Generator error:', err));
processor.on('error', (err) => console.error('Processor error:', err));
consumer.on('error', (err) => console.error('Consumer error:', err));
consumer.on('finish', () => console.log('All data processed.'));