Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jquense committed May 17, 2021
1 parent e2c22e7 commit 5c0f46f
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 @@ -47,8 +47,11 @@
]
},
"dependencies": {
"@types/ws": "^7.4.1",
"express": "^4.17.1",
"redis": "^3.0.0"
"graphql-ws": "^4.3.2",
"redis": "^3.0.0",
"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 @@ -1995,6 +1995,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 @@ -5830,6 +5837,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.5
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==

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.4.0:
version "15.4.0"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.4.0.tgz#e459dea1150da5a106486ba7276518b5295a4347"
Expand Down Expand Up @@ -12525,6 +12537,11 @@ ws@^7.2.3:
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.0.tgz#a5dd76a24197940d4a8bb9e0e152bb4503764da7"
integrity sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==

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==

xdg-basedir@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
Expand Down

0 comments on commit 5c0f46f

Please sign in to comment.