@eleven-am/pondsocket 0.1.49 → 0.1.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/abstracts/abstractRequest.js +58 -0
- package/abstracts/middleware.js +51 -0
- package/channel/channel.js +253 -0
- package/{server/channel → channel}/eventRequest.js +4 -1
- package/channel/eventResponse.js +150 -0
- package/client/channel.js +120 -97
- package/client.d.ts +2 -3
- package/client.js +34 -20
- package/endpoint/endpoint.js +233 -0
- package/endpoint/response.js +86 -0
- package/enums.js +14 -10
- package/errors/pondError.js +27 -0
- package/express.d.ts +2 -2
- package/express.js +3 -3
- package/index.d.ts +1 -2
- package/index.js +1 -4
- package/lobby/joinRequest.js +39 -0
- package/lobby/joinResponse.js +125 -0
- package/lobby/lobby.js +174 -0
- package/matcher/matcher.js +94 -0
- package/node.d.ts +2 -3
- package/node.js +3 -4
- package/package.json +3 -2
- package/presence/presence.js +113 -0
- package/server/pondSocket.js +123 -0
- package/subjects/subject.js +93 -0
- package/types.d.ts +274 -323
- package/client/channel.test.js +0 -546
- package/server/abstracts/abstractRequest.js +0 -40
- package/server/abstracts/abstractRequest.test.js +0 -41
- package/server/abstracts/middleware.js +0 -38
- package/server/abstracts/middleware.test.js +0 -70
- package/server/channel/channelEngine.js +0 -280
- package/server/channel/channelEngine.test.js +0 -377
- package/server/channel/channelRequest.test.js +0 -29
- package/server/channel/channelResponse.test.js +0 -164
- package/server/channel/eventResponse.js +0 -153
- package/server/endpoint/connectionResponse.js +0 -64
- package/server/endpoint/endpoint.js +0 -253
- package/server/endpoint/endpoint.test.js +0 -428
- package/server/endpoint/endpointResponse.test.js +0 -43
- package/server/pondChannel/joinRequest.js +0 -29
- package/server/pondChannel/joinResponse.js +0 -103
- package/server/pondChannel/pondChannel.js +0 -185
- package/server/pondChannel/pondChannelResponse.test.js +0 -109
- package/server/presence/presenceEngine.js +0 -107
- package/server/presence/presenceEngine.test.js +0 -105
- package/server/server/pondSocket.js +0 -121
- package/server/server/server.test.js +0 -121
- package/server/utils/matchPattern.js +0 -108
- package/server/utils/matchPattern.test.js +0 -76
- package/server/utils/subjectUtils.js +0 -68
- package/server/utils/subjectUtils.test.js +0 -128
- /package/{server/abstracts → abstracts}/abstractResponse.js +0 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _Endpoint_instances, _Endpoint_middleware, _Endpoint_server, _Endpoint_channels, _Endpoint_sockets, _Endpoint_sendMessage, _Endpoint_joinChannel, _Endpoint_execute, _Endpoint_handleMessage, _Endpoint_readMessage, _Endpoint_isObjectEmpty;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.Endpoint = void 0;
|
|
16
|
+
const middleware_1 = require("../abstracts/middleware");
|
|
17
|
+
const enums_1 = require("../enums");
|
|
18
|
+
const pondError_1 = require("../errors/pondError");
|
|
19
|
+
const joinRequest_1 = require("../lobby/joinRequest");
|
|
20
|
+
const joinResponse_1 = require("../lobby/joinResponse");
|
|
21
|
+
const lobby_1 = require("../lobby/lobby");
|
|
22
|
+
const matcher_1 = require("../matcher/matcher");
|
|
23
|
+
class Endpoint {
|
|
24
|
+
constructor(server) {
|
|
25
|
+
_Endpoint_instances.add(this);
|
|
26
|
+
_Endpoint_middleware.set(this, void 0);
|
|
27
|
+
_Endpoint_server.set(this, void 0);
|
|
28
|
+
_Endpoint_channels.set(this, void 0);
|
|
29
|
+
_Endpoint_sockets.set(this, void 0);
|
|
30
|
+
__classPrivateFieldSet(this, _Endpoint_server, server, "f");
|
|
31
|
+
__classPrivateFieldSet(this, _Endpoint_sockets, new Set(), "f");
|
|
32
|
+
__classPrivateFieldSet(this, _Endpoint_middleware, new middleware_1.Middleware(), "f");
|
|
33
|
+
__classPrivateFieldSet(this, _Endpoint_channels, new Set(), "f");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @desc Adds a new PondChannel to this path on this endpoint
|
|
37
|
+
* @param path - The path to add the channel to
|
|
38
|
+
* @param handler - The handler to use to authenticate the client
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const channel = endpoint.createChannel('/chat', (request, response) => {
|
|
42
|
+
* if (request.user.assigns.admin)
|
|
43
|
+
* response.accept();
|
|
44
|
+
*
|
|
45
|
+
* else
|
|
46
|
+
* response.reject('You are not an admin', 403);
|
|
47
|
+
* });
|
|
48
|
+
*/
|
|
49
|
+
createChannel(path, handler) {
|
|
50
|
+
const pondChannel = new lobby_1.LobbyEngine();
|
|
51
|
+
__classPrivateFieldGet(this, _Endpoint_middleware, "f").use((user, joinParams, next) => {
|
|
52
|
+
const event = (0, matcher_1.parseAddress)(path, user.channelName);
|
|
53
|
+
if (event) {
|
|
54
|
+
const newChannel = pondChannel.getChannel(user.channelName) || pondChannel.createChannel(user.channelName);
|
|
55
|
+
const request = new joinRequest_1.JoinRequest(user, joinParams, newChannel);
|
|
56
|
+
const response = new joinResponse_1.JoinResponse(user, newChannel);
|
|
57
|
+
if (request._parseQueries(path)) {
|
|
58
|
+
return handler(request, response);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
next();
|
|
62
|
+
});
|
|
63
|
+
__classPrivateFieldGet(this, _Endpoint_channels, "f").add(pondChannel);
|
|
64
|
+
return new lobby_1.PondChannel(pondChannel);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @desc List all clients connected to this endpoint
|
|
68
|
+
*/
|
|
69
|
+
listConnections() {
|
|
70
|
+
return [...__classPrivateFieldGet(this, _Endpoint_sockets, "f")].map(({ clientId }) => clientId);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* @desc Gets all clients connected to this endpoint
|
|
74
|
+
*/
|
|
75
|
+
getClients() {
|
|
76
|
+
return [...__classPrivateFieldGet(this, _Endpoint_sockets, "f")];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @desc Broadcasts a message to all clients connected to this endpoint
|
|
80
|
+
* @param event - The event to broadcast
|
|
81
|
+
* @param payload - The payload to broadcast
|
|
82
|
+
*/
|
|
83
|
+
broadcast(event, payload) {
|
|
84
|
+
__classPrivateFieldGet(this, _Endpoint_sockets, "f").forEach(({ socket }) => {
|
|
85
|
+
const message = {
|
|
86
|
+
event,
|
|
87
|
+
payload,
|
|
88
|
+
action: enums_1.ServerActions.BROADCAST,
|
|
89
|
+
channelName: enums_1.SystemSender.ENDPOINT,
|
|
90
|
+
};
|
|
91
|
+
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_sendMessage).call(this, socket, message);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* @desc Closes specific clients connected to this endpoint
|
|
96
|
+
* @param clientIds - The id for the client / clients to close
|
|
97
|
+
*/
|
|
98
|
+
closeConnection(clientIds) {
|
|
99
|
+
const clients = typeof clientIds === 'string' ? [clientIds] : clientIds;
|
|
100
|
+
this.getClients()
|
|
101
|
+
.forEach(({ clientId, socket }) => {
|
|
102
|
+
if (clients.includes(clientId)) {
|
|
103
|
+
socket.close();
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* @desc Manages a new socket connection
|
|
109
|
+
* @param cache - The socket cache
|
|
110
|
+
*/
|
|
111
|
+
manageSocket(cache) {
|
|
112
|
+
__classPrivateFieldGet(this, _Endpoint_sockets, "f").add(cache);
|
|
113
|
+
const socket = cache.socket;
|
|
114
|
+
socket.addEventListener('message', (message) => {
|
|
115
|
+
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_readMessage).call(this, cache, message.data);
|
|
116
|
+
});
|
|
117
|
+
socket.addEventListener('close', () => {
|
|
118
|
+
__classPrivateFieldGet(this, _Endpoint_channels, "f")
|
|
119
|
+
.forEach((manager) => manager.removeUser(cache.clientId, true));
|
|
120
|
+
});
|
|
121
|
+
socket.addEventListener('error', () => {
|
|
122
|
+
__classPrivateFieldGet(this, _Endpoint_channels, "f")
|
|
123
|
+
.forEach((manager) => manager.removeUser(cache.clientId, true));
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.Endpoint = Endpoint;
|
|
128
|
+
_Endpoint_middleware = new WeakMap(), _Endpoint_server = new WeakMap(), _Endpoint_channels = new WeakMap(), _Endpoint_sockets = new WeakMap(), _Endpoint_instances = new WeakSet(), _Endpoint_sendMessage = function _Endpoint_sendMessage(socket, message) {
|
|
129
|
+
socket.send(JSON.stringify(message));
|
|
130
|
+
}, _Endpoint_joinChannel = function _Endpoint_joinChannel(channel, socket, joinParams) {
|
|
131
|
+
const cache = Object.assign(Object.assign({}, socket), { channelName: channel });
|
|
132
|
+
__classPrivateFieldGet(this, _Endpoint_middleware, "f").run(cache, joinParams, () => {
|
|
133
|
+
throw new pondError_1.EndpointError(`GatewayEngine: Channel ${channel} does not exist`, 404);
|
|
134
|
+
});
|
|
135
|
+
}, _Endpoint_execute = function _Endpoint_execute(channel, handler) {
|
|
136
|
+
for (const manager of __classPrivateFieldGet(this, _Endpoint_channels, "f")) {
|
|
137
|
+
const isPresent = manager.listChannels()
|
|
138
|
+
.includes(channel);
|
|
139
|
+
if (isPresent) {
|
|
140
|
+
return manager.execute(channel, handler);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
throw new Error(`GatewayEngine: Channel ${channel} does not exist`);
|
|
144
|
+
}, _Endpoint_handleMessage = function _Endpoint_handleMessage(cache, message) {
|
|
145
|
+
switch (message.action) {
|
|
146
|
+
case enums_1.ClientActions.JOIN_CHANNEL:
|
|
147
|
+
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_joinChannel).call(this, message.channelName, cache, message.payload);
|
|
148
|
+
break;
|
|
149
|
+
case enums_1.ClientActions.LEAVE_CHANNEL:
|
|
150
|
+
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_execute).call(this, message.channelName, (channel) => {
|
|
151
|
+
channel.removeUser(cache.clientId);
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
case enums_1.ClientActions.BROADCAST:
|
|
155
|
+
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_execute).call(this, message.channelName, (channel) => {
|
|
156
|
+
channel.broadcastMessage(cache.clientId, message);
|
|
157
|
+
});
|
|
158
|
+
break;
|
|
159
|
+
default:
|
|
160
|
+
throw new Error(`GatewayEngine: Action ${message.action} does not exist`);
|
|
161
|
+
}
|
|
162
|
+
}, _Endpoint_readMessage = function _Endpoint_readMessage(cache, message) {
|
|
163
|
+
const errorMessage = {
|
|
164
|
+
event: enums_1.ErrorTypes.INVALID_MESSAGE,
|
|
165
|
+
action: enums_1.ServerActions.ERROR,
|
|
166
|
+
channelName: enums_1.SystemSender.ENDPOINT,
|
|
167
|
+
payload: {},
|
|
168
|
+
};
|
|
169
|
+
try {
|
|
170
|
+
const data = JSON.parse(message);
|
|
171
|
+
if (!data.action) {
|
|
172
|
+
errorMessage.payload = {
|
|
173
|
+
message: 'No action provided',
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
else if (!data.channelName) {
|
|
177
|
+
errorMessage.payload = {
|
|
178
|
+
message: 'No channel name provided',
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
else if (!data.payload) {
|
|
182
|
+
errorMessage.payload = {
|
|
183
|
+
message: 'No payload provided',
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
if (!__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_isObjectEmpty).call(this, errorMessage.payload)) {
|
|
187
|
+
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_sendMessage).call(this, cache.socket, errorMessage);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_handleMessage).call(this, cache, data);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
if (e instanceof SyntaxError) {
|
|
195
|
+
errorMessage.payload = {
|
|
196
|
+
message: 'Invalid JSON',
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
else if (e instanceof Error) {
|
|
200
|
+
errorMessage.event = enums_1.ErrorTypes.INTERNAL_SERVER_ERROR;
|
|
201
|
+
errorMessage.payload = {
|
|
202
|
+
message: e.message,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
else if (e instanceof pondError_1.PresenceError) {
|
|
206
|
+
errorMessage.event = enums_1.ErrorTypes.PRESENCE_ERROR;
|
|
207
|
+
errorMessage.channelName = e.channel;
|
|
208
|
+
errorMessage.payload = {
|
|
209
|
+
message: e.message,
|
|
210
|
+
code: e.code,
|
|
211
|
+
action: e.event,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
else if (e instanceof pondError_1.ChannelError) {
|
|
215
|
+
errorMessage.event = enums_1.ErrorTypes.CHANNEL_ERROR;
|
|
216
|
+
errorMessage.channelName = e.channel;
|
|
217
|
+
errorMessage.payload = {
|
|
218
|
+
message: e.message,
|
|
219
|
+
code: e.code,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
else if (e instanceof pondError_1.EndpointError) {
|
|
223
|
+
errorMessage.event = enums_1.ErrorTypes.ENDPOINT_ERROR;
|
|
224
|
+
errorMessage.payload = {
|
|
225
|
+
message: e.message,
|
|
226
|
+
code: e.code,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_sendMessage).call(this, cache.socket, errorMessage);
|
|
230
|
+
}
|
|
231
|
+
}, _Endpoint_isObjectEmpty = function _Endpoint_isObjectEmpty(obj) {
|
|
232
|
+
return Object.keys(obj).length === 0;
|
|
233
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _ConnectionResponse_instances, _ConnectionResponse_webSocket, _ConnectionResponse_engine, _ConnectionResponse_clientId, _ConnectionResponse_executed, _ConnectionResponse_sendMessage, _ConnectionResponse_performChecks;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ConnectionResponse = void 0;
|
|
16
|
+
const abstractResponse_1 = require("../abstracts/abstractResponse");
|
|
17
|
+
const enums_1 = require("../enums");
|
|
18
|
+
const pondError_1 = require("../errors/pondError");
|
|
19
|
+
class ConnectionResponse extends abstractResponse_1.PondResponse {
|
|
20
|
+
constructor(webSocket, engine, clientId) {
|
|
21
|
+
super();
|
|
22
|
+
_ConnectionResponse_instances.add(this);
|
|
23
|
+
_ConnectionResponse_webSocket.set(this, void 0);
|
|
24
|
+
_ConnectionResponse_engine.set(this, void 0);
|
|
25
|
+
_ConnectionResponse_clientId.set(this, void 0);
|
|
26
|
+
_ConnectionResponse_executed.set(this, void 0);
|
|
27
|
+
__classPrivateFieldSet(this, _ConnectionResponse_webSocket, webSocket, "f");
|
|
28
|
+
__classPrivateFieldSet(this, _ConnectionResponse_engine, engine, "f");
|
|
29
|
+
__classPrivateFieldSet(this, _ConnectionResponse_clientId, clientId, "f");
|
|
30
|
+
__classPrivateFieldSet(this, _ConnectionResponse_executed, false, "f");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @desc Accepts the request and optionally assigns data to the client
|
|
34
|
+
* @param assigns - the data to assign to the client
|
|
35
|
+
*/
|
|
36
|
+
accept(assigns) {
|
|
37
|
+
__classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_performChecks).call(this);
|
|
38
|
+
const cache = {
|
|
39
|
+
clientId: __classPrivateFieldGet(this, _ConnectionResponse_clientId, "f"),
|
|
40
|
+
socket: __classPrivateFieldGet(this, _ConnectionResponse_webSocket, "f"),
|
|
41
|
+
assigns: assigns || {},
|
|
42
|
+
};
|
|
43
|
+
__classPrivateFieldGet(this, _ConnectionResponse_engine, "f").manageSocket(cache);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @desc Rejects the request with the given error message
|
|
47
|
+
* @param message - the error message
|
|
48
|
+
* @param errorCode - the error code
|
|
49
|
+
*/
|
|
50
|
+
reject(message, errorCode) {
|
|
51
|
+
__classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_performChecks).call(this);
|
|
52
|
+
const payload = {
|
|
53
|
+
message: message || 'Unauthorized connection',
|
|
54
|
+
code: errorCode || 401,
|
|
55
|
+
};
|
|
56
|
+
__classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_sendMessage).call(this, enums_1.ServerActions.ERROR, enums_1.ErrorTypes.UNAUTHORIZED_CONNECTION, payload);
|
|
57
|
+
__classPrivateFieldGet(this, _ConnectionResponse_webSocket, "f").close();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @desc Emits a direct message to the client
|
|
61
|
+
* @param event - the event name
|
|
62
|
+
* @param payload - the payload to send
|
|
63
|
+
* @param assigns - the data to assign to the client
|
|
64
|
+
*/
|
|
65
|
+
send(event, payload, assigns) {
|
|
66
|
+
this.accept(assigns);
|
|
67
|
+
__classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_sendMessage).call(this, enums_1.ServerActions.BROADCAST, event, payload);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.ConnectionResponse = ConnectionResponse;
|
|
71
|
+
_ConnectionResponse_webSocket = new WeakMap(), _ConnectionResponse_engine = new WeakMap(), _ConnectionResponse_clientId = new WeakMap(), _ConnectionResponse_executed = new WeakMap(), _ConnectionResponse_instances = new WeakSet(), _ConnectionResponse_sendMessage = function _ConnectionResponse_sendMessage(action, event, payload) {
|
|
72
|
+
const message = {
|
|
73
|
+
action,
|
|
74
|
+
event,
|
|
75
|
+
payload,
|
|
76
|
+
channelName: enums_1.SystemSender.ENDPOINT,
|
|
77
|
+
};
|
|
78
|
+
__classPrivateFieldGet(this, _ConnectionResponse_webSocket, "f").send(JSON.stringify(message));
|
|
79
|
+
}, _ConnectionResponse_performChecks = function _ConnectionResponse_performChecks() {
|
|
80
|
+
if (__classPrivateFieldGet(this, _ConnectionResponse_executed, "f")) {
|
|
81
|
+
const message = 'Cannot execute response more than once';
|
|
82
|
+
const code = 403;
|
|
83
|
+
throw new pondError_1.EndpointError(message, code);
|
|
84
|
+
}
|
|
85
|
+
__classPrivateFieldSet(this, _ConnectionResponse_executed, true, "f");
|
|
86
|
+
};
|
package/enums.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.Events = exports.ChannelReceiver = exports.SystemSender = exports.ErrorTypes = exports.ChannelState = exports.ClientActions = exports.ServerActions = exports.PresenceEventTypes = void 0;
|
|
4
4
|
var PresenceEventTypes;
|
|
5
5
|
(function (PresenceEventTypes) {
|
|
6
6
|
PresenceEventTypes["JOIN"] = "JOIN";
|
|
@@ -20,13 +20,6 @@ var ClientActions;
|
|
|
20
20
|
ClientActions["LEAVE_CHANNEL"] = "LEAVE_CHANNEL";
|
|
21
21
|
ClientActions["BROADCAST"] = "BROADCAST";
|
|
22
22
|
})(ClientActions = exports.ClientActions || (exports.ClientActions = {}));
|
|
23
|
-
var PondState;
|
|
24
|
-
(function (PondState) {
|
|
25
|
-
PondState["CONNECTING"] = "CONNECTING";
|
|
26
|
-
PondState["OPEN"] = "OPEN";
|
|
27
|
-
PondState["CLOSING"] = "CLOSING";
|
|
28
|
-
PondState["CLOSED"] = "CLOSED";
|
|
29
|
-
})(PondState = exports.PondState || (exports.PondState = {}));
|
|
30
23
|
var ChannelState;
|
|
31
24
|
(function (ChannelState) {
|
|
32
25
|
ChannelState["IDLE"] = "IDLE";
|
|
@@ -37,16 +30,27 @@ var ChannelState;
|
|
|
37
30
|
})(ChannelState = exports.ChannelState || (exports.ChannelState = {}));
|
|
38
31
|
var ErrorTypes;
|
|
39
32
|
(function (ErrorTypes) {
|
|
33
|
+
ErrorTypes["UNAUTHORIZED_CONNECTION"] = "UNAUTHORIZED_CONNECTION";
|
|
40
34
|
ErrorTypes["UNAUTHORIZED_JOIN_REQUEST"] = "UNAUTHORIZED_JOIN_REQUEST";
|
|
41
35
|
ErrorTypes["UNAUTHORIZED_BROADCAST"] = "UNAUTHORIZED_BROADCAST";
|
|
42
36
|
ErrorTypes["INVALID_MESSAGE"] = "INVALID_MESSAGE";
|
|
43
37
|
ErrorTypes["HANDLER_NOT_FOUND"] = "HANDLER_NOT_FOUND";
|
|
44
|
-
ErrorTypes["
|
|
38
|
+
ErrorTypes["PRESENCE_ERROR"] = "PRESENCE_ERROR";
|
|
39
|
+
ErrorTypes["CHANNEL_ERROR"] = "CHANNEL_ERROR";
|
|
40
|
+
ErrorTypes["ENDPOINT_ERROR"] = "ENDPOINT_ERROR";
|
|
45
41
|
ErrorTypes["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
|
|
46
42
|
})(ErrorTypes = exports.ErrorTypes || (exports.ErrorTypes = {}));
|
|
47
43
|
var SystemSender;
|
|
48
44
|
(function (SystemSender) {
|
|
49
|
-
SystemSender["SERVER"] = "SERVER";
|
|
50
45
|
SystemSender["ENDPOINT"] = "ENDPOINT";
|
|
51
46
|
SystemSender["CHANNEL"] = "CHANNEL";
|
|
52
47
|
})(SystemSender = exports.SystemSender || (exports.SystemSender = {}));
|
|
48
|
+
var ChannelReceiver;
|
|
49
|
+
(function (ChannelReceiver) {
|
|
50
|
+
ChannelReceiver["ALL_USERS"] = "ALL_USERS";
|
|
51
|
+
ChannelReceiver["ALL_EXCEPT_SENDER"] = "ALL_EXCEPT_SENDER";
|
|
52
|
+
})(ChannelReceiver = exports.ChannelReceiver || (exports.ChannelReceiver = {}));
|
|
53
|
+
var Events;
|
|
54
|
+
(function (Events) {
|
|
55
|
+
Events["ACKNOWLEDGE"] = "ACKNOWLEDGE";
|
|
56
|
+
})(Events = exports.Events || (exports.Events = {}));
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PresenceError = exports.ChannelError = exports.EndpointError = exports.PondError = void 0;
|
|
4
|
+
class PondError {
|
|
5
|
+
constructor(message, code) {
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.message = message;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.PondError = PondError;
|
|
11
|
+
class EndpointError extends PondError {
|
|
12
|
+
}
|
|
13
|
+
exports.EndpointError = EndpointError;
|
|
14
|
+
class ChannelError extends EndpointError {
|
|
15
|
+
constructor(message, code, channel) {
|
|
16
|
+
super(message, code);
|
|
17
|
+
this.channel = channel;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.ChannelError = ChannelError;
|
|
21
|
+
class PresenceError extends ChannelError {
|
|
22
|
+
constructor(message, code, channel, event) {
|
|
23
|
+
super(message, code, channel);
|
|
24
|
+
this.event = event;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.PresenceError = PresenceError;
|
package/express.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pondSocket } from './types';
|
|
2
2
|
|
|
3
|
-
export default
|
|
3
|
+
export default pondSocket;
|
package/express.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const http_1 = require("http");
|
|
4
|
-
const pondSocket_1 = require("./server/
|
|
4
|
+
const pondSocket_1 = require("./server/pondSocket");
|
|
5
5
|
/**
|
|
6
6
|
* @desc Creates a pond socket server
|
|
7
7
|
* @param app - The Express app to be used by the server
|
|
8
8
|
* @constructor
|
|
9
9
|
*/
|
|
10
|
-
const
|
|
10
|
+
const pondSocket = (app) => {
|
|
11
11
|
const server = (0, http_1.createServer)(app);
|
|
12
12
|
const pondSocket = new pondSocket_1.PondSocket(server);
|
|
13
13
|
app.upgrade = (path, handler) => pondSocket.createEndpoint(path, handler);
|
|
14
14
|
app.listen = (...args) => pondSocket.listen(...args);
|
|
15
15
|
return app;
|
|
16
16
|
};
|
|
17
|
-
exports.default =
|
|
17
|
+
exports.default = pondSocket;
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
const pondChannel_1 = require("./server/pondChannel/pondChannel");
|
|
5
|
-
Object.defineProperty(exports, "PondChannel", { enumerable: true, get: function () { return pondChannel_1.PondChannel; } });
|
|
6
|
-
const pondSocket_1 = require("./server/server/pondSocket");
|
|
3
|
+
const pondSocket_1 = require("./server/pondSocket");
|
|
7
4
|
exports.default = pondSocket_1.PondSocket;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _JoinRequest_params, _JoinRequest_clientId, _JoinRequest_assigns;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.JoinRequest = void 0;
|
|
16
|
+
const abstractRequest_1 = require("../abstracts/abstractRequest");
|
|
17
|
+
class JoinRequest extends abstractRequest_1.AbstractRequest {
|
|
18
|
+
constructor(event, params, engine) {
|
|
19
|
+
super(engine.name, engine, params);
|
|
20
|
+
_JoinRequest_params.set(this, void 0);
|
|
21
|
+
_JoinRequest_clientId.set(this, void 0);
|
|
22
|
+
_JoinRequest_assigns.set(this, void 0);
|
|
23
|
+
__classPrivateFieldSet(this, _JoinRequest_params, params, "f");
|
|
24
|
+
__classPrivateFieldSet(this, _JoinRequest_clientId, event.clientId, "f");
|
|
25
|
+
__classPrivateFieldSet(this, _JoinRequest_assigns, event.assigns, "f");
|
|
26
|
+
}
|
|
27
|
+
get joinParams() {
|
|
28
|
+
return __classPrivateFieldGet(this, _JoinRequest_params, "f");
|
|
29
|
+
}
|
|
30
|
+
get user() {
|
|
31
|
+
return {
|
|
32
|
+
id: __classPrivateFieldGet(this, _JoinRequest_clientId, "f"),
|
|
33
|
+
assigns: __classPrivateFieldGet(this, _JoinRequest_assigns, "f"),
|
|
34
|
+
presence: {},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.JoinRequest = JoinRequest;
|
|
39
|
+
_JoinRequest_params = new WeakMap(), _JoinRequest_clientId = new WeakMap(), _JoinRequest_assigns = new WeakMap();
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _JoinResponse_instances, _JoinResponse_user, _JoinResponse_engine, _JoinResponse_executed, _JoinResponse_performChecks;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.JoinResponse = void 0;
|
|
16
|
+
const abstractResponse_1 = require("../abstracts/abstractResponse");
|
|
17
|
+
const enums_1 = require("../enums");
|
|
18
|
+
const pondError_1 = require("../errors/pondError");
|
|
19
|
+
class JoinResponse extends abstractResponse_1.PondResponse {
|
|
20
|
+
constructor(user, engine) {
|
|
21
|
+
super();
|
|
22
|
+
_JoinResponse_instances.add(this);
|
|
23
|
+
_JoinResponse_user.set(this, void 0);
|
|
24
|
+
_JoinResponse_engine.set(this, void 0);
|
|
25
|
+
_JoinResponse_executed.set(this, void 0);
|
|
26
|
+
__classPrivateFieldSet(this, _JoinResponse_user, user, "f");
|
|
27
|
+
__classPrivateFieldSet(this, _JoinResponse_engine, engine, "f");
|
|
28
|
+
__classPrivateFieldSet(this, _JoinResponse_executed, false, "f");
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @desc Accepts the request and optionally assigns data to the client
|
|
32
|
+
* @param assigns - the data to assign to the client
|
|
33
|
+
*/
|
|
34
|
+
accept(assigns) {
|
|
35
|
+
__classPrivateFieldGet(this, _JoinResponse_instances, "m", _JoinResponse_performChecks).call(this);
|
|
36
|
+
assigns = Object.assign(Object.assign({}, assigns), __classPrivateFieldGet(this, _JoinResponse_user, "f").assigns);
|
|
37
|
+
const acknowledgement = {
|
|
38
|
+
action: enums_1.ServerActions.SYSTEM,
|
|
39
|
+
channelName: __classPrivateFieldGet(this, _JoinResponse_engine, "f").name,
|
|
40
|
+
event: enums_1.Events.ACKNOWLEDGE,
|
|
41
|
+
payload: {},
|
|
42
|
+
};
|
|
43
|
+
__classPrivateFieldGet(this, _JoinResponse_user, "f").socket.send(JSON.stringify(acknowledgement));
|
|
44
|
+
__classPrivateFieldGet(this, _JoinResponse_engine, "f").addUser(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, assigns, (event) => {
|
|
45
|
+
__classPrivateFieldGet(this, _JoinResponse_user, "f").socket.send(JSON.stringify(event));
|
|
46
|
+
});
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* @desc Rejects the request and optionally assigns data to the client
|
|
51
|
+
* @param message - the error message
|
|
52
|
+
* @param errorCode - the error code
|
|
53
|
+
*/
|
|
54
|
+
reject(message, errorCode) {
|
|
55
|
+
__classPrivateFieldGet(this, _JoinResponse_instances, "m", _JoinResponse_performChecks).call(this);
|
|
56
|
+
const text = `Request to join channel ${__classPrivateFieldGet(this, _JoinResponse_engine, "f").name} rejected: ${message || 'Unauthorized request'}`;
|
|
57
|
+
const errorMessage = {
|
|
58
|
+
event: enums_1.ErrorTypes.UNAUTHORIZED_JOIN_REQUEST,
|
|
59
|
+
payload: {
|
|
60
|
+
message: text,
|
|
61
|
+
code: errorCode || 403,
|
|
62
|
+
},
|
|
63
|
+
channelName: __classPrivateFieldGet(this, _JoinResponse_engine, "f").name,
|
|
64
|
+
action: enums_1.ServerActions.ERROR,
|
|
65
|
+
};
|
|
66
|
+
__classPrivateFieldGet(this, _JoinResponse_user, "f").socket.send(JSON.stringify(errorMessage));
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @desc Emits a direct message to the client
|
|
71
|
+
* @param event - the event name
|
|
72
|
+
* @param payload - the payload to send
|
|
73
|
+
* @param assigns - the data to assign to the client
|
|
74
|
+
*/
|
|
75
|
+
send(event, payload, assigns) {
|
|
76
|
+
this.accept(assigns);
|
|
77
|
+
__classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(enums_1.SystemSender.CHANNEL, [__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId], enums_1.ServerActions.SYSTEM, event, payload);
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* @desc Emits a message to all clients in the channel
|
|
82
|
+
* @param event - the event name
|
|
83
|
+
* @param payload - the payload to send
|
|
84
|
+
*/
|
|
85
|
+
broadcast(event, payload) {
|
|
86
|
+
__classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, enums_1.ChannelReceiver.ALL_USERS, enums_1.ServerActions.BROADCAST, event, payload);
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* @desc Emits a message to all clients in the channel except the sender
|
|
91
|
+
* @param event - the event name
|
|
92
|
+
* @param payload - the payload to send
|
|
93
|
+
*/
|
|
94
|
+
broadcastFromUser(event, payload) {
|
|
95
|
+
__classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, enums_1.ChannelReceiver.ALL_EXCEPT_SENDER, enums_1.ServerActions.BROADCAST, event, payload);
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* @desc Emits a message to a specific set of clients
|
|
100
|
+
* @param event - the event name
|
|
101
|
+
* @param payload - the payload to send
|
|
102
|
+
* @param userIds - the ids of the clients to send the message to
|
|
103
|
+
*/
|
|
104
|
+
sendToUsers(event, payload, userIds) {
|
|
105
|
+
__classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, userIds, enums_1.ServerActions.BROADCAST, event, payload);
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* @desc tracks the presence of a client
|
|
110
|
+
* @param presence - the presence data to track
|
|
111
|
+
*/
|
|
112
|
+
trackPresence(presence) {
|
|
113
|
+
__classPrivateFieldGet(this, _JoinResponse_engine, "f").trackPresence(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, presence);
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.JoinResponse = JoinResponse;
|
|
118
|
+
_JoinResponse_user = new WeakMap(), _JoinResponse_engine = new WeakMap(), _JoinResponse_executed = new WeakMap(), _JoinResponse_instances = new WeakSet(), _JoinResponse_performChecks = function _JoinResponse_performChecks() {
|
|
119
|
+
if (__classPrivateFieldGet(this, _JoinResponse_executed, "f")) {
|
|
120
|
+
const message = `Request to join channel ${__classPrivateFieldGet(this, _JoinResponse_engine, "f").name} rejected: Request already executed`;
|
|
121
|
+
const code = 403;
|
|
122
|
+
throw new pondError_1.ChannelError(message, code, __classPrivateFieldGet(this, _JoinResponse_engine, "f").name);
|
|
123
|
+
}
|
|
124
|
+
__classPrivateFieldSet(this, _JoinResponse_executed, true, "f");
|
|
125
|
+
};
|