@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
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const middleware_1 = require("./middleware");
|
|
13
|
-
describe('Middleware', () => {
|
|
14
|
-
it('should be able to add middleware to the stack', () => {
|
|
15
|
-
const middleware = new middleware_1.Middleware();
|
|
16
|
-
middleware.use(() => { });
|
|
17
|
-
expect(middleware['_stack'].length).toBe(1);
|
|
18
|
-
});
|
|
19
|
-
it('should be able to run middleware', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
-
const middleware = new middleware_1.Middleware();
|
|
21
|
-
const mock = jest.fn();
|
|
22
|
-
middleware.use(mock);
|
|
23
|
-
yield middleware.run({}, {}, () => { });
|
|
24
|
-
expect(mock).toHaveBeenCalled();
|
|
25
|
-
}));
|
|
26
|
-
it('should be able to run multiple middleware', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
-
const middleware = new middleware_1.Middleware();
|
|
28
|
-
const mock = jest.fn();
|
|
29
|
-
middleware.use((_, __, next) => {
|
|
30
|
-
mock('first');
|
|
31
|
-
next();
|
|
32
|
-
});
|
|
33
|
-
middleware.use((_, __, next) => {
|
|
34
|
-
mock('second');
|
|
35
|
-
next();
|
|
36
|
-
});
|
|
37
|
-
yield middleware.run({}, {}, () => { });
|
|
38
|
-
expect(mock).toHaveBeenCalledTimes(2);
|
|
39
|
-
expect(mock.mock.calls[0][2]).toBe(mock.mock.calls[1][2]);
|
|
40
|
-
}));
|
|
41
|
-
it('should be merge middleware in the correct order', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
-
const middleware = new middleware_1.Middleware();
|
|
43
|
-
const mock = jest.fn();
|
|
44
|
-
middleware.use(mock);
|
|
45
|
-
middleware.use(mock);
|
|
46
|
-
const middleware2 = new middleware_1.Middleware(middleware);
|
|
47
|
-
expect(middleware2['_stack'].length).toBe(2);
|
|
48
|
-
}));
|
|
49
|
-
it('should call the final function when the middleware stack is empty', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
-
const middleware = new middleware_1.Middleware();
|
|
51
|
-
const mock = jest.fn();
|
|
52
|
-
yield middleware.run({}, {}, mock);
|
|
53
|
-
expect(mock).toHaveBeenCalled();
|
|
54
|
-
}));
|
|
55
|
-
it('should be able to run middleware in the correct order when using a second middleware', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
-
const middleware = new middleware_1.Middleware();
|
|
57
|
-
const mock = jest.fn();
|
|
58
|
-
middleware.use((_, __, next) => {
|
|
59
|
-
mock('first');
|
|
60
|
-
next();
|
|
61
|
-
});
|
|
62
|
-
middleware.use((_, __, next) => {
|
|
63
|
-
mock('second');
|
|
64
|
-
next();
|
|
65
|
-
});
|
|
66
|
-
const middleware2 = new middleware_1.Middleware(middleware);
|
|
67
|
-
yield middleware2.run({}, {}, () => { });
|
|
68
|
-
expect(mock.mock.calls[0][2]).toBe(mock.mock.calls[1][2]);
|
|
69
|
-
}));
|
|
70
|
-
});
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
-
var t = {};
|
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
-
t[p] = s[p];
|
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
-
t[p[i]] = s[p[i]];
|
|
10
|
-
}
|
|
11
|
-
return t;
|
|
12
|
-
};
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.ChannelEngine = exports.ServerActions = void 0;
|
|
15
|
-
const eventRequest_1 = require("./eventRequest");
|
|
16
|
-
const eventResponse_1 = require("./eventResponse");
|
|
17
|
-
const enums_1 = require("../../enums");
|
|
18
|
-
const presenceEngine_1 = require("../presence/presenceEngine");
|
|
19
|
-
const subjectUtils_1 = require("../utils/subjectUtils");
|
|
20
|
-
var ServerActions;
|
|
21
|
-
(function (ServerActions) {
|
|
22
|
-
ServerActions["PRESENCE"] = "PRESENCE";
|
|
23
|
-
ServerActions["SYSTEM"] = "SYSTEM";
|
|
24
|
-
ServerActions["BROADCAST"] = "BROADCAST";
|
|
25
|
-
ServerActions["ERROR"] = "ERROR";
|
|
26
|
-
})(ServerActions = exports.ServerActions || (exports.ServerActions = {}));
|
|
27
|
-
class ChannelEngine {
|
|
28
|
-
constructor(name, parent) {
|
|
29
|
-
this.name = name;
|
|
30
|
-
this._receiver = new subjectUtils_1.Subject();
|
|
31
|
-
this._users = new Map();
|
|
32
|
-
this._parentEngine = parent;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* @desc Adds a user to the channel
|
|
36
|
-
* @param userId - The id of the user to add
|
|
37
|
-
* @param assigns - The assigns to add to the user
|
|
38
|
-
* @param onMessage - The callback to call when a message is received
|
|
39
|
-
*/
|
|
40
|
-
addUser(userId, assigns, onMessage) {
|
|
41
|
-
const oldUser = this._users.get(userId);
|
|
42
|
-
if (oldUser) {
|
|
43
|
-
throw new Error(`ChannelEngine: User with id ${userId} already exists in channel ${this.name}`);
|
|
44
|
-
}
|
|
45
|
-
this._users.set(userId, assigns);
|
|
46
|
-
return this._subscribe(userId, onMessage);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* @desc Removes a user from the channel
|
|
50
|
-
* @param userId - The id of the user to remove
|
|
51
|
-
* @param isPond - Whether the user is a pond or not
|
|
52
|
-
*/
|
|
53
|
-
removeUser(userId, isPond = false) {
|
|
54
|
-
const user = this._users.get(userId);
|
|
55
|
-
if (user) {
|
|
56
|
-
this._users.delete(userId);
|
|
57
|
-
this.unTrackPresence(userId, true);
|
|
58
|
-
this._receiver.unsubscribe(userId);
|
|
59
|
-
if (this._users.size === 0) {
|
|
60
|
-
this._parentEngine.destroyChannel();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
else if (!isPond) {
|
|
64
|
-
throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* @desc Kicks a user from the channel
|
|
69
|
-
* @param userId - The id of the user to kick
|
|
70
|
-
* @param reason - The reason for kicking the user
|
|
71
|
-
*/
|
|
72
|
-
kickUser(userId, reason) {
|
|
73
|
-
this.sendMessage(enums_1.SystemSender.CHANNEL, [userId], ServerActions.SYSTEM, 'kicked_out', {
|
|
74
|
-
message: 'You have been kicked out of the channel',
|
|
75
|
-
reason,
|
|
76
|
-
});
|
|
77
|
-
this.removeUser(userId);
|
|
78
|
-
this.sendMessage(enums_1.SystemSender.CHANNEL, 'all_users', ServerActions.SYSTEM, 'kicked', {
|
|
79
|
-
userId,
|
|
80
|
-
reason,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* @desc Self destructs the channel
|
|
85
|
-
* @param reason - The reason for self-destructing the channel
|
|
86
|
-
*/
|
|
87
|
-
destroy(reason) {
|
|
88
|
-
this.sendMessage(enums_1.SystemSender.CHANNEL, 'all_users', ServerActions.ERROR, 'destroyed', {
|
|
89
|
-
message: 'Channel has been destroyed',
|
|
90
|
-
reason,
|
|
91
|
-
});
|
|
92
|
-
this._parentEngine.destroyChannel();
|
|
93
|
-
this._users.forEach((_, userId) => this._receiver.unsubscribe(userId));
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* @desc Begins tracking a user's presence
|
|
97
|
-
* @param userId - The id of the user to track
|
|
98
|
-
* @param presence - The initial presence of the user
|
|
99
|
-
*/
|
|
100
|
-
trackPresence(userId, presence) {
|
|
101
|
-
this._presenceEngine = this._presenceEngine || new presenceEngine_1.PresenceEngine();
|
|
102
|
-
if (!this._users.has(userId)) {
|
|
103
|
-
throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
|
|
104
|
-
}
|
|
105
|
-
if (this._presenceEngine.getUserPresence(userId)) {
|
|
106
|
-
throw new Error(`ChannelEngine: User with id ${userId} already has a presence subscription in channel ${this.name}`);
|
|
107
|
-
}
|
|
108
|
-
this._presenceEngine.trackPresence(userId, presence, (change) => {
|
|
109
|
-
const { type } = change, rest = __rest(change, ["type"]);
|
|
110
|
-
this.sendMessage(enums_1.SystemSender.CHANNEL, [userId], ServerActions.PRESENCE, type, rest);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* @desc Updates a user's presence
|
|
115
|
-
* @param userId - The id of the user to update
|
|
116
|
-
* @param presence - The new presence of the user
|
|
117
|
-
*/
|
|
118
|
-
updatePresence(userId, presence) {
|
|
119
|
-
if (!this._users.has(userId)) {
|
|
120
|
-
throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
|
|
121
|
-
}
|
|
122
|
-
if (this._presenceEngine) {
|
|
123
|
-
this._presenceEngine.updatePresence(userId, presence);
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
throw new Error('ChannelEngine: Presence engine is not initialized');
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* @desc Updates a user's assigns
|
|
131
|
-
* @param userId - The id of the user to update
|
|
132
|
-
* @param assigns - The new assigns of the user
|
|
133
|
-
*/
|
|
134
|
-
updateAssigns(userId, assigns) {
|
|
135
|
-
const user = this._users.get(userId);
|
|
136
|
-
if (user) {
|
|
137
|
-
this._users.set(userId, Object.assign(Object.assign({}, user), assigns));
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* @desc Gets the data of a user
|
|
145
|
-
* @param userId - The id of the user to get
|
|
146
|
-
*/
|
|
147
|
-
getUserData(userId) {
|
|
148
|
-
const presence = this._presenceEngine ? this._presenceEngine.getUserPresence(userId) : {};
|
|
149
|
-
if (this._users.has(userId)) {
|
|
150
|
-
return {
|
|
151
|
-
id: userId,
|
|
152
|
-
assigns: this._users.get(userId),
|
|
153
|
-
presence: presence || {},
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
return undefined;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* @desc Gets the assign data of all users
|
|
160
|
-
*/
|
|
161
|
-
getAssigns() {
|
|
162
|
-
const assigns = {};
|
|
163
|
-
this._users.forEach((value, key) => {
|
|
164
|
-
assigns[key] = value;
|
|
165
|
-
});
|
|
166
|
-
return assigns;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* @desc Gets the presence data of all users
|
|
170
|
-
*/
|
|
171
|
-
getPresence() {
|
|
172
|
-
if (this._presenceEngine) {
|
|
173
|
-
return this._presenceEngine.getPresence();
|
|
174
|
-
}
|
|
175
|
-
return {};
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* @desc Stops tracking a user's presence
|
|
179
|
-
* @param userId - The id of the user to be untracked
|
|
180
|
-
* @param isPond - Whether the user is a pond
|
|
181
|
-
*/
|
|
182
|
-
unTrackPresence(userId, isPond = false) {
|
|
183
|
-
if (this._presenceEngine) {
|
|
184
|
-
if (isPond && this._presenceEngine.getUserPresence(userId)) {
|
|
185
|
-
this._presenceEngine.removePresence(userId);
|
|
186
|
-
}
|
|
187
|
-
else if (!isPond) {
|
|
188
|
-
this._presenceEngine.removePresence(userId);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* @desc Sends a message to a specified set of users, from a specified sender
|
|
194
|
-
* @param sender - The sender of the message
|
|
195
|
-
* @param recipient - The users to send the message to
|
|
196
|
-
* @param action - The action of the message
|
|
197
|
-
* @param event - The event name
|
|
198
|
-
* @param payload - The payload of the message
|
|
199
|
-
* @private
|
|
200
|
-
*/
|
|
201
|
-
sendMessage(sender, recipient, action, event, payload) {
|
|
202
|
-
if (!this._users.has(sender) && sender !== enums_1.SystemSender.CHANNEL) {
|
|
203
|
-
throw new Error(`ChannelEngine: User with id ${sender} does not exist in channel ${this.name}`);
|
|
204
|
-
}
|
|
205
|
-
this._receiver.next({
|
|
206
|
-
sender,
|
|
207
|
-
recipients: this._getUsersFromRecipients(recipient, sender),
|
|
208
|
-
action,
|
|
209
|
-
payload,
|
|
210
|
-
event,
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* @desc Handles a message from a user
|
|
215
|
-
* @param userId - The id of the user who sent the message
|
|
216
|
-
* @param message - The message received
|
|
217
|
-
*/
|
|
218
|
-
broadcastMessage(userId, message) {
|
|
219
|
-
if (!this._users.has(userId)) {
|
|
220
|
-
throw new Error(`ChannelEngine: User with id ${userId} does not exist in channel ${this.name}`);
|
|
221
|
-
}
|
|
222
|
-
const responseEvent = {
|
|
223
|
-
event: message.event,
|
|
224
|
-
payload: message.payload,
|
|
225
|
-
action: ServerActions.BROADCAST,
|
|
226
|
-
sender: userId,
|
|
227
|
-
recipients: this._getUsersFromRecipients(message.addresses || 'all_users', userId),
|
|
228
|
-
};
|
|
229
|
-
const request = new eventRequest_1.EventRequest(responseEvent, this);
|
|
230
|
-
const response = new eventResponse_1.EventResponse(responseEvent, this);
|
|
231
|
-
this._parentEngine.execute(request, response, () => {
|
|
232
|
-
this.sendMessage(enums_1.SystemSender.CHANNEL, [userId], ServerActions.ERROR, enums_1.ErrorTypes.HANDLER_NOT_FOUND, {
|
|
233
|
-
message: 'A handler did not respond to the event',
|
|
234
|
-
code: 404,
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* @desc Subscribes to a user's messages
|
|
240
|
-
* @param userId - The id of the user to subscribe to
|
|
241
|
-
* @param onMessage - The callback to call when a message is received
|
|
242
|
-
* @private
|
|
243
|
-
*/
|
|
244
|
-
_subscribe(userId, onMessage) {
|
|
245
|
-
this._receiver.subscribe(userId, (event) => {
|
|
246
|
-
if (event.recipients.includes(userId)) {
|
|
247
|
-
onMessage({
|
|
248
|
-
action: event.action,
|
|
249
|
-
event: event.event,
|
|
250
|
-
payload: event.payload,
|
|
251
|
-
channelName: this.name,
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
_getUsersFromRecipients(recipients, sender) {
|
|
257
|
-
const allUsers = Array.from(this._users.keys());
|
|
258
|
-
let users;
|
|
259
|
-
switch (recipients) {
|
|
260
|
-
case 'all_users':
|
|
261
|
-
users = allUsers;
|
|
262
|
-
break;
|
|
263
|
-
case 'all_except_sender':
|
|
264
|
-
if (sender === enums_1.SystemSender.CHANNEL) {
|
|
265
|
-
throw new Error('ChannelEngine: Cannot send to all users except sender when sender is channel');
|
|
266
|
-
}
|
|
267
|
-
users = allUsers.filter((user) => user !== sender);
|
|
268
|
-
break;
|
|
269
|
-
default:
|
|
270
|
-
const absentUsers = recipients.filter((user) => !allUsers.includes(user));
|
|
271
|
-
if (absentUsers.length > 0) {
|
|
272
|
-
throw new Error(`ChannelEngine: Users ${absentUsers.join(', ')} are not in channel ${this.name}`);
|
|
273
|
-
}
|
|
274
|
-
users = recipients;
|
|
275
|
-
break;
|
|
276
|
-
}
|
|
277
|
-
return users;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
exports.ChannelEngine = ChannelEngine;
|