@jcbuisson/express-x 1.4.3 → 1.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jcbuisson/express-x",
3
- "version": "1.4.3",
3
+ "version": "1.5.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "src/index.mjs",
package/src/index.mjs CHANGED
@@ -1,11 +1,10 @@
1
1
 
2
2
  import { expressX } from './server.mjs'
3
- import { hashPassword, protect, setSessionJWT, } from './common-hooks.mjs'
3
+ import { hashPassword, protect, } from './common-hooks.mjs'
4
4
 
5
5
  export {
6
6
  expressX,
7
7
 
8
8
  hashPassword,
9
9
  protect,
10
- setSessionJWT,
11
10
  }
package/src/server.mjs CHANGED
@@ -15,15 +15,64 @@ export function expressX(prisma, options = {}) {
15
15
 
16
16
  const services = {}
17
17
 
18
- app.connections = {}
19
- let lastConnectionId = options.initialConnectionId || 1
20
- // TODO: use redis to store `connections` and `lastConnectionId` for a clustered deployment
21
- // (a connection/reconnection may occur on two different servers)
18
+ const cnx2Socket = {}
22
19
 
23
- app.printCnx = (label) => {
20
+ function createConnection() {
21
+ return app.service('Connection').create({})
22
+ }
23
+
24
+ async function deleteConnection(id) {
25
+ try {
26
+ await app.service('Connection')._delete({ where: { id }})
27
+ } catch(err) {
28
+ console.log('111')
29
+ }
30
+ }
31
+
32
+ function getConnection(id) {
33
+ return app.service('Connection').findUnique({ where: { id }})
34
+ }
35
+
36
+ async function copyConnection(id, connection) {
37
+ await app.service('Connection').update({
38
+ where: { id },
39
+ data: {
40
+ channelNames: connection.channelNames,
41
+ data: connection.data,
42
+ }
43
+ })
44
+ }
45
+
46
+ async function getChannelConnections(channelName) {
47
+ const connections = await app.service('Connection').findMany({})
48
+ return connections.filter(connection => {
49
+ const channelNames = JSON.parse(connection.channelNames)
50
+ return channelNames.includes(channelName)
51
+ })
52
+ }
53
+
54
+ async function addChannelToConnection(connection, channelName) {
55
+ const channelNames = JSON.parse(connection.channelNames)
56
+ if (!channelNames.includes(channelName)) channelNames.push(channelName)
57
+ await app.service('Connection').update({
58
+ where: { id: connection.id },
59
+ data: { channelNames: JSON.stringify(channelNames) },
60
+ })
61
+ }
62
+
63
+ async function removeChannelFromConnection(connection, channelName) {
64
+ const channelNames = JSON.parse(connection.channelNames).filter(name => name !== channelName)
65
+ await app.service('Connection').update({
66
+ where: { id },
67
+ data: { channelNames: JSON.stringify(channelNames) },
68
+ })
69
+ }
70
+
71
+ app.printCnx = async (label) => {
24
72
  console.log(label)
25
- for (const id in app.connections) {
26
- console.log(`CNX ${id}, data ${JSON.stringify(app.connections[id].data)}`)
73
+ const connections = await app.service('Connection').findMany({})
74
+ for (const connection of connections) {
75
+ console.log(`CNX ${connection.id}, data ${JSON.stringify(connection.data)}`)
27
76
  }
28
77
  }
29
78
 
@@ -257,18 +306,11 @@ export function expressX(prisma, options = {}) {
257
306
  */
258
307
  const io = new Server(server)
259
308
 
260
- io.on('connection', function(socket) {
261
- const connection = {
262
- id: lastConnectionId++,
263
- createdAt: new Date(),
264
- socket,
265
- channelNames: new Set(),
266
- data: {},
267
- }
309
+ io.on('connection', async function(socket) {
310
+ const connection = await createConnection()
268
311
  app.log('verbose', `Client connected ${connection.id}`)
269
- // store connection in cache
270
- app.connections[connection.id] = connection
271
- // app.log('verbose', `Connection ids: ${Object.keys(app.connections)}`)
312
+
313
+ cnx2Socket[connection.id] = socket
272
314
 
273
315
  // emit 'connection' event for app (expressjs extends EventEmitter)
274
316
  app.emit('connection', connection)
@@ -282,32 +324,24 @@ export function expressX(prisma, options = {}) {
282
324
  // remove connection record after 1mn (leaves time in case of connection transfer)
283
325
  setTimeout(() => {
284
326
  app.log('verbose', `Delete connection ${connection.id}`)
285
- delete app.connections[connection.id]
286
- }, 60 * 1000)
287
- })
288
-
289
- socket.on('reconnect', () => {
290
- console.log('Client reconnected:', socket.id)
291
- // Add your custom logic to link the reconnected WebSocket with the previous session
327
+ deleteConnection(connection.id)
328
+ }, 10 * 1000)
292
329
  })
293
330
 
294
331
 
295
332
  // handle connection data transfer caused by a disconnection/reconnection (page reload, network issue, etc.)
296
333
  socket.on('cnx-transfer', async ({ from, to }) => {
297
334
  app.log('verbose', `cnx-transfer from ${from} to ${to}`)
298
- if (!app.connections[from]) return
299
- app.connections[to] = app.connections[from]
300
- app.connections[to].socket = socket
301
- delete app.connections[from]
335
+ const fromConnection = await getConnection(from)
336
+ if (!fromConnection) return
337
+ await copyConnection(to, fromConnection)
338
+ cnx2Socket[to] = socket
339
+ await deleteConnection(from)
302
340
  app.printCnx('AFTER TRANSFER')
303
341
  // send acknowledge to client
304
342
  io.emit('cnx-transfer-ack', to)
305
343
  })
306
344
 
307
- function wait(ms) {
308
- return new Promise(resolve => setTimeout(resolve, ms));
309
- }
310
-
311
345
  /*
312
346
  * Handle websocket client request
313
347
  * Emit in return a 'client-response' message
@@ -371,10 +405,12 @@ export function expressX(prisma, options = {}) {
371
405
  app.log('verbose', `publish channels ${service.name} ${action} ${channelNames}`)
372
406
  for (const channelName of channelNames) {
373
407
  app.log('verbose', `service-event ${service.name} ${action} ${channelName}`)
374
- const connectionList = Object.values(app.connections).filter(cnx => cnx.channelNames.has(channelName))
408
+ // const connectionList = Object.values(app.connections).filter(cnx => cnx.channelNames.has(channelName))
409
+ const connectionList = getChannelConnections(channelName)
375
410
  for (const connection of connectionList) {
376
411
  app.log('verbose', `emit to ${connection.id} ${service.name} ${action} ${result}`)
377
- connection.socket.emit('service-event', {
412
+ const socket = cnx2Socket(connection.id)
413
+ socket.emit('service-event', {
378
414
  name: service.name,
379
415
  action,
380
416
  result,
@@ -385,11 +421,11 @@ export function expressX(prisma, options = {}) {
385
421
  }
386
422
 
387
423
  function joinChannel(channelName, connection) {
388
- connection.channelNames.add(channelName)
424
+ addChannelToConnection(connection, channelName)
389
425
  }
390
426
 
391
427
  function leaveChannel(channelName, connection) {
392
- connection.channelNames.delete(channelName)
428
+ removeChannelFromConnection(connection, channelName)
393
429
  }
394
430
 
395
431
  // enhance `app` with objects and methods