From 450c6fa0149ba4a66644daf0bb625dab684e73d2 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 16 Jul 2024 23:41:36 +0200 Subject: [PATCH 1/6] feat: add CloseEvent class as it doesn't exist for some versions of Node.js --- packages/node-ws/src/events.ts | 32 ++++++++++++++++++++++++++++++++ packages/node-ws/src/index.ts | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 packages/node-ws/src/events.ts diff --git a/packages/node-ws/src/events.ts b/packages/node-ws/src/events.ts new file mode 100644 index 00000000..c2875ed1 --- /dev/null +++ b/packages/node-ws/src/events.ts @@ -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 class CloseEvent 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 ?? '' + } +} diff --git a/packages/node-ws/src/index.ts b/packages/node-ws/src/index.ts index d95f704b..e8a45b8a 100644 --- a/packages/node-ws/src/index.ts +++ b/packages/node-ws/src/index.ts @@ -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 From e7f367efab4b20ba7c5a9e2b12f6b3fe10a255f2 Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 16 Jul 2024 23:45:25 +0200 Subject: [PATCH 2/6] chore(style): remove semicolon --- packages/node-ws/src/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node-ws/src/index.test.ts b/packages/node-ws/src/index.test.ts index 5ab99312..0848a576 100644 --- a/packages/node-ws/src/index.test.ts +++ b/packages/node-ws/src/index.test.ts @@ -126,7 +126,7 @@ describe('WebSocket helper', () => { await new Promise((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) From 09c1d62b6dcd40ca273029111a58cbc546b794dc Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 16 Jul 2024 23:53:26 +0200 Subject: [PATCH 3/6] test: add promise to check if "onClose" doesn't crashes --- packages/node-ws/src/index.test.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/node-ws/src/index.test.ts b/packages/node-ws/src/index.test.ts index 0848a576..2bad65f1 100644 --- a/packages/node-ws/src/index.test.ts +++ b/packages/node-ws/src/index.test.ts @@ -13,7 +13,7 @@ describe('WebSocket helper', () => { beforeEach(async () => { app = new Hono() - ;({ injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })) + ; ({ injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })) server = await new Promise((resolve) => { const server = serve({ fetch: app.fetch, port: 3030 }, () => resolve(server)) @@ -108,6 +108,19 @@ describe('WebSocket helper', () => { connections.forEach((ws) => ws.close()) }) + it('CloseEvent should be executed without crash', async () => { + app.get( + '/', + upgradeWebSocket(() => ({ + onClose() {}, + })) + ) + + const ws = new WebSocket('ws://localhost:3030/') + await new Promise((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((resolve) => app.get( From da69a9f9232987c75b7753c762537806841eaab7 Mon Sep 17 00:00:00 2001 From: Quentin Date: Wed, 17 Jul 2024 11:35:18 +0000 Subject: [PATCH 4/6] chore(style): apply eslint rules --- packages/node-ws/src/index.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/node-ws/src/index.test.ts b/packages/node-ws/src/index.test.ts index 2bad65f1..9cb12cb0 100644 --- a/packages/node-ws/src/index.test.ts +++ b/packages/node-ws/src/index.test.ts @@ -13,7 +13,8 @@ describe('WebSocket helper', () => { beforeEach(async () => { app = new Hono() - ; ({ injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })) + + ;({ injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })) server = await new Promise((resolve) => { const server = serve({ fetch: app.fetch, port: 3030 }, () => resolve(server)) @@ -112,13 +113,15 @@ describe('WebSocket helper', () => { app.get( '/', upgradeWebSocket(() => ({ - onClose() {}, + onClose() { + // doing some stuff here + }, })) ) const ws = new WebSocket('ws://localhost:3030/') await new Promise((resolve) => ws.on('open', resolve)) - ws.close(); + ws.close() }) it('Should be able to send and receive binary content with good length', async () => { From 64f7c92e2b205469fbc56c706d27ddaf9dbb982c Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 18 Jul 2024 19:41:59 +0200 Subject: [PATCH 5/6] ref: use `globalThis.CloseEvent` whenever possible or fallback to custom CloseEvent class --- packages/node-ws/src/events.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node-ws/src/events.ts b/packages/node-ws/src/events.ts index c2875ed1..539762b2 100644 --- a/packages/node-ws/src/events.ts +++ b/packages/node-ws/src/events.ts @@ -7,7 +7,7 @@ interface CloseEventInit extends EventInit { /** * @link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent */ -export class CloseEvent extends Event { +export const CloseEvent = globalThis.CloseEvent ?? class extends Event { #eventInitDict constructor( From 86632adbe33b3acef41a4f710516e621aebb5aff Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 18 Jul 2024 19:45:40 +0200 Subject: [PATCH 6/6] chore: add changeset --- .changeset/light-goats-teach.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/light-goats-teach.md diff --git a/.changeset/light-goats-teach.md b/.changeset/light-goats-teach.md new file mode 100644 index 00000000..bb4933eb --- /dev/null +++ b/.changeset/light-goats-teach.md @@ -0,0 +1,5 @@ +--- +'@hono/node-ws': patch +--- + +Add a `CloseEvent` class to avoid exception "CloseEvent is not defined"