xresilient
raw JSON → 0.8.2 verified Sat Apr 25 auth: no javascript
Builds regenerative, resumable Node.js readable streams that automatically retry on failure. Version 0.8.2 – stable, with TypeScript definitions included. Unlike manual retry logic or generic stream wrappers, xresilient tracks bytes read and supports range headers for resumable HTTP downloads. The stream can retry a user-supplied generator function a configurable number of times (default 5), emitting 'retry' and 'error' events. It extends stream.ReadableOptions, allowing custom destroyer functions and seamless integration with Node's stream pipeline. Suitable for fetching large files over unreliable networks.
Common errors
error TypeError: xresilient is not a function ↓
cause CommonJS require returns an object with default property in some bundlers.
fix
Use const xresilient = require('xresilient').default instead of require('xresilient').
error Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed ↓
cause The underlying stream was destroyed but the generator function returned a stale stream.
fix
Ensure the generator creates a new stream each invocation, and avoid reusing destroyed streams.
error Unhandled 'error' event in xresilient stream ↓
cause No error listener attached; errors after retries are exhausted propagate unhandled.
fix
Add
retriableStream.on('error', ...) to handle final errors. Warnings
gotcha The generator function must return a Readable stream; returning a destroyed or ended stream triggers retries or ends the resilient stream. ↓
fix Ensure fn always returns a valid, non-ended Readable stream unless you intend to end the resilient stream.
gotcha The 'error' event is only emitted after all retries are exhausted. Early errors do not surface directly. ↓
fix Listen to the 'retry' event to be notified of errors during retries, or check retryCount in the generator.
gotcha If the underlying stream emits a 'close' event prematurely, the retry logic may not trigger because it's not an 'error' event. ↓
fix Wrap the stream to convert 'close' into 'error' if needed, or rely only on 'error' events.
Install
npm install xresilient yarn add xresilient pnpm add xresilient Imports
- default wrong
const xresilient = require('xresilient').defaultcorrectimport xresilient from 'xresilient' - ResilientStream wrong
const ResilientStream = require('xresilient').ResilientStreamcorrectimport { ResilientStream } from 'xresilient' - xresilient wrong
const { xresilient } = require('xresilient')correctconst xresilient = require('xresilient')
Quickstart
import xresilient from 'xresilient';
import request from 'request';
import fs from 'fs';
const retriableStream = xresilient(
function returnStream({ bytesRead, retryCount }) {
console.log(`Retry #${retryCount}, bytes so far: ${bytesRead}`);
return request.get('https://example.com/file.bin', {
headers: { Range: `bytes=${bytesRead}-` },
});
},
{ retries: 3 }
);
retriableStream.pipe(fs.createWriteStream('file.bin'));
retriableStream.on('retry', (slice) => {
console.log('Retrying...', slice);
});
retriableStream.on('error', (err) => {
console.error('Failed after retries:', err.message);
});