From 230fff792928a2fd892bac8d293bca4e6015ef72 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 3 Jul 2025 21:50:31 +0200 Subject: [PATCH] fix: reuse `makeHooks` method from graphql-ws --- package.json | 6 ++--- pnpm-lock.yaml | 40 ++++++++++++++++++------------ src/websocket.ts | 63 +++--------------------------------------------- 3 files changed, 31 insertions(+), 78 deletions(-) diff --git a/package.json b/package.json index 59199be..f84cb03 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,7 @@ "@apollo/server": "^4.1.1", "h3": "^1.11.0", "graphql": "^16.0.0", - "graphql-ws": "^5.0.0", - "crossws": "^0.2.4" + "graphql-ws": "^6.0.5" }, "peerDependenciesMeta": { "graphql-ws": { @@ -52,7 +51,6 @@ "@graphql-tools/schema": "^10.0.3", "@jest/globals": "^29.7.0", "@typescript-eslint/parser": "^7.16.0", - "crossws": "^0.2.4", "@vitest/coverage-v8": "^2.0.1", "eslint": "^9.6.0", "eslint-config-prettier": "^9.1.0", @@ -60,7 +58,7 @@ "eslint-plugin-unused-imports": "^4.0.0", "graphql": "^16.9.0", "graphql-subscriptions": "^2.0.0", - "graphql-ws": "^5.15.0", + "graphql-ws": "^6.0.5", "h3": "^1.12.0", "jest": "^29.7.0", "listhen": "^1.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95fc5ec..9421ea5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 4.10.4(graphql@16.9.0) '@apollo/server-integration-testsuite': specifier: ^4.10.4 - version: 4.10.4(@jest/globals@29.7.0)(graphql-ws@5.16.0(graphql@16.9.0))(graphql@16.9.0)(jest@29.7.0(@types/node@20.11.30)) + version: 4.10.4(@jest/globals@29.7.0)(graphql-ws@6.0.5(graphql@16.9.0))(graphql@16.9.0)(jest@29.7.0(@types/node@20.11.30)) '@apollo/utils.withrequired': specifier: ^3.0.0 version: 3.0.0 @@ -29,9 +29,6 @@ importers: '@vitest/coverage-v8': specifier: ^2.0.1 version: 2.0.1(vitest@2.0.1(@types/node@20.11.30)) - crossws: - specifier: ^0.2.4 - version: 0.2.4 eslint: specifier: ^9.6.0 version: 9.6.0 @@ -51,8 +48,8 @@ importers: specifier: ^2.0.0 version: 2.0.0(graphql@16.9.0) graphql-ws: - specifier: ^5.15.0 - version: 5.16.0(graphql@16.9.0) + specifier: ^6.0.5 + version: 6.0.5(graphql@16.9.0) h3: specifier: ^1.12.0 version: 1.12.0 @@ -2296,11 +2293,24 @@ packages: peerDependencies: graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - graphql-ws@5.16.0: - resolution: {integrity: sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==} - engines: {node: '>=10'} + graphql-ws@6.0.5: + resolution: {integrity: sha512-HzYw057ch0hx2gZjkbgk1pur4kAtgljlWRP+Gccudqm3BRrTpExjWCQ9OHdIsq47Y6lHL++1lTvuQHhgRRcevw==} + engines: {node: '>=20'} peerDependencies: - graphql: '>=0.11 <=16' + '@fastify/websocket': ^10 || ^11 + crossws: ~0.3 + graphql: ^15.10.1 || ^16 + uWebSockets.js: ^20 + ws: ^8 + peerDependenciesMeta: + '@fastify/websocket': + optional: true + crossws: + optional: true + uWebSockets.js: + optional: true + ws: + optional: true graphql@16.9.0: resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} @@ -4201,7 +4211,7 @@ snapshots: dependencies: graphql: 16.9.0 - '@apollo/client@3.9.8(graphql-ws@5.16.0(graphql@16.9.0))(graphql@16.9.0)': + '@apollo/client@3.9.8(graphql-ws@6.0.5(graphql@16.9.0))(graphql@16.9.0)': dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@16.9.0) '@wry/caches': 1.0.1 @@ -4219,7 +4229,7 @@ snapshots: tslib: 2.6.2 zen-observable-ts: 1.2.5 optionalDependencies: - graphql-ws: 5.16.0(graphql@16.9.0) + graphql-ws: 6.0.5(graphql@16.9.0) transitivePeerDependencies: - '@types/react' @@ -4246,10 +4256,10 @@ snapshots: '@apollo/utils.logger': 2.0.1 graphql: 16.9.0 - '@apollo/server-integration-testsuite@4.10.4(@jest/globals@29.7.0)(graphql-ws@5.16.0(graphql@16.9.0))(graphql@16.9.0)(jest@29.7.0(@types/node@20.11.30))': + '@apollo/server-integration-testsuite@4.10.4(@jest/globals@29.7.0)(graphql-ws@6.0.5(graphql@16.9.0))(graphql@16.9.0)(jest@29.7.0(@types/node@20.11.30))': dependencies: '@apollo/cache-control-types': 1.0.3(graphql@16.9.0) - '@apollo/client': 3.9.8(graphql-ws@5.16.0(graphql@16.9.0))(graphql@16.9.0) + '@apollo/client': 3.9.8(graphql-ws@6.0.5(graphql@16.9.0))(graphql@16.9.0) '@apollo/server': 4.10.4(graphql@16.9.0) '@apollo/usage-reporting-protobuf': 4.1.1 '@apollo/utils.createhash': 2.0.1 @@ -6641,7 +6651,7 @@ snapshots: graphql: 16.9.0 tslib: 2.6.2 - graphql-ws@5.16.0(graphql@16.9.0): + graphql-ws@6.0.5(graphql@16.9.0): dependencies: graphql: 16.9.0 diff --git a/src/websocket.ts b/src/websocket.ts index 426d518..eb8addc 100644 --- a/src/websocket.ts +++ b/src/websocket.ts @@ -1,19 +1,14 @@ import { - makeServer, ServerOptions, ConnectionInitMessage, - GRAPHQL_TRANSPORT_WS_PROTOCOL, } from 'graphql-ws' +import { makeHooks } from 'graphql-ws/use/crossws' + import { - defineWebSocket, defineWebSocketHandler, EventHandler, EventHandlerRequest, } from 'h3' -// TODO: Import from h3 once it's exposed there -// Then also remove the explicit reference to crossws as a dependency in package.json -// https://github.com/unjs/h3/issues/716 -import type { Hooks, Peer } from 'crossws' /** * The extra that will be put in the `Context`. @@ -46,58 +41,8 @@ interface Client { export function defineGraphqlWebSocket< P extends ConnectionInitMessage['payload'] = ConnectionInitMessage['payload'], E extends Record = Record, ->(options: ServerOptions>): Partial { - const server = makeServer(options) - const peers = new WeakMap() - return defineWebSocket({ - open(peer) { - const client: Client = { - handleMessage: () => { - throw new Error('Message received before handler was registered') - }, - closed: () => { - throw new Error('Closed before handler was registered') - }, - } - - client.closed = server.opened( - { - // TODO: use protocol on socket once h3 exposes it - // https://github.com/unjs/crossws/issues/31 - protocol: GRAPHQL_TRANSPORT_WS_PROTOCOL, - send: (message) => { - // The peer might have been destroyed in the meantime, send only if exists - if (peers.has(peer)) { - peer.send(message) - } - }, - close: (_code, _reason) => { - if (peers.has(peer)) { - // TODO: No way to close a connection in crossws - // https://github.com/unjs/crossws/issues/23 - // peer.close(code, reason); - } - }, - onMessage: (cb) => (client.handleMessage = cb), - }, - { peer } as Extra & Partial, - ) - peers.set(peer, client) - }, - message(peer, message) { - const client = peers.get(peer) - if (!client) throw new Error('Message received for a missing client') - return client.handleMessage(message.text()) - }, - close(peer, details) { - const client = peers.get(peer) - if (!client) throw new Error('Closing a missing client') - // TODO: Once h3 exposes the protocol, add a check here for deprecated protocols - // similar to https://github.com/enisdenjo/graphql-ws/blob/6013eb54829b27bd7c598f0985ec80a0e1acf09c/src/use/deno.ts#L109-L116 - // TODO: Remove the fallback to 1000 once https://github.com/enisdenjo/graphql-ws/issues/547 is fixed - return client.closed(details.code ?? 1000, details.reason ?? '') - }, - }) +>(options: ServerOptions>) { + return makeHooks(options); } /** * Create a event handler to be used with [h3](https://h3.unjs.io/).