or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-eventsource-polyfill

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/eventsource-polyfill@0.9.x

To install, run

npx @tessl/cli install tessl/npm-eventsource-polyfill@0.9.0

index.mddocs/

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