CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-reconnect-core

Generic stream reconnection module that provides intelligent reconnection logic with configurable backoff strategies.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Reconnect Core

Reconnect Core is a generic stream reconnection module that provides intelligent reconnection logic with configurable backoff strategies. It serves as a foundation for building specialized reconnection libraries for TCP, WebSocket, and other network protocols, handling connection state management and automatic reconnection with robust error handling.

Package Information

  • Package Name: reconnect-core
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install reconnect-core

Core Imports

const inject = require('reconnect-core');

For ES modules:

import inject from 'reconnect-core';

Basic Usage

const inject = require('reconnect-core');
const net = require('net');

// Create a TCP reconnection module
const reconnect = inject(function() {
  // Arguments are passed from .connect() call
  // 'this' refers to the reconnect emitter instance
  return net.connect.apply(null, arguments);
});

// Create a reconnection instance
const connection = reconnect({
  initialDelay: 1000,
  maxDelay: 30000,
  strategy: 'fibonacci'
}, function(stream) {
  // Handle connected stream
  console.log('Connected!');
  stream.on('data', function(data) {
    console.log('Received:', data.toString());
  });
})
.on('connect', function(con) {
  console.log('Connection established');
})
.on('reconnect', function(n, delay) {
  console.log(`Reconnection attempt ${n}, delay: ${delay}ms`);
})
.on('disconnect', function(err) {
  console.log('Disconnected:', err?.message);
})
.on('error', function(err) {
  console.log('Connection error:', err.message);
});

// Start connecting
connection.connect(8080, 'localhost');

// Later: stop reconnecting
connection.disconnect();

Architecture

Reconnect Core follows an injection pattern where users provide their own connection creation function. The module wraps this function with:

  • Backoff Strategy Integration: Uses the backoff library for intelligent retry timing
  • Event-Driven Architecture: Full EventEmitter interface for monitoring connection lifecycle
  • Connection State Management: Tracks connection status and handles cleanup
  • Error Recovery: Automatic reconnection with configurable failure limits
  • Flexible Configuration: Support for multiple backoff strategies and custom options

Capabilities

Injection Function

The main export is a factory function that creates reconnection modules by injecting a connection creation function.

/**
 * Creates a reconnection module by injecting a connection creation function
 * @param {Function} createConnection - Function that creates the underlying connection
 * @returns {Function} Reconnection function that creates reconnection instances
 */
function inject(createConnection);

The createConnection function signature:

  • Called with arguments passed to .connect() method
  • Called with this bound to the reconnect emitter instance
  • Must return a connection object that emits 'connect', 'close', 'end', and 'error' events

Reconnection Function

The injected function returns a reconnection function that creates reconnection instances.

/**
 * Creates a reconnection instance with specified options and callback
 * @param {Object|Function} opts - Configuration options or connection callback
 * @param {Function} [onConnect] - Optional connection callback function
 * @returns {ReconnectEmitter} EventEmitter instance with reconnection capabilities
 */
function reconnect(opts, onConnect);

Configuration Options

interface ReconnectOptions {
  /** Initial delay before first reconnection attempt (default: 1000ms) */
  initialDelay?: number;
  /** Maximum delay between reconnection attempts (default: 30000ms) */
  maxDelay?: number;
  /** Backoff strategy: 'fibonacci', 'exponential', or custom backoff instance */
  strategy?: string | BackoffStrategy;
  /** Alias for strategy */
  type?: string | BackoffStrategy;
  /** Number of failed attempts before giving up (default: undefined/unlimited) */
  failAfter?: number;
  /** Randomization factor for backoff delays (0-1) */
  randomisationFactor?: number;
  /** Whether to treat connection as immediately connected (default: false) */
  immediate?: boolean;
  /** Alternative way to specify connection callback */
  onConnect?: Function;
}

Reconnect Emitter Instance

The reconnection function returns an EventEmitter instance with additional properties and methods.

interface ReconnectEmitter extends EventEmitter {
  /** Current connection state (read-only) */
  connected: boolean;
  /** Whether to continue reconnecting (read-write) */
  reconnect: boolean;
  /** Reference to current underlying connection (internal) */
  _connection?: any;
  
  /**
   * Start connection/reconnection process
   * @param {...any} args - Arguments passed to createConnection function
   * @returns {ReconnectEmitter} Self for chaining
   */
  connect(...args): ReconnectEmitter;
  
