Fork of eventsource that adds support for passing in a custom MessageEvent constructor. This is needed for environments like the Vercel Edge Runtime where MessageEvent is either missing or throws when constructed.
npm install --save @instantdb/eventsource- Node.js >= 20
- Chrome >= 71
- Safari >= 11.3
- Firefox >= 65
- Edge >= 79
- Deno >= 1.30
- Bun >= 1.1.23
Basically, any environment that supports:
If you need to support older runtimes, try the 2.x branch/version range (note: 2.x branch is primarily targetted at Node.js, not browsers).
import {EventSource} from 'eventsource'
const es = new EventSource('https://my-server.com/sse')
/*
* This will listen for events with the field `event: notice`.
*/
es.addEventListener('notice', (event) => {
console.log(event.data)
})
/*
* This will listen for events with the field `event: update`.
*/
es.addEventListener('update', (event) => {
console.log(event.data)
})
/*
* The event "message" is a special case, as it will capture events _without_ an
* event field, as well as events that have the specific type `event: message`.
* It will not trigger on any other event type.
*/
es.addEventListener('message', (event) => {
console.log(event.data)
})
/**
* To explicitly close the connection, call the `close` method.
* This will prevent any reconnection from happening.
*/
setTimeout(() => {
es.close()
}, 10_000)Make sure you have configured your TSConfig so it matches the environment you are targetting. If you are targetting browsers, this would be dom:
If you're using Node.js, ensure you have @types/node installed (and it is version 18 or higher). Cloudflare workers have @cloudflare/workers-types etc.
The following errors are caused by targetting an environment that does not have the necessary types available:
error TS2304: Cannot find name 'Event'.
error TS2304: Cannot find name 'EventTarget'.
error TS2304: Cannot find name 'MessageEvent'.
See MIGRATION.md for a detailed migration guide.
The error event has a message and code property that can be used to get more information about the error. In the specification, the Event
es.addEventListener('error', (err) => {
if (err.code === 401 || err.code === 403) {
console.log('not authorized')
}
})The EventSource constructor accepts an optional fetch property in the second argument that can be used to specify the fetch implementation to use.
This can be useful in environments where the global fetch function is not available - but it can also be used to alter the request/response behaviour.
const es = new EventSource('https://my-server.com/sse', {
fetch: (input, init) =>
fetch(input, {
...init,
headers: {
...init.headers,
Authorization: 'Bearer myToken',
},
}),
})Use a package like undici to add proxy support, either through environment variables or explicit configuration.
// npm install undici --save
import {fetch, EnvHttpProxyAgent} from 'undici'
const proxyAgent = new EnvHttpProxyAgent()
const es = new EventSource('https://my-server.com/sse', {
fetch: (input, init) => fetch(input, {...init, dispatcher: proxyAgent}),
})Use a package like undici that supports HTTP2.
// npm install undici --save
import {Agent, fetch} from 'undici'
const http2Dispatcher = new Agent({allowH2: true})
const es = new EventSource('https://my-server.com/sse', {
fetch: (url, init) => fetch(url, {...init, dispatcher: http2Dispatcher}),
})Use a package like undici for more control of fetch options through the use of an Agent.
// npm install undici --save
import {fetch, Agent} from 'undici'
const unsafeAgent = new Agent({
connect: {
rejectUnauthorized: false,
},
})
await fetch('https://my-server.com/sse', {
dispatcher: unsafeAgent,
})For library authors, you may want to feature-check if an EventSource implementation supports passing a custom fetch implementation (such as this library does). We declare (from v4.1.0 and onwards) a non-enumerable symbol on the EventSource class to indicate this, named eventsource.supports-fetch-override. It can be used downstream such as:
function yourLibrary(options) {
const OurEventSource = options.polyfills.EventSource || globalThis.EventSource
if (OurEventSource && Symbol.for('eventsource.supports-fetch-override') in OurEventSource) {
// We can safely assume this supports overriding/specifying `fetch`!
const es = new OurEventSource('https://some.url', {
fetch: (input, init) =>
fetch(input, {
...init,
headers: {
...(init.headers || {}),
'x-some-header': 'foo',
},
}),
})
// …
}
}To publish a new version:
- Bump the
versionfield inpackage.jsonand commit tomain - Go to Actions > Release in GitHub and click "Run workflow" on
main
The workflow runs npm publish, publishing whatever version is in package.json.
Versions follow the upstream eventsource package version with a prerelease suffix for our changes. For example, if upstream is at 4.1.0, our versions are 4.1.0-0, 4.1.0-1, 4.1.0-2, etc. Increment the number after the dash for each release. When syncing with a new upstream version, reset the suffix (e.g. 4.2.0-0).
The repo must be linked to the @instantdb/eventsource npm package with GitHub Actions as a trusted publishing source (configured in the npm package settings). No secret tokens are needed — authentication is handled via GitHub's OIDC provider.
MIT-licensed. See LICENSE.
{ "compilerOptions": { "lib": ["dom"], }, }