Skip to content
This repository has been archived by the owner on Apr 14, 2023. It is now read-only.

Adds Support for Graphql ^0.11.0 #261

Merged
merged 7 commits into from
Sep 13, 2017
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog

### vNEXT
- Add support for GraphQL 0.11.0 [PR #261](https://github.com/apollographql/subscriptions-transport-ws/pull/261)
- **BREAKING CHANGE**: Remove support for Subscription Manager [PR #261](https://github.com/apollographql/subscriptions-transport-ws/pull/261)

### 0.8.3
- docs(README): Fix options example for subscribe methods [PR #266](https://github.com/apollographql/subscriptions-transport-ws/pull/266)
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ A quick way to add the `subscribe` and `unsubscribe` functions to the [network i
* `rootValue?: any` : Root value to use when executing GraphQL root operations
* `schema?: GraphQLSchema` : GraphQL schema object
* `execute?: (schema, document, rootValue, contextValue, variableValues, operationName) => Promise<ExecutionResult> | AsyncIterator<ExecutionResult>` : GraphQL `execute` function, provide the default one from `graphql` package. Return value of `AsyncItrator` is also valid since this package also support reactive `execute` methods.
* `subscribe?: (schema, document, rootValue, contextValue, variableValues, operationName) => AsyncIterator<ExecutionResult>` : GraphQL `subscribe` function, provide the default one from `graphql` package.
* `subscribe?: (schema, document, rootValue, contextValue, variableValues, operationName) => Promise<AsyncIterator<ExecutionResult>>` : GraphQL `subscribe` function, provide the default one from `graphql` package.
* `onOperation?: (message: SubscribeMessage, params: SubscriptionOptions, webSocket: WebSocket)` : optional method to create custom params that will be used when resolving this operation
* `onOperationComplete?: (webSocket: WebSocket, opId: string)` : optional method that called when a GraphQL operation is done (for query and mutation it's immeditaly, and for subscriptions when unsubscribing)
* `onConnect?: (connectionParams: Object, webSocket: WebSocket)` : optional method that called when a client connects to the socket, called with the `connectionParams` from the client, if the return value is an object, its elements will be added to the context. return `false` or throw an exception to reject the connection. May return a Promise.
Expand All @@ -324,7 +324,6 @@ A quick way to add the `subscribe` and `unsubscribe` functions to the [network i

* **@deprecated** `onSubscribe?: (message: SubscribeMessage, params: SubscriptionOptions, webSocket: WebSocket)` : optional method to create custom params that will be used when resolving this subscription
* **@deprecated** `onUnsubscribe?: (webSocket: WebSocket)` : optional method that called when a client unsubscribe
* **@deprecated** `subscriptionManager?: SubscriptionManager` : support for old implementation using `SubscriptionsManager` from `graphql-subscriptions` - an alternative for `graphql`'s built-in `execute` and `subscribe`.

- `socketOptions: {WebSocket.IServerOptions}` : options to pass to the WebSocket object (full docs [here](https://github.com/websockets/ws/blob/master/doc/ws.md))
* `server?: HttpServer` - existing HTTP server to use (use without `host`/`port`)
Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
"dependencies": {
"backo2": "^1.0.2",
"eventemitter3": "^2.0.3",
"graphql-subscriptions": "^0.4.4",
"graphql-tag": "^2.4.2",
"iterall": "^1.1.1",
"lodash.assign": "^4.2.0",
"lodash.isobject": "^3.0.2",
Expand All @@ -34,16 +32,20 @@
"prepublishOnly": "npm run compile && npm run browser-compile && rimraf src",
"postinstall": "node scripts/post-install.js"
},
"peerDependencies": {
"graphql": "^0.10.0 || ^0.11.0"
},
"devDependencies": {
"@types/chai": "^4.0.0",
"@types/graphql": "^0.10.1",
"@types/graphql": "^0.11.2",
"@types/lodash": "^4.14.68",
"@types/mocha": "^2.2.41",
"@types/node": "^8.0.8",
"@types/sinon": "^2.3.0",
"@types/ws": "^3.0.0",
"chai": "^4.0.2",
"graphql": "^0.10.1",
"graphql": "^0.11.3",
"graphql-subscriptions": "^0.5.0",
"istanbul": "^1.0.0-alpha.2",
"lodash": "^4.17.1",
"mocha": "^3.4.2",
Expand Down
110 changes: 0 additions & 110 deletions src/adapters/subscription-manager.ts

This file was deleted.

71 changes: 29 additions & 42 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as WebSocket from 'ws';

import MessageTypes from './message-types';
import { GRAPHQL_WS, GRAPHQL_SUBSCRIPTIONS } from './protocol';
import { SubscriptionManager } from 'graphql-subscriptions';
import isObject = require('lodash.isobject');
import {
parse,
Expand All @@ -13,7 +12,6 @@ import {
ValidationContext,
specifiedRules,
} from 'graphql';
import { executeFromSubscriptionManager } from './adapters/subscription-manager';
import { createEmptyIterable } from './utils/empty-iterable';
import { createAsyncIterator, forAwaitEach, isAsyncIterable } from 'iterall';
import { createIterableFromPromise } from './utils/promise-to-iterable';
Expand All @@ -24,6 +22,16 @@ import { IncomingMessage } from 'http';

export type ExecutionIterator = AsyncIterator<ExecutionResult>;

export interface ExecutionParams<TContext = any> {
query: string | DocumentNode;
variables: { [key: string]: any };
operationName: string;
context: TContext;
formatResponse?: Function;
formatError?: Function;
callback?: Function;
}

export type ConnectionContext = {
initPromise?: Promise<any>,
isLegacy: boolean,
Expand Down Expand Up @@ -51,14 +59,16 @@ export type ExecuteFunction = (schema: GraphQLSchema,
rootValue?: any,
contextValue?: any,
variableValues?: { [key: string]: any },
operationName?: string) => Promise<ExecutionResult> | AsyncIterator<ExecutionResult>;
operationName?: string) => Promise<ExecutionResult> |
AsyncIterator<ExecutionResult> |
Promise<AsyncIterator<ExecutionResult>>;

export type SubscribeFunction = (schema: GraphQLSchema,
document: DocumentNode,
rootValue?: any,
contextValue?: any,
variableValues?: { [key: string]: any },
operationName?: string) => AsyncIterator<ExecutionResult>;
operationName?: string) => AsyncIterator<ExecutionResult> | Promise<AsyncIterator<ExecutionResult>>;

export interface ServerOptions {
rootValue?: any;
Expand All @@ -73,10 +83,6 @@ export interface ServerOptions {
onDisconnect?: Function;
keepAlive?: number;

/**
* @deprecated subscriptionManager is deprecated, use executor instead
*/
subscriptionManager?: SubscriptionManager;
/**
* @deprecated onSubscribe is deprecated, use onOperation instead
*/
Expand Down Expand Up @@ -211,37 +217,20 @@ export class SubscriptionServer {
}

private loadExecutor(options: ServerOptions) {
const { subscriptionManager, execute, subscribe, schema, rootValue } = options;
const { execute, subscribe, schema, rootValue } = options;

if (!subscriptionManager && !execute) {
throw new Error('Must provide `subscriptionManager` or `execute` to websocket server constructor.');
if (!execute) {
throw new Error('Must provide `execute` for websocket server constructor.');
}

if (subscriptionManager && execute) {
throw new Error('Must provide `subscriptionManager` or `execute` and not both.');
}

if (subscribe && !execute) {
throw new Error('Must provide `execute` when providing `subscribe`!');
}

if (execute && !schema) {
throw new Error('Must provide `schema` when using `execute`.');
}

if (subscriptionManager) {
console.warn('subscriptionManager is deprecated, use `execute` or `subscribe` directly from `graphql-js`!');
if (!schema) {
throw new Error('`schema` is missing');
}

this.schema = schema;
this.rootValue = rootValue;

if (subscriptionManager) {
this.execute = executeFromSubscriptionManager(subscriptionManager);
} else {
this.execute = execute;
this.subscribe = subscribe;
}
this.execute = execute;
this.subscribe = subscribe;
}

private unsubscribe(connectionContext: ConnectionContext, opId: string) {
Expand Down Expand Up @@ -349,7 +338,7 @@ export class SubscriptionServer {
this.unsubscribe(connectionContext, opId);
}

const baseParams = {
const baseParams: ExecutionParams = {
query: parsedMessage.payload.query,
variables: parsedMessage.payload.variables,
operationName: parsedMessage.payload.operationName,
Expand Down Expand Up @@ -385,15 +374,8 @@ export class SubscriptionServer {
}

const document = typeof baseParams.query !== 'string' ? baseParams.query : parse(baseParams.query);
let executionIterable: AsyncIterator<ExecutionResult>;
let validationErrors: Error[] = [];

if ( this.schema ) {
// NOTE: This is a temporary condition to support the legacy subscription manager.
// As soon as subscriptionManager support is removed, we can remove the if
// and keep only the validation part.
validationErrors = validate(this.schema, document, this.specifiedRules);
}
let executionIterable: AsyncIterator<ExecutionResult> | Promise<AsyncIterator<ExecutionResult>>;
const validationErrors: Error[] = validate(this.schema, document, this.specifiedRules);

if ( validationErrors.length > 0 ) {
executionIterable = createIterableFromPromise<ExecutionResult>(
Expand Down Expand Up @@ -428,6 +410,11 @@ export class SubscriptionServer {
}
}

return Promise.resolve(executionIterable).then((ei) => ({
executionIterable: ei,
params,
}));
}).then(({ executionIterable, params }) => {
forAwaitEach(
createAsyncIterator(executionIterable) as any,
(value: ExecutionResult) => {
Expand Down
Loading