-
Notifications
You must be signed in to change notification settings - Fork 252
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat!: modernize - use
fetch
, WebStreams, TypeScript, ESM (#330)
BREAKING CHANGE: The module now uses a named export instead of a default export. BREAKING CHANGE: UMD bundle dropped. Use a bundler. BREAKING CHANGE: `headers` in init dict dropped, pass a custom `fetch` function instead. BREAKING CHANGE: HTTP/HTTPS proxy support dropped. Pass a custom `fetch` function instead. BREAKING CHANGE: `https.*` options dropped. Pass a custom `fetch` function that provides an agent/dispatcher instead. BREAKING CHANGE: New default reconnect delay: 3 seconds instead of 1 second. BREAKING CHANGE: Reconnecting after a redirect will now always use the original URL, even if the status code was HTTP 307.
- Loading branch information
Showing
53 changed files
with
17,573 additions
and
26,314 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,13 @@ | ||
# http://editorconfig.org | ||
; editorconfig.org | ||
root = true | ||
charset= utf8 | ||
|
||
[*] | ||
# Use hard or soft tabs | ||
indent_style = space | ||
|
||
# Size of a single indent | ||
indent_size = tab | ||
|
||
# Number of columns representing a tab character | ||
tab_width = 2 | ||
|
||
# Use line-feed as EOL indicator | ||
end_of_line = lf | ||
|
||
# Use UTF-8 character encoding for all files | ||
charset = utf-8 | ||
|
||
# Remove any whitespace characters preceding newline characters | ||
trim_trailing_whitespace = true | ||
|
||
# Ensure file ends with a newline when saving | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/dist | ||
/coverage | ||
/demo/dist | ||
.nyc_output |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
name: Release | ||
|
||
# Workflow name based on selected inputs. | ||
# Fallback to default GitHub naming when expression evaluates to empty string | ||
run-name: >- | ||
${{ | ||
inputs.release && 'Release ➤ Publish to NPM' || | ||
'' | ||
}} | ||
on: | ||
pull_request: | ||
push: | ||
branches: [main] | ||
workflow_dispatch: | ||
inputs: | ||
release: | ||
description: 'Publish new release' | ||
required: true | ||
default: false | ||
type: boolean | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
release: | ||
# only run if opt-in during workflow_dispatch | ||
name: 'Release: Publish to NPM' | ||
if: always() && github.event.inputs.release == 'true' | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
# Need to fetch entire commit history to | ||
# analyze every commit since last release | ||
fetch-depth: 0 | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: lts/* | ||
cache: npm | ||
- run: npm ci | ||
# Branches that will release new versions are defined in .releaserc.json | ||
- run: npx semantic-release | ||
# Don't allow interrupting the release step if the job is cancelled, as it can lead to an inconsistent state | ||
# e.g. git tags were pushed but it exited before `npm publish` | ||
if: always() | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
name: Test | ||
on: | ||
push: | ||
workflow_dispatch: | ||
|
||
jobs: | ||
testBrowser: | ||
name: 'Test: Browsers' | ||
timeout-minutes: 15 | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: 20 | ||
- name: Cache node modules | ||
id: cache-node-modules | ||
uses: actions/cache@v4 | ||
env: | ||
cache-name: cache-node-modules | ||
with: | ||
path: '**/node_modules' | ||
key: ${{ runner.os }}-modules-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} | ||
restore-keys: | | ||
${{ runner.os }}-modules-${{ env.cache-name }}- | ||
${{ runner.os }}-modules- | ||
${{ runner.os }}- | ||
- name: Install dependencies | ||
if: steps.cache-node-modules.outputs.cache-hit != 'true' | ||
run: npx playwright install && npm ci | ||
- name: Install Playwright Browsers | ||
run: npx playwright install --with-deps | ||
- name: Run browser tests | ||
run: npm run test:browser | ||
|
||
testNode: | ||
name: 'Test: Node.js ${{ matrix.node-version }}' | ||
timeout-minutes: 15 | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node-version: ['18.x', '20.x', '22.x'] | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
- name: Cache node modules | ||
id: cache-node-modules | ||
uses: actions/cache@v4 | ||
env: | ||
cache-name: cache-node-modules | ||
with: | ||
path: '**/node_modules' | ||
key: ${{ runner.os }}-modules-${{ env.cache-name }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }} | ||
restore-keys: | | ||
${{ runner.os }}-modules-${{ env.cache-name }}--node-${{ matrix.node-version }}- | ||
${{ runner.os }}-modules-${{ env.cache-name }} | ||
${{ runner.os }}-modules- | ||
${{ runner.os }}- | ||
- name: Install dependencies | ||
if: steps.cache-node-modules.outputs.cache-hit != 'true' | ||
run: npm ci | ||
- name: Run tests | ||
run: npm run test:node | ||
|
||
testDeno: | ||
name: 'Test: Deno' | ||
timeout-minutes: 15 | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: denoland/setup-deno@v2 | ||
with: | ||
deno-version: v2.x | ||
- name: Install dependencies | ||
run: deno install | ||
- name: Run tests | ||
run: npm run test:deno | ||
|
||
testBun: | ||
name: 'Test: Bun' | ||
timeout-minutes: 15 | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: oven-sh/setup-bun@v2 | ||
with: | ||
bun-version: latest | ||
- name: Install Dependencies | ||
run: bun install --frozen-lockfile | ||
- name: Run tests | ||
run: npm run test:bun |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,50 @@ | ||
/node_modules/ | ||
npm-debug.log | ||
.DS_Store | ||
yarn.lock | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
/coverage | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules | ||
jspm_packages | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# macOS finder cache file | ||
.DS_Store | ||
|
||
# VS Code settings | ||
.vscode | ||
|
||
# Cache | ||
.cache | ||
|
||
# Compiled output | ||
/dist | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": "@sanity/semantic-release-preset", | ||
"branches": ["main"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# Migration guide | ||
|
||
## v2 to v3 | ||
|
||
### Code changes | ||
|
||
#### Named export | ||
|
||
The module now uses named exports instead of a default export. This means you need to change your import statements from: | ||
|
||
**ESM:** | ||
|
||
```diff | ||
-import EventSource from 'eventsource' | ||
import {EventSource} from 'eventsource' | ||
``` | ||
|
||
**CommonJS:** | ||
|
||
```diff | ||
-const EventSource = require('eventsource') | ||
const {EventSource} = require('eventsource') | ||
``` | ||
|
||
#### UMD bundle dropped | ||
|
||
If you were previously importing/using the `eventsource-polyfill.js` file/module, you should instead use a bundler like Vite, Rollup or similar. You can theoretically also use something like [esm.sh](https://esm.sh/) to load the module directly in the browser - eg: | ||
|
||
```ts | ||
import {EventSource} from 'https://esm.sh/[email protected]' | ||
``` | ||
|
||
#### Custom headers dropped | ||
|
||
In v2 you could specify custom headers through the `headers` property in the options/init object to the constructor. In v3, the same can be achieved by passing a custom `fetch` function: | ||
|
||
```diff | ||
const es = new EventSource('https://my-server.com/sse', { | ||
- headers: {Authorization: 'Bearer foobar'} | ||
+ fetch: (input, init) => fetch(input, { | ||
+ ...init, | ||
+ headers: {...init.headers, Authorization: 'Bearer foobar'}, | ||
+ }), | ||
}) | ||
``` | ||
|
||
#### HTTP/HTTPS proxy dropped | ||
|
||
Use a package like [`node-fetch-native`](https://github.com/unjs/node-fetch-native) to add proxy support, either through environment variables or explicit configuration. | ||
|
||
```ts | ||
// npm install node-fetch-native --save | ||
import {fetch} from 'node-fetch-native/proxy' | ||
|
||
const es = new EventSource('https://my-server.com/sse', { | ||
fetch: (input, init) => fetch(input, init), | ||
}) | ||
``` | ||
|
||
#### Custom HTTPS/connection options dropped | ||
|
||
Use a package like [`undici`](https://github.com/nodejs/undici) for more control of fetch options through the use of an [`Agent`](https://undici.nodejs.org/#/docs/api/Agent.md). | ||
|
||
```ts | ||
// npm install undici --save | ||
import {fetch, Agent} from 'undici' | ||
|
||
await fetch('https://my-server.com/sse', { | ||
dispatcher: new Agent({ | ||
connect: { | ||
rejectUnauthorized: false, | ||
}, | ||
}), | ||
}) | ||
``` | ||
|
||
### Behavior changes | ||
|
||
#### New default reconnect timeout | ||
|
||
The default reconnect timeout is now 3 seconds - up from 1 second in v1/v2. This aligns better with browsers (Chrome and Safari, Firefox uses 5 seconds). Servers are (as always) free to set their own reconnect timeout through the `retry` field. | ||
|
||
#### Redirect handling | ||
|
||
Redirect handling now matches Chrome/Safari. On disconnects, we will always reconnect to the _original_ URL. In v1/v2, only HTTP 307 would reconnect to the original, while 301 and 302 would both redirect to the _destination_. | ||
|
||
While the _ideal_ behavior would be for 301 and 308 to reconnect to the redirect _destination_, and 302/307 to reconnect to the _original_ URL, this is not possible to do cross-platform (cross-origin requests in browsers do not allow reading location headers, and redirect handling will have to be done manually). |
Oops, something went wrong.