@eleven-am/pondsocket 0.1.141 → 0.1.142

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.
@@ -10,24 +10,26 @@ 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 _ConnectionResponse_instances, _ConnectionResponse_webSocket, _ConnectionResponse_engine, _ConnectionResponse_clientId, _ConnectionResponse_executed, _ConnectionResponse_sendMessage, _ConnectionResponse_performChecks;
13
+ var _ConnectionResponse_instances, _ConnectionResponse_webSocket, _ConnectionResponse_engine, _ConnectionResponse_clientId, _ConnectionResponse_executed, _ConnectionResponse_assigns, _ConnectionResponse_requestId, _ConnectionResponse_sendMessage, _ConnectionResponse_performChecks;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ConnectionResponse = void 0;
16
16
  const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
17
- const abstractResponse_1 = require("../abstracts/abstractResponse");
18
17
  const pondError_1 = require("../errors/pondError");
19
- class ConnectionResponse extends abstractResponse_1.PondResponse {
18
+ class ConnectionResponse {
20
19
  constructor(webSocket, engine, clientId) {
21
- super((0, pondsocket_common_1.uuid)());
22
20
  _ConnectionResponse_instances.add(this);
23
21
  _ConnectionResponse_webSocket.set(this, void 0);
24
22
  _ConnectionResponse_engine.set(this, void 0);
25
23
  _ConnectionResponse_clientId.set(this, void 0);
26
24
  _ConnectionResponse_executed.set(this, void 0);
25
+ _ConnectionResponse_assigns.set(this, void 0);
26
+ _ConnectionResponse_requestId.set(this, void 0);
27
27
  __classPrivateFieldSet(this, _ConnectionResponse_webSocket, webSocket, "f");
28
28
  __classPrivateFieldSet(this, _ConnectionResponse_engine, engine, "f");
29
29
  __classPrivateFieldSet(this, _ConnectionResponse_clientId, clientId, "f");
30
+ __classPrivateFieldSet(this, _ConnectionResponse_assigns, {}, "f");
30
31
  __classPrivateFieldSet(this, _ConnectionResponse_executed, false, "f");
32
+ __classPrivateFieldSet(this, _ConnectionResponse_requestId, (0, pondsocket_common_1.uuid)(), "f");
31
33
  }
32
34
  /**
33
35
  * @desc Whether the server has responded to the request
@@ -36,24 +38,40 @@ class ConnectionResponse extends abstractResponse_1.PondResponse {
36
38
  return __classPrivateFieldGet(this, _ConnectionResponse_executed, "f");
37
39
  }
38
40
  /**
39
- * @desc Accepts the request and optionally assigns data to the client
40
- * @param assigns - the data to assign to the client
41
+ * @desc Accepts the join request
41
42
  */
42
- accept(assigns) {
43
+ accept() {
43
44
  __classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_performChecks).call(this);
44
45
  const cache = {
45
46
  clientId: __classPrivateFieldGet(this, _ConnectionResponse_clientId, "f"),
46
47
  socket: __classPrivateFieldGet(this, _ConnectionResponse_webSocket, "f"),
47
- assigns: assigns || {},
48
+ assigns: __classPrivateFieldGet(this, _ConnectionResponse_assigns, "f"),
49
+ subscriptions: new Map(),
50
+ pendingSubscriptions: new Set(),
48
51
  };
49
52
  __classPrivateFieldGet(this, _ConnectionResponse_engine, "f").manageSocket(cache);
53
+ return this;
54
+ }
55
+ /**
56
+ * @desc Assigns data to the user
57
+ * @param assigns - the data to assign
58
+ */
59
+ assign(assigns) {
60
+ if (!__classPrivateFieldGet(this, _ConnectionResponse_executed, "f")) {
61
+ __classPrivateFieldSet(this, _ConnectionResponse_assigns, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _ConnectionResponse_assigns, "f")), assigns), "f");
62
+ }
63
+ else {
64
+ const user = __classPrivateFieldGet(this, _ConnectionResponse_engine, "f").getUser(__classPrivateFieldGet(this, _ConnectionResponse_clientId, "f"));
65
+ user.assigns = Object.assign(Object.assign({}, user.assigns), assigns);
66
+ }
67
+ return this;
50
68
  }
51
69
  /**
52
70
  * @desc Rejects the request with the given error message
53
71
  * @param message - the error message
54
72
  * @param errorCode - the error code
55
73
  */
