-
Notifications
You must be signed in to change notification settings - Fork 2
/
socket.js
78 lines (62 loc) · 2.03 KB
/
socket.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import {graphql} from 'graphql';
import * as db from '../database';
import * as events from '../events';
import {schema} from '../schema';
let userCounter = 0;
let version = new Date().getTime().toString();
export const connect = socket => {
const user = db.createUser({name: `Guest${userCounter++}`});
db.loginUser(user.id);
let subscriptions = {};
const rootValue = {userId: user.id};
socket.on('disconnect', () => {
db.logoutUser(user.id);
Object.values(subscriptions).forEach(({channel,listener}) =>
events.unsubscribe(channel, listener)
)
});
socket.on('graphql/queries', requests => {
requests.forEach(request => {
execute(schema, request.query, rootValue, request.variables).then(response => {
socket.emit('graphql/query/response', {
id: request.id,
...response
});
});
});
});
socket.on('graphql/mutation', request => {
execute(schema, request.query, rootValue, request.variables).then(response => {
socket.emit('graphql/mutation/response', {
id: request.id,
...response
});
});
});
socket.on('graphql/subscription', async request => {
const channel = await events.channelForSubscription(request);
const listener = ev => handleSubscription(request, ev);
subscriptions[request.id] = {
channel,
listener
}
events.subscribe(channel, listener);
});
socket.on('graphql/subscription/unsubscribe', ({id}) => {
const {channel,listener} = subscriptions[id];
events.unsubscribe(channel, listener);
delete subscriptions[id];
});
const handleSubscription = (request, event) => {
execute(schema, request.query, {...rootValue, event }, request.variables).then(response => {
socket.emit('graphql/subscription/response', {
id: request.id,
...response
});
});
}
}
const execute = (schema, query, rootValue, variables, operationName) => {
return graphql(schema, query, rootValue, variables, operationName)
.catch(error => ({errors: [error]}));
}