@eleven-am/pondsocket 0.1.9 → 0.1.11
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/package.json +1 -1
- package/pondBase/baseClass.js +32 -51
- package/pondBase/baseClass.test.js +34 -34
- package/pondBase/pondBase.js +34 -95
- package/pondBase/pondBase.test.js +39 -67
- package/pondBase/pubSub.d.ts +8 -9
- package/pondBase/pubSub.js +65 -121
- package/pondBase/pubSub.test.js +119 -110
- package/pondBase/simpleBase.js +92 -166
- package/pondBase/simpleBase.test.js +66 -124
- package/pondClient/channel.d.ts +14 -3
- package/pondClient/channel.js +71 -46
- package/pondClient/socket.js +35 -38
- package/pondSocket/channel.js +123 -176
- package/pondSocket/channel.test.js +78 -89
- package/pondSocket/channelMiddleWare.js +16 -43
- package/pondSocket/endpoint.js +93 -188
- package/pondSocket/endpoint.test.js +447 -632
- package/pondSocket/pondChannel.js +81 -142
- package/pondSocket/pondChannel.test.js +40 -40
- package/pondSocket/pondResponse.js +52 -87
- package/pondSocket/pondSocket.js +35 -55
- package/pondSocket/server.test.js +88 -142
- package/pondSocket/socketMiddleWare.js +14 -16
package/pondSocket/endpoint.js
CHANGED
|
@@ -1,90 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __assign = (this && this.__assign) || function () {
|
|
18
|
-
__assign = Object.assign || function(t) {
|
|
19
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
-
s = arguments[i];
|
|
21
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
-
t[p] = s[p];
|
|
23
|
-
}
|
|
24
|
-
return t;
|
|
25
|
-
};
|
|
26
|
-
return __assign.apply(this, arguments);
|
|
27
|
-
};
|
|
28
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
29
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
30
|
-
if (!m) return o;
|
|
31
|
-
var i = m.call(o), r, ar = [], e;
|
|
32
|
-
try {
|
|
33
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
34
|
-
}
|
|
35
|
-
catch (error) { e = { error: error }; }
|
|
36
|
-
finally {
|
|
37
|
-
try {
|
|
38
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
39
|
-
}
|
|
40
|
-
finally { if (e) throw e.error; }
|
|
41
|
-
}
|
|
42
|
-
return ar;
|
|
43
|
-
};
|
|
44
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
45
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
46
|
-
if (ar || !(i in from)) {
|
|
47
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
48
|
-
ar[i] = from[i];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
52
|
-
};
|
|
53
|
-
var __values = (this && this.__values) || function(o) {
|
|
54
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
55
|
-
if (m) return m.call(o);
|
|
56
|
-
if (o && typeof o.length === "number") return {
|
|
57
|
-
next: function () {
|
|
58
|
-
if (o && i >= o.length) o = void 0;
|
|
59
|
-
return { value: o && o[i++], done: !o };
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
63
|
-
};
|
|
64
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
3
|
exports.Endpoint = void 0;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
_this._server = server;
|
|
78
|
-
return _this;
|
|
4
|
+
const enums_1 = require("./enums");
|
|
5
|
+
const pondBase_1 = require("../pondBase");
|
|
6
|
+
const pondChannel_1 = require("./pondChannel");
|
|
7
|
+
const pondResponse_1 = require("./pondResponse");
|
|
8
|
+
class Endpoint extends pondBase_1.BaseClass {
|
|
9
|
+
constructor(server, handler) {
|
|
10
|
+
super();
|
|
11
|
+
this._channels = new pondBase_1.SimpleBase();
|
|
12
|
+
this._sockets = new pondBase_1.SimpleBase();
|
|
13
|
+
this._handler = handler;
|
|
14
|
+
this._server = server;
|
|
79
15
|
}
|
|
80
16
|
/**
|
|
81
17
|
* @desc Sends a message to a client
|
|
82
18
|
* @param socket - The socket to send the message to
|
|
83
19
|
* @param message - The message to send
|
|
84
20
|
*/
|
|
85
|
-
|
|
21
|
+
static _sendMessage(socket, message) {
|
|
86
22
|
socket.send(JSON.stringify(message));
|
|
87
|
-
}
|
|
23
|
+
}
|
|
88
24
|
/**
|
|
89
25
|
* @desc Accepts a new socket join request to the room provided using the handler function to authorise the socket
|
|
90
26
|
* @param path - the pattern to accept || can also be a regex
|
|
@@ -116,11 +52,11 @@ var Endpoint = /** @class */ (function (_super) {
|
|
|
116
52
|
* });
|
|
117
53
|
* })
|
|
118
54
|
*/
|
|
119
|
-
|
|
120
|
-
|
|
55
|
+
createChannel(path, handler) {
|
|
56
|
+
const pondChannel = new pondChannel_1.PondChannel(path, handler);
|
|
121
57
|
this._channels.set(path.toString(), pondChannel);
|
|
122
58
|
return pondChannel;
|
|
123
|
-
}
|
|
59
|
+
}
|
|
124
60
|
/**
|
|
125
61
|
* @desc Authenticates the client to the endpoint
|
|
126
62
|
* @param request - Incoming request
|
|
@@ -128,25 +64,24 @@ var Endpoint = /** @class */ (function (_super) {
|
|
|
128
64
|
* @param head - Incoming head
|
|
129
65
|
* @param data - Incoming the data resolved from the handler
|
|
130
66
|
*/
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
var resolver = function (assigns, data) {
|
|
67
|
+
authoriseConnection(request, socket, head, data) {
|
|
68
|
+
const doc = this._sockets.createGenericDocument();
|
|
69
|
+
const req = Object.assign(Object.assign({ headers: request.headers }, data), { clientId: doc.id });
|
|
70
|
+
const resolver = (assigns, data) => {
|
|
136
71
|
if (data.error) {
|
|
137
|
-
socket.write(
|
|
72
|
+
socket.write(`HTTP/1.1 ${data.error.code} ${data.error.message}\r\n\r\n`);
|
|
138
73
|
return socket.destroy();
|
|
139
74
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
75
|
+
this._server.handleUpgrade(request, socket, head, (ws) => {
|
|
76
|
+
this._server.emit("connection", ws);
|
|
77
|
+
const socketCache = {
|
|
143
78
|
socket: ws,
|
|
144
79
|
assigns: assigns
|
|
145
80
|
};
|
|
146
81
|
doc.updateDoc(socketCache);
|
|
147
|
-
|
|
82
|
+
this._manageSocket(doc);
|
|
148
83
|
if (data.message) {
|
|
149
|
-
|
|
84
|
+
const newMessage = {
|
|
150
85
|
action: enums_1.ServerActions.MESSAGE,
|
|
151
86
|
event: data.message.event,
|
|
152
87
|
channelName: "SERVER",
|
|
@@ -156,160 +91,131 @@ var Endpoint = /** @class */ (function (_super) {
|
|
|
156
91
|
}
|
|
157
92
|
});
|
|
158
93
|
};
|
|
159
|
-
|
|
94
|
+
const res = new pondResponse_1.EndpointResponse(resolver);
|
|
160
95
|
this._handler(req, res, this);
|
|
161
|
-
}
|
|
96
|
+
}
|
|
162
97
|
/**
|
|
163
98
|
* @desc Closes a client connection to the endpoint.
|
|
164
99
|
* @param clientId - The id of the client to close the connection to.
|
|
165
100
|
*/
|
|
166
|
-
|
|
167
|
-
|
|
101
|
+
closeConnection(clientId) {
|
|
102
|
+
const message = {
|
|
168
103
|
action: enums_1.ServerActions.CLOSE,
|
|
169
104
|
channelName: "SERVER",
|
|
170
105
|
event: "CLOSED_FROM_SERVER", payload: {}
|
|
171
106
|
};
|
|
172
|
-
|
|
173
|
-
|
|
107
|
+
const stringifiedMessage = JSON.stringify(message);
|
|
108
|
+
const socketDoc = this._sockets.get(clientId);
|
|
174
109
|
if (socketDoc) {
|
|
175
110
|
socketDoc.doc.socket.send(stringifiedMessage);
|
|
176
111
|
socketDoc.doc.socket.close();
|
|
177
112
|
socketDoc.removeDoc();
|
|
178
113
|
}
|
|
179
|
-
}
|
|
114
|
+
}
|
|
180
115
|
/**
|
|
181
116
|
* @desc Sends a message to a client on the endpoint.
|
|
182
117
|
* @param clientId - The id of the client to send the message to.
|
|
183
118
|
* @param event - The event to send the message with.
|
|
184
119
|
* @param message - The message to send.
|
|
185
120
|
*/
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
var newMessage = {
|
|
121
|
+
send(clientId, event, message) {
|
|
122
|
+
const newMessage = {
|
|
189
123
|
action: enums_1.ServerActions.MESSAGE,
|
|
190
124
|
channelName: enums_1.PondSenders.ENDPOINT,
|
|
191
|
-
event:
|
|
192
|
-
payload: message
|
|
125
|
+
event, payload: message
|
|
193
126
|
};
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
addresses.forEach(
|
|
197
|
-
|
|
127
|
+
const stringifiedMessage = JSON.stringify(newMessage);
|
|
128
|
+
const addresses = Array.isArray(clientId) ? clientId : [clientId];
|
|
129
|
+
addresses.forEach((address) => {
|
|
130
|
+
const socketDoc = this._sockets.get(address);
|
|
198
131
|
if (socketDoc)
|
|
199
132
|
socketDoc.doc.socket.send(stringifiedMessage);
|
|
200
133
|
});
|
|
201
|
-
}
|
|
134
|
+
}
|
|
202
135
|
/**
|
|
203
136
|
* @desc lists all the channels in the endpoint
|
|
204
137
|
*/
|
|
205
|
-
|
|
206
|
-
return this._channels.map(
|
|
207
|
-
}
|
|
138
|
+
listChannels() {
|
|
139
|
+
return this._channels.map(channel => channel.info).flat();
|
|
140
|
+
}
|
|
208
141
|
/**
|
|
209
142
|
* @desc lists all the clients in the endpoint
|
|
210
143
|
*/
|
|
211
|
-
|
|
212
|
-
return this._sockets.map(
|
|
213
|
-
}
|
|
144
|
+
listConnections() {
|
|
145
|
+
return this._sockets.map(socket => socket.socket);
|
|
146
|
+
}
|
|
214
147
|
/**
|
|
215
148
|
* @desc Broadcasts a message to all clients in the endpoint.
|
|
216
149
|
* @param event - The event to broadcast.
|
|
217
150
|
* @param message - The message to broadcast.
|
|
218
151
|
*/
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
152
|
+
broadcast(event, message) {
|
|
153
|
+
const sockets = [...this._sockets.generator()];
|
|
154
|
+
const newMessage = {
|
|
222
155
|
action: enums_1.ServerActions.MESSAGE,
|
|
223
156
|
channelName: enums_1.PondSenders.ENDPOINT,
|
|
224
|
-
event:
|
|
225
|
-
payload: message
|
|
157
|
+
event, payload: message
|
|
226
158
|
};
|
|
227
|
-
|
|
228
|
-
sockets.forEach(
|
|
229
|
-
}
|
|
159
|
+
const stringifiedMessage = JSON.stringify(newMessage);
|
|
160
|
+
sockets.forEach(doc => doc.doc.socket.send(stringifiedMessage));
|
|
161
|
+
}
|
|
230
162
|
/**
|
|
231
163
|
* @desc Searches for a channel in the endpoint.
|
|
232
164
|
* @param name - The name of the channel to search for.
|
|
233
165
|
*/
|
|
234
|
-
|
|
235
|
-
|
|
166
|
+
_findChannel(name) {
|
|
167
|
+
const pond = this._findPondChannel(name);
|
|
236
168
|
if (pond) {
|
|
237
|
-
|
|
169
|
+
const channel = pond.doc.getChannel(name);
|
|
238
170
|
if (channel)
|
|
239
171
|
return channel;
|
|
240
172
|
}
|
|
241
173
|
return undefined;
|
|
242
|
-
}
|
|
174
|
+
}
|
|
243
175
|
/**
|
|
244
176
|
* @desc Manages a new socket connection
|
|
245
177
|
* @param cache - The socket cache
|
|
246
178
|
* @private
|
|
247
179
|
*/
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
_this._readMessage(cache, message.data);
|
|
180
|
+
_manageSocket(cache) {
|
|
181
|
+
const socket = cache.doc.socket;
|
|
182
|
+
socket.addEventListener("message", (message) => {
|
|
183
|
+
this._readMessage(cache, message.data);
|
|
253
184
|
});
|
|
254
|
-
socket.addEventListener("close",
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
for (var _b = __values(_this._channels.generator()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
258
|
-
var channel = _c.value;
|
|
259
|
-
channel.doc.removeUser(cache.id);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
263
|
-
finally {
|
|
264
|
-
try {
|
|
265
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
266
|
-
}
|
|
267
|
-
finally { if (e_1) throw e_1.error; }
|
|
268
|
-
}
|
|
185
|
+
socket.addEventListener("close", () => {
|
|
186
|
+
for (const channel of this._channels.generator())
|
|
187
|
+
channel.doc.removeUser(cache.id);
|
|
269
188
|
cache.removeDoc();
|
|
270
189
|
});
|
|
271
|
-
socket.addEventListener("error",
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
for (var _b = __values(_this._channels.generator()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
275
|
-
var channel = _c.value;
|
|
276
|
-
channel.doc.removeUser(cache.id);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
280
|
-
finally {
|
|
281
|
-
try {
|
|
282
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
283
|
-
}
|
|
284
|
-
finally { if (e_2) throw e_2.error; }
|
|
285
|
-
}
|
|
190
|
+
socket.addEventListener("error", () => {
|
|
191
|
+
for (const channel of this._channels.generator())
|
|
192
|
+
channel.doc.removeUser(cache.id);
|
|
286
193
|
cache.removeDoc();
|
|
287
194
|
});
|
|
288
|
-
}
|
|
195
|
+
}
|
|
289
196
|
/**
|
|
290
197
|
* @desc Finds a pond channel in the endpoint.
|
|
291
198
|
* @param channelName - The name of the channel to find.
|
|
292
199
|
* @private
|
|
293
200
|
*/
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
};
|
|
201
|
+
_findPondChannel(channelName) {
|
|
202
|
+
return this._channels.find(channel => this.generateEventRequest(channel.path, channelName) !== null);
|
|
203
|
+
}
|
|
298
204
|
/**
|
|
299
205
|
* @desc Handles a message sent from a client
|
|
300
206
|
* @param cache - The socket cache of the client
|
|
301
207
|
* @param message - The message to handle
|
|
302
208
|
* @private
|
|
303
209
|
*/
|
|
304
|
-
|
|
305
|
-
|
|
210
|
+
_readMessage(cache, message) {
|
|
211
|
+
const errorMessage = {
|
|
306
212
|
action: enums_1.ServerActions.ERROR,
|
|
307
213
|
event: "error",
|
|
308
214
|
channelName: enums_1.PondSenders.ENDPOINT,
|
|
309
215
|
payload: {}
|
|
310
216
|
};
|
|
311
217
|
try {
|
|
312
|
-
|
|
218
|
+
const data = JSON.parse(message);
|
|
313
219
|
if (!data.action)
|
|
314
220
|
errorMessage.payload = {
|
|
315
221
|
message: "No action provided"
|
|
@@ -341,18 +247,18 @@ var Endpoint = /** @class */ (function (_super) {
|
|
|
341
247
|
Endpoint._sendMessage(cache.doc.socket, errorMessage);
|
|
342
248
|
}
|
|
343
249
|
}
|
|
344
|
-
}
|
|
250
|
+
}
|
|
345
251
|
/**
|
|
346
252
|
* @desc Deals with a message sent from a client
|
|
347
253
|
* @param cache - The socket cache of the client
|
|
348
254
|
* @param message - The message to handle
|
|
349
255
|
*/
|
|
350
|
-
|
|
256
|
+
_handleMessage(cache, message) {
|
|
351
257
|
switch (message.action) {
|
|
352
258
|
case "JOIN_CHANNEL":
|
|
353
|
-
|
|
259
|
+
const pond = this._findPondChannel(message.channelName);
|
|
354
260
|
if (pond) {
|
|
355
|
-
|
|
261
|
+
const user = {
|
|
356
262
|
clientId: cache.id,
|
|
357
263
|
socket: cache.doc.socket,
|
|
358
264
|
assigns: cache.doc.assigns
|
|
@@ -360,38 +266,38 @@ var Endpoint = /** @class */ (function (_super) {
|
|
|
360
266
|
pond.doc.addUser(user, message.channelName, message.payload);
|
|
361
267
|
}
|
|
362
268
|
else
|
|
363
|
-
throw new Error(
|
|
269
|
+
throw new Error(`Channel ${message.channelName} does not exist`);
|
|
364
270
|
break;
|
|
365
271
|
case "LEAVE_CHANNEL":
|
|
366
|
-
this._channelAction(message.channelName, "LEAVE_CHANNEL",
|
|
272
|
+
this._channelAction(message.channelName, "LEAVE_CHANNEL", channel => {
|
|
367
273
|
channel.removeUser(cache.id);
|
|
368
274
|
});
|
|
369
275
|
break;
|
|
370
276
|
case "BROADCAST_FROM":
|
|
371
|
-
this._channelAction(message.channelName, message.event,
|
|
277
|
+
this._channelAction(message.channelName, message.event, (channel) => {
|
|
372
278
|
channel.broadcastFrom(message.event, message.payload, cache.id);
|
|
373
279
|
});
|
|
374
280
|
break;
|
|
375
281
|
case "BROADCAST":
|
|
376
|
-
this._channelAction(message.channelName, message.event,
|
|
282
|
+
this._channelAction(message.channelName, message.event, (channel) => {
|
|
377
283
|
channel.broadcast(message.event, message.payload, cache.id);
|
|
378
284
|
});
|
|
379
285
|
break;
|
|
380
286
|
case "SEND_MESSAGE_TO_USER":
|
|
381
|
-
this._channelAction(message.channelName, message.event,
|
|
287
|
+
this._channelAction(message.channelName, message.event, (channel) => {
|
|
382
288
|
if (!message.addresses || message.addresses.length === 0)
|
|
383
|
-
throw new Error(
|
|
289
|
+
throw new Error(`No addresses provided`);
|
|
384
290
|
channel.sendTo(message.event, message.payload, cache.id, message.addresses);
|
|
385
291
|
});
|
|
386
292
|
break;
|
|
387
293
|
case "UPDATE_PRESENCE":
|
|
388
|
-
this._channelAction(message.channelName, "UPDATE_PRESENCE",
|
|
294
|
+
this._channelAction(message.channelName, "UPDATE_PRESENCE", (channel) => {
|
|
389
295
|
var _a, _b;
|
|
390
296
|
channel.updateUser(cache.id, ((_a = message.payload) === null || _a === void 0 ? void 0 : _a.presence) || {}, ((_b = message.payload) === null || _b === void 0 ? void 0 : _b.assigns) || {});
|
|
391
297
|
});
|
|
392
298
|
break;
|
|
393
299
|
}
|
|
394
|
-
}
|
|
300
|
+
}
|
|
395
301
|
/**
|
|
396
302
|
* @desc Handles a channel action by finding the channel and executing the callback.
|
|
397
303
|
* @param channelName - The name of the channel to find.
|
|
@@ -399,17 +305,16 @@ var Endpoint = /** @class */ (function (_super) {
|
|
|
399
305
|
* @param action - The action to execute.
|
|
400
306
|
* @private
|
|
401
307
|
*/
|
|
402
|
-
|
|
403
|
-
|
|
308
|
+
_channelAction(channelName, event, action) {
|
|
309
|
+
const channel = this._findChannel(channelName);
|
|
404
310
|
if (!channel)
|
|
405
|
-
throw new Error(
|
|
311
|
+
throw new Error(`Channel ${channelName} does not exist`);
|
|
406
312
|
try {
|
|
407
313
|
return action(channel);
|
|
408
314
|
}
|
|
409
315
|
catch (e) {
|
|
410
|
-
throw new Error(
|
|
316
|
+
throw new Error(`Error while executing event '${event}' on channel '${channelName}': ${e.message}`);
|
|
411
317
|
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
}(pondBase_1.BaseClass));
|
|
318
|
+
}
|
|
319
|
+
}
|
|
415
320
|
exports.Endpoint = Endpoint;
|