What is eventsource-parser?
The eventsource-parser npm package is a utility for parsing Server-Sent Events (SSE) streams. It allows you to handle real-time data streams from servers efficiently by parsing the incoming data into manageable events.
What are eventsource-parser's main functionalities?
Parsing SSE Streams
This feature allows you to parse incoming SSE data streams. The `createParser` function initializes a parser that processes incoming data and triggers a callback for each event.
const { createParser } = require('eventsource-parser');
const parser = createParser((event) => {
if (event.type === 'event') {
console.log('Received event:', event);
}
});
const sseData = `data: Hello\n\n`;
parser.feed(sseData);
Handling Different Event Types
This feature allows you to handle different types of events, such as comments and data events. The parser can differentiate between these types and process them accordingly.
const { createParser } = require('eventsource-parser');
const parser = createParser((event) => {
if (event.type === 'event') {
console.log('Received event:', event);
} else if (event.type === 'comment') {
console.log('Received comment:', event);
}
});
const sseData = `: This is a comment\ndata: Hello\n\n`;
parser.feed(sseData);
Error Handling
This feature demonstrates how to handle errors that may occur during the parsing of SSE data. The parser can throw errors if the data is not in the correct format, and you can catch these errors to handle them gracefully.
const { createParser } = require('eventsource-parser');
const parser = createParser((event) => {
if (event.type === 'event') {
console.log('Received event:', event);
}
});
try {
const invalidSseData = `data: Hello\ninvalid\n`;
parser.feed(invalidSseData);
} catch (error) {
console.error('Error parsing SSE data:', error);
}
Other packages similar to eventsource-parser
eventsource
The 'eventsource' package is a polyfill for the EventSource API, which is used to receive server-sent events. Unlike eventsource-parser, which focuses on parsing SSE streams, 'eventsource' provides a full implementation of the EventSource interface, including connection management and event handling.
sse-channel
The 'sse-channel' package is designed for creating SSE channels on the server side. It allows you to manage multiple clients and broadcast events to them. While eventsource-parser is focused on parsing incoming SSE data, 'sse-channel' is more about managing and sending SSE data from the server.
express-sse
The 'express-sse' package is a simple SSE implementation for Express.js. It allows you to easily set up SSE endpoints in an Express application. Unlike eventsource-parser, which is a low-level parser, 'express-sse' provides higher-level abstractions for integrating SSE into web applications.
eventsource-parser
A streaming parser for server-sent events/eventsource, without any assumptions about how the actual stream of data is retrieved. It is intended to be a building block for clients and polyfills in javascript environments such as browsers, node.js and deno.
If you are looking for a modern client implementation, see eventsource-client.
You create an instance of the parser, and feed it chunks of data - partial or complete, and the parse emits parsed messages once it receives a complete message. A TransformStream variant is also available for environments that support it (modern browsers, Node 18 and higher).
Other modules in the EventSource family:
- eventsource-client: modern, feature rich eventsource client for browsers, node.js, bun, deno and other modern JavaScript environments.
- eventsource-encoder: encodes messages in the EventSource/Server-Sent Events format.
- eventsource: Node.js polyfill for the WhatWG EventSource API.
[!NOTE]
Migrating from eventsource-parser 1.x/2.x? See the migration guide.
Installation
npm install --save eventsource-parser
Usage
import {createParser, type EventSourceMessage} from 'eventsource-parser'
function onEvent(event: EventSourceMessage) {
console.log('Received event!')
console.log('id: %s', event.id || '<none>')
console.log('name: %s', event.name || '<none>')
console.log('data: %s', event.data)
}
const parser = createParser({onEvent})
const sseStream = getSomeReadableStream()
for await (const chunk of sseStream) {
parser.feed(chunk)
}
parser.reset()
console.log('Done!')
Retry intervals
If the server sends a retry
field in the event stream, the parser will call any onRetry
callback specified to the createParser
function:
const parser = createParser({
onRetry(retryInterval) {
console.log('Server requested retry interval of %dms', retryInterval)
},
onEvent(event) {
},
})
Parse errors
If the parser encounters an error while parsing, it will call any onError
callback provided to the createParser
function:
import {type ParseError} from 'eventsource-parser'
const parser = createParser({
onError(error: ParseError) {
console.error('Error parsing event:', error)
if (error.type === 'invalid-field') {
console.error('Field name:', error.field)
console.error('Field value:', error.value)
console.error('Line:', error.line)
} else if (error.type === 'invalid-retry') {
console.error('Invalid retry interval:', error.value)
}
},
onEvent(event) {
},
})
Note that invalid-field
errors will usually be called for any invalid data - not only data shaped as field: value
. This is because the EventSource specification says to treat anything prior to a :
as the field name. Use the error.line
property to get the full line that caused the error.
[!NOTE]
When encountering the end of a stream, calling .reset({consume: true})
on the parser to flush any remaining data and reset the parser state. This will trigger the onError
callback if the pending data is not a valid event.
The parser will ignore comments (lines starting with :
) by default. If you want to handle comments, you can provide an onComment
callback to the createParser
function:
const parser = createParser({
onComment(comment) {
console.log('Received comment:', comment)
},
onEvent(event) {
},
})
[!NOTE]
Leading whitespace is not stripped from comments, eg : comment
will give comment
as the comment value, not comment
(note the leading space).
Stream usage
import {EventSourceParserStream} from 'eventsource-parser/stream'
const eventStream = response.body
.pipeThrough(new TextDecoderStream())
.pipeThrough(new EventSourceParserStream())
Note that the TransformStream is exposed under a separate export (eventsource-parser/stream
), in order to maximize compatibility with environments that do not have the TransformStream
constructor available.
License
MIT © Espen Hovlandsdal