diff --git a/packages/graphql-playground-react/package.json b/packages/graphql-playground-react/package.json index cb94a232c..d3b607efa 100644 --- a/packages/graphql-playground-react/package.json +++ b/packages/graphql-playground-react/package.json @@ -112,7 +112,6 @@ "@types/lru-cache": "^4.1.1", "apollo-link": "^1.2.13", "apollo-link-http": "^1.5.16", - "apollo-link-ws": "^1.0.19", "calculate-size": "^1.1.1", "codemirror": "^5.58.1", "codemirror-graphql": "^0.12.3", @@ -121,6 +120,7 @@ "cuid": "^1.3.8", "graphiql": "^0.17.5", "graphql": "^15.3.0", + "graphql-ws": "^2.0.1", "immutable": "^4.0.0-rc.9", "isomorphic-fetch": "^2.2.1", "js-yaml": "^3.10.0", @@ -157,7 +157,6 @@ "reselect": "^4.0.0", "seamless-immutable": "^7.0.1", "styled-components": "^4.0.0", - "subscriptions-transport-ws": "^0.9.5", "utility-types": "^1.0.0", "webpack-bundle-analyzer": "^3.3.2", "zen-observable": "^0.7.1" diff --git a/packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts b/packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts new file mode 100644 index 000000000..35df59b49 --- /dev/null +++ b/packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts @@ -0,0 +1,43 @@ +import { ApolloLink, Operation, FetchResult, Observable } from 'apollo-link'; +import { print, GraphQLError } from 'graphql'; +import { Client } from 'graphql-ws'; + +export class WebSocketLink extends ApolloLink { + + constructor(private client: Client) { + super(); + } + + public request(operation: Operation): Observable { + return new Observable((sink) => { + return this.client.subscribe( + { ...operation, query: print(operation.query) }, + { + next: sink.next.bind(sink), + complete: sink.complete.bind(sink), + error: (err) => { + if (err instanceof Error) { + sink.error(err); + } else if (err instanceof CloseEvent) { + sink.error( + new Error( + `Socket closed with event ${err.code}` + err.reason + ? `: ${err.reason}` // reason will be available on clean closes + : '', + ), + ); + } else { + sink.error( + new Error( + (err as GraphQLError[]) + .map(({ message }) => message) + .join(', '), + ), + ); + } + }, + }, + ); + }); + } +} \ No newline at end of file diff --git a/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts b/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts index 43c8e5443..68d4f4b02 100644 --- a/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts +++ b/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts @@ -1,8 +1,8 @@ import { ApolloLink, execute } from 'apollo-link' import { parseHeaders } from '../../components/Playground/util/parseHeaders' -import { SubscriptionClient } from 'subscriptions-transport-ws' +import { createClient as createSubscriptionClient, Client as SubscriptionClient } from 'graphql-ws' import { HttpLink } from 'apollo-link-http' -import { WebSocketLink } from 'apollo-link-ws' +import { WebSocketLink } from './WebSocketLink' import { isSubscription } from '../../components/Playground/util/hasSubscription' import { takeLatest, @@ -77,10 +77,11 @@ export const defaultLinkCreator = ( return { link: httpLink } } - const subscriptionClient = new SubscriptionClient(subscriptionEndpoint, { - timeout: 20000, + const subscriptionClient = createSubscriptionClient({ + retryTimeout: 20000, lazy: true, connectionParams, + url: session.endpoint.replace('http', 'ws'), }) const webSocketLink = new WebSocketLink(subscriptionClient) @@ -143,7 +144,7 @@ function* runQuerySaga(action) { const channel = eventChannel(emitter => { let closed = false if (subscriptionClient && operationIsSubscription) { - subscriptionClient.onDisconnected(() => { + subscriptionClient.on('closed', () => { closed = true emitter({ error: new Error(