Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jquense committed Oct 5, 2021
1 parent 52d8b6e commit 030b3df
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 1 deletion.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@
"conventionalCommits": true
},
"dependencies": {
"@types/ws": "^7.4.1",
"express": "^4.17.1",
"redis": "^3.1.2"
"graphql-ws": "^4.3.2",
"redis": "^3.1.2",
"ws": "^7.4.4"
},
"peerDependencies": {
"graphql": ">=0.12.3",
Expand Down
110 changes: 110 additions & 0 deletions src/GraphqlSocketSubscriptionServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import type { IncomingMessage } from 'http';
import { promisify } from 'util';

import express from 'express';
import type { GraphQLSchema } from 'graphql';
import { useServer } from 'graphql-ws/lib/use/ws';
import ws from 'ws';

import AuthorizedSocketConnection from './AuthorizedSocketConnection';
import type { CreateValidationRules } from './AuthorizedSocketConnection';
import type { CredentialsManager } from './CredentialsManager';
import type { CreateLogger, Logger } from './Logger';
import type { Subscriber } from './Subscriber';

export type SubscriptionServerConfig<TContext, TCredentials> = {
path: string;
schema: GraphQLSchema;
subscriber: Subscriber<any>;
createCredentialsManager: (request: any) => CredentialsManager<TCredentials>;
hasPermission: (data: any, credentials: TCredentials) => boolean;
createContext?: (
request: any,
credentials: TCredentials | null | undefined,
) => TContext;
maxSubscriptionsPerConnection?: number;
createValidationRules?: CreateValidationRules;
createLogger?: CreateLogger;
};

// eslint-disable-next-line @typescript-eslint/no-empty-function
const defaultCreateLogger = () => () => {};

export default class SubscriptionServer<TContext, TCredentials> {
config: SubscriptionServerConfig<TContext, TCredentials>;

log: Logger;

server: ws.Server | null = null;

constructor(config: SubscriptionServerConfig<TContext, TCredentials>) {
this.config = config;

const createLogger: CreateLogger =
config.createLogger || defaultCreateLogger;
this.log = createLogger('@4c/SubscriptionServer::Server');
}

attach(httpServer: any) {
this.server = new ws.Server({
server: httpServer,
path: this.config.path,
});

const { createContext } = this.config;

useServer(
// from the previous step
{
schema: this.config.schema,
context: (ctx, msg, args) => {

},
onConnect()

// credentialsManager: this.config.createCredentialsManager(request),
// hasPermission: this.config.hasPermission,
createContext:
createContext &&
((credentials: TCredentials | null | undefined) =>
createContext(request, credentials)),
maxSubscriptionsPerConnection: this.config
.maxSubscriptionsPerConnection,
createValidationRules: this.config.createValidationRules,
createLogger: this.config.createLogger || defaultCreateLogger,
},
wsServer,
);

this.server.on('connection', this.handleConnection);
}

handleConnection = (socket: ws, req: IncomingMessage) => {
this.log('debug', 'new socket connection');

const request = Object.create((express as any).request);
Object.assign(request, req);

const { createContext } = this.config;

// eslint-disable-next-line no-new
new AuthorizedSocketConnection(socket, {
schema: this.config.schema,
subscriber: this.config.subscriber,
credentialsManager: this.config.createCredentialsManager(request),
hasPermission: this.config.hasPermission,
createContext:
createContext &&
((credentials: TCredentials | null | undefined) =>
createContext(request, credentials)),
maxSubscriptionsPerConnection: this.config.maxSubscriptionsPerConnection,
createValidationRules: this.config.createValidationRules,
createLogger: this.config.createLogger || defaultCreateLogger,
});
};

async close() {
// @ts-ignore
await promisify((...args) => this.io.close(...args))();
}
}
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1985,6 +1985,13 @@
dependencies:
"@types/node" "*"

"@types/ws@^7.4.1":
version "7.4.1"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.1.tgz#49eacb15a0534663d53a36fbf5b4d98f5ae9a73a"
integrity sha512-ISCK1iFnR+jYv7+jLNX0wDqesZ/5RAeY3wUx6QaphmocphU61h+b+PHjS18TF4WIPTu/MMzxIq2PHr32o2TS5Q==
dependencies:
"@types/node" "*"

"@types/yargs-parser@*":
version "15.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
Expand Down Expand Up @@ -5902,6 +5909,11 @@ graphql-relay@^0.8.0:
resolved "https://registry.yarnpkg.com/graphql-relay/-/graphql-relay-0.8.0.tgz#35f0090f0f056192767c1acdaa402daed19ede6d"
integrity sha512-NU7CkwNxPzkqpBgv76Cgycrc3wmWVA2K5Sxm9DHSSLLuQTpaSRAUsX1sf2gITf+XQpkccsv56/z0LojXTyQbUw==

graphql-ws@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.3.2.tgz#c58b03acc3bd5d4a92a6e9f729d29ba5e90d46a3"
integrity sha512-jsW6eOlko7fJek1iaSGQFj97AWuhexL9A3PuxYtyke/VlMdbSFzmDR4PlPPCTBBskRg6tNRb5RTbBVSd2T60JQ==

graphql@^15.5.1:
version "15.5.1"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.1.tgz#f2f84415d8985e7b84731e7f3536f8bb9d383aad"
Expand Down Expand Up @@ -12751,6 +12763,11 @@ ws@^6.2.1:
dependencies:
async-limiter "~1.0.0"

ws@^7.4.4:
version "7.4.4"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59"
integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==

ws@^7.4.5:
version "7.5.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6"
Expand Down

0 comments on commit 030b3df

Please sign in to comment.