fix(node-ws): `CloseEvent` is not defined (#648)
* feat: add CloseEvent class as it doesn't exist for some versions of Node.js * chore(style): remove semicolon * test: add promise to check if "onClose" doesn't crashes * chore(style): apply eslint rules * ref: use `globalThis.CloseEvent` whenever possible or fallback to custom CloseEvent class * chore: add changesetpull/653/head
parent
9467b7e54c
commit
139e34a907
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/node-ws': patch
|
||||
---
|
||||
|
||||
Add a `CloseEvent` class to avoid exception "CloseEvent is not defined"
|
|
@ -0,0 +1,32 @@
|
|||
interface CloseEventInit extends EventInit {
|
||||
code?: number;
|
||||
reason?: string;
|
||||
wasClean?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
|
||||
*/
|
||||
export const CloseEvent = globalThis.CloseEvent ?? class extends Event {
|
||||
#eventInitDict
|
||||
|
||||
constructor(
|
||||
type: string,
|
||||
eventInitDict: CloseEventInit = {}
|
||||
) {
|
||||
super(type, eventInitDict)
|
||||
this.#eventInitDict = eventInitDict
|
||||
}
|
||||
|
||||
get wasClean(): boolean {
|
||||
return this.#eventInitDict.wasClean ?? false
|
||||
}
|
||||
|
||||
get code(): number {
|
||||
return this.#eventInitDict.code ?? 0
|
||||
}
|
||||
|
||||
get reason(): string {
|
||||
return this.#eventInitDict.reason ?? ''
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ describe('WebSocket helper', () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
app = new Hono()
|
||||
|
||||
;({ injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app }))
|
||||
|
||||
server = await new Promise<ServerType>((resolve) => {
|
||||
|
@ -108,6 +109,21 @@ describe('WebSocket helper', () => {
|
|||
connections.forEach((ws) => ws.close())
|
||||
})
|
||||
|
||||
it('CloseEvent should be executed without crash', async () => {
|
||||
app.get(
|
||||
'/',
|
||||
upgradeWebSocket(() => ({
|
||||
onClose() {
|
||||
// doing some stuff here
|
||||
},
|
||||
}))
|
||||
)
|
||||
|
||||
const ws = new WebSocket('ws://localhost:3030/')
|
||||
await new Promise<void>((resolve) => ws.on('open', resolve))
|
||||
ws.close()
|
||||
})
|
||||
|
||||
it('Should be able to send and receive binary content with good length', async () => {
|
||||
const mainPromise = new Promise<WSMessageReceive>((resolve) =>
|
||||
app.get(
|
||||
|
@ -126,7 +142,7 @@ describe('WebSocket helper', () => {
|
|||
await new Promise<void>((resolve) => ws.on('open', resolve))
|
||||
ws.send(binaryData)
|
||||
|
||||
const receivedMessage = await mainPromise;
|
||||
const receivedMessage = await mainPromise
|
||||
expect(receivedMessage).toBeInstanceOf(Buffer)
|
||||
expect((receivedMessage as Buffer).byteLength).toBe(binaryData.length)
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Buffer } from 'buffer'
|
||||
import type { Server } from 'node:http'
|
||||
import type { Http2SecureServer, Http2Server } from 'node:http2'
|
||||
import type { Hono } from 'hono'
|
||||
|
@ -6,6 +5,7 @@ import type { UpgradeWebSocket, WSContext } from 'hono/ws'
|
|||
import type { WebSocket } from 'ws'
|
||||
import { WebSocketServer } from 'ws'
|
||||
import type { IncomingMessage } from 'http'
|
||||
import { CloseEvent } from './events'
|
||||
|
||||
export interface NodeWebSocket {
|
||||
upgradeWebSocket: UpgradeWebSocket
|
||||
|
|
Loading…
Reference in New Issue