just-another-http-api 1.2.4 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "just-another-http-api",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "A framework built on top of fastify aimed at removing the need for any network or server configuration. ",
5
5
  "homepage": "https://github.com/OllieEdge/just-another-http-api#readme",
6
6
  "repository": {
@@ -3,35 +3,57 @@ const { redis } = require ( 'eip-cloud-services' );
3
3
 
4
4
  class WebsocketGroup {
5
5
 
6
- constructor ( groupName ) {
6
+ constructor ( groupName, destroy, messageReceivedHandler, connectionClosedHandler ) {
7
+ this.timeOfCreation = Date.now ();
7
8
  this.groupName = groupName;
9
+ this.destroy = destroy;
10
+ this.groupUuid = crypto.randomUUID ().substring ( 0, 8 );
8
11
  this.connections = new Map ();
12
+ this.messageReceivedHandler = messageReceivedHandler || ( async () => {} );
13
+ this.connectionClosedHandler = connectionClosedHandler;
9
14
  }
10
15
 
11
16
  async initialize () {
12
17
  try {
13
- await redis.subscribe ( `${this.groupName}_broadcast`, this.handleMessage.bind ( this ) );
14
- await redis.subscribe ( `${this.groupName}_messageReceived`, this.handleUserMessage.bind ( this ) );
18
+ await redis.subscribe ( `${this.groupName}_individualMessage`, this.#handleIndividualMessage.bind ( this ) );
19
+ await redis.subscribe ( `${this.groupName}_broadcast`, this.#broadcastMessageToClients.bind ( this ) );
20
+ await redis.subscribe ( `${this.groupName}_messageReceived`, this.#handleUserMessage.bind ( this ) );
15
21
  }
16
22
  catch ( error ){
17
- console.log ( error );
23
+ console.error ( error );
18
24
  }
19
25
  }
20
26
 
21
- handleMessage ( message ) {
22
- this.broadcastMessageToClients ( message );
27
+ async #handleUserMessage ( jsonMessage ) {
28
+ const userMessage = JSON.parse ( jsonMessage );
29
+ await this.messageReceivedHandler ( userMessage );
23
30
  }
24
31
 
25
- async handleUserMessage ( userMessage ) {
26
- // don't really need to do anything with this message.
27
- }
28
-
29
- broadcastMessageToClients ( message ) {
32
+ #broadcastMessageToClients ( message ) {
30
33
  this.connections.forEach ( conn => {
31
- conn.socket.send ( JSON.stringify ( message ) );
34
+ conn.socket.send ( typeof message === 'string' ? message : JSON.stringify ( message ) );
32
35
  } );
33
36
  }
34
37
 
38
+ #handleIndividualMessage ( individualMessage ) {
39
+ const { connectionId, message } = JSON.parse ( individualMessage );
40
+ if(this.connections.has(connectionId)) {
41
+ this.connections.get(connectionId).socket.send(message);
42
+ }
43
+ }
44
+
45
+ getConnections () {
46
+ return this.connections;
47
+ }
48
+
49
+ individualMessage ( connectionId, message ) {
50
+ redis.publish ( `${this.groupName}_individualMessage`, JSON.stringify ( { connectionId, message } ) );
51
+ }
52
+
53
+ broadcastMessage ( message ) {
54
+ redis.publish ( `${this.groupName}_broadcast`, JSON.stringify ( message ) );
55
+ }
56
+
35
57
  addNewConnection ( connection, connectionId = crypto.randomUUID () ) {
36
58
  this.connections.set ( connectionId, connection );
37
59
 
@@ -46,15 +68,37 @@ class WebsocketGroup {
46
68
 
47
69
  connection.socket.on ( 'close', () => {
48
70
  this.connections.delete ( connectionId );
71
+ this.#clean(connectionId);
49
72
  } );
50
-
73
+
51
74
  connection.socket.on ( 'error', error => {
52
75
  console.error ( 'WebSocket error:', error );
53
76
  this.connections.delete ( connectionId );
77
+ this.#clean(connectionId);
54
78
  } );
55
79
 
56
80
  return { connectionId, groupName: this.groupName, connection };
57
81
  }
82
+
83
+ async #clean (connectionId) {
84
+
85
+ if ( this.connectionClosedHandler !== null && typeof this.connectionClosedHandler === 'function') {
86
+ try{
87
+ await this.connectionClosedHandler ( {groupName:this.groupName, connectionId} );
88
+ }
89
+ catch (error) {
90
+ console.error('Error in connectionClosedHandler:', error);
91
+ }
92
+ }
93
+
94
+ if ( this.connections.size === 0 ) {
95
+ this.connections.clear ();
96
+ await redis.unsubscribe ( `${this.groupName}_individualMessage` );
97
+ await redis.unsubscribe ( `${this.groupName}_broadcast` );
98
+ await redis.unsubscribe ( `${this.groupName}_messageReceived` );
99
+ this.destroy(this.groupName);
100
+ }
101
+ }
58
102
  }
59
103
 
60
104
  module.exports = WebsocketGroup;
@@ -2,13 +2,19 @@ const WebsocketGroup = require ( './WebsocketGroup' );
2
2
 
3
3
  const websocketGroups = {};
4
4
 
5
- const getGroupInstance = async ( groupName ) => {
6
- if ( !websocketGroups[ groupName ] ) {
7
- websocketGroups[ groupName ] = new WebsocketGroup ( groupName );
5
+ const getGroupInstance = async ( groupName, messageReceivedHandler, connectionClosedHandler ) => {
6
+ if ( !websocketGroups[ groupName ] && messageReceivedHandler && connectionClosedHandler ) {
7
+ websocketGroups[ groupName ] = new WebsocketGroup ( groupName, removeGroupInstance, messageReceivedHandler, connectionClosedHandler );
8
8
  await websocketGroups[ groupName ].initialize ();
9
9
  }
10
10
 
11
- return websocketGroups[ groupName ];
11
+ return websocketGroups[ groupName ] || null;
12
12
  };
13
13
 
14
+ const removeGroupInstance = async groupName => {
15
+ if ( websocketGroups[ groupName ] ) {
16
+ delete websocketGroups[ groupName ];
17
+ }
18
+ }
19
+
14
20
  module.exports = getGroupInstance;