Skip to content
This repository was archived by the owner on May 17, 2025. It is now read-only.

chore(deps): update dependency graphql-ws to v6 #346

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented Jan 20, 2025

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
graphql-ws (source) 5.16.2 -> 6.0.5 age adoption passing confidence

Release Notes

enisdenjo/graphql-ws (graphql-ws)

v6.0.5

Compare Source

Patch Changes

v6.0.4

Compare Source

Patch Changes

v6.0.3

Compare Source

Patch Changes
  • 747c01c Thanks @​enisdenjo! - Drop ExecutionPatchResult and FormattedExecutionPatchResult types

    Neither of the types are officially supported (yet) and the future versions of graphql-js adding support for stream/defer will a different signature for the incremental execution result.

v6.0.2

Compare Source

Patch Changes

v6.0.1

Compare Source

Patch Changes

v6.0.0

Compare Source

Major Changes
Migrating from v5 to v6
import { makeHandler } from 'graphql-ws/use/@​fastify/websocket';

makeHandler({
  schema(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  context(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onConnect(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onDisconnect(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onClose(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onSubscribe(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onOperation(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onError(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onNext(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
  onComplete(ctx) {
-   const websocket = ctx.connection;
+   const websocket = ctx.socket;
  },
});
Migrating from v5 to v6

Simply remove the /lib/ part from your graphql-ws imports that use a handler.

ws
- import { useServer } from 'graphql-ws/lib/use/ws';
+ import { useServer } from 'graphql-ws/use/ws';
uWebSockets.js
- import { makeBehavior } from 'graphql-ws/lib/use/uWebSockets';
+ import { makeBehavior } from 'graphql-ws/use/uWebSockets';
@​fastify/websocket
- import { makeHandler } from 'graphql-ws/lib/use/@​fastify/websocket';
+ import { makeHandler } from 'graphql-ws/use/@​fastify/websocket';
Bun
- import { handleProtocols, makeHandler } from 'graphql-ws/lib/use/bun';
+ import { handleProtocols, makeHandler } from 'graphql-ws/use/bun';
Deno
- import { makeHandler } from 'https://esm.sh/graphql-ws/lib/use/deno';
+ import { makeHandler } from 'https://esm.sh/graphql-ws/use/deno';
  • #​613 3f11aba Thanks @​enisdenjo! - ErrorMessage uses and onError returns GraphQLFormattedError (instead of GraphQLError)

    Thanks @​benjie for working on this in #​599

  • #​613 3f11aba Thanks @​enisdenjo! - Least supported Node version is v20

    Node v10 has been deprecated for years now. There is no reason to support it. Bumping the engine to the current LTS (v20) also allows the code to be leaner and use less polyfills.

  • #​613 3f11aba Thanks @​enisdenjo! - Least supported graphql peer dependency is ^15.10.1 and ^16

    Users are advised to use the latest of graphql because of various improvements in performance and security.

  • #​613 3f11aba Thanks @​enisdenjo! - NextMessage uses and onNext returns FormattedExecutionResult (instead of ExecutionResult)

  • #​613 3f11aba Thanks @​enisdenjo! - schema, context, onSubscribe, onOperation, onError, onNext and onComplete hooks don't have the full accompanying message anymore, only the ID and the relevant part from the message

    There is really no need to pass the full SubscribeMessage to the onSubscribe hook. The only relevant parts from the message are the id and the payload, the type is useless since the hook inherently has it (onNext is next type, onError is error type, etc).

    The actual techincal reason for not having the full message is to avoid serialising results and errors twice. Both onNext and onError allow the user to augment the result and return it to be used instead. onNext originally had the NextMessage argument which already has the FormattedExecutionResult, and onError originally had the ErrorMessage argument which already has the GraphQLFormattedError, and they both also returned FormattedExecutionResult and GraphQLFormattedError respectivelly - meaning, if the user serialised the results - the serialisation would happen twice.

    Additionally, the onOperation, onError, onNext and onComplete now have the payload which is the SubscribeMessage.payload (SubscribePayload) for easier access to the original query as well as execution params extensions.

Migrating from v5 to v6
schema
import { ExecutionArgs } from 'graphql';
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- schema(ctx, message, argsWithoutSchema: Omit<ExecutionArgs, 'schema'>) {
-   const messageId = message.id;
-   const messagePayload: SubscribePayload = message.payload;
- },
+ schema(ctx, id, payload) {
+   const messageId = id;
+   const messagePayload: SubscribePayload = payload;
+ },
};
context
import { ExecutionArgs } from 'graphql';
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- context(ctx, message, args: ExecutionArgs) {
-   const messageId = message.id;
-   const messagePayload: SubscribePayload = message.payload;
- },
+ context(ctx, id, payload, args: ExecutionArgs) {
+   const messageId = id;
+   const messagePayload: SubscribePayload = payload;
+ },
};
onSubscribe
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- onSubscribe(ctx, message) {
-   const messageId = message.id;
-   const messagePayload: SubscribePayload = message.payload;
- },
+ onSubscribe(ctx, id, payload) {
+   const messageId = id;
+   const messagePayload: SubscribePayload = payload;
+ },
};
onOperation

The SubscribeMessage.payload is not useful here at all, the payload has been parsed to ready-to-use graphql execution args and should be used instead.

import { ExecutionArgs } from 'graphql';
import { ServerOptions, SubscribePayload, OperationResult } from 'graphql-ws';

const opts: ServerOptions = {
- onOperation(ctx, message, args: ExecutionArgs, result: OperationResult) {
-   const messageId = message.id;
-   const messagePayload: SubscribePayload = message.payload;
- },
+ onOperation(ctx, id, payload, args: ExecutionArgs, result: OperationResult) {
+   const messageId = id;
+   const messagePayload: SubscribePayload = payload;
+ },
};
onError

The ErrorMessage.payload (GraphQLFormattedError[]) is not useful here at all, the user has access to GraphQLError[] that are true instances of the error containing object references to originalErrors and other properties. The user can always convert and return GraphQLFormattedError[] by using the .toJSON() method.

import { GraphQLError, GraphQLFormattedError } from 'graphql';
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- onError(ctx, message, errors) {
-   const messageId = message.id;
-   const graphqlErrors: readonly GraphQLError[] = errors;
-   const errorMessagePayload: readonly GraphQLFormattedError[] = message.payload;
- },
+ onError(ctx, id, payload, errors) {
+   const messageId = id;
+   const graphqlErrors: readonly GraphQLError[] = errors;
+   const subscribeMessagePayload: SubscribePayload = payload;
+   const errorMessagePayload: readonly GraphQLFormattedError[] = errors.map((e) => e.toJSON());
+ },
};
onNext

The NextMessage.payload (FormattedExecutionResult) is not useful here at all, the user has access to ExecutionResult that contains actual object references to error instances. The user can always convert and return FormattedExecutionResult by serialising the errors with GraphQLError.toJSON() method.

import { ExecutionArgs, ExecutionResult, FormattedExecutionResult } from 'graphql';
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- onNext(ctx, message, args: ExecutionArgs, result: ExecutionResult) {
-   const messageId = message.id;
-   const nextMessagePayload: FormattedExecutionResult = message.payload;
- },
+ onNext(ctx, id, payload, args: ExecutionArgs, result: ExecutionResult) {
+   const messageId = id;
+   const subscribeMessagePayload: SubscribePayload = payload;
+   const nextMessagePayload: FormattedExecutionResult = { ...result, errors: result.errors?.map((e) => e.toJSON()) };
+ },
};
onComplete
import { ServerOptions, SubscribePayload } from 'graphql-ws';

const opts: ServerOptions = {
- onComplete(ctx, message) {
-   const messageId = message.id;
- },
+ onComplete(ctx, id, payload) {
+   const messageId = id;
+   const subscribeMessagePayload: SubscribePayload = payload;
+ },
};
Migrating from v5 to v6

If you had used the suggested "ws server usage with custom subscribe method that gracefully handles thrown errors" recipe, you can simply remove it since this behaviour is now baked in.

import { subscribe } from 'graphql';
import { useServer } from 'graphql-ws/use/ws';
import { WebSocketServer } from 'ws'; // yarn add ws

const wsServer = new WebSocketServer({
  port: 4000,
  path: '/graphql',
});

useServer(
  {
    schema,
-   async subscribe(...args) {
-     const result = await subscribe(...args);
-     if ('next' in result) {
-       // is an async iterable, augment the next method to handle thrown errors
-       const originalNext = result.next;
-       result.next = async () => {
-         try {
-           return await originalNext();
-         } catch (err) {
-           // gracefully handle the error thrown from the next method
-           return { value: { errors: [err] } };
-         }
-       };
-     }
-     return result;
-   },
  },
  wsServer,
);
Migrating from v5 to v6

Replace all ocurrances of isMessage with validateMessage. Note that validateMessage throws if the message is not valid, compared with isMessage that simply returned true/false.

- import { isMessage } from 'graphql-ws';
+ import { validateMessage } from 'graphql-ws';

function isGraphQLWSMessage(val) {
- return isMessage(val);
+ try {
+   validateMessage(val);
+   return true;
+ } catch {
+   return false;
+ }
}
Migrating from v5 to v6

Replace all ocurrances of isFatalConnectionProblem with shouldRetry. Note that the result is inverted, where you returned false in isFatalConnectionProblem you should return true in shouldRetry.

import { createClient } from 'graphql-ws';

const client = createClient({
  url: 'ws://localhost:4000/graphql',
- isFatalConnectionProblem: () => false,
+ shouldRetry: () => true,
});
Minor Changes
  • #​613 3f11aba Thanks @​enisdenjo! - Client is truly zero-dependency, not even a peer dependency on graphql

    In non-browser environments, you can use only the client and not even depend on graphql by importing from graphql-ws/client.

    import { createClient } from 'graphql-ws/client';
    
    const client = createClient({
      url: 'ws://localhost:4000/graphql',
    });

    Note that, in browser envirments (and of course having your bundler use the browser package.json field), you don't have to import from graphql-ws/client - simply importing from graphql-ws will only have the createClient available.

  • #​615 29dd26a Thanks @​enisdenjo! - Define optional peer dependencies and least supported versions

    Using the peerDependencies in combination with peerDependenciesMeta configuration in package.json.


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

Copy link
Contributor Author

renovate bot commented Jan 20, 2025

Branch automerge failure

This PR was configured for branch automerge. However, this is not possible, so it has been raised as a PR instead.


  • Branch has one or more failed status checks

@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 4 times, most recently from 3f08236 to 80dd3be Compare January 27, 2025 08:09
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 2 times, most recently from b9e91fe to b5cd8ed Compare February 1, 2025 10:33
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 4 times, most recently from 91bfc4e to ab6582d Compare February 16, 2025 11:49
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 6 times, most recently from 2f3347f to c79738f Compare February 25, 2025 18:57
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 6 times, most recently from 7c49c87 to 4b92de5 Compare March 6, 2025 03:13
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 5 times, most recently from fe7f848 to 6453a33 Compare March 14, 2025 05:44
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 2 times, most recently from bbc8ca9 to 21c7398 Compare March 23, 2025 21:48
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 4 times, most recently from 1ef7e8c to e7248ad Compare March 30, 2025 22:26
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 3 times, most recently from 23b6c3f to c33e6d6 Compare April 5, 2025 02:35
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 2 times, most recently from bd8e987 to 896eb88 Compare April 12, 2025 14:15
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 3 times, most recently from 24020a9 to 17b1c61 Compare April 23, 2025 12:26
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 6 times, most recently from 2be0f06 to 1ab34fc Compare May 3, 2025 09:50
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 3 times, most recently from 2aad8ca to f19df7f Compare May 13, 2025 08:01
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch 2 times, most recently from a582c40 to 80a53a4 Compare May 16, 2025 22:45
@renovate renovate bot force-pushed the renovate/graphql-ws-6.x branch from 80a53a4 to 1732080 Compare May 17, 2025 02:42
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0 participants