CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-eventsource-polyfill

A browser polyfill for W3C EventSource (Server-Sent Events) with cross-browser compatibility for IE8+ and Android browser 2.1+

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

EventSource Polyfill

EventSource Polyfill provides a comprehensive browser polyfill for the W3C EventSource API (Server-Sent Events). It enables SSE functionality in browsers that don't natively support it, including Internet Explorer 8+ and Android browser 2.1+, with automatic reconnection, event parsing, custom event types, and cross-browser compatibility.

Package Information

  • Package Name: eventsource-polyfill
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install eventsource-polyfill

Core Imports

For browserify/webpack/CommonJS environments (automatic polyfill):

require('eventsource-polyfill');
// This automatically adds the polyfill to window.EventSource if not present
// After requiring, use: new EventSource(url)

Direct module import (manual usage):

const EventSourcePolyfill = require('eventsource-polyfill');
const eventSource = new EventSourcePolyfill(url);

For browser script inclusion:

<script src="dist/eventsource.js"></script>
<!-- This makes EventSource available globally if not already present -->

Basic Usage

// Import the polyfill (for browserify/webpack environments)
require('eventsource-polyfill');

// Create an EventSource connection
const eventSource = new EventSource('https://example.com/events');

// Handle connection events
eventSource.onopen = function(event) {
    console.log('Connection opened:', event);
};

eventSource.onmessage = function(event) {
    console.log('Received message:', event.data);
};

eventSource.onerror = function(event) {
    console.log('Error occurred:', event);
};

// Listen for custom event types
eventSource.addEventListener('custom-event', function(event) {
    console.log('Custom event received:', event.data);
});

// Close the connection when done
eventSource.close();

Architecture

The polyfill is built around several key components:

  • EventSource Constructor: Main polyfill class providing W3C-compliant EventSource API
  • Transport Layer: Intelligent selection between XMLHttpRequest (modern browsers) and XDomainRequest (IE 8-9)
  • Event Processing: Complete SSE protocol implementation with message parsing and event dispatching
  • Configuration System: Extensive options for connection timeouts, buffer limits, headers, and logging
  • Automatic Reconnection: Built-in retry logic with configurable intervals and timeout handling

Capabilities

EventSource Constructor

Creates a new EventSource connection for Server-Sent Events with optional configuration.

/**
 * EventSource constructor for Server-Sent Events polyfill
 * @param {string} url - The URL to connect to for Server-Sent Events
 * @param {object} options - Optional configuration options
 */
function EventSource(url, options);

Usage Examples:

// Basic connection
const eventSource = new EventSource('/api/events');

// With configuration options
const eventSource = new EventSource('/api/events', {
    loggingEnabled: true,
    interval: 1000,
    silentTimeout: 60000,
    xhrHeaders: {
        'Authorization': 'Bearer token123'
    }
});

Event Management

Methods for managing event listeners on the EventSource instance.

/**
 * Add an event listener for the specified event type
 * @param {string} type - Event type ('open', 'message', 'error', or custom type)
 * @param {function} handler - Event handler function
 */
addEventListener(type, handler);

/**
 * Remove an event listener for the specified event type
 * @param {string} type - Event type
 * @param {function} handler - Event handler function to remove
 */
removeEventListener(type, handler);

Usage Examples:

// Add listeners
eventSource.addEventListener('message', function(event) {
    console.log('Message:', event.data);
});

eventSource.addEventListener('custom-notification', function(event) {
    console.log('Notification:', event.data);
});

// Remove listeners
function messageHandler(event) {
    console.log('Message:', event.data);
}
eventSource.addEventListener('message', messageHandler);
eventSource.removeEventListener('message', messageHandler);

Connection Management

Methods for controlling the EventSource connection lifecycle.

/**
 * Close the EventSource connection
 */
close();

Usage Example:

// Close the connection
eventSource.close();
console.log('Connection state:', eventSource.readyState); // 2 (CLOSED)

State Properties

Properties providing information about the current connection state.

/**
 * Current connection state
 * @type {number} - 0 (CONNECTING), 1 (OPEN), or 2 (CLOSED)
 */
readyState;

/**
 * The URL being connected to
 * @type {string}
 */
URL;

/**
 * ID of the last received event
 * @type {string|null}
 */
lastEventId;

State Constants

Constants defining the possible connection states.

/**
 * Connection state constants
 */
EventSource.prototype.CONNECTING = 0;
EventSource.prototype.OPEN = 1;
EventSource.prototype.CLOSED = 2;

Event Handler Properties

Properties for setting event handlers directly.

/**
 * Handler for connection open events
 * @type {function|null}
 */
onopen;

/**
 * Handler for message events
 * @type {function|null}
 */
onmessage;

/**
 * Handler for error events
 * @type {function|null}
 */
onerror;

Usage Example:

eventSource.onopen = function(event) {
    console.log('Connection opened');
};

eventSource.onmessage = function(event) {
    console.log('Received:', event.data);
};

