Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions lib/web/eventsource/eventsource.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@ class EventSource extends EventTarget {
url = webidl.converters.USVString(url)
eventSourceInitDict = webidl.converters.EventSourceInitDict(eventSourceInitDict, prefix, 'eventSourceInitDict')

this.#dispatcher = eventSourceInitDict.dispatcher
this.#dispatcher = eventSourceInitDict.node.dispatcher || eventSourceInitDict.dispatcher
this.#state = {
lastEventId: '',
reconnectionTime: defaultReconnectionTime
reconnectionTime: eventSourceInitDict.node.reconnectionTime
}

// 2. Let settings be ev's relevant settings object.
Expand Down Expand Up @@ -472,6 +472,21 @@ webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([
{
key: 'dispatcher', // undici only
converter: webidl.converters.any
},
{
key: 'node', // undici only
converter: webidl.dictionaryConverter([
{
key: 'reconnectionTime',
converter: webidl.converters['unsigned long'],
defaultValue: () => defaultReconnectionTime
},
{
key: 'dispatcher',
converter: webidl.converters.any
}
]),
defaultValue: () => ({})
}
])

Expand Down
35 changes: 32 additions & 3 deletions test/eventsource/eventsource-connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const assert = require('node:assert')
const events = require('node:events')
const http = require('node:http')
const { test, describe } = require('node:test')
const { EventSource } = require('../../lib/web/eventsource/eventsource')
const { EventSource, defaultReconnectionTime } = require('../../lib/web/eventsource/eventsource')
const { randomInt } = require('node:crypto')

describe('EventSource - sending correct request headers', () => {
Expand Down Expand Up @@ -184,6 +184,7 @@ describe('EventSource - received response must have content-type to be text/even
})

test('should try to connect again if server is unreachable', async () => {
const reconnectionTime = defaultReconnectionTime
const domain = 'bad.n' + randomInt(1e10).toString(36) + '.proxy'

const eventSourceInstance = new EventSource(`http://${domain}`)
Expand All @@ -192,11 +193,39 @@ describe('EventSource - received response must have content-type to be text/even
eventSourceInstance.onerror = (error) => {
onerrorCalls.push(error)
}
await events.once(eventSourceInstance, 'error')

await new Promise(resolve => setTimeout(resolve, 8000))
const start = Date.now()
await events.once(eventSourceInstance, 'error')
await events.once(eventSourceInstance, 'error')
await events.once(eventSourceInstance, 'error')
const end = Date.now()

eventSourceInstance.close()

assert.strictEqual(onerrorCalls.length, 3)
assert.strictEqual(end - start < (3.5 * reconnectionTime), true)
})

test('should try to connect again if server is unreachable', async () => {
const reconnectionTime = 500

const domain = 'bad.n' + randomInt(1e10).toString(36) + '.proxy'

const eventSourceInstance = new EventSource(`http://${domain}`, {
node: {
reconnectionTime
}
})
await events.once(eventSourceInstance, 'error')

const start = Date.now()
await events.once(eventSourceInstance, 'error')
await events.once(eventSourceInstance, 'error')
await events.once(eventSourceInstance, 'error')
const end = Date.now()

eventSourceInstance.close()

assert.strictEqual(end - start < (3.5 * reconnectionTime), true)
})
})
33 changes: 33 additions & 0 deletions test/eventsource/eventsource-custom-dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,36 @@ test('EventSource allows setting custom dispatcher.', async (t) => {

await completed
})

test('EventSource allows setting custom dispatcher in EventSourceDict.', async (t) => {
const { completed, deepStrictEqual } = tspl(t, { plan: 1 })

const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => {
res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' })
deepStrictEqual(req.headers['x-customer-header'], 'hello world')

res.end()
}).listen(0)

t.after(() => {
server.close()
eventSourceInstance.close()
})

await once(server, 'listening')

class CustomHeaderAgent extends Agent {
dispatch (opts) {
opts.headers['x-customer-header'] = 'hello world'
return super.dispatch(...arguments)
}
}

const eventSourceInstance = new EventSource(`http://localhost:${server.address().port}`, {
node: {
dispatcher: new CustomHeaderAgent()
}
})

await completed
})
7 changes: 6 additions & 1 deletion types/eventsource.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ export declare const EventSource: {
}

interface EventSourceInit {
withCredentials?: boolean,
withCredentials?: boolean
// @deprecated use `node.dispatcher` instead
dispatcher?: Dispatcher
node?: {
dispatcher?: Dispatcher
reconnectionTime?: number
}
}
Loading