@eleven-am/pondsocket 0.1.125 → 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 CHANGED
@@ -30,18 +30,6 @@ const endpoint = pond.createEndpoint('/api/socket', (req, res) => {
30
30
 
31
31
  // Start the server
32
32
  pond.listen(3000);
33
-
34
- // Or alternatively, working with express
35
- import pondSocket from "@eleven-am/pondsocket/express";
36
- import express from "express";
37
-
38
- const app = pondSocket(express());
39
-
40
- const endpoint = app.upgrade('/api/socket', (req, res) => {
41
- // Handle socket connection and authentication
42
- });
43
-
44
- app.listen(3000);
45
33
  ```
46
34
 
47
35
  Within each endpoint, sockets interact through channels. Channels provide an organized way to group users and manage efficient communication among them. When users join a channel, they can participate in real-time events and exchange information with other users in the same channel.
@@ -57,7 +45,7 @@ const channel = endpoint.createChannel('/channel/:id', (req, res) => {
57
45
  On the client-side, PondSocket provides the PondClient class to establish connections with the server. Clients can easily initiate connections, join channels, and participate in real-time interactions.
58
46
 
59
47
  ```javascript
60
- import PondClient from "@eleven-am/pondsocket/client";
48
+ import PondClient from "@eleven-am/pondsocket-client";
61
49
 
62
50
  const socket = new PondClient('/api/socket', {});
63
51
  socket.connect();
@@ -75,7 +63,7 @@ channel.join();
75
63
  PondSocket also offers a Node.js client, which can be imported using:
76
64
 
77
65
  ```javascript
78
- import PondClient from "@eleven-am/pondsocket/node";
66
+ import PondClient from "@eleven-am/pondsocket-client";
79
67
  ```
80
68
 
81
69
  This node client allows you to turn another server into a client, enabling easy communication between different server instances.
@@ -96,7 +84,7 @@ This node client allows you to turn another server into a client, enabling easy
96
84
  To connect to the PondSocket server and send messages while associating a username with the client connection, follow the steps below:
97
85
 
98
86
  ```javascript
99
- import PondClient from "@eleven-am/pondsocket/client";
87
+ import PondClient from "@eleven-am/pondsocket-client";
100
88
 
101
89
  // Your server URL
102
90
  const serverUrl = 'ws://your-server-url/api/socket';
@@ -500,6 +488,8 @@ The `ClientChannel` class represents a channel in the PondClient.
500
488
 
501
489
  - `sendMessage(event: string, payload: PondMessage, recipient: string[]): void`: Sends a message to specific clients in the channel with the specified event, payload, and recipient.
502
490
 
491
+ - `sendForResponse(event: string, payload: PondMessage): Promise<PondMessage>`: Sends a message to the server with the specified event, payload, and returns a promise that resolves with the response.
492
+
503
493
  - `broadcastFrom(event: string, payload: PondMessage): void`: Broadcasts a message to every other client in the channel except yourself with the specified event and payload.
504
494
 
505
495
  - `broadcast(event: string, payload: PondMessage): void`: Broadcasts a message to the channel, including yourself, with the specified event and payload.
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const abstractRequest_1 = require("./abstractRequest");
4
+ const createMockChannelEngine = () => ({
5
+ name: 'test',
6
+ getAssigns: () => ({}),
7
+ getPresence: () => ({}),
8
+ });
9
+ describe('AbstractRequest', () => {
10
+ it('should be able to be instantiated', () => {
11
+ const request = new abstractRequest_1.AbstractRequest('/test', createMockChannelEngine(), {});
12
+ expect(request).toBeTruthy();
13
+ expect(request.channelName).toBe('test');
14
+ expect(request.assigns).toEqual({});
15
+ expect(request.presence).toEqual({});
16
+ });
17
+ it('should be able to parse queries', () => {
18
+ const request = new abstractRequest_1.AbstractRequest('/1234?choke=balls', createMockChannelEngine(), {});
19
+ expect(() => request.event).toThrowError('Event was not parsed');
20
+ expect(request['_parseQueries']('/:id')).toBe(true);
21
+ expect(request.event).toEqual({
22
+ event: '/1234?choke=balls',
23
+ params: { id: '1234' },
24
+ query: { choke: 'balls' },
25
+ payload: {},
26
+ });
27
+ });
28
+ it('should be return the value of the payload', () => {
29
+ const request = new abstractRequest_1.AbstractRequest('/test', createMockChannelEngine(), { test: 'test' });
30
+ expect(request['_parseQueries']('/:id')).toBe(true);
31
+ expect(request.event.payload).toEqual({ test: 'test' });
32
+ const request2 = new abstractRequest_1.AbstractRequest('/test', createMockChannelEngine(), {
33
+ test: 'test',
34
+ test2: 'test2',
35
+ });
36
+ expect(request2['_parseQueries']('/:id')).toBe(true);
37
+ expect(request2.event.payload).toEqual({
38
+ test: 'test',
39
+ test2: 'test2',
40
+ });
41
+ });
42
+ });
@@ -2,5 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PondResponse = void 0;
4
4
  class PondResponse {
5
+ constructor(requestId) {
6
+ this.requestId = requestId;
7
+ }
5
8
  }
6
9
  exports.PondResponse = PondResponse;
@@ -0,0 +1,70 @@
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.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', () => {
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.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
+ });
@@ -24,12 +24,11 @@ var __rest = (this && this.__rest) || function (s, e) {
24
24
  var _Channel_engine, _ChannelEngine_instances, _ChannelEngine_receiver, _ChannelEngine_presenceEngine, _ChannelEngine_users, _ChannelEngine_parentEngine, _ChannelEngine_subscribe, _ChannelEngine_getUsersFromRecipients;
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.ChannelEngine = exports.Channel = void 0;
27
+ const pondsocket_common_1 = require("@eleven-am/pondsocket-common");
27
28
  const eventRequest_1 = require("./eventRequest");
28
29
  const eventResponse_1 = require("./eventResponse");
29
- const enums_1 = require("../enums");
30
30
  const pondError_1 = require("../errors/pondError");
31
31
  const presence_1 = require("../presence/presence");
32
- const subject_1 = require("../subjects/subject");
33
32
  class Channel {
34
33
  constructor(engine) {
35
34
  _Channel_engine.set(this, void 0);
@@ -45,16 +44,16 @@ class Channel {
45
44
  return __classPrivateFieldGet(this, _Channel_engine, "f").getUserData(userId);
46
45
  }
47
46
  broadcastMessage(event, payload) {
48
- __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(enums_1.SystemSender.CHANNEL, enums_1.ChannelReceiver.ALL_USERS, enums_1.ServerActions.BROADCAST, event, payload);
47
+ __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
49
48
  }
50
49
  broadcastMessageFromUser(userId, event, payload) {
51
- __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(userId, enums_1.ChannelReceiver.ALL_EXCEPT_SENDER, enums_1.ServerActions.BROADCAST, event, payload);
50
+ __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage((0, pondsocket_common_1.uuid)(), userId, pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
52
51
  }
53
52
  sendToUser(userId, event, payload) {
54
- __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(enums_1.SystemSender.CHANNEL, [userId], enums_1.ServerActions.BROADCAST, event, payload);
53
+ __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, [userId], pondsocket_common_1.ServerActions.BROADCAST, event, payload);
55
54
  }
56
55
  sendToUsers(userIds, event, payload) {
57
- __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage(enums_1.SystemSender.CHANNEL, userIds, enums_1.ServerActions.BROADCAST, event, payload);
56
+ __classPrivateFieldGet(this, _Channel_engine, "f").sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, userIds, pondsocket_common_1.ServerActions.BROADCAST, event, payload);
58
57
  }
59
58
  evictUser(userId, reason) {
60
59
  __classPrivateFieldGet(this, _Channel_engine, "f").kickUser(userId, reason !== null && reason !== void 0 ? reason : 'You have been banned from the channel');
@@ -79,7 +78,7 @@ class ChannelEngine {
79
78
  _ChannelEngine_users.set(this, void 0);
80
79
  _ChannelEngine_parentEngine.set(this, void 0);
81
80
  this.name = name;
82
- __classPrivateFieldSet(this, _ChannelEngine_receiver, new subject_1.Subject(), "f");
81
+ __classPrivateFieldSet(this, _ChannelEngine_receiver, new pondsocket_common_1.Subject(), "f");
83
82
  __classPrivateFieldSet(this, _ChannelEngine_users, new Map(), "f");
84
83
  __classPrivateFieldSet(this, _ChannelEngine_parentEngine, parent, "f");
85
84
  }
@@ -132,12 +131,12 @@ class ChannelEngine {
132
131
  * @param reason - The reason for kicking the user
133
132
  */
134
133
  kickUser(userId, reason) {
135
- this.sendMessage(enums_1.SystemSender.CHANNEL, [userId], enums_1.ServerActions.SYSTEM, 'kicked_out', {
134
+ this.sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, [userId], pondsocket_common_1.ServerActions.SYSTEM, 'kicked_out', {
136
135
  message: reason,
137
136
  code: 403,
138
137
  });
139
138
  this.removeUser(userId);
140
- this.sendMessage(enums_1.SystemSender.CHANNEL, enums_1.ChannelReceiver.ALL_USERS, enums_1.ServerActions.SYSTEM, 'kicked', {
139
+ this.sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.SYSTEM, 'kicked', {
141
140
  userId,
142
141
  reason,
143
142
  });
@@ -147,7 +146,7 @@ class ChannelEngine {
147
146
  * @param reason - The reason for self-destructing the channel
148
147
  */
149
148
  destroy(reason) {
150
- this.sendMessage(enums_1.SystemSender.CHANNEL, enums_1.ChannelReceiver.ALL_USERS, enums_1.ServerActions.ERROR, 'destroyed', {
149
+ this.sendMessage((0, pondsocket_common_1.uuid)(), pondsocket_common_1.SystemSender.CHANNEL, pondsocket_common_1.ChannelReceiver.ALL_USERS, pondsocket_common_1.ServerActions.ERROR, 'destroyed', {
151
150
  message: reason !== null && reason !== void 0 ? reason : 'Channel has been destroyed',
152
151
  });
153
152
  __classPrivateFieldGet(this, _ChannelEngine_parentEngine, "f").destroyChannel();
@@ -195,19 +194,21 @@ class ChannelEngine {
195
194
  }
196
195
  /**
197
196
  * @desc Sends a message to a specified set of users, from a specified sender
197
+ * @param requestId - The id of the request
198
198
  * @param sender - The sender of the message
199
199
  * @param recipient - The users to send the message to
200
200
  * @param action - The action of the message
201
201
  * @param event - The event name
202
202
  * @param payload - The payload of the message
203
203
  */
204
- sendMessage(sender, recipient, action, event, payload) {
205
- if (!__classPrivateFieldGet(this, _ChannelEngine_users, "f").has(sender) && sender !== enums_1.SystemSender.CHANNEL) {
204
+ sendMessage(requestId, sender, recipient, action, event, payload) {
205
+ if (!__classPrivateFieldGet(this, _ChannelEngine_users, "f").has(sender) && sender !== pondsocket_common_1.SystemSender.CHANNEL) {
206
206
  throw new pondError_1.ChannelError(`ChannelEngine: User with id ${sender} does not exist in channel ${this.name}`, 404, this.name);
207
207
  }
208
208
  const eventMessage = {
209
209
  recipients: __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_getUsersFromRecipients).call(this, recipient, sender),
210
210
  channelName: this.name,
211
+ requestId,
211
212
  action,
212
213
  payload,
213
214
  event,
@@ -227,14 +228,15 @@ class ChannelEngine {
227
228
  sender: userId,
228
229
  event: message.event,
229
230
  payload: message.payload,
230
- action: enums_1.ServerActions.BROADCAST,
231
+ action: pondsocket_common_1.ServerActions.BROADCAST,
231
232
  channelName: this.name,
232
- recipients: __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_getUsersFromRecipients).call(this, message.addresses || enums_1.ChannelReceiver.ALL_USERS, userId),
233
+ requestId: message.requestId,
234
+ recipients: __classPrivateFieldGet(this, _ChannelEngine_instances, "m", _ChannelEngine_getUsersFromRecipients).call(this, message.addresses || pondsocket_common_1.ChannelReceiver.ALL_USERS, userId),
233
235
  };
234
236
  const request = new eventRequest_1.EventRequest(responseEvent, this);
235
237
  const response = new eventResponse_1.EventResponse(responseEvent, this);
236
238
  __classPrivateFieldGet(this, _ChannelEngine_parentEngine, "f").execute(request, response, () => {
237
- this.sendMessage(enums_1.SystemSender.CHANNEL, [userId], enums_1.ServerActions.ERROR, enums_1.ErrorTypes.HANDLER_NOT_FOUND, {
239
+ this.sendMessage(responseEvent.requestId, pondsocket_common_1.SystemSender.CHANNEL, [userId], pondsocket_common_1.ServerActions.ERROR, pondsocket_common_1.ErrorTypes.HANDLER_NOT_FOUND, {
238
240
  message: 'A handler did not respond to the event',
239
241
  code: 404,
240
242
  });
@@ -268,17 +270,17 @@ _ChannelEngine_receiver = new WeakMap(), _ChannelEngine_presenceEngine = new Wea
268
270
  const allUsers = Array.from(__classPrivateFieldGet(this, _ChannelEngine_users, "f").keys());
269
271
  let users;
270
272
  switch (recipients) {
271
- case enums_1.ChannelReceiver.ALL_USERS:
273
+ case pondsocket_common_1.ChannelReceiver.ALL_USERS:
272
274
  users = allUsers;
273
275
  break;
274
- case enums_1.ChannelReceiver.ALL_EXCEPT_SENDER:
275
- if (sender === enums_1.SystemSender.CHANNEL) {
276
- throw new pondError_1.ChannelError(`ChannelEngine: Cannot use ${enums_1.ChannelReceiver.ALL_EXCEPT_SENDER} with ${enums_1.SystemSender.CHANNEL}`, 500, this.name);
276
+ case pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER:
277
+ if (sender === pondsocket_common_1.SystemSender.CHANNEL) {
278
+ throw new pondError_1.ChannelError(`ChannelEngine: Cannot use ${pondsocket_common_1.ChannelReceiver.ALL_EXCEPT_SENDER} with ${pondsocket_common_1.SystemSender.CHANNEL}`, 500, this.name);
277
279
  }
278
280
  users = allUsers.filter((user) => user !== sender);
279
281
  break;
280
282
  default:
281
- if (!Array.isArray(recipients) || !recipients.every((recipient) => typeof recipient === 'string')) {
283
+ if (!Array.isArray(recipients)) {
282
284
  throw new pondError_1.ChannelError(`ChannelEngine: Invalid recipients ${recipients}`, 500, this.name);
283
285
  }
284
286
  if (recipients.some((user) => !allUsers.includes(user))) {