eventSource.onerror = function(event) {
    console.error('Connection error:', event);
};

Configuration Options

Configuration options available when creating an EventSource instance.

/**
 * Default configuration options
 */
const defaultOptions = {
    /** Enable/disable console logging */
    loggingEnabled: false,
    
    /** Prefix for log messages */
    loggingPrefix: "eventsource",
    
    /** Reconnection interval in milliseconds */
    interval: 500,
    
    /** Maximum buffer size in bytes */
    bufferSizeLimit: 256 * 1024,
    
    /** Timeout for silent connections in milliseconds */
    silentTimeout: 300000,
    
    /** GET parameters to append to URL */
    getArgs: {
        'evs_buffer_size_limit': 256 * 1024
    },
    
    /** HTTP headers for XMLHttpRequest */
    xhrHeaders: {
        'Accept': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'X-Requested-With': 'XMLHttpRequest'
    }
};

Usage Example:

const eventSource = new EventSource('/events', {
    loggingEnabled: true,
    loggingPrefix: 'MyApp',
    interval: 2000,
    silentTimeout: 120000,
    xhrHeaders: {
        'Accept': 'text/event-stream',
        'Authorization': 'Bearer ' + token
    },
    getArgs: {
        'user_id': '12345',
        'evs_buffer_size_limit': 512 * 1024
    }
});

Polyfill Detection

Static property indicating the polyfill implementation type.

/**
 * Indicates the polyfill implementation type (only present when using polyfill)
 * @type {string} - "XHR" for modern browsers, "IE_8-9" for older IE versions
 */
EventSource.isPolyfill;

Usage Example:

// Note: This property only exists when using the polyfill, not native EventSource
if (typeof EventSource.isPolyfill !== 'undefined') {
    console.log('Using polyfill with transport:', EventSource.isPolyfill);
} else {
    console.log('Using native EventSource implementation');
}

Types

/**
 * MessageEvent object for Server-Sent Events
 */
interface MessageEvent {
    /** Event type */
    type: string;
    /** Event data payload */
    data: string | null;
    /** Event origin */
    origin: string;
    /** Event ID for reconnection */
    lastEventId: string;
    /** Event bubbling (always false) */
    bubbles: boolean;
    /** Event cancelable (always false) */
    cancelable: boolean;
    /** Event cancel bubble (always false) */
    cancelBubble: boolean;
}

/**
 * EventSource configuration options
 */
interface EventSourceOptions {
    /** Enable console logging */
    loggingEnabled?: boolean;
    /** Log message prefix */
    loggingPrefix?: string;
    /** Reconnection interval in ms */
    interval?: number;
    /** Buffer size limit in bytes */
    bufferSizeLimit?: number;
    /** Silent connection timeout in ms */
    silentTimeout?: number;
    /** URL query parameters */
    getArgs?: { [key: string]: any };
    /** HTTP request headers */
    xhrHeaders?: { [key: string]: string };
}

Cross-Browser Compatibility

The polyfill automatically detects the browser environment and uses the appropriate transport:

  • Modern browsers: Uses XMLHttpRequest with full header support and progress events
  • Internet Explorer 8-9: Uses XDomainRequest with modified configuration for cross-domain support

IE 8-9 Specific Behavior

When running in IE 8-9, the polyfill automatically:

  • Disables custom headers (uses xhrHeaders: null)
  • Adds evs_preamble: 2056 to GET arguments for XDomainRequest buffering
  • Uses evs_last_event_id GET parameter instead of Last-Event-Id header for reconnection

Error Handling

The polyfill handles various error conditions and connection issues:

eventSource.onerror = function(event) {
    // Different error types based on event.data
    switch(event.data) {
        case 'Reconnecting ':
            console.log('Connection lost, attempting to reconnect...');
            break;
        case 'XDomainRequest error':
            console.log('IE XDomainRequest failed (IE 8-9 only)');
            break;
        case 'XDomainRequest timed out':
            console.log('IE XDomainRequest timed out (IE 8-9 only)');
            break;
        default:
            // Server HTTP error responses
            if (event.data && event.data.startsWith('The server responded with ')) {
                console.log('HTTP error:', event.data);
            } else {
                console.log('Unknown error:', event.data);
            }
    }
};

Advanced Usage

Custom Event Types

// Server sends: event: notification\ndata: New message\n\n
eventSource.addEventListener('notification', function(event) {
    console.log('Notification received:', event.data);
});

Reconnection Handling

eventSource.addEventListener('error', function(event) {
    if (event.data === 'Reconnecting ') {
        console.log('Lost connection, will retry...');
        // The polyfill handles reconnection automatically
    }
});

Last Event ID Tracking

// Access the last event ID for manual reconnection
console.log('Last event ID:', eventSource.lastEventId);

// Server can send: id: 12345\ndata: Some data\n\n
// On reconnection, the polyfill sends Last-Event-Id: 12345 header
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/eventsource-polyfill@0.9.x
Publish Source
CLI
Badge
tessl/npm-eventsource-polyfill badge