@cocreate/socket-server 1.18.0 → 1.19.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,32 @@
1
+ # [1.19.0](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.18.1...v1.19.0) (2023-10-09)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * added '@cocreate/utlis' ([cc8267a](https://github.com/CoCreate-app/CoCreate-socket-server/commit/cc8267abf7ded45033929bd4c4997eb9adc89d42))
7
+ * handling of socket.id and clientId ([9e66f16](https://github.com/CoCreate-app/CoCreate-socket-server/commit/9e66f16f4e869e7ec29a261068fb61c46569f408))
8
+ * Improved handling of data.sync ([190ebd6](https://github.com/CoCreate-app/CoCreate-socket-server/commit/190ebd6c10f337fbd4e8be81caba865cfffb5c0a))
9
+ * send _id with syncMessage ([e37e2de](https://github.com/CoCreate-app/CoCreate-socket-server/commit/e37e2de8aff8945a3884c416514adc1e89fc54e2))
10
+ * update to use data.socketId and data.clientId ([125f2be](https://github.com/CoCreate-app/CoCreate-socket-server/commit/125f2bedd6090488ae26dc2228b53bb4aa63d4ff))
11
+ * use message_log ([d4b4c4a](https://github.com/CoCreate-app/CoCreate-socket-server/commit/d4b4c4ad2708cd61567d7172ac7bcb0635349a6a))
12
+
13
+
14
+ ### Features
15
+
16
+ * Authentication happens during upgrade ([c01cb0e](https://github.com/CoCreate-app/CoCreate-socket-server/commit/c01cb0eeb5fc4e135a8d9855fbab7e8b9535423d))
17
+ * get, set, delete socket functions ([9066911](https://github.com/CoCreate-app/CoCreate-socket-server/commit/9066911016072841cd08463c8354eeef892b41e3))
18
+ * method sync sent to server with sync details ([3c914b7](https://github.com/CoCreate-app/CoCreate-socket-server/commit/3c914b74d720949c8ae56f3f9159041ef1d5f24f))
19
+ * on socket connection the data is parsed from ([0b69b35](https://github.com/CoCreate-app/CoCreate-socket-server/commit/0b69b357c891da63c3e94aaca8361866f252de98))
20
+
21
+ ## [1.18.1](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.18.0...v1.18.1) (2023-09-18)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * Add path and pathname ([5b5fb7e](https://github.com/CoCreate-app/CoCreate-socket-server/commit/5b5fb7e6d718f916dfdbfc3754cb63c6b1a51c47))
27
+ * Update clients array to use map for improved management of each client ([cff2f2a](https://github.com/CoCreate-app/CoCreate-socket-server/commit/cff2f2ad3d34ac1d7b926180da508c65e5855b37))
28
+ * Update dCoCreate dpendencies to latest versions ([03fa429](https://github.com/CoCreate-app/CoCreate-socket-server/commit/03fa429efc31db9f0ed5aec41dbf5b471475e0ba))
29
+
1
30
  # [1.18.0](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.17.0...v1.18.0) (2023-09-17)
2
31
 
3
32
 
@@ -1,24 +1,24 @@
1
- module.exports = {
2
- "organization_id": "",
3
- "key": "",
4
- "host": "",
5
- "sources": [
6
- {
7
- "array": "files",
8
- "object": {
9
- "_id": "6204254580b409001727b744",
10
- "name": "index.html",
11
- "path": "/docs/socket-server/index.html",
12
- "src": "{{./docs/index.html}}",
13
- "host": [
14
- "*",
15
- "general.cocreate.app"
16
- ],
17
- "directory": "/docs/socket-server",
18
- "content-type": "text/html",
19
- "public": "true",
20
- "website_id": "5ffbceb7f11d2d00103c4535"
21
- }
22
- }
23
- ]
24
- }
1
+ module.exports = {
2
+ "organization_id": "",
3
+ "key": "",
4
+ "host": "",
5
+ "sources": [
6
+ {
7
+ "array": "files",
8
+ "object": {
9
+ "_id": "6204254580b409001727b744",
10
+ "name": "index.html",
11
+ "path": "/docs/socket-server",
12
+ "pathname": "/docs/socket-server/index.html",
13
+ "src": "{{./docs/index.html}}",
14
+ "host": [
15
+ "*",
16
+ "general.cocreate.app"
17
+ ],
18
+ "directory": "socket-server",
19
+ "content-type": "text/html",
20
+ "public": "true"
21
+ }
22
+ }
23
+ ]
24
+ };
package/docs/index.html CHANGED
@@ -218,7 +218,6 @@
218
218
  </div>
219
219
  </div>
220
220
  </div>
221
- <script src="/apikey.js"></script>
222
221
  <script src="https://CoCreate.app/dist/CoCreate.js"></script>
223
222
  </body>
224
223
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/socket-server",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "CoCreate-socket-server",
5
5
  "keywords": [
6
6
  "cocreate-socket",
@@ -40,8 +40,9 @@
40
40
  },
41
41
  "homepage": "https://cocreate.app/docs/CoCreate-socket-server",
42
42
  "dependencies": {
43
- "@cocreate/config": "^1.5.0",
44
- "@cocreate/uuid": "^1.7.0",
43
+ "@cocreate/config": "^1.5.2",
44
+ "@cocreate/uuid": "^1.7.2",
45
+ "@cocreate/utils": "^1.24.2",
45
46
  "ws": "7.5.9"
46
47
  }
47
48
  }
package/src/index.js CHANGED
@@ -2,107 +2,266 @@ const WebSocket = require('ws');
2
2
  const { URL } = require("url");
3
3
  const EventEmitter = require("events").EventEmitter;
4
4
  const uid = require('@cocreate/uuid')
5
+ const { ObjectId } = require('@cocreate/utils')
5
6
  const config = require('@cocreate/config')
6
7
 
7
8
  class SocketServer extends EventEmitter {
8
- constructor(server, prefix) {
9
+ constructor(server) {
9
10
  super();
11
+ this.serverId = uid.generate(12)
10
12
  this.organizations = new Map();
11
13
  this.clients = new Map();
12
- this.prefix = prefix || "ws";
14
+ this.sockets = new Map();
15
+ this.users = new Map();
16
+
13
17
  config({ organization_id: { prompt: 'Enter your organization_id: ' } })
14
18
 
15
19
  this.wss = new WebSocket.Server({ noServer: true });
20
+
16
21
  this.wss.on('headers', (headers, request) => {
17
22
  headers.push('Access-Control-Allow-Origin: *');
18
23
  });
19
24
 
25
+ this.wss.on('error', (error) => {
26
+ socket.destroy();
27
+ });
28
+
20
29
  server.on('upgrade', (request, socket, head) => {
21
- if (!this.handleUpgrade(request, socket, head)) {
22
- socket.destroy();
30
+ const self = this;
31
+ let organization_id = request.url.split('/')
32
+ organization_id = organization_id[organization_id.length - 1]
33
+
34
+ if (organization_id) {
35
+ this.wss.handleUpgrade(request, socket, head, function (socket) {
36
+ let options = decodeURIComponent(request.headers['sec-websocket-protocol'])
37
+ options = JSON.parse(options)
38
+
39
+ socket.organization_id = organization_id
40
+ socket.id = options.socketId;
41
+ socket.clientId = options.clientId;
42
+ socket.pathname = request.url
43
+ socket.origin = request.headers.origin || request.headers.host
44
+
45
+ if (socket.origin.startsWith('http'))
46
+ socket.origin = socket.origin.replace('http', 'ws')
47
+
48
+ socket.socketUrl = socket.origin + socket.pathname
49
+
50
+ if (socket.origin && socket.origin !== 'null') {
51
+ const url = new URL(socket.origin);
52
+ socket.host = url.host || socket.origin;
53
+ }
54
+
55
+ let data = {
56
+ socket,
57
+ method: 'read.object',
58
+ array: 'message_log',
59
+ $filter: {
60
+ sort: [
61
+ { key: '_id', direction: 'desc' }
62
+ ]
63
+ },
64
+ sync: true,
65
+ organization_id
66
+ }
67
+
68
+ if (options.lastSynced)
69
+ data.$filter.query = [
70
+ { key: '_id', value: options.lastSynced, operator: '$gt' }
71
+ ]
72
+ else
73
+ data.$filter.limit = 1
74
+
75
+ self.emit('read.object', data);
76
+
77
+ if (self.authenticate && options.token)
78
+ self.authenticate.decodeToken(options.token).then(({ user_id, expires }) => {
79
+ if (user_id) {
80
+ socket.user_id = user_id;
81
+ socket.expires = expires;
82
+ self.emit('userStatus', { socket, method: 'userStatus', user_id, userStatus: 'on', organization_id });
83
+ } else
84
+ this.emit('userStatus', { socket, user_id, status: 'off', organization_id });
85
+
86
+ self.onWebSocket(socket);
87
+ })
88
+ else
89
+ self.onWebSocket(socket);
90
+ })
23
91
  }
24
92
  });
25
93
  }
26
94
 
27
- handleUpgrade(req, socket, head) {
28
- const self = this;
29
- // const url = new URL(req.url);
30
- // const pathname = req.url;
31
- const config = this.getKeyFromUrl(req.url)
32
- if (config.type == this.prefix) {
33
- this.wss.handleUpgrade(req, socket, head, function (socket) {
34
- socket.config = config
35
- self.onWebSocket(req, socket);
36
- })
37
- return true;
38
- }
39
- return false;
40
- }
41
-
42
- onWebSocket(req, socket) {
95
+ onWebSocket(socket) {
43
96
  const self = this;
44
-
45
- this.addClient(socket);
97
+ this.add(socket);
46
98
 
47
99
  socket.on('message', async (message) => {
48
- self.onMessage(req, socket, message);
100
+ self.onMessage(socket, message);
49
101
  })
50
102
 
51
- socket.on('close', function () {
52
- self.removeClient(socket)
103
+ socket.on('close', () => {
104
+ self.delete(socket)
53
105
  })
54
106
 
55
107
  socket.on("error", () => {
56
- self.removeClient(socket)
108
+ self.delete(socket)
57
109
  });
58
110
 
59
- this.send(socket, { socket, method: 'connect', connectedKey: socket.config.key });
111
+ socket.send(JSON.stringify({ method: 'connect', connectedKey: socket.pathname }))
60
112
 
61
113
  }
62
114
 
63
- addClient(socket) {
64
- let organization_id = socket.config.organization_id
65
- if (!this.organizations.has(organization_id))
66
- this.organizations.set(organization_id, true)
115
+ add(socket) {
116
+ let organization_id = socket.organization_id
117
+
118
+ let organization = this.organizations.get(organization_id)
119
+ if (!organization) {
120
+ organization = {
121
+ status: true,
122
+ clients: {}
123
+ }
124
+
125
+ this.organizations.set(organization_id, organization)
126
+
127
+ this.emit('update.object', {
128
+ method: 'update.object',
129
+ array: 'organizations',
130
+ object: {
131
+ _id: organization_id, ['$push.activeHost']: socket.socketUrl // needs socketId
132
+ },
133
+ organization_id
134
+ });
135
+
136
+ this.emit('mesh.create', {
137
+ url: socket.socketUrl,
138
+ organization_id
139
+ });
67
140
 
68
- let user_id = socket.config.user_id
69
- let key = socket.config.key
70
- let clients = this.clients.get(key);
71
- if (clients) {
72
- clients.push(socket);
73
- } else {
74
- clients = [socket];
75
141
  }
76
- this.clients.set(key, clients);
77
142
 
78
- if (user_id)
79
- this.emit('userStatus', socket, { socket, user_id, userStatus: 'on', organization_id });
143
+ if (!this.clients.has(socket.clientId)) {
144
+ this.clients.set(socket.clientId, []);
145
+ organization.clients[socket.clientId] = []
146
+ }
147
+
148
+ if (!this.sockets.has(socket.id)) {
149
+ this.sockets.set(socket.id, socket);
150
+ this.clients.get(socket.clientId).push(socket);
151
+ organization.clients[socket.clientId].push(socket)
152
+ }
153
+
154
+ if (socket.user_id) {
155
+ this.emit('userStatus', { socket, user_id: socket.user_id, userStatus: 'on', organization_id });
156
+
157
+ if (!this.users.has(socket.user_id)) {
158
+ this.users.set(socket.user_id, [socket])
159
+ } else {
160
+ this.users.get(socket.user_id).push(socket)
161
+ }
162
+ }
163
+
164
+ }
165
+
166
+ get(data) {
167
+ let sockets = []
168
+ if (data.broadcast !== false) {
169
+ let organization = this.organizations.get(data.organization_id)
170
+ if (organization) {
171
+ const clients = organization.clients
172
+ for (let client of Object.keys(clients)) {
173
+ if (data.broadcastSender === false && client === data.clientId) continue
174
+
175
+ if (data.broadcastClient)
176
+ sockets.push(clients[client][0])
177
+ else
178
+ sockets.push(...clients[client])
179
+ }
180
+ } else {
181
+ // TODO: requires a messageQueue that expires
182
+ console.log('organization could not be found', data)
183
+ }
184
+ } else if (data.broadcastSender !== false) {
185
+ sockets.push(data.socket)
186
+ }
187
+ return sockets
80
188
  }
81
189
 
82
- removeClient(socket) {
83
- let organization_id = socket.config.organization_id
84
- let user_id = socket.config.user_id
85
- let key = socket.config.key
86
- let clients = this.clients.get(key)
87
- const index = clients.indexOf(socket);
190
+ delete(socket) {
191
+ let organization_id = socket.organization_id
192
+ if (this.organizations.has(organization_id)) {
193
+ const clients = this.organizations.get(organization_id).clients;
88
194
 
89
- if (index > -1) {
90
- clients.splice(index, 1);
195
+ // Check if the client exists
196
+ if (clients && clients[socket.clientId]) {
197
+ const client = clients[socket.clientId]
198
+
199
+ // Check if the socket exists in the client's sockets
200
+ const index = client.findIndex(item => item.id === socket.id);
201
+ if (index !== -1) {
202
+ client.splice(index, 1);
203
+ }
204
+
205
+ if (!client.length) {
206
+ delete clients[socket.clientId];
207
+ }
208
+
209
+ if (!Object.keys(clients).length) {
210
+ this.organizations.delete(socket.organization_id);
211
+ this.emit('update.object', {
212
+ method: 'update.object',
213
+ array: 'organizations',
214
+ object: {
215
+ _id: organization_id, ['$pull.activeHost']: socket.socketUrl
216
+ },
217
+ organization_id
218
+ });
219
+
220
+ this.emit('mesh.update', {
221
+ url: socket.socketUrl,
222
+ organization_id
223
+ });
224
+ }
225
+
226
+ }
91
227
  }
92
228
 
93
- if (user_id)
94
- this.emit('userStatus', socket, { socket, user_id, status: 'off', organization_id });
229
+ if (this.clients.has(socket.clientId)) {
230
+ const client = this.clients.get(socket.clientId)
231
+ const index = client.findIndex(item => item.id === socket.id);
232
+ if (index !== -1) {
233
+ client.splice(index, 1);
234
+ }
95
235
 
96
- if (clients.length == 0) {
97
- this.organizations.delete(organization_id)
98
- this.emit('disconnect', organization_id)
236
+ if (!client.length) {
237
+ this.clients.delete(socket.clientId);
238
+ }
99
239
  }
100
240
 
241
+ if (this.clients.size === 0) {
242
+ this.organizations.delete(socket.organization_id);
243
+ }
244
+
245
+ this.sockets.delete(socket.id);
246
+
247
+ if (socket.user_id) {
248
+ let sockets = this.users.get(socket.user_id)
249
+ if (sockets) {
250
+ const index = sockets.findIndex(item => item.id === socket.id);
251
+ if (index !== -1) {
252
+ sockets.splice(index, 1);
253
+ }
254
+ if (!sockets.length) {
255
+ this.users.delete(socket.user_id);
256
+ this.emit('userStatus', { socket, user_id, status: 'off', organization_id });
257
+ }
258
+ }
259
+ }
101
260
  }
102
261
 
103
- async onMessage(req, socket, message) {
262
+ async onMessage(socket, message) {
104
263
  try {
105
- const organization_id = socket.config.organization_id
264
+ const organization_id = socket.organization_id
106
265
 
107
266
  this.emit("setBandwidth", {
108
267
  type: 'in',
@@ -110,35 +269,38 @@ class SocketServer extends EventEmitter {
110
269
  organization_id
111
270
  });
112
271
 
113
- let active = this.organizations.get(organization_id)
114
- if (active === false)
272
+ if (this.organizations.has(organization_id) && !this.organizations.get(organization_id).status)
115
273
  return this.send({ socket, method: 'Access Denied', balance: 'Your balance has fallen bellow 0' })
116
274
 
117
275
  let data = JSON.parse(message)
118
-
119
276
  if (data.method) {
120
- let user_id = null;
121
- if (this.authenticate)
122
- user_id = await this.authenticate.decodeToken(req);
277
+ if (data.method === 'region.added' || data.method === 'region.removed')
278
+ console.log('data.method: ', data.method)
279
+
280
+ if (socket.user_id && socket.expires && new Date().getTime() >= socket.expires) {
281
+ socket.user_id = socket.expires = null
282
+ this.send({ socket, method: 'updateUserStatus', userStatus: 'off', socketId: data.socketId, organization_id })
283
+ }
123
284
 
124
285
  if (this.authorize) {
286
+ if (!this.sockets.has(socket.id)) {
287
+ if (!this.organizations.get(organization_id).status)
288
+ return this.send({ socket, method: 'Access Denied', balance: 'Your balance has fallen bellow 0' })
289
+ }
290
+
125
291
  data.socket = socket
126
292
 
127
- data.host = this.getHost(req)
128
- const authorized = await this.authorize.check(data, user_id)
293
+ const authorized = await this.authorize.check(data, socket.user_id)
129
294
  if (authorized.storage === false) {
130
295
  data.database = process.env.organization_id
131
296
  data.organization_id = process.env.organization_id
132
297
 
133
- const authorized2 = await this.authorize.check(data, req, user_id)
298
+ const authorized2 = await this.authorize.check(data, req, socket.user_id)
134
299
  if (!authorized2 || authorized2.error) {
135
300
  return this.send({ socket, method: 'Access Denied', authorized2, ...data })
136
301
  }
137
302
  } else if (!authorized || authorized.error) {
138
- if (!user_id)
139
- this.send({ socket, method: 'updateUserStatus', userStatus: 'off', clientId: data.clientId, organization_id })
140
-
141
- return this.send({ method: 'Access Denied', authorized, ...data })
303
+ return this.send({ socket, method: 'Access Denied', authorized, ...data })
142
304
  }
143
305
  // dburl is true and db does not have 'keys' array
144
306
  // action: syncCollection data{array: 'keys', object[]}
@@ -150,15 +312,6 @@ class SocketServer extends EventEmitter {
150
312
  if (authorized.authorized)
151
313
  data = authorized.authorized
152
314
 
153
- if (user_id) {
154
- if (!socket.config.user_id) {
155
- socket.config.user_id = user_id
156
- this.emit('userStatus', { socket, method: 'userStatus', user_id, userStatus: 'on', organization_id });
157
- }
158
- } else {
159
- this.send({ socket, method: 'updateUserStatus', userStatus: 'off', clientId: data.clientId, organization_id })
160
- }
161
-
162
315
  this.emit(data.method, data);
163
316
 
164
317
  }
@@ -168,85 +321,77 @@ class SocketServer extends EventEmitter {
168
321
  }
169
322
  }
170
323
 
171
- broadcast(data) {
172
- if (!data.uid)
173
- data.uid = uid.generate()
174
-
175
- let organization_id = socket.config.organization_id;
176
- let url = `/${this.prefix}/${organization_id}`;
177
-
178
- let namespace = data.namespace;
179
- if (namespace) {
180
- url += `/${namespace}`
181
- }
324
+ async send(data) {
325
+ // const socket = this.sockets.get(data.socketId)
326
+ const socket = data.socket
182
327
 
328
+ if (data.sync) {
329
+ if (!data.object || !data.object.length)
330
+ return
183
331
 
184
- let rooms = data.room;
185
- if (rooms) {
186
- if (!rooms.isArray())
187
- rooms = [rooms]
188
- for (let room of rooms) {
189
- let url = url;
190
- url += `/${room}`;
332
+ for (let i = 0; i < data.object.length; i++) {
333
+ data.object[i].data._id = data.object[i]._id
334
+ data.object[i].data.sync = true
191
335
 
192
- this.send(data, url)
336
+ const authorized = await this.authorize.check(data.object[i].data, socket.user_id)
337
+ if (authorized && authorized.authorized)
338
+ socket.send(JSON.stringify(authorized.authorized));
339
+ else
340
+ socket.send(JSON.stringify(data.object[i].data));
193
341
  }
194
342
  } else {
195
- this.send(data, url)
196
- }
197
- }
343
+ const sent = []
344
+
345
+ const authorized = await this.authorize.check(data, socket.user_id)
346
+ if (authorized && authorized.authorized)
347
+ data = authorized.authorized
348
+
349
+ if (!data.method.startsWith('read.') || data.log) {
350
+ let object = { url: socket.socketUrl, data }
351
+ delete object.socket
352
+ this.emit('create.object', {
353
+ method: 'create.object',
354
+ array: 'message_log',
355
+ object,
356
+ organization_id: data.organization_id
357
+ });
358
+ }
198
359
 
199
- async send(data, url) {
200
- const socket = data.socket
201
- delete data.socket
202
-
203
- let clients
204
- if (!url)
205
- clients = [socket]
206
- else
207
- clients = this.clients.get(url);
208
-
209
- if (clients) {
210
- for (let client of clients) {
211
- if (socket != client && data.broadcast != false || socket == client && data.broadcastSender != false) {
212
- const authorized = await this.authorize.check(data, socket.config.user_id)
213
- if (authorized && authorized.authorized)
214
- data = authorized.authorized
215
- let responseData = JSON.stringify(data);
216
- client.send(responseData);
217
-
218
- if (socket.config && socket.config.organization_id)
219
- this.emit("setBandwidth", {
220
- type: 'out',
221
- data: responseData,
222
- organization_id: socket.config.organization_id
223
- })
224
- }
360
+ let sockets = this.get(data);
361
+
362
+ delete data.socket
363
+
364
+ for (let i = 0; i < sockets.length; i++) {
365
+ const authorized = await this.authorize.check(data, sockets[i].user_id)
366
+ if (authorized && authorized.authorized)
367
+ sockets[i].send(JSON.stringify(authorized.authorized));
368
+ else
369
+ sockets[i].send(JSON.stringify(data));
370
+ sent.push(socket.clientId)
371
+ this.emit("setBandwidth", {
372
+ type: 'out',
373
+ data: authorized.authorized || data,
374
+ organization_id: socket.organization_id
375
+ })
225
376
  }
226
- }
227
377
 
378
+ // TODO: sent is an array of clientId's so that notification can send to subscribed clients that are not currently connected
379
+ this.emit("notification", { sent })
380
+ }
228
381
  }
229
382
 
230
- getKeyFromUrl(pathname) {
231
- var path = pathname.split("/");
232
- var params = {
233
- type: null,
234
- key: pathname
383
+ getConfigFromUrl(pathname) {
384
+ const path = pathname.split("/");
385
+ if (path[2]) {
386
+ path[2] = decodeURIComponent(path[2]);
387
+ path[2] = JSON.parse(path[2]) || {};
235
388
  }
236
- if (path.length > 0) {
237
- params.type = path[1];
238
- params.organization_id = path[2]
239
- }
240
- return params
241
- }
242
389
 
243
- getHost(req) {
244
- if (req.headers.origin && req.headers.origin !== 'null') {
245
- const url = new URL(req.headers.origin);
246
- return url.host;
247
- } else if (req.headers.host && req.headers.host !== 'null') {
248
- return req.headers.host;
390
+ const config = {
391
+ organization_id: path[1],
392
+ ...path[2]
249
393
  }
394
+ return config
250
395
  }
251
396
 
252
397
  }
package/src/mesh.js ADDED
@@ -0,0 +1,71 @@
1
+ const socket = require('@cocreate/socket-client')
2
+ const crud = require('@cocreate/crud-client')
3
+ const EventEmitter = require('events');
4
+ const eventEmitter = new EventEmitter();
5
+
6
+
7
+ const organizations = {}
8
+ const urls = new Map()
9
+ const servers = {}
10
+
11
+ async function addServer(data) {
12
+ if (!servers[data.url])
13
+ servers[data.url] = { [data.serverId]: { [data.organization_id]: true } }
14
+ else
15
+ servers[data.url][data.serverId][data.organization_id] = true
16
+
17
+ // TODO: needs to get orgaizations activeRegions
18
+ let activeRegions = await crud.send({
19
+ method: 'read.object',
20
+ array: 'organizations',
21
+ object: { _id: data.organization_id },
22
+ organization_id: data.organization_id
23
+ })
24
+
25
+ console.log('mesh activeRegions: ', activeRegions)
26
+ // socket.send({
27
+ // method: 'region.added',
28
+ // host: data.url,
29
+ // activeRegions: '',
30
+ // serverId: data.serverId,
31
+ // broadcast: false,
32
+ // broadcastSender: false,
33
+ // organization_id: data.organization_id
34
+ // })
35
+ }
36
+
37
+ function deleteServer(data) {
38
+ delete servers[data.url][data.serverId][data.organization_id]
39
+ if (!Object.keys(servers[data.url][data.serverId]).length)
40
+ delete servers[data.url][data.serverId]
41
+ if (!Object.keys(servers[data.url]).length) {
42
+ console.log('mesh deleteServer: ', data.url)
43
+
44
+ // socket.send({
45
+ // method: 'region.removed', // delete.region
46
+ // host: data.url,
47
+ // serverId: data.serverId,
48
+ // organization_id: data.organization_id
49
+ // })
50
+ socket.delete(data.url)
51
+ }
52
+
53
+ }
54
+
55
+ socket.listen('region.added', function (data) {
56
+ addServer(data)
57
+ });
58
+
59
+ socket.listen('region.removed', function (data) {
60
+ delete servers[data.url][data.serverId]
61
+ if (!Object.keys(servers[data.url]).length)
62
+ socket.delete(data.url)
63
+ });
64
+
65
+ eventEmitter.on('mesh.create', addServer);
66
+ eventEmitter.on('mesh.delete', deleteServer);
67
+
68
+ // eventEmitter.emit('customEvent', 'Hello, Node.js!');
69
+
70
+
71
+ // let response = await crud.send(request)