56
- reject(message, errorCode) {
74
+ decline(message, errorCode) {
57
75
  __classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_performChecks).call(this);
58
76
  const payload = {
59
77
  message: message || 'Unauthorized connection',
@@ -66,20 +84,36 @@ class ConnectionResponse extends abstractResponse_1.PondResponse {
66
84
  * @desc Emits a direct message to the client
67
85
  * @param event - the event name
68
86
  * @param payload - the payload to send
69
- * @param assigns - the data to assign to the client
70
87
  */
71
- send(event, payload, assigns) {
72
- this.accept(assigns);
88
+ reply(event, payload) {
89
+ __classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_performChecks).call(this);
73
90
  __classPrivateFieldGet(this, _ConnectionResponse_instances, "m", _ConnectionResponse_sendMessage).call(this, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
91
+ return this;
92
+ }
93
+ /**
94
+ * @desc Subscribes the client to a channel
95
+ * @param channel - the channel to subscribe to
96
+ */
97
+ subscribeTo(channel) {
98
+ __classPrivateFieldGet(this, _ConnectionResponse_engine, "f").subscribeTo(__classPrivateFieldGet(this, _ConnectionResponse_clientId, "f"), channel);
99
+ return this;
100
+ }
101
+ /**
102
+ * @desc Unsubscribes the client from a channel
103
+ * @param channel - the channel to unsubscribe from
104
+ */
105
+ unsubscribeFrom(channel) {
106
+ __classPrivateFieldGet(this, _ConnectionResponse_engine, "f").unsubscribeFrom(__classPrivateFieldGet(this, _ConnectionResponse_clientId, "f"), channel);
107
+ return this;
74
108
  }
75
109
  }
76
110
  exports.ConnectionResponse = ConnectionResponse;
77
- _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) {
111
+ _ConnectionResponse_webSocket = new WeakMap(), _ConnectionResponse_engine = new WeakMap(), _ConnectionResponse_clientId = new WeakMap(), _ConnectionResponse_executed = new WeakMap(), _ConnectionResponse_assigns = new WeakMap(), _ConnectionResponse_requestId = new WeakMap(), _ConnectionResponse_instances = new WeakSet(), _ConnectionResponse_sendMessage = function _ConnectionResponse_sendMessage(action, event, payload) {
78
112
  const message = {
79
113
  event,
80
114
  action,
81
115
  payload,
82
- requestId: this.requestId,
116
+ requestId: __classPrivateFieldGet(this, _ConnectionResponse_requestId, "f"),
83
117
  channelName: pondsocket_common_1.SystemSender.ENDPOINT,
84
118
  };
85
119
  __classPrivateFieldGet(this, _ConnectionResponse_webSocket, "f").send(JSON.stringify(message));
@@ -1,18 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMockSocket = void 0;
3
4
  const joinRequest_1 = require("./joinRequest");
4
5
  const eventResponse_test_1 = require("../channel/eventResponse.test");
5
- const createMockSocket = (params = {}) => {
6
- const channelEngine = (0, eventResponse_test_1.createChannelEngine)();
6
+ const createMockSocket = () => {
7
+ const { channelEngine } = (0, eventResponse_test_1.createChannelEngine)();
7
8
  const socket = {
8
9
  clientId: 'sender',
9
10
  assigns: { assign: 'assign' },
10
- requestId: 'requestId',
11
11
  channelName: 'channel',
12
+ requestId: 'requestId',
13
+ subscriptions: new Map(),
14
+ pendingSubscriptions: new Set(),
12
15
  socket: {
13
16
  send: jest.fn(),
14
17
  },
15
18
  };
19
+ return {
20
+ channelEngine,
21
+ socket,
22
+ };
23
+ };
24
+ exports.createMockSocket = createMockSocket;
25
+ const createJoinRequest = (params = {}) => {
26
+ const { channelEngine, socket } = (0, exports.createMockSocket)();
16
27
  const request = new joinRequest_1.JoinRequest(socket, params, channelEngine);
17
28
  return {
18
29
  channelEngine,
@@ -22,15 +33,15 @@ const createMockSocket = (params = {}) => {
22
33
  };
23
34
  describe('JoinRequest', () => {
24
35
  it('should create a new PondChannelResponse', () => {
25
- const { request } = createMockSocket();
36
+ const { request } = createJoinRequest();
26
37
  expect(request).toBeDefined();
27
38
  });
28
39
  it('should return the join params', () => {
29
- const { request } = createMockSocket({ params: 'params' });
40
+ const { request } = createJoinRequest({ params: 'params' });
30
41
  expect(request.joinParams).toEqual({ params: 'params' });
31
42
  });
32
43
  it('should return the user data', () => {
33
- const { request } = createMockSocket();
44
+ const { request } = createJoinRequest();
34
45
  expect(request.user).toEqual({
35
46
  id: 'sender',
36
47
  assigns: { assign: 'assign' },
@@ -1,19 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
4
+ const JoinRequest_test_1 = require("./JoinRequest.test");
4
5
  const joinResponse_1 = require("./joinResponse");
5
- const eventResponse_test_1 = require("../channel/eventResponse.test");
6
6
  const createPondResponse = () => {
7
- const channelEngine = (0, eventResponse_test_1.createChannelEngine)();
8
- const socket = {
9
- clientId: 'sender',
10
- assigns: { assign: 'assign' },
11
- channelName: 'channel',
12
- requestId: 'requestId',
13
- socket: {
14
- send: jest.fn(),
15
- },
16
- };
7
+ const { channelEngine, socket } = (0, JoinRequest_test_1.createMockSocket)();
17
8
  const response = new joinResponse_1.JoinResponse(socket, channelEngine);
18
9
  return {
19
10
  channelEngine,
@@ -39,7 +30,7 @@ describe('JoinResponse', () => {
39
30
  const { response, channelEngine, socket } = createPondResponse();
40
31
  // spy on the channelEngine to see if the user was added
41
32
  jest.spyOn(channelEngine, 'addUser');
42
- response.reject();
33
+ response.decline();
43
34
  // check if the response was sent
44
35
  expect(channelEngine.addUser).not.toHaveBeenCalled();
45
36
  expect(channelEngine.getUserData(socket.clientId)).toBeUndefined();
@@ -61,9 +52,12 @@ describe('JoinResponse', () => {
61
52
  const { response, channelEngine, socket } = createPondResponse();
62
53
  // spy on the channelEngine to see if the user was added
63
54
  jest.spyOn(channelEngine, 'addUser');
64
- response.send('POND_MESSAGE', { message: 'message' });
65
- // check if the response was sent
55
+ response
56
+ .accept()
57
+ .reply('POND_MESSAGE', { message: 'message' })
58
+ .assign({ assign: 'assign' });
66
59
  expect(channelEngine.addUser).toHaveBeenCalled();
60
+ // check if the response was sent
67
61
  expect(channelEngine.getUserData(socket.clientId)).toStrictEqual({
68
62
  assigns: {
69
63
  assign: 'assign',
@@ -98,27 +92,28 @@ describe('JoinResponse', () => {
98
92
  const { response, channelEngine } = createPondResponse();
99
93
  // spy on the channelEngine to see if any messages were published
100
94
  const broadcast = jest.spyOn(channelEngine, 'sendMessage');
95
+ const receiver = jest.fn();
101
96
  // add a second user to the channel
102
- channelEngine.addUser('user2', { assign: 'assign' }, () => { });
97
+ channelEngine.addUser('user2', { assign: 'assign' }, receiver);
103
98
  // send a message to a single user
104
99
  // this is because the sender does not exist in the channel yet
105
- expect(() => response.sendToUsers('hello_everyone', { message: 'hello' }, ['user2'])).toThrow();
100
+ expect(() => response.broadcastTo('hello_everyone', { message: 'hello' }, ['user2'])).toThrow();
106
101
  // clear the spy
107
102
  broadcast.mockClear();
108
103
  // add the sender to the channel by using the response.accept() method
109
- response.accept().sendToUsers('hello_everyone', { message: 'hello' }, ['user2']);
104
+ response.accept().broadcastTo('hello_everyone', { message: 'hello' }, ['user2']);
110
105
  // check if the message was sent
111
- expect(broadcast).toHaveBeenCalledWith('requestId', 'sender', ['user2'], pondsocket_common_1.ServerActions.BROADCAST, 'hello_everyone', { message: 'hello' });
106
+ expect(broadcast).toHaveBeenCalledWith('sender', ['user2'], pondsocket_common_1.ServerActions.BROADCAST, 'hello_everyone', { message: 'hello' }, 'requestId');
112
107
  // clear the spy
113
108
  broadcast.mockClear();
114
109
  // send a message to all users
115
110
  response.broadcast('hello_everyone', { message: 'hello' });
116
- expect(broadcast).toHaveBeenCalledWith('requestId', 'sender', pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.BROADCAST, 'hello_everyone', { message: 'hello' });
111
+ expect(broadcast).toHaveBeenCalledWith('sender', pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.BROADCAST, 'hello_everyone', { message: 'hello' }, 'requestId');
117
112
  // clear the spy
118
113
  broadcast.mockClear();
119
114
  // send a message to all users except the sender
120
- response.broadcastFromUser('hello_everyone', { message: 'hello' });
121
- expect(broadcast).toHaveBeenCalledWith('requestId', 'sender', pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER, pondsocket_common_1.ServerActions.BROADCAST, 'hello_everyone', { message: 'hello' });
115
+ response.broadcastFrom('hello_everyone', { message: 'hello' });
116
+ expect(broadcast).toHaveBeenCalledWith('sender', pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER, pondsocket_common_1.ServerActions.BROADCAST, 'hello_everyone', { message: 'hello' }, 'requestId');
122
117
  });
123
118
  it('should be able to track the presence of users', () => {
124
119
  const { response, channelEngine } = createPondResponse();
@@ -139,7 +134,7 @@ describe('JoinResponse', () => {
139
134
  response.accept();
140
135
  expect(channelEngine.addUser).toHaveBeenCalledWith(socket.clientId, socket.assigns, expect.any(Function));
141
136
  expect(() => response.accept()).toThrow('Request to join channel test rejected: Request already executed');
142
- expect(() => response.reject()).toThrow('Request to join channel test rejected: Request already executed');
143
- expect(() => response.send('event', { payload: 'payload' })).toThrow('Request to join channel test rejected: Request already executed');
137
+ expect(() => response.decline()).toThrow('Request to join channel test rejected: Request already executed');
138
+ expect(() => response.reply('event', { payload: 'payload' })).not.toThrow();
144
139
  });
145
140
  });
@@ -10,22 +10,24 @@ 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 _JoinResponse_instances, _JoinResponse_user, _JoinResponse_engine, _JoinResponse_executed, _JoinResponse_performChecks;
13
+ var _JoinResponse_instances, _JoinResponse_user, _JoinResponse_engine, _JoinResponse_newAssigns, _JoinResponse_executed, _JoinResponse_accepted, _JoinResponse_performChecks, _JoinResponse_sendMessage;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.JoinResponse = void 0;
16
16
  const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
17
- const abstractResponse_1 = require("../abstracts/abstractResponse");
18
17
  const pondError_1 = require("../errors/pondError");
19
- class JoinResponse extends abstractResponse_1.PondResponse {
18
+ class JoinResponse {
20
19
  constructor(user, engine) {
21
- super(user.requestId);
22
20
  _JoinResponse_instances.add(this);
23
21
  _JoinResponse_user.set(this, void 0);
24
22
  _JoinResponse_engine.set(this, void 0);
23
+ _JoinResponse_newAssigns.set(this, void 0);
25
24
  _JoinResponse_executed.set(this, void 0);
25
+ _JoinResponse_accepted.set(this, void 0);
26
26
  __classPrivateFieldSet(this, _JoinResponse_user, user, "f");
27
27
  __classPrivateFieldSet(this, _JoinResponse_engine, engine, "f");
28
28
  __classPrivateFieldSet(this, _JoinResponse_executed, false, "f");
29
+ __classPrivateFieldSet(this, _JoinResponse_accepted, false, "f");
30
+ __classPrivateFieldSet(this, _JoinResponse_newAssigns, Object.assign({}, user.assigns), "f");
29
31
  }
30
32
  /**
31
33
  * @desc Whether the server has responded to the request
@@ -34,23 +36,23 @@ class JoinResponse extends abstractResponse_1.PondResponse {
34
36
  return __classPrivateFieldGet(this, _JoinResponse_executed, "f");
35
37
  }
36
38
  /**
37
- * @desc Accepts the request and optionally assigns data to the client
38
- * @param assigns - the data to assign to the client
39
+ * @desc Accepts the join request to the channel
39
40
  */
40
- accept(assigns) {
41
+ accept() {
41
42
  __classPrivateFieldGet(this, _JoinResponse_instances, "m", _JoinResponse_performChecks).call(this);
42
- const newAssigns = Object.assign(Object.assign({}, assigns || {}), __classPrivateFieldGet(this, _JoinResponse_user, "f").assigns);
43
43
  const acknowledgement = {
44
44
  action: pondsocket_common_1.ServerActions.SYSTEM,
45
45
  channelName: __classPrivateFieldGet(this, _JoinResponse_engine, "f").name,
46
46
  event: pondsocket_common_1.Events.ACKNOWLEDGE,
47
- requestId: this.requestId,
47
+ requestId: __classPrivateFieldGet(this, _JoinResponse_user, "f").requestId,
48
48
  payload: {},
49
49
  };
50
50
  __classPrivateFieldGet(this, _JoinResponse_user, "f").socket.send(JSON.stringify(acknowledgement));
51
- __classPrivateFieldGet(this, _JoinResponse_engine, "f").addUser(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, newAssigns, (event) => {
51
+ const unsubscribe = __classPrivateFieldGet(this, _JoinResponse_engine, "f").addUser(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, __classPrivateFieldGet(this, _JoinResponse_newAssigns, "f"), (event) => {
52
52
  __classPrivateFieldGet(this, _JoinResponse_user, "f").socket.send(JSON.stringify(event));
53
53
  });
54
+ __classPrivateFieldGet(this, _JoinResponse_user, "f").subscriptions.set(__classPrivateFieldGet(this, _JoinResponse_engine, "f").name, unsubscribe);
55
+ __classPrivateFieldSet(this, _JoinResponse_accepted, true, "f");
54
56
  return this;
55
57
  }
56
58
  /**
@@ -58,7 +60,7 @@ class JoinResponse extends abstractResponse_1.PondResponse {
58
60
  * @param message - the error message
59
61
  * @param errorCode - the error code
60
62
  */
61
- reject(message, errorCode) {
63
+ decline(message, errorCode) {
62
64
  __classPrivateFieldGet(this, _JoinResponse_instances, "m", _JoinResponse_performChecks).call(this);
63
65
  const errorMessage = {
64
66
  event: pondsocket_common_1.ErrorTypes.UNAUTHORIZED_JOIN_REQUEST,
@@ -68,65 +70,102 @@ class JoinResponse extends abstractResponse_1.PondResponse {
68
70
  },
69
71
  channelName: __classPrivateFieldGet(this, _JoinResponse_engine, "f").name,
70
72
  action: pondsocket_common_1.ServerActions.ERROR,
71
- requestId: this.requestId,
73
+ requestId: __classPrivateFieldGet(this, _JoinResponse_user, "f").requestId,
72
74
  };
73
75
  __classPrivateFieldGet(this, _JoinResponse_user, "f").socket.send(JSON.stringify(errorMessage));
74
76
  return this;
75
77
  }
78
+ /**
79
+ * @desc Assigns data to the client
80
+ * @param assigns - the data to assign
81
+ */
82
+ assign(assigns) {
83
+ if (__classPrivateFieldGet(this, _JoinResponse_accepted, "f")) {
84
+ __classPrivateFieldGet(this, _JoinResponse_engine, "f").updateAssigns(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, assigns);
85
+ }
86
+ else {
87
+ __classPrivateFieldSet(this, _JoinResponse_newAssigns, Object.assign(Object.assign({}, __classPrivateFieldGet(this, _JoinResponse_newAssigns, "f")), assigns), "f");
88
+ }
89
+ return this;
90
+ }
76
91
  /**
77
92
  * @desc Emits a direct message to the client
78
93
  * @param event - the event name
79
94
  * @param payload - the payload to send
80
- * @param assigns - the data to assign to the client
81
95
  */
82
- send(event, payload, assigns) {
83
- this.accept(assigns);
84
- __classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(this.requestId, pondsocket_common_1.SystemSender.CHANNEL, [__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId], pondsocket_common_1.ServerActions.SYSTEM, event, payload);
96
+ reply(event, payload) {
97
+ const message = {
98
+ action: pondsocket_common_1.ServerActions.SYSTEM,
99
+ channelName: __classPrivateFieldGet(this, _JoinResponse_engine, "f").name,
100
+ requestId: __classPrivateFieldGet(this, _JoinResponse_user, "f").requestId,
101
+ payload,
102
+ event,
103
+ };
104
+ __classPrivateFieldGet(this, _JoinResponse_user, "f").socket.send(JSON.stringify(message));
85
105
  return this;
86
106
  }
87
107
  /**
88
- * @desc Emits a message to all clients in the channel
89
- * @param event - the event name
108
+ * @desc Sends a message to all clients in the channel
109
+ * @param event - the event to send
90
110
  * @param payload - the payload to send
91
111
  */
92
112
  broadcast(event, payload) {
93
- __classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(this.requestId, __classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
113
+ __classPrivateFieldGet(this, _JoinResponse_instances, "m", _JoinResponse_sendMessage).call(this, pondsocket_common_1.ChannelReceiver.ALL_USERS, event, payload);
94
114
  return this;
95
115
  }
96
116
  /**
97
- * @desc Emits a message to all clients in the channel except the sender
98
- * @param event - the event name
117
+ * @desc Sends a message to all clients in the channel except the client making the request
118
+ * @param event - the event to send
99
119
  * @param payload - the payload to send
100
120
  */
101
- broadcastFromUser(event, payload) {
102
- __classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(this.requestId, __classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
121
+ broadcastFrom(event, payload) {
122
+ __classPrivateFieldGet(this, _JoinResponse_instances, "m", _JoinResponse_sendMessage).call(this, pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER, event, payload);
103
123
  return this;
104
124
  }
105
125
  /**
106
- * @desc Emits a message to a specific set of clients
107
- * @param event - the event name
108
- * @param payload - the payload to send
126
+ * @desc Sends a message to a set of clients in the channel
127
+ * @param event - the event to send
128
+ * @param payload - the payload to send
109
129
  * @param userIds - the ids of the clients to send the message to
110
130
  */
111
- sendToUsers(event, payload, userIds) {
112
- __classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(this.requestId, __classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, userIds, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
131
+ broadcastTo(event, payload, userIds) {
132
+ const ids = Array.isArray(userIds) ? userIds : [userIds];
133
+ __classPrivateFieldGet(this, _JoinResponse_instances, "m", _JoinResponse_sendMessage).call(this, ids, event, payload);
113
134
  return this;
114
135
  }
115
136
  /**
116
- * @desc tracks the presence of a client
117
- * @param presence - the presence data to track
137
+ * @desc Tracks a user's presence in the channel
138
+ * @param presence - the initial presence data
118
139
  */
119
140
  trackPresence(presence) {
120
141
  __classPrivateFieldGet(this, _JoinResponse_engine, "f").presenceEngine.trackPresence(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, presence);
121
142
  return this;
122
143
  }
144
+ /**
145
+ * @desc Subscribes the client to a channel
146
+ * @param channel - the channel to subscribe to
147
+ */
148
+ subscribeTo(channel) {
149
+ __classPrivateFieldGet(this, _JoinResponse_engine, "f").subscribeTo(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, channel);
150
+ return this;
151
+ }
152
+ /**
153
+ * @desc Unsubscribes the client from a channel
154
+ * @param channel - the channel to unsubscribe from
155
+ */
156
+ unsubscribeFrom(channel) {
157
+ __classPrivateFieldGet(this, _JoinResponse_engine, "f").unsubscribeFrom(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, channel);
158
+ return this;
159
+ }
123
160
  }
124
161
  exports.JoinResponse = JoinResponse;
125
- _JoinResponse_user = new WeakMap(), _JoinResponse_engine = new WeakMap(), _JoinResponse_executed = new WeakMap(), _JoinResponse_instances = new WeakSet(), _JoinResponse_performChecks = function _JoinResponse_performChecks() {
162
+ _JoinResponse_user = new WeakMap(), _JoinResponse_engine = new WeakMap(), _JoinResponse_newAssigns = new WeakMap(), _JoinResponse_executed = new WeakMap(), _JoinResponse_accepted = new WeakMap(), _JoinResponse_instances = new WeakSet(), _JoinResponse_performChecks = function _JoinResponse_performChecks() {
126
163
  if (__classPrivateFieldGet(this, _JoinResponse_executed, "f")) {
127
164
  const message = `Request to join channel ${__classPrivateFieldGet(this, _JoinResponse_engine, "f").name} rejected: Request already executed`;
128
165
  const code = 403;
129
166
  throw new pondError_1.ChannelError(message, code, __classPrivateFieldGet(this, _JoinResponse_engine, "f").name);
130
167
  }
131
168
  __classPrivateFieldSet(this, _JoinResponse_executed, true, "f");
169
+ }, _JoinResponse_sendMessage = function _JoinResponse_sendMessage(recipient, event, payload) {
170
+ __classPrivateFieldGet(this, _JoinResponse_engine, "f").sendMessage(__classPrivateFieldGet(this, _JoinResponse_user, "f").clientId, recipient, pondsocket_common_1.ServerActions.BROADCAST, event, payload, __classPrivateFieldGet(this, _JoinResponse_user, "f").requestId);
132
171
  };
package/lobby/lobby.js CHANGED
@@ -10,20 +10,31 @@ 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 _LobbyEngine_channels, _LobbyEngine_middleware, _LobbyEngine_leaveCallback, _PondChannel_lobby;
13
+ var _LobbyEngine_channels, _LobbyEngine_middleware, _LobbyEngine_leaveCallback, _LobbyEngine_parentEngine, _PondChannel_lobby;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.PondChannel = exports.LobbyEngine = void 0;
16
16
  const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
17
17
  const middleware_1 = require("../abstracts/middleware");
18
18
  const channel_1 = require("../channel/channel");
19
19
  class LobbyEngine {
20
- constructor() {
20
+ constructor(endpointEngine) {
21
21
  _LobbyEngine_channels.set(this, void 0);
22
22
  _LobbyEngine_middleware.set(this, void 0);
23
23
  _LobbyEngine_leaveCallback.set(this, void 0);
24
+ _LobbyEngine_parentEngine.set(this, void 0);
25
+ __classPrivateFieldSet(this, _LobbyEngine_parentEngine, endpointEngine, "f");
24
26
  __classPrivateFieldSet(this, _LobbyEngine_channels, new Set(), "f");
25
27
  __classPrivateFieldSet(this, _LobbyEngine_middleware, new middleware_1.Middleware(), "f");
26
28
  }
29
+ get parent() {
30
+ return __classPrivateFieldGet(this, _LobbyEngine_parentEngine, "f");
31
+ }
32
+ get leaveCallback() {
33
+ return __classPrivateFieldGet(this, _LobbyEngine_leaveCallback, "f");
34
+ }
35
+ get middleware() {
36
+ return __classPrivateFieldGet(this, _LobbyEngine_middleware, "f");
37
+ }
27
38
  /**
28
39
  * @desc Handles an event request made by a user
29
40
  * @param event - The event to listen for
@@ -68,23 +79,14 @@ class LobbyEngine {
68
79
  if (!channel) {
69
80
  throw new Error(`GatewayEngine: Channel ${channelName} does not exist`);
70
81
  }
71
- channel.sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.SYSTEM, event, payload);
82
+ channel.sendMessage(pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.SYSTEM, event, payload);
72
83
  }
73
84
  else {
74
85
  __classPrivateFieldGet(this, _LobbyEngine_channels, "f").forEach((channel) => {
75
- channel.sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.SYSTEM, event, payload);
86
+ channel.sendMessage(pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.SYSTEM, event, payload);
76
87
  });
77
88
  }
78
89
  }
79
- /**
80
- * @desc Removes a user from all channels
81
- * @param clientId - The client id of the user to remove
82
- */
83
- removeUser(clientId) {
84
- __classPrivateFieldGet(this, _LobbyEngine_channels, "f").forEach((channel) => {
85
- channel.removeUser(clientId, true);
86
- });
87
- }
88
90
  /**
89
91
  * @desc Executes a function on a channel
90
92
  * @param channelName - The name of the channel to execute the function on
@@ -132,20 +134,14 @@ class LobbyEngine {
132
134
  * @private
133
135
  */
134
136
  createChannel(channelName) {
135
- const destroyChannel = this.destroyChannel.bind(this, channelName);
136
- const execute = __classPrivateFieldGet(this, _LobbyEngine_middleware, "f").run.bind(__classPrivateFieldGet(this, _LobbyEngine_middleware, "f"));
137
- const parentEngine = {
138
- execute,
139
- destroyChannel,
140
- leaveCallback: __classPrivateFieldGet(this, _LobbyEngine_leaveCallback, "f"),
141
- };
142
- const newChannel = new channel_1.ChannelEngine(channelName, parentEngine);
137
+ const newChannel = new channel_1.ChannelEngine(channelName, this);
138
+ __classPrivateFieldGet(this, _LobbyEngine_parentEngine, "f").subscribePendingUsers(newChannel);
143
139
  __classPrivateFieldGet(this, _LobbyEngine_channels, "f").add(newChannel);
144
140
  return newChannel;
145
141
  }
146
142
  }
147
143
  exports.LobbyEngine = LobbyEngine;
148
- _LobbyEngine_channels = new WeakMap(), _LobbyEngine_middleware = new WeakMap(), _LobbyEngine_leaveCallback = new WeakMap();
144
+ _LobbyEngine_channels = new WeakMap(), _LobbyEngine_middleware = new WeakMap(), _LobbyEngine_leaveCallback = new WeakMap(), _LobbyEngine_parentEngine = new WeakMap();
149
145
  class PondChannel {
150
146
  constructor(lobby) {
151
147
  _PondChannel_lobby.set(this, void 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eleven-am/pondsocket",
3
- "version": "0.1.141",
3
+ "version": "0.1.142",
4
4
  "description": "PondSocket is a fast simple socket server",
5
5
  "keywords": [
6
6
  "socket",
@@ -16,7 +16,7 @@
16
16
  "access": "public"
17
17
  },
18
18
  "scripts": {
19
- "test": "jest --coverage --verbose",
19
+ "test": "jest --coverage --verbose --forceExit --detectOpenHandles --runInBand --bail",
20
20
  "build": "rimraf dist && tsc && npm run remove",
21
21
  "lint": "eslint --ext .ts src",
22
22
  "lint:fix": "eslint --fix --ext .ts src",
@@ -34,22 +34,22 @@
34
34
  "url": "git+https://github.com/Eleven-am/pondSocket.git"
35
35
  },
36
36
  "dependencies": {
37
- "@eleven-am/pondsocket-common": "^0.0.10",
37
+ "@eleven-am/pondsocket-common": "^0.0.11",
38
38
  "ws": "^8.16.0",
39
39
  "zod": "^3.22.4"
40
40
  },
41
41
  "devDependencies": {
42
- "@types/jest": "^29.5.11",
43
- "@types/node": "^20.11.5",
42
+ "@types/jest": "^29.5.12",
43
+ "@types/node": "^20.11.20",
44
44
  "@types/websocket": "^1.0.10",
45
45
  "@types/ws": "^8.5.10",
46
- "@typescript-eslint/eslint-plugin": "^6.19.0",
47
- "eslint": "^8.56.0",
46
+ "@typescript-eslint/eslint-plugin": "^7.0.2",
47
+ "eslint": "^8.57.0",
48
48
  "eslint-plugin-file-progress": "^1.3.0",
49
49
  "eslint-plugin-import": "^2.29.1",
50
50
  "jest": "^29.7.0",
51
51
  "superwstest": "^2.0.3",
52
- "ts-jest": "^29.1.1",
52
+ "ts-jest": "^29.1.2",
53
53
  "ts-node": "^10.9.2",
54
54
  "typescript": "^5.3.3"
55
55
  },
@@ -107,5 +107,5 @@ _PresenceEngine_presenceMap = new WeakMap(), _PresenceEngine_channel = new WeakM
107
107
  if (recipients.length === 0) {
108
108
  return;
109
109
  }
110
- __classPrivateFieldGet(this, _PresenceEngine_channel, "f").sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, recipients, pondsocket_common_1.ServerActions.PRESENCE, event, payload);
110
+ __classPrivateFieldGet(this, _PresenceEngine_channel, "f").sendMessage(pondsocket_common_1.SystemSender.CHANNEL, recipients, pondsocket_common_1.ServerActions.PRESENCE, event, payload);
111
111
  };
@@ -9,7 +9,7 @@ describe('PresenceEngine', () => {
9
9
  let presenceKey;
10
10
  let channel;
11
11
  beforeEach(() => {
12
- channel = (0, eventResponse_test_1.createChannelEngine)();
12
+ channel = (0, eventResponse_test_1.createChannelEngine)().channelEngine;
13
13
  channel.addUser('presenceKey', { assign: 'assign' }, () => {
14
14
  // do nothing
15
15
  });
@@ -33,7 +33,6 @@ describe('PresenceEngine', () => {
33
33
  // remove the first element as it contains the request id which is random
34
34
  params.shift();
35
35
  expect(params).toEqual([
36
- pondsocket_common_1.SystemSender.CHANNEL,
37
36
  ['presenceKey'],
38
37
  pondsocket_common_1.ServerActions.PRESENCE,
39
38
  pondsocket_common_1.PresenceEventTypes.JOIN,
@@ -65,7 +64,6 @@ describe('PresenceEngine', () => {
65
64
  // remove the first element as it contains the request id which is random
66
65
  params.shift();
67
66
  expect(params).toEqual([
68
- pondsocket_common_1.SystemSender.CHANNEL,
69
67
  ['presenceKey'],
70
68
  pondsocket_common_1.ServerActions.PRESENCE,
71
69
  pondsocket_common_1.PresenceEventTypes.UPDATE,
@@ -98,7 +96,6 @@ describe('PresenceEngine', () => {
98
96
  // remove the first element as it contains the request id which is random
99
97
  params.shift();
100
98
  expect(params).toEqual([
101
- pondsocket_common_1.SystemSender.CHANNEL,
102
99
  ['presenceKey2'],
103
100
  pondsocket_common_1.ServerActions.PRESENCE,
104
101
  pondsocket_common_1.PresenceEventTypes.LEAVE,
package/schema.js CHANGED
@@ -9,5 +9,4 @@ exports.clientMessageSchema = zod_1.z.object({
9
9
  channelName: zod_1.z.string(),
10
10
  payload: zod_1.z.record(zod_1.z.any()),
11
11
  action: zod_1.z.nativeEnum(pondsocket_common_1.ClientActions),
12
- addresses: zod_1.z.union([zod_1.z.nativeEnum(pondsocket_common_1.ChannelReceiver), zod_1.z.array(zod_1.z.string())]).optional(),
13
12
  });