@eleven-am/pondsocket 0.1.126 → 0.1.127
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/README.md +5 -15
- package/abstracts/abstractRequest.test.js +42 -0
- package/abstracts/middleware.test.js +70 -0
- package/channel/channel.js +18 -20
- package/channel/channel.test.js +415 -0
- package/channel/eventRequest.test.js +30 -0
- package/channel/eventResponse.js +7 -7
- package/channel/eventResponse.test.js +197 -0
- package/endpoint/endpoint.js +16 -19
- package/endpoint/endpoint.test.js +297 -0
- package/endpoint/response.js +5 -6
- package/index.d.ts +2 -0
- package/lobby/JoinRequest.test.js +40 -0
- package/lobby/JoinResponse.test.js +145 -0
- package/lobby/joinResponse.js +9 -9
- package/lobby/lobby.js +3 -4
- package/matcher/matcher.test.js +90 -0
- package/package.json +32 -13
- package/presence/presence.js +8 -9
- package/presence/presenceEngine.test.js +128 -0
- package/schema.js +3 -3
- package/server/pondSocket.js +5 -4
- package/types.d.ts +0 -496
- package/types.js +2 -0
- package/client/channel.js +0 -305
- package/client.d.ts +0 -5
- package/client.js +0 -107
- package/enums.js +0 -56
- package/express.d.ts +0 -3
- package/express.js +0 -17
- package/misc/uuid.js +0 -12
- package/nest.d.ts +0 -19
- package/nest.js +0 -769
- package/node.d.ts +0 -3
- package/node.js +0 -30
- package/subjects/subject.js +0 -137
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createChannelEvent = exports.createChannelEngine = void 0;
|
|
4
|
+
const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
|
|
5
|
+
const channel_1 = require("./channel");
|
|
6
|
+
const channel_test_1 = require("./channel.test");
|
|
7
|
+
const eventResponse_1 = require("./eventResponse");
|
|
8
|
+
const createChannelEngine = () => {
|
|
9
|
+
const parentEngine = (0, channel_test_1.createParentEngine)();
|
|
10
|
+
return new channel_1.ChannelEngine('test', parentEngine);
|
|
11
|
+
};
|
|
12
|
+
exports.createChannelEngine = createChannelEngine;
|
|
13
|
+
const createChannelEvent = (name) => {
|
|
14
|
+
const responseEvent = {
|
|
15
|
+
event: 'event',
|
|
16
|
+
payload: {
|
|
17
|
+
payload: 'payload',
|
|
18
|
+
},
|
|
19
|
+
sender: 'sender',
|
|
20
|
+
action: pondsocket_common_1.ServerActions.BROADCAST,
|
|
21
|
+
recipients: ['recipient'],
|
|
22
|
+
channelName: name,
|
|
23
|
+
requestId: 'requestId',
|
|
24
|
+
};
|
|
25
|
+
return responseEvent;
|
|
26
|
+
};
|
|
27
|
+
exports.createChannelEvent = createChannelEvent;
|
|
28
|
+
const createChannelResponse = () => {
|
|
29
|
+
const channelEngine = (0, exports.createChannelEngine)();
|
|
30
|
+
const event = (0, exports.createChannelEvent)(channelEngine.name);
|
|
31
|
+
channelEngine.addUser(event.sender, { assign: 'assign' }, () => { });
|
|
32
|
+
channelEngine.addUser(event.recipients[0], { assign: 'assign' }, () => { });
|
|
33
|
+
const response = new eventResponse_1.EventResponse(event, channelEngine);
|
|
34
|
+
return {
|
|
35
|
+
channelEngine,
|
|
36
|
+
event,
|
|
37
|
+
response,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
describe('ChannelResponse', () => {
|
|
41
|
+
it('should create a new ChannelResponse', () => {
|
|
42
|
+
const { response } = createChannelResponse();
|
|
43
|
+
expect(response).toBeDefined();
|
|
44
|
+
});
|
|
45
|
+
it('should accept the request', () => {
|
|
46
|
+
const { response, channelEngine } = createChannelResponse();
|
|
47
|
+
jest.spyOn(channelEngine, 'sendMessage');
|
|
48
|
+
response.accept();
|
|
49
|
+
expect(channelEngine.sendMessage).toHaveBeenCalledWith('requestId', 'sender', ['recipient'], pondsocket_common_1.ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
50
|
+
});
|
|
51
|
+
it('should reject the request', () => {
|
|
52
|
+
const { response, channelEngine, event } = createChannelResponse();
|
|
53
|
+
jest.spyOn(channelEngine, 'sendMessage');
|
|
54
|
+
response.reject();
|
|
55
|
+
expect(channelEngine.sendMessage).toHaveBeenCalledWith('requestId', pondsocket_common_1.SystemSender.CHANNEL, [event.sender], pondsocket_common_1.ServerActions.ERROR, pondsocket_common_1.ErrorTypes.UNAUTHORIZED_BROADCAST, {
|
|
56
|
+
message: 'Unauthorized request',
|
|
57
|
+
code: 403,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
it('should send a direct message', () => {
|
|
61
|
+
const { response, channelEngine, event } = createChannelResponse();
|
|
62
|
+
jest.spyOn(channelEngine, 'sendMessage');
|
|
63
|
+
response.send('event', { payload: 'payload' });
|
|
64
|
+
expect(channelEngine.sendMessage).toHaveBeenCalledWith('requestId', pondsocket_common_1.SystemSender.CHANNEL, [event.sender], pondsocket_common_1.ServerActions.SYSTEM, 'event', { payload: 'payload' });
|
|
65
|
+
});
|
|
66
|
+
it('should broadcast a message', () => {
|
|
67
|
+
const { response, channelEngine } = createChannelResponse();
|
|
68
|
+
jest.spyOn(channelEngine, 'sendMessage');
|
|
69
|
+
response.broadcast('event', { payload: 'payload' });
|
|
70
|
+
expect(channelEngine.sendMessage).toHaveBeenCalledWith('requestId', 'sender', pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
71
|
+
});
|
|
72
|
+
it('should broadcastFromUser a message', () => {
|
|
73
|
+
const { response, channelEngine } = createChannelResponse();
|
|
74
|
+
jest.spyOn(channelEngine, 'sendMessage');
|
|
75
|
+
response.broadcastFromUser('event', { payload: 'payload' });
|
|
76
|
+
expect(channelEngine.sendMessage).toHaveBeenCalledWith('requestId', 'sender', pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER, pondsocket_common_1.ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
77
|
+
});
|
|
78
|
+
it('should sendToUsers a message', () => {
|
|
79
|
+
const { response, channelEngine } = createChannelResponse();
|
|
80
|
+
jest.spyOn(channelEngine, 'sendMessage');
|
|
81
|
+
response.sendToUsers('event', { payload: 'payload' }, ['recipient']);
|
|
82
|
+
expect(channelEngine.sendMessage).toHaveBeenCalledWith('requestId', 'sender', ['recipient'], pondsocket_common_1.ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
83
|
+
});
|
|
84
|
+
it('should fail to send to non existing users', () => {
|
|
85
|
+
const { event, response, channelEngine } = createChannelResponse();
|
|
86
|
+
jest.spyOn(channelEngine, 'sendMessage');
|
|
87
|
+
event.recipients = ['non_existing_user'];
|
|
88
|
+
expect(() => response.accept()).toThrow('ChannelEngine: Invalid recipients non_existing_user some users do not exist in channel test');
|
|
89
|
+
expect(channelEngine.sendMessage).toHaveBeenCalledWith('requestId', event.sender, ['non_existing_user'], pondsocket_common_1.ServerActions.BROADCAST, event.event, event.payload);
|
|
90
|
+
expect(() => response.sendToUsers('event', { payload: 'payload' }, ['non_existing_user']))
|
|
91
|
+
.toThrow('ChannelEngine: Invalid recipients non_existing_user some users do not exist in channel test');
|
|
92
|
+
});
|
|
93
|
+
it('should track a trackPresence', () => {
|
|
94
|
+
const { response, channelEngine } = createChannelResponse();
|
|
95
|
+
jest.spyOn(channelEngine.presenceEngine, 'trackPresence');
|
|
96
|
+
response.trackPresence({ status: 'online' });
|
|
97
|
+
expect(channelEngine.presenceEngine.trackPresence).toHaveBeenCalledWith('sender', { status: 'online' });
|
|
98
|
+
});
|
|
99
|
+
it('should update a users assign data', () => {
|
|
100
|
+
const { response, channelEngine } = createChannelResponse();
|
|
101
|
+
jest.spyOn(channelEngine, 'updateAssigns');
|
|
102
|
+
response.accept({ assign: 'updated' });
|
|
103
|
+
expect(channelEngine.updateAssigns).toHaveBeenCalledWith('sender', { assign: 'updated' });
|
|
104
|
+
});
|
|
105
|
+
it('should evict a user', () => {
|
|
106
|
+
const { response, channelEngine } = createChannelResponse();
|
|
107
|
+
jest.spyOn(channelEngine, 'kickUser');
|
|
108
|
+
response.evictUser('recipient');
|
|
109
|
+
expect(channelEngine.kickUser).toHaveBeenCalledWith('sender', 'recipient');
|
|
110
|
+
});
|
|
111
|
+
it('should destroy the channel', () => {
|
|
112
|
+
const { response, channelEngine } = createChannelResponse();
|
|
113
|
+
jest.spyOn(channelEngine, 'destroy');
|
|
114
|
+
response.closeChannel('recipient');
|
|
115
|
+
expect(channelEngine.destroy).toHaveBeenCalledWith('recipient');
|
|
116
|
+
});
|
|
117
|
+
it('should call the presence engine when the trackPresence is called', () => {
|
|
118
|
+
const { response, channelEngine } = createChannelResponse();
|
|
119
|
+
jest.spyOn(channelEngine.presenceEngine, 'trackPresence');
|
|
120
|
+
expect(channelEngine.presenceEngine.trackPresence).not.toHaveBeenCalled();
|
|
121
|
+
response.accept();
|
|
122
|
+
response.trackPresence({ status: 'online' });
|
|
123
|
+
expect(channelEngine.presenceEngine.trackPresence).toHaveBeenCalledWith('sender', { status: 'online' });
|
|
124
|
+
});
|
|
125
|
+
it('should throw an error if trackPresence is called twice', () => {
|
|
126
|
+
const { response, channelEngine } = createChannelResponse();
|
|
127
|
+
jest.spyOn(channelEngine.presenceEngine, 'trackPresence');
|
|
128
|
+
expect(channelEngine.presenceEngine.trackPresence).not.toHaveBeenCalled();
|
|
129
|
+
response.accept();
|
|
130
|
+
response.trackPresence({ status: 'online' });
|
|
131
|
+
expect(channelEngine.presenceEngine.trackPresence).toHaveBeenCalledWith('sender', { status: 'online' });
|
|
132
|
+
expect(() => response.trackPresence({ status: 'online' })).toThrow('PresenceEngine: Presence with key sender already exists');
|
|
133
|
+
});
|
|
134
|
+
it('should throw an error if trackPresence is called for a non existing user', () => {
|
|
135
|
+
const { response, channelEngine } = createChannelResponse();
|
|
136
|
+
jest.spyOn(channelEngine.presenceEngine, 'trackPresence');
|
|
137
|
+
expect(channelEngine.presenceEngine.trackPresence).not.toHaveBeenCalled();
|
|
138
|
+
response.accept();
|
|
139
|
+
expect(() => response.trackPresence({ status: 'online' }, 'non_existent_user'))
|
|
140
|
+
.toThrow('ChannelEngine: Invalid recipients non_existent_user some users do not exist in channel test');
|
|
141
|
+
});
|
|
142
|
+
it('should update the presence of a user that is already tracked', () => {
|
|
143
|
+
var _a, _b;
|
|
144
|
+
const { response, channelEngine } = createChannelResponse();
|
|
145
|
+
jest.spyOn(channelEngine.presenceEngine, 'trackPresence');
|
|
146
|
+
expect(channelEngine.presenceEngine.trackPresence).not.toHaveBeenCalled();
|
|
147
|
+
response.accept();
|
|
148
|
+
response.trackPresence({ status: 'online' });
|
|
149
|
+
expect(channelEngine.presenceEngine.trackPresence).toHaveBeenCalledWith('sender', { status: 'online' });
|
|
150
|
+
expect((_a = channelEngine.presenceEngine) === null || _a === void 0 ? void 0 : _a.getPresence()).toEqual({
|
|
151
|
+
sender: { status: 'online' },
|
|
152
|
+
});
|
|
153
|
+
response.updatePresence({ status: 'offline' });
|
|
154
|
+
expect((_b = channelEngine.presenceEngine) === null || _b === void 0 ? void 0 : _b.getPresence()).toEqual({
|
|
155
|
+
sender: { status: 'offline' },
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
it('should throw an error if updatePresence is called for a non existing user', () => {
|
|
159
|
+
const { response, channelEngine } = createChannelResponse();
|
|
160
|
+
jest.spyOn(channelEngine.presenceEngine, 'trackPresence');
|
|
161
|
+
expect(channelEngine.presenceEngine.trackPresence).not.toHaveBeenCalled();
|
|
162
|
+
response.accept();
|
|
163
|
+
response.trackPresence({ status: 'online' });
|
|
164
|
+
expect(() => response.updatePresence({ status: 'online' }, 'non_existent_user'))
|
|
165
|
+
.toThrow('PresenceEngine: Presence with key non_existent_user does not exist');
|
|
166
|
+
});
|
|
167
|
+
it('should unTrack a trackPresence', () => {
|
|
168
|
+
var _a, _b;
|
|
169
|
+
const { response, channelEngine } = createChannelResponse();
|
|
170
|
+
response.trackPresence({ status: 'online' });
|
|
171
|
+
expect((_a = channelEngine.presenceEngine) === null || _a === void 0 ? void 0 : _a.getPresence()).toEqual({
|
|
172
|
+
sender: { status: 'online' },
|
|
173
|
+
});
|
|
174
|
+
response.unTrackPresence();
|
|
175
|
+
expect((_b = channelEngine.presenceEngine) === null || _b === void 0 ? void 0 : _b.getPresence()).toEqual({});
|
|
176
|
+
});
|
|
177
|
+
it('should throw an error if unTrackPresence is called for a non existing user', () => {
|
|
178
|
+
var _a;
|
|
179
|
+
const { response, channelEngine } = createChannelResponse();
|
|
180
|
+
response.trackPresence({ status: 'online' });
|
|
181
|
+
expect((_a = channelEngine.presenceEngine) === null || _a === void 0 ? void 0 : _a.getPresence()).toEqual({
|
|
182
|
+
sender: { status: 'online' },
|
|
183
|
+
});
|
|
184
|
+
expect(() => response.unTrackPresence('non_existent_user'))
|
|
185
|
+
.toThrow('PresenceEngine: Presence with key non_existent_user does not exist');
|
|
186
|
+
});
|
|
187
|
+
it('should throw an error if accept, reject / send is called more than once', () => {
|
|
188
|
+
const { response, channelEngine } = createChannelResponse();
|
|
189
|
+
jest.spyOn(channelEngine, 'sendMessage');
|
|
190
|
+
expect(channelEngine.sendMessage).not.toHaveBeenCalled();
|
|
191
|
+
response.accept();
|
|
192
|
+
expect(channelEngine.sendMessage).toHaveBeenCalledWith('requestId', 'sender', ['recipient'], pondsocket_common_1.ServerActions.BROADCAST, 'event', { payload: 'payload' });
|
|
193
|
+
expect(() => response.accept()).toThrow('Event response has already been executed');
|
|
194
|
+
expect(() => response.reject()).toThrow('Event response has already been executed');
|
|
195
|
+
expect(() => response.send('event', { payload: 'payload' })).toThrow('Event response has already been executed');
|
|
196
|
+
});
|
|
197
|
+
});
|
package/endpoint/endpoint.js
CHANGED
|
@@ -10,18 +10,17 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
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
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _Endpoint_instances, _Endpoint_middleware, _Endpoint_channels, _Endpoint_sockets, _Endpoint_sendMessage, _Endpoint_joinChannel, _Endpoint_execute, _Endpoint_handleMessage, _Endpoint_readMessage
|
|
13
|
+
var _Endpoint_instances, _Endpoint_middleware, _Endpoint_channels, _Endpoint_sockets, _Endpoint_sendMessage, _Endpoint_joinChannel, _Endpoint_execute, _Endpoint_handleMessage, _Endpoint_readMessage;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.Endpoint = void 0;
|
|
16
|
+
const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
|
|
16
17
|
const zod_1 = require("zod");
|
|
17
18
|
const middleware_1 = require("../abstracts/middleware");
|
|
18
|
-
const enums_1 = require("../enums");
|
|
19
19
|
const pondError_1 = require("../errors/pondError");
|
|
20
20
|
const joinRequest_1 = require("../lobby/joinRequest");
|
|
21
21
|
const joinResponse_1 = require("../lobby/joinResponse");
|
|
22
22
|
const lobby_1 = require("../lobby/lobby");
|
|
23
23
|
const matcher_1 = require("../matcher/matcher");
|
|
24
|
-
const uuid_1 = require("../misc/uuid");
|
|
25
24
|
const schema_1 = require("../schema");
|
|
26
25
|
class Endpoint {
|
|
27
26
|
constructor() {
|
|
@@ -86,9 +85,9 @@ class Endpoint {
|
|
|
86
85
|
const message = {
|
|
87
86
|
event,
|
|
88
87
|
payload,
|
|
89
|
-
requestId: (0,
|
|
90
|
-
action:
|
|
91
|
-
channelName:
|
|
88
|
+
requestId: (0, pondsocket_common_1.uuid)(),
|
|
89
|
+
action: pondsocket_common_1.ServerActions.BROADCAST,
|
|
90
|
+
channelName: pondsocket_common_1.SystemSender.ENDPOINT,
|
|
92
91
|
};
|
|
93
92
|
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_sendMessage).call(this, socket, message);
|
|
94
93
|
});
|
|
@@ -145,15 +144,15 @@ _Endpoint_middleware = new WeakMap(), _Endpoint_channels = new WeakMap(), _Endpo
|
|
|
145
144
|
throw new Error(`GatewayEngine: Channel ${channel} does not exist`);
|
|
146
145
|
}, _Endpoint_handleMessage = function _Endpoint_handleMessage(cache, message) {
|
|
147
146
|
switch (message.action) {
|
|
148
|
-
case
|
|
147
|
+
case pondsocket_common_1.ClientActions.JOIN_CHANNEL:
|
|
149
148
|
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_joinChannel).call(this, message.channelName, cache, message.payload, message.requestId);
|
|
150
149
|
break;
|
|
151
|
-
case
|
|
150
|
+
case pondsocket_common_1.ClientActions.LEAVE_CHANNEL:
|
|
152
151
|
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_execute).call(this, message.channelName, (channel) => {
|
|
153
152
|
channel.removeUser(cache.clientId);
|
|
154
153
|
});
|
|
155
154
|
break;
|
|
156
|
-
case
|
|
155
|
+
case pondsocket_common_1.ClientActions.BROADCAST:
|
|
157
156
|
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_execute).call(this, message.channelName, (channel) => {
|
|
158
157
|
channel.broadcastMessage(cache.clientId, message);
|
|
159
158
|
});
|
|
@@ -163,10 +162,10 @@ _Endpoint_middleware = new WeakMap(), _Endpoint_channels = new WeakMap(), _Endpo
|
|
|
163
162
|
}
|
|
164
163
|
}, _Endpoint_readMessage = function _Endpoint_readMessage(cache, message) {
|
|
165
164
|
const errorMessage = {
|
|
166
|
-
event:
|
|
167
|
-
action:
|
|
168
|
-
channelName:
|
|
169
|
-
requestId: (0,
|
|
165
|
+
event: pondsocket_common_1.ErrorTypes.INVALID_MESSAGE,
|
|
166
|
+
action: pondsocket_common_1.ServerActions.ERROR,
|
|
167
|
+
channelName: pondsocket_common_1.SystemSender.ENDPOINT,
|
|
168
|
+
requestId: (0, pondsocket_common_1.uuid)(),
|
|
170
169
|
payload: {},
|
|
171
170
|
};
|
|
172
171
|
try {
|
|
@@ -187,13 +186,13 @@ _Endpoint_middleware = new WeakMap(), _Endpoint_channels = new WeakMap(), _Endpo
|
|
|
187
186
|
};
|
|
188
187
|
}
|
|
189
188
|
else if (e instanceof Error) {
|
|
190
|
-
errorMessage.event =
|
|
189
|
+
errorMessage.event = pondsocket_common_1.ErrorTypes.INTERNAL_SERVER_ERROR;
|
|
191
190
|
errorMessage.payload = {
|
|
192
191
|
message: e.message,
|
|
193
192
|
};
|
|
194
193
|
}
|
|
195
194
|
else if (e instanceof pondError_1.PresenceError) {
|
|
196
|
-
errorMessage.event =
|
|
195
|
+
errorMessage.event = pondsocket_common_1.ErrorTypes.PRESENCE_ERROR;
|
|
197
196
|
errorMessage.channelName = e.channel;
|
|
198
197
|
errorMessage.payload = {
|
|
199
198
|
message: e.message,
|
|
@@ -202,7 +201,7 @@ _Endpoint_middleware = new WeakMap(), _Endpoint_channels = new WeakMap(), _Endpo
|
|
|
202
201
|
};
|
|
203
202
|
}
|
|
204
203
|
else if (e instanceof pondError_1.ChannelError) {
|
|
205
|
-
errorMessage.event =
|
|
204
|
+
errorMessage.event = pondsocket_common_1.ErrorTypes.CHANNEL_ERROR;
|
|
206
205
|
errorMessage.channelName = e.channel;
|
|
207
206
|
errorMessage.payload = {
|
|
208
207
|
message: e.message,
|
|
@@ -210,7 +209,7 @@ _Endpoint_middleware = new WeakMap(), _Endpoint_channels = new WeakMap(), _Endpo
|
|
|
210
209
|
};
|
|
211
210
|
}
|
|
212
211
|
else if (e instanceof pondError_1.EndpointError) {
|
|
213
|
-
errorMessage.event =
|
|
212
|
+
errorMessage.event = pondsocket_common_1.ErrorTypes.ENDPOINT_ERROR;
|
|
214
213
|
errorMessage.payload = {
|
|
215
214
|
message: e.message,
|
|
216
215
|
code: e.code,
|
|
@@ -223,6 +222,4 @@ _Endpoint_middleware = new WeakMap(), _Endpoint_channels = new WeakMap(), _Endpo
|
|
|
223
222
|
}
|
|
224
223
|
__classPrivateFieldGet(this, _Endpoint_instances, "m", _Endpoint_sendMessage).call(this, cache.socket, errorMessage);
|
|
225
224
|
}
|
|
226
|
-
}, _Endpoint_isObjectEmpty = function _Endpoint_isObjectEmpty(obj) {
|
|
227
|
-
return Object.keys(obj).length === 0;
|
|
228
225
|
};
|
|
@@ -0,0 +1,297 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
|
|
16
|
+
const superwstest_1 = __importDefault(require("superwstest"));
|
|
17
|
+
const pondSocket_1 = require("../server/pondSocket");
|
|
18
|
+
/* eslint-disable line-comment-position, no-inline-comments */
|
|
19
|
+
describe('endpoint', () => {
|
|
20
|
+
let socket;
|
|
21
|
+
let server;
|
|
22
|
+
beforeEach((done) => {
|
|
23
|
+
socket = new pondSocket_1.PondSocket();
|
|
24
|
+
server = socket.listen(3000, 'localhost', done);
|
|
25
|
+
});
|
|
26
|
+
afterEach((done) => {
|
|
27
|
+
server.close(done);
|
|
28
|
+
});
|
|
29
|
+
it('should be able to close a single socket', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
let count = 0;
|
|
31
|
+
const endpoint = socket.createEndpoint('/api/:room', (req, res) => {
|
|
32
|
+
if (req.params.room === 'socket') {
|
|
33
|
+
res.accept();
|
|
34
|
+
count++;
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
endpoint.closeConnection(req.id);
|
|
37
|
+
}, 1000);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
res.reject();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
yield (0, superwstest_1.default)(server)
|
|
44
|
+
.ws('/api/socket')
|
|
45
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
46
|
+
.wait(200)
|
|
47
|
+
.expectClosed();
|
|
48
|
+
expect(count).toBe(1);
|
|
49
|
+
}));
|
|
50
|
+
it('should be able to list connections', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
const endpoint = socket.createEndpoint('/api/:room', (req, res) => {
|
|
52
|
+
if (req.params.room === 'socket') {
|
|
53
|
+
res.accept();
|
|
54
|
+
const connections = endpoint.listConnections();
|
|
55
|
+
expect(connections).toHaveLength(1);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
res.reject();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
yield (0, superwstest_1.default)(server)
|
|
62
|
+
.ws('/api/socket')
|
|
63
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101));
|
|
64
|
+
}));
|
|
65
|
+
it('should be able to refuse connections to the endpoint', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
+
let count = 0;
|
|
67
|
+
socket.createEndpoint('/api/:path', (req, res) => {
|
|
68
|
+
count++;
|
|
69
|
+
expect(req.params.path).toBe('socket');
|
|
70
|
+
res.reject();
|
|
71
|
+
});
|
|
72
|
+
yield (0, superwstest_1.default)(server)
|
|
73
|
+
.ws('/api/socket')
|
|
74
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101)) // the connection is still upgraded, so we can send error messages
|
|
75
|
+
.expectMessage(expect.objectContaining({
|
|
76
|
+
action: pondsocket_common_1.ServerActions.ERROR,
|
|
77
|
+
event: pondsocket_common_1.ErrorTypes.UNAUTHORIZED_CONNECTION,
|
|
78
|
+
channelName: pondsocket_common_1.SystemSender.ENDPOINT,
|
|
79
|
+
payload: {
|
|
80
|
+
message: 'Unauthorized connection',
|
|
81
|
+
code: 401,
|
|
82
|
+
},
|
|
83
|
+
}))
|
|
84
|
+
.expectClosed();
|
|
85
|
+
expect(count).toBe(1);
|
|
86
|
+
}));
|
|
87
|
+
it('should be able to send a message to all connection', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
88
|
+
const endpoint = socket.createEndpoint('/api/:room', (req, res) => {
|
|
89
|
+
if (req.params.room === 'socket') {
|
|
90
|
+
res.accept();
|
|
91
|
+
const connections = endpoint.listConnections();
|
|
92
|
+
expect(connections).toHaveLength(1);
|
|
93
|
+
endpoint.broadcast('TEST', { test: 'test' });
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
res.reject();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
yield (0, superwstest_1.default)(server)
|
|
100
|
+
.ws('/api/socket')
|
|
101
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
102
|
+
.expectMessage(expect.objectContaining({
|
|
103
|
+
event: 'TEST',
|
|
104
|
+
action: pondsocket_common_1.ServerActions.BROADCAST,
|
|
105
|
+
channelName: pondsocket_common_1.SystemSender.ENDPOINT,
|
|
106
|
+
payload: {
|
|
107
|
+
test: 'test',
|
|
108
|
+
},
|
|
109
|
+
}));
|
|
110
|
+
}));
|
|
111
|
+
it('should be able to accept connections on this handler', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
|
+
const message = {
|
|
113
|
+
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
114
|
+
channelName: '/test/socket',
|
|
115
|
+
event: 'TEST',
|
|
116
|
+
payload: {},
|
|
117
|
+
};
|
|
118
|
+
const endpoint = socket.createEndpoint('/api/:room', (req, res) => {
|
|
119
|
+
if (req.params.room === 'socket') {
|
|
120
|
+
res.accept();
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
res.reject();
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
endpoint.createChannel('/test/:room', (req, res) => {
|
|
127
|
+
expect(req.event.params.room).toBeDefined();
|
|
128
|
+
res.accept({
|
|
129
|
+
assigns: {
|
|
130
|
+
status: 'online',
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
yield (0, superwstest_1.default)(server)
|
|
135
|
+
.ws('/api/socket')
|
|
136
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
137
|
+
.sendJson(message)
|
|
138
|
+
.close()
|
|
139
|
+
.expectClosed();
|
|
140
|
+
yield (0, superwstest_1.default)(server)
|
|
141
|
+
.ws('/api/socket')
|
|
142
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
143
|
+
.sendJson(Object.assign(Object.assign({}, message), { channelName: '/socket/socket' }))
|
|
144
|
+
.expectMessage(expect.objectContaining({
|
|
145
|
+
action: pondsocket_common_1.ServerActions.SYSTEM,
|
|
146
|
+
channelName: '/socket/socket',
|
|
147
|
+
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
148
|
+
payload: {},
|
|
149
|
+
}))
|
|
150
|
+
.close()
|
|
151
|
+
.expectClosed();
|
|
152
|
+
}));
|
|
153
|
+
it('should send an error when the channel exists but other things happen', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
154
|
+
const message = {
|
|
155
|
+
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
156
|
+
channelName: '/test/socket',
|
|
157
|
+
event: 'TEST',
|
|
158
|
+
payload: {},
|
|
159
|
+
};
|
|
160
|
+
const endpoint = socket.createEndpoint('/api/:room', (_, res) => {
|
|
161
|
+
res.accept();
|
|
162
|
+
});
|
|
163
|
+
endpoint.createChannel('/test/:room', (req, res) => {
|
|
164
|
+
expect(req.event.params.room).toBeDefined();
|
|
165
|
+
res.reject('Something went wrong');
|
|
166
|
+
});
|
|
167
|
+
yield (0, superwstest_1.default)(server)
|
|
168
|
+
.ws('/api/socket')
|
|
169
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
170
|
+
.sendJson(message)
|
|
171
|
+
.expectMessage(expect.objectContaining({
|
|
172
|
+
action: pondsocket_common_1.ServerActions.ERROR,
|
|
173
|
+
channelName: '/test/socket',
|
|
174
|
+
event: pondsocket_common_1.ErrorTypes.UNAUTHORIZED_JOIN_REQUEST,
|
|
175
|
+
payload: {
|
|
176
|
+
message: 'Request to join channel /test/socket rejected: Something went wrong',
|
|
177
|
+
code: 403,
|
|
178
|
+
},
|
|
179
|
+
}))
|
|
180
|
+
.close()
|
|
181
|
+
.expectClosed();
|
|
182
|
+
}));
|
|
183
|
+
it('should be able to track the presence of its users', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
184
|
+
const message = {
|
|
185
|
+
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
186
|
+
channelName: '/test/socket',
|
|
187
|
+
event: 'TEST',
|
|
188
|
+
payload: {},
|
|
189
|
+
};
|
|
190
|
+
const endpoint = socket.createEndpoint('/api/:room', (_, res) => {
|
|
191
|
+
res.accept();
|
|
192
|
+
});
|
|
193
|
+
endpoint.createChannel('/test/:room', (req, res) => {
|
|
194
|
+
expect(req.event.params.room).toBeDefined();
|
|
195
|
+
res
|
|
196
|
+
.accept()
|
|
197
|
+
.trackPresence({
|
|
198
|
+
status: 'online',
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
yield (0, superwstest_1.default)(server)
|
|
202
|
+
.ws('/api/socket')
|
|
203
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
204
|
+
.sendJson(message)
|
|
205
|
+
.expectMessage(expect.objectContaining({
|
|
206
|
+
action: pondsocket_common_1.ServerActions.SYSTEM,
|
|
207
|
+
channelName: '/test/socket',
|
|
208
|
+
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
209
|
+
payload: {},
|
|
210
|
+
}))
|
|
211
|
+
.close();
|
|
212
|
+
}));
|
|
213
|
+
it('should throw an error if accept, reject / send is called more than once', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
socket.createEndpoint('/api/:room', (_, res) => {
|
|
215
|
+
res.send('hello', {
|
|
216
|
+
test: 'test',
|
|
217
|
+
});
|
|
218
|
+
expect(() => res.accept()).toThrowError('Cannot execute response more than once');
|
|
219
|
+
});
|
|
220
|
+
yield (0, superwstest_1.default)(server)
|
|
221
|
+
.ws('/api/socket')
|
|
222
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
223
|
+
.expectMessage(expect.objectContaining({
|
|
224
|
+
action: pondsocket_common_1.ServerActions.BROADCAST,
|
|
225
|
+
channelName: pondsocket_common_1.SystemSender.ENDPOINT,
|
|
226
|
+
event: 'hello',
|
|
227
|
+
payload: {
|
|
228
|
+
test: 'test',
|
|
229
|
+
},
|
|
230
|
+
}));
|
|
231
|
+
}));
|
|
232
|
+
it('should be able to connect, join a channel and send a message', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
233
|
+
const message = {
|
|
234
|
+
action: pondsocket_common_1.ClientActions.JOIN_CHANNEL,
|
|
235
|
+
channelName: '/test/socket',
|
|
236
|
+
event: 'TEST',
|
|
237
|
+
payload: {},
|
|
238
|
+
};
|
|
239
|
+
const endpoint = socket.createEndpoint('/api/:room', (_, res) => {
|
|
240
|
+
res.accept();
|
|
241
|
+
});
|
|
242
|
+
const channel = endpoint.createChannel('/test/:room', (req, res) => {
|
|
243
|
+
expect(req.event.params.room).toBeDefined();
|
|
244
|
+
res.accept();
|
|
245
|
+
});
|
|
246
|
+
channel.onEvent('echo', (req, res) => {
|
|
247
|
+
res.send('echo', req.event.payload);
|
|
248
|
+
});
|
|
249
|
+
channel.onEvent('broadcast', (req) => {
|
|
250
|
+
channel.broadcast('broadcast', Object.assign(Object.assign({}, req.event.payload), { broadcast: true }));
|
|
251
|
+
});
|
|
252
|
+
yield (0, superwstest_1.default)(server)
|
|
253
|
+
.ws('/api/socket')
|
|
254
|
+
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
255
|
+
.sendJson(message)
|
|
256
|
+
.expectMessage(expect.objectContaining({
|
|
257
|
+
action: pondsocket_common_1.ServerActions.SYSTEM,
|
|
258
|
+
channelName: '/test/socket',
|
|
259
|
+
event: pondsocket_common_1.Events.ACKNOWLEDGE,
|
|
260
|
+
payload: {},
|
|
261
|
+
}))
|
|
262
|
+
.sendJson({
|
|
263
|
+
addresses: pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER,
|
|
264
|
+
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
265
|
+
channelName: '/test/socket',
|
|
266
|
+
event: 'echo',
|
|
267
|
+
payload: {
|
|
268
|
+
test: 'test',
|
|
269
|
+
},
|
|
270
|
+
})
|
|
271
|
+
.expectMessage(expect.objectContaining({
|
|
272
|
+
action: pondsocket_common_1.ServerActions.SYSTEM,
|
|
273
|
+
channelName: '/test/socket',
|
|
274
|
+
event: 'echo',
|
|
275
|
+
payload: {
|
|
276
|
+
test: 'test',
|
|
277
|
+
},
|
|
278
|
+
}))
|
|
279
|
+
.sendJson({
|
|
280
|
+
action: pondsocket_common_1.ClientActions.BROADCAST,
|
|
281
|
+
channelName: '/test/socket',
|
|
282
|
+
event: 'broadcast',
|
|
283
|
+
payload: {
|
|
284
|
+
test: 'test',
|
|
285
|
+
},
|
|
286
|
+
})
|
|
287
|
+
.expectMessage(expect.objectContaining({
|
|
288
|
+
action: pondsocket_common_1.ServerActions.SYSTEM,
|
|
289
|
+
channelName: '/test/socket',
|
|
290
|
+
event: 'broadcast',
|
|
291
|
+
payload: {
|
|
292
|
+
test: 'test',
|
|
293
|
+
broadcast: true,
|
|
294
|
+
},
|
|
295
|
+
}));
|
|
296
|
+
}));
|
|
297
|
+
});
|
package/endpoint/response.js
CHANGED
|
@@ -13,13 +13,12 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var _ConnectionResponse_instances, _ConnectionResponse_webSocket, _ConnectionResponse_engine, _ConnectionResponse_clientId, _ConnectionResponse_executed, _ConnectionResponse_sendMessage, _ConnectionResponse_performChecks;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.ConnectionResponse = void 0;
|
|
16
|
+
const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
|
|
16
17
|
const abstractResponse_1 = require("../abstracts/abstractResponse");
|
|
17
|
-
const enums_1 = require("../enums");
|
|
18
18
|
const pondError_1 = require("../errors/pondError");
|
|
19
|
-
const uuid_1 = require("../misc/uuid");
|
|
20
19
|
class ConnectionResponse extends abstractResponse_1.PondResponse {
|
|
21
20
|
constructor(webSocket, engine, clientId) {
|
|
22
|
-
super((0,
|
|
21
|
+
super((0, pondsocket_common_1.uuid)());
|
|
23
22
|
_ConnectionResponse_instances.add(this);
|
|
24
23
|
_ConnectionResponse_webSocket.set(this, void 0);
|
|
25
24
|
_ConnectionResponse_engine.set(this, void 0);
|
|
@@ -60,7 +59,7 @@ class ConnectionResponse extends abstractResponse_1.PondResponse {
|
|
|
60
59
|
message: message || 'Unauthorized connection',
|
|
61
60
|
code: errorCode || 401,
|
|
62
61
|
};
|
|
63
|
-
__classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_sendMessage).call(this,
|
|
62
|
+
__classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_sendMessage).call(this, pondsocket_common_1.ServerActions.ERROR, pondsocket_common_1.ErrorTypes.UNAUTHORIZED_CONNECTION, payload);
|
|
64
63
|
__classPrivateFieldGet(this, _ConnectionResponse_webSocket, "f").close();
|
|
65
64
|
}
|
|
66
65
|
/**
|
|
@@ -71,7 +70,7 @@ class ConnectionResponse extends abstractResponse_1.PondResponse {
|
|
|
71
70
|
*/
|
|
72
71
|
send(event, payload, assigns) {
|
|
73
72
|
this.accept(assigns);
|
|
74
|
-
__classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_sendMessage).call(this,
|
|
73
|
+
__classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_sendMessage).call(this, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
76
|
exports.ConnectionResponse = ConnectionResponse;
|
|
@@ -81,7 +80,7 @@ _ConnectionResponse_webSocket = new WeakMap(), _ConnectionResponse_engine = new
|
|
|
81
80
|
action,
|
|
82
81
|
payload,
|
|
83
82
|
requestId: this.requestId,
|
|
84
|
-
channelName:
|
|
83
|
+
channelName: pondsocket_common_1.SystemSender.ENDPOINT,
|
|
85
84
|
};
|
|
86
85
|
__classPrivateFieldGet(this, _ConnectionResponse_webSocket, "f").send(JSON.stringify(message));
|
|
87
86
|
}, _ConnectionResponse_performChecks = function _ConnectionResponse_performChecks() {
|