  /**
   * Alias for connect method
   * @param {...any} args - Arguments passed to createConnection function
   * @returns {ReconnectEmitter} Self for chaining
   */
  listen(...args): ReconnectEmitter;
  
  /**
   * Stop reconnecting and end current connection
   * @returns {ReconnectEmitter} Self for chaining
   */
  disconnect(): ReconnectEmitter;
  
  /**
   * Reset backoff timer and attempt immediate reconnection
   * @returns {undefined} No return value
   */
  reset(): void;
}

Events

The reconnect emitter instance emits the following events:

// Connection established successfully
emitter.on('connect', (connection) => {});
emitter.on('connection', (connection) => {}); // Alias for 'connect'

// Before each reconnection attempt
emitter.on('reconnect', (attemptNumber, delay) => {});

// Connection lost or ended
emitter.on('disconnect', (error) => {});

// Connection error occurred
emitter.on('error', (error) => {});

// Backoff process events (from backoff library)
emitter.on('backoff', (attemptNumber, delay, error) => {});

// Maximum attempts reached, giving up
emitter.on('fail', (error) => {});

Event Details:

  • 'connect'/'connection': Emitted when connection is successfully established

    • connection: The underlying connection object returned by createConnection
  • 'reconnect': Emitted before each reconnection attempt

    • attemptNumber: Current attempt number (starts at 0)
    • delay: Delay used before this attempt (in milliseconds)
  • 'disconnect': Emitted when connection is lost or closed

    • error: Optional error object if disconnection was due to an error
  • 'error': Emitted when connection errors occur

    • error: Error object describing the failure
  • 'backoff': Emitted during backoff timing process

    • attemptNumber: Current attempt number
    • delay: Delay being used
    • error: Error that triggered the backoff
  • 'fail': Emitted when failAfter limit is reached

    • error: Final error before giving up

Backoff Strategies

Reconnect Core integrates with the backoff library and supports multiple strategies:

// Built-in strategies (pass as string to 'strategy' option)
type BuiltInStrategy = 'fibonacci' | 'exponential';

// Custom backoff strategy interface
interface BackoffStrategy {
  /** Calculate next delay value */
  next(): number;
  /** Reset the strategy to initial state */
  reset(): void;
}

Strategy Examples:

// Fibonacci backoff (default)
const connection = reconnect({ strategy: 'fibonacci' });

// Exponential backoff
const connection = reconnect({ strategy: 'exponential' });

// Custom strategy
const customStrategy = {
  next: function() { return 5000; }, // Always 5 seconds
  reset: function() { }
};
const connection = reconnect({ 
  strategy: new (require('backoff')).Backoff(customStrategy)
});

Usage Patterns

TCP Reconnection

const inject = require('reconnect-core');
const net = require('net');

const reconnect = inject(() => net.connect.apply(null, arguments));
const connection = reconnect().connect(8080, 'localhost');

WebSocket Reconnection

const inject = require('reconnect-core');
const WebSocket = require('ws');

const reconnect = inject((url) => new WebSocket(url));
const connection = reconnect({ immediate: true }, (ws) => {
  ws.send('Hello Server!');
}).connect('ws://localhost:8080');

HTTP Request Reconnection

const inject = require('reconnect-core');
const http = require('http');

const reconnect = inject((options) => http.request(options));
const connection = reconnect({ immediate: true }, (req) => {
  req.write('POST data');
  req.end();
}).connect({ host: 'localhost', port: 8080, method: 'POST' });

Advanced Configuration

const connection = reconnect({
  initialDelay: 500,
  maxDelay: 60000,
  strategy: 'exponential',
  failAfter: 10,
  randomisationFactor: 0.2,
  immediate: false
}, function(stream) {
  // Handle connection
})
.on('connect', (con) => console.log('Connected'))
.on('reconnect', (n, delay) => console.log(`Attempt ${n}, delay: ${delay}ms`))
.on('disconnect', (err) => console.log('Disconnected:', err?.message))
.on('fail', (err) => console.log('Max attempts reached, giving up'))
.connect(port, host);

// Manual control
setTimeout(() => {
  connection.reconnect = false; // Disable auto-reconnection
  connection.disconnect();      // Disconnect immediately
}, 30000);

// Force immediate reconnection
connection.reset();
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/reconnect-core@1.3.x
Publish Source
CLI
Badge
tessl/npm-reconnect-core badge