@scpxl/nodejs-framework 1.0.24 → 1.0.25

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.
Files changed (101) hide show
  1. package/README.md +65 -17
  2. package/dist/api-requester/api-requester.d.ts.map +1 -1
  3. package/dist/api-requester/api-requester.js +2 -1
  4. package/dist/api-requester/api-requester.js.map +2 -2
  5. package/dist/application/base-application.d.ts.map +1 -1
  6. package/dist/application/base-application.js +4 -3
  7. package/dist/application/base-application.js.map +2 -2
  8. package/dist/cache/manager.d.ts.map +1 -1
  9. package/dist/cache/manager.js +2 -1
  10. package/dist/cache/manager.js.map +2 -2
  11. package/dist/cli/index.js +7019 -83
  12. package/dist/cli/index.js.map +4 -4
  13. package/dist/cluster/cluster-manager.d.ts +3 -0
  14. package/dist/cluster/cluster-manager.d.ts.map +1 -1
  15. package/dist/cluster/cluster-manager.js +45 -8
  16. package/dist/cluster/cluster-manager.js.map +2 -2
  17. package/dist/database/dynamic-entity-form-decorators.d.ts +2 -2
  18. package/dist/database/dynamic-entity-form-decorators.d.ts.map +1 -1
  19. package/dist/database/dynamic-entity-form-decorators.js.map +1 -1
  20. package/dist/database/dynamic-entity.d.ts +7 -4
  21. package/dist/database/dynamic-entity.d.ts.map +1 -1
  22. package/dist/database/dynamic-entity.js +11 -1
  23. package/dist/database/dynamic-entity.js.map +2 -2
  24. package/dist/database/manager.d.ts.map +1 -1
  25. package/dist/database/manager.js +3 -2
  26. package/dist/database/manager.js.map +2 -2
  27. package/dist/error/error-reporter.d.ts +20 -7
  28. package/dist/error/error-reporter.d.ts.map +1 -1
  29. package/dist/error/error-reporter.js +32 -29
  30. package/dist/error/error-reporter.js.map +2 -2
  31. package/dist/error/index.d.ts +1 -1
  32. package/dist/error/index.d.ts.map +1 -1
  33. package/dist/error/index.js +3 -2
  34. package/dist/error/index.js.map +2 -2
  35. package/dist/event/controller/base.d.ts.map +1 -1
  36. package/dist/event/controller/base.js +2 -1
  37. package/dist/event/controller/base.js.map +2 -2
  38. package/dist/event/manager.d.ts.map +1 -1
  39. package/dist/event/manager.js +5 -4
  40. package/dist/event/manager.js.map +2 -2
  41. package/dist/lifecycle/exit.d.ts.map +1 -1
  42. package/dist/lifecycle/exit.js.map +2 -2
  43. package/dist/logger/logger.d.ts.map +1 -1
  44. package/dist/logger/logger.js +3 -2
  45. package/dist/logger/logger.js.map +2 -2
  46. package/dist/performance/performance-monitor.d.ts.map +1 -1
  47. package/dist/performance/performance-monitor.js +10 -3
  48. package/dist/performance/performance-monitor.js.map +2 -2
  49. package/dist/queue/processor/base.d.ts.map +1 -1
  50. package/dist/queue/processor/base.js +2 -1
  51. package/dist/queue/processor/base.js.map +2 -2
  52. package/dist/redis/manager.d.ts.map +1 -1
  53. package/dist/redis/manager.js +3 -2
  54. package/dist/redis/manager.js.map +2 -2
  55. package/dist/schemas/common.d.ts +197 -0
  56. package/dist/schemas/common.d.ts.map +1 -0
  57. package/dist/schemas/common.js +108 -0
  58. package/dist/schemas/common.js.map +7 -0
  59. package/dist/schemas/index.d.ts +6 -0
  60. package/dist/schemas/index.d.ts.map +1 -0
  61. package/dist/schemas/index.js +2 -0
  62. package/dist/schemas/index.js.map +7 -0
  63. package/dist/util/loader.d.ts.map +1 -1
  64. package/dist/util/loader.js.map +2 -2
  65. package/dist/webserver/controller/base.d.ts.map +1 -1
  66. package/dist/webserver/controller/base.js +4 -4
  67. package/dist/webserver/controller/base.js.map +2 -2
  68. package/dist/webserver/controller/entity.js.map +2 -2
  69. package/dist/webserver/controller/health.d.ts +0 -2
  70. package/dist/webserver/controller/health.d.ts.map +1 -1
  71. package/dist/webserver/controller/health.js +0 -14
  72. package/dist/webserver/controller/health.js.map +2 -2
  73. package/dist/webserver/webserver.d.ts.map +1 -1
  74. package/dist/webserver/webserver.interface.d.ts +2 -2
  75. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  76. package/dist/webserver/webserver.interface.js.map +1 -1
  77. package/dist/webserver/webserver.js +2 -2
  78. package/dist/webserver/webserver.js.map +2 -2
  79. package/dist/websocket/index.d.ts +2 -0
  80. package/dist/websocket/index.d.ts.map +1 -1
  81. package/dist/websocket/index.js +2 -0
  82. package/dist/websocket/index.js.map +2 -2
  83. package/dist/websocket/websocket-auth.d.ts +17 -0
  84. package/dist/websocket/websocket-auth.d.ts.map +1 -0
  85. package/dist/websocket/websocket-auth.js +46 -0
  86. package/dist/websocket/websocket-auth.js.map +7 -0
  87. package/dist/websocket/websocket-client-manager.d.ts.map +1 -1
  88. package/dist/websocket/websocket-client-manager.js +6 -5
  89. package/dist/websocket/websocket-client-manager.js.map +2 -2
  90. package/dist/websocket/websocket-client.d.ts +29 -0
  91. package/dist/websocket/websocket-client.d.ts.map +1 -1
  92. package/dist/websocket/websocket-client.js +97 -3
  93. package/dist/websocket/websocket-client.js.map +2 -2
  94. package/dist/websocket/websocket-server.d.ts +10 -0
  95. package/dist/websocket/websocket-server.d.ts.map +1 -1
  96. package/dist/websocket/websocket-server.js +40 -52
  97. package/dist/websocket/websocket-server.js.map +2 -2
  98. package/dist/websocket/websocket.interface.d.ts +13 -0
  99. package/dist/websocket/websocket.interface.d.ts.map +1 -1
  100. package/dist/websocket/websocket.interface.js.map +2 -2
  101. package/package.json +9 -12
@@ -12,8 +12,7 @@ import path from "path";
12
12
  import { baseDir } from "../index.js";
13
13
  import WebSocketRoomManager from "./websocket-room-manager.js";
14
14
  import logger from "../logger/logger.js";
15
- import { URL } from "url";
16
- import Jwt from "../auth/jwt.js";
15
+ import { WebSocketAuthService } from "./websocket-auth.js";
17
16
  class WebSocketServer extends WebSocketBase {
18
17
  static {
19
18
  __name(this, "WebSocketServer");
@@ -40,6 +39,7 @@ class WebSocketServer extends WebSocketBase {
40
39
  roomManager = new WebSocketRoomManager({
41
40
  clientManager: this.clientManager
42
41
  });
42
+ authService;
43
43
  get rooms() {
44
44
  return this.roomManager.rooms;
45
45
  }
@@ -70,33 +70,13 @@ class WebSocketServer extends WebSocketBase {
70
70
  this.databaseInstance = props.databaseInstance;
71
71
  this.routes = props.routes;
72
72
  this.workerId = props.workerId;
73
+ this.authService = new WebSocketAuthService(props.applicationConfig);
73
74
  }
74
75
  get type() {
75
76
  return "server";
76
77
  }
77
78
  async validateWebSocketAuth(url) {
78
- try {
79
- const parsedUrl = new URL(url, "ws://localhost");
80
- const token = parsedUrl.searchParams.get("token");
81
- if (!token) {
82
- return null;
83
- }
84
- const jwtSecretKey = this.applicationConfig.auth?.jwtSecretKey;
85
- if (!jwtSecretKey) {
86
- throw new Error("JWT secret key not configured");
87
- }
88
- const importedJwtSecretKey = await Jwt.importJwtSecretKey({
89
- jwtSecretKey
90
- });
91
- const { payload } = await Jwt.jwtVerify(token, importedJwtSecretKey);
92
- const userId = parseInt(payload.sub);
93
- if (isNaN(userId)) {
94
- throw new Error("Invalid user ID in token");
95
- }
96
- return { userId, payload };
97
- } catch (error) {
98
- throw new Error(`JWT verification failed: ${error.message}`);
99
- }
79
+ return this.authService.validateAuth(url);
100
80
  }
101
81
  async load() {
102
82
  const libraryControllersDirectory = path.join(baseDir, "websocket", "controllers", "server");
@@ -241,10 +221,6 @@ class WebSocketServer extends WebSocketBase {
241
221
  clientId: parsedMessage.clientId
242
222
  // requireWs: true,
243
223
  });
244
- log(
245
- `GOT A REQUEST TO POTENTIALLY DISCONNECT LCIENT IF THIS CLIENT IS CONNETED HERE, GET CLIENT ------------------------- ${clientToDisconnect ?? "NO CLIENT"}`
246
- );
247
- console.log("clientToDisconnect", clientToDisconnect, "workerId: ", this.workerId);
248
224
  if (clientToDisconnect) {
249
225
  this.clientManager.disconnectClient({
250
226
  clientId: parsedMessage.clientId
@@ -444,7 +420,14 @@ class WebSocketServer extends WebSocketBase {
444
420
  response: serverMessageResponse?.response
445
421
  });
446
422
  if (serverMessageResponse?.response && typeof serverMessageResponse.response === "object" && "error" in serverMessageResponse.response) {
447
- Logger.error({ error: serverMessageResponse.response.error });
423
+ Logger.error({
424
+ error: serverMessageResponse.response.error,
425
+ meta: {
426
+ clientId,
427
+ type: serverMessageResponse.type,
428
+ action: serverMessageResponse.action
429
+ }
430
+ });
448
431
  }
449
432
  }
450
433
  } catch (error) {
@@ -464,32 +447,38 @@ class WebSocketServer extends WebSocketBase {
464
447
  })
465
448
  );
466
449
  }
450
+ /**
451
+ * Check and disconnect inactive clients based on configuration
452
+ * This helps prevent stale connections from accumulating
453
+ */
467
454
  checkInactiveClients() {
468
- const now = Date.now();
469
- if (this.options.disconnectInactiveClients?.enabled && this.options.disconnectInactiveClients.log) {
470
- log("Checking inactive clients...");
471
- }
472
- if (!this.options.disconnectInactiveClients?.enabled) {
455
+ const config = this.options.disconnectInactiveClients;
456
+ if (!config?.enabled || !config.inactiveTime) {
473
457
  return;
474
458
  }
475
- const maxInactiveTime = this.options.disconnectInactiveClients.inactiveTime;
476
- if (!maxInactiveTime) {
477
- return;
459
+ if (config.log) {
460
+ log("Checking inactive clients...");
478
461
  }
462
+ const now = Date.now();
479
463
  const clients = this.clientManager.getClients();
480
- clients.forEach((client) => {
464
+ for (const client of clients) {
481
465
  const inactiveTime = now - client.lastActivity;
482
- if (inactiveTime > maxInactiveTime) {
466
+ if (inactiveTime > config.inactiveTime) {
483
467
  this.clientManager.disconnectClient(client.clientId);
484
- if (this.options.disconnectInactiveClients?.log) {
468
+ if (config.log) {
485
469
  log("Disconnected inactive client", {
486
470
  "Client ID": client.clientId,
487
471
  "Inactive Time": `${inactiveTime}ms`
488
472
  });
489
473
  }
490
474
  }
491
- });
475
+ }
492
476
  }
477
+ /**
478
+ * Broadcast a message to all connected WebSocket clients
479
+ * @param data - The data to broadcast (will be JSON stringified)
480
+ * @param excludeClientId - Optional client ID to exclude from broadcast
481
+ */
493
482
  broadcastToAllClients({
494
483
  data,
495
484
  excludeClientId
@@ -498,18 +487,18 @@ class WebSocketServer extends WebSocketBase {
498
487
  log("Server not started when broadcasting to all clients");
499
488
  return;
500
489
  }
501
- this.server.clients.forEach((client) => {
502
- let excludeClient = false;
503
- if (excludeClientId) {
504
- const clientId = this.clientManager.getClientId({
505
- ws: client
506
- });
507
- excludeClient = clientId === excludeClientId;
490
+ for (const client of this.server.clients) {
491
+ if (client.readyState !== WebSocket.OPEN) {
492
+ continue;
508
493
  }
509
- if (client.readyState === WebSocket.OPEN && !excludeClient) {
510
- client.send(JSON.stringify(data));
494
+ if (excludeClientId) {
495
+ const clientId = this.clientManager.getClientId({ ws: client });
496
+ if (clientId === excludeClientId) {
497
+ continue;
498
+ }
511
499
  }
512
- });
500
+ client.send(JSON.stringify(data));
501
+ }
513
502
  }
514
503
  sendMessageError({ webSocketClientId, error }) {
515
504
  const client = this.clientManager.getClient({
@@ -673,7 +662,6 @@ class WebSocketServer extends WebSocketBase {
673
662
  ...data,
674
663
  workerId: this.workerId
675
664
  };
676
- console.log("SEND CUSTOM MESSAGE:", formattedData);
677
665
  this.redisInstance.publisherClient.publish(WebSocketRedisSubscriberEvent.Custom, JSON.stringify(formattedData));
678
666
  }, "sendCustomMessage");
679
667
  getClients({ userType }) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/websocket-server.ts"],
4
- "sourcesContent": ["import { type RawData, WebSocketServer as WS, WebSocket } from 'ws';\nimport {\n type WebSocketOptions,\n WebSocketRedisSubscriberEvent,\n type WebSocketRoute,\n type WebSocketType,\n} from './websocket.interface.js';\nimport type RedisInstance from '../redis/instance.js';\nimport type QueueManager from '../queue/manager.js';\nimport type DatabaseInstance from '../database/instance.js';\nimport type { WebSocketServerProps } from './websocket-server.interface.js';\nimport WebSocketClientManager from './websocket-client-manager.js';\nimport { generateClientId, log } from './utils.js';\nimport WebSocketBase from './websocket-base.js';\nimport { Logger } from '../logger/index.js';\nimport path from 'path';\nimport { type WebApplicationConfig, baseDir } from '../index.js';\nimport WebSocketRoomManager from './websocket-room-manager.js';\nimport logger from '../logger/logger.js';\nimport type { FastifyInstance } from 'fastify';\nimport { URL } from 'url';\nimport Jwt from '../auth/jwt.js';\n\nexport default class WebSocketServer extends WebSocketBase {\n protected defaultRoutes: WebSocketRoute[] = [\n {\n type: 'system',\n action: 'joinRoom',\n controllerName: 'system',\n },\n {\n type: 'system',\n action: 'leaveRoom',\n controllerName: 'system',\n },\n ];\n\n private server?: WS;\n\n private abortController = new AbortController();\n private workerId: number | null;\n private uniqueInstanceId: string;\n private applicationConfig: WebApplicationConfig;\n private options: WebSocketOptions;\n public clientManager = new WebSocketClientManager();\n private roomManager = new WebSocketRoomManager({\n clientManager: this.clientManager,\n });\n\n public get rooms() {\n return this.roomManager.rooms;\n }\n private redisInstance: RedisInstance;\n private queueManager: QueueManager;\n private databaseInstance: DatabaseInstance;\n\n /** Redis subscriber events */\n private redisSubscriberEvents: string[] = [\n WebSocketRedisSubscriberEvent.ClientConnected,\n WebSocketRedisSubscriberEvent.ClientJoinedRoom,\n WebSocketRedisSubscriberEvent.ClientLeftRoom,\n WebSocketRedisSubscriberEvent.ClientDisconnected,\n WebSocketRedisSubscriberEvent.DisconnectClient,\n WebSocketRedisSubscriberEvent.SendMessage,\n WebSocketRedisSubscriberEvent.SendMessageToAll,\n WebSocketRedisSubscriberEvent.MessageError,\n WebSocketRedisSubscriberEvent.QueueJobCompleted,\n WebSocketRedisSubscriberEvent.QueueJobError,\n WebSocketRedisSubscriberEvent.Custom,\n ];\n\n constructor(props: WebSocketServerProps) {\n super();\n\n this.uniqueInstanceId = props.uniqueInstanceId;\n this.applicationConfig = props.applicationConfig;\n this.options = props.options;\n this.redisInstance = props.redisInstance;\n this.queueManager = props.queueManager;\n this.databaseInstance = props.databaseInstance;\n this.routes = props.routes;\n this.workerId = props.workerId;\n }\n\n public get type(): WebSocketType {\n return 'server';\n }\n\n private async validateWebSocketAuth(\n url: string,\n ): Promise<{ userId: number; payload: Record<string, unknown> } | null> {\n try {\n const parsedUrl = new URL(url, 'ws://localhost');\n const token = parsedUrl.searchParams.get('token');\n\n if (!token) {\n return null; // No token provided, allow unauthenticated connection\n }\n\n // Get JWT secret key from application config\n const jwtSecretKey = this.applicationConfig.auth?.jwtSecretKey;\n\n if (!jwtSecretKey) {\n throw new Error('JWT secret key not configured');\n }\n\n // Import JWT secret key\n const importedJwtSecretKey = await Jwt.importJwtSecretKey({\n jwtSecretKey,\n });\n\n // Verify JWT token\n const { payload } = await Jwt.jwtVerify(token, importedJwtSecretKey);\n\n const userId = parseInt(payload.sub as string);\n\n if (isNaN(userId)) {\n throw new Error('Invalid user ID in token');\n }\n\n return { userId, payload };\n } catch (error: any) {\n throw new Error(`JWT verification failed: ${error.message}`);\n }\n }\n\n public async load(): Promise<void> {\n const libraryControllersDirectory = path.join(baseDir, 'websocket', 'controllers', 'server');\n\n // Configure default routes\n await this.configureRoutes(this.defaultRoutes, libraryControllersDirectory);\n\n // Configure custom routes\n await this.configureRoutes(this.routes, this.options.controllersDirectory);\n }\n\n public async start({ fastifyServer }: { fastifyServer: FastifyInstance }): Promise<{ server: WS }> {\n return new Promise(resolve => {\n const server = new WS({\n noServer: true, // We're handling the server externally\n });\n\n this.server = server;\n\n // Ensure this is called after the server has been properly set up\n this.handleServerStart();\n\n fastifyServer.server.on('upgrade', async (request, socket, head) => {\n if (request.url?.startsWith('/ws')) {\n try {\n // Validate authentication token if provided\n const authenticatedUser = await this.validateWebSocketAuth(request.url);\n\n server.handleUpgrade(request, socket, head, ws => {\n server.emit('connection', ws, request, authenticatedUser);\n });\n } catch (error: any) {\n log('WebSocket authentication failed', { error: error.message });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n }\n } else {\n socket.destroy();\n }\n });\n\n server.on('error', this.handleServerError);\n\n server.on(\n 'connection',\n (ws: WebSocket, request: any, authenticatedUser: { userId: number; payload: any } | null) => {\n this.handleServerClientConnection(ws, authenticatedUser);\n },\n );\n\n // Resolve the promise with the server instance\n resolve({ server });\n });\n }\n\n public async stop(): Promise<void> {\n // Abort all ongoing operations (intervals, etc.)\n this.abortController.abort();\n\n // Clean up Redis subscriber listeners\n this.redisInstance.subscriberClient?.removeListener('message', this.handleSubscriberMessage);\n\n // Unsubscribe from all Redis events\n this.redisSubscriberEvents.forEach(subscriberEventName => {\n this.redisInstance.subscriberClient?.unsubscribe(subscriberEventName);\n });\n\n // Close all client connections and clean up\n if (this.server) {\n this.server.clients.forEach(client => {\n client.removeAllListeners();\n client.close();\n });\n\n this.server.removeAllListeners();\n this.server.close();\n }\n\n // Clean up client manager and room manager\n this.clientManager.cleanup();\n this.roomManager.cleanup();\n\n // Reset managers\n this.clientManager = new WebSocketClientManager();\n this.roomManager = new WebSocketRoomManager({\n clientManager: this.clientManager,\n });\n\n // Create new AbortController for potential restart\n this.abortController = new AbortController();\n\n log('Server stopped');\n }\n\n protected getControllerDependencies(): {\n webSocketServer: WebSocketServer;\n redisInstance: RedisInstance;\n queueManager: QueueManager;\n databaseInstance: DatabaseInstance;\n } {\n return {\n webSocketServer: this,\n redisInstance: this.redisInstance,\n queueManager: this.queueManager,\n databaseInstance: this.databaseInstance,\n };\n }\n\n protected shouldPrintRoutes(): boolean {\n return this.options.debug?.printRoutes ?? false;\n }\n\n private handleServerStart = (): void => {\n if (!this.server) {\n throw new Error('WebSocket server not started');\n }\n\n if (this.options.disconnectInactiveClients?.enabled && this.options.disconnectInactiveClients.intervalCheckTime) {\n // Note: setInterval with signal option requires Node.js 15+\n // TypeScript types may not reflect this, so we use type assertion\n (setInterval as (fn: () => void, ms: number, options?: { signal: AbortSignal }) => NodeJS.Timeout)(\n () => this.checkInactiveClients(),\n this.options.disconnectInactiveClients.intervalCheckTime,\n { signal: this.abortController.signal },\n );\n }\n\n // Go through each event and subscribe to it\n this.redisSubscriberEvents.forEach(subscriberEventName => {\n // Subscribe to event\n this.redisInstance.subscriberClient?.subscribe(subscriberEventName);\n });\n\n // Handle subscriber message\n this.redisInstance.subscriberClient.on('message', this.handleSubscriberMessage);\n\n log('Server started', {\n Host: this.options.host,\n URL: this.options.url,\n });\n\n if (this.options.events?.onServerStarted) {\n this.options.events.onServerStarted({\n webSocketServer: this.server,\n });\n }\n };\n\n /**\n * Handle subscriber message.\n */\n private handleSubscriberMessage = async (channel: string, message: string): Promise<void> => {\n let parsedMessage: { [key: string]: any };\n\n try {\n parsedMessage = JSON.parse(message);\n } catch (error) {\n log('Failed to parse subscriber message', {\n Channel: channel,\n Message: message,\n Error: error,\n });\n\n return;\n }\n\n const includeSender = parsedMessage.includeSender === true;\n\n const isSameWorker = parsedMessage.workerId === this.workerId;\n\n // Check if message is from the same worker\n if (includeSender !== true && isSameWorker) {\n // Ignore the message if it's from the same worker\n return;\n }\n\n log('Incoming subscriber message', {\n Channel: channel,\n // 'Run Same Worker': parsedMessage.includeSender ? 'Yes' : 'No',\n 'Client ID': parsedMessage.clientId ?? '-',\n });\n\n switch (channel) {\n case WebSocketRedisSubscriberEvent.ClientConnected: {\n this.onClientConnect({\n clientId: parsedMessage.clientId,\n lastActivity: parsedMessage.lastActivity,\n user: parsedMessage.user,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.ClientDisconnected: {\n this.onClientDisconnect({\n clientId: parsedMessage.clientId,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.DisconnectClient: {\n const clientToDisconnect = this.clientManager.getClient({\n clientId: parsedMessage.clientId,\n // requireWs: true,\n });\n\n log(\n `GOT A REQUEST TO POTENTIALLY DISCONNECT LCIENT IF THIS CLIENT IS CONNETED HERE, GET CLIENT ------------------------- ${clientToDisconnect ?? 'NO CLIENT'}`,\n );\n\n console.log('clientToDisconnect', clientToDisconnect, 'workerId: ', this.workerId);\n\n if (clientToDisconnect) {\n this.clientManager.disconnectClient({\n clientId: parsedMessage.clientId,\n });\n\n // Remove client from rooms\n this.roomManager.removeClientFromAllRooms({\n clientId: parsedMessage.clientId,\n });\n }\n\n break;\n }\n case WebSocketRedisSubscriberEvent.ClientJoinedRoom: {\n this.onJoinRoom({\n clientId: parsedMessage.clientId,\n roomName: parsedMessage.roomName,\n userData: parsedMessage.user,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.ClientLeftRoom: {\n this.roomManager.removeClientFromRoom({\n roomName: parsedMessage.room,\n clientId: parsedMessage.clientId,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.SendMessage: {\n break;\n }\n case WebSocketRedisSubscriberEvent.SendMessageToAll: {\n this.broadcastToAllClients({ data: parsedMessage });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.MessageError: {\n this.sendMessageError({\n webSocketClientId: parsedMessage.clientId,\n error: parsedMessage.error,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.QueueJobCompleted: {\n // const parsedMessage = JSON.parse(message);\n\n break;\n }\n case WebSocketRedisSubscriberEvent.QueueJobError: {\n // For queue job errors, merge error information into data field\n // This maintains backward compatibility while allowing flexible error data\n parsedMessage.data = {\n ...(parsedMessage.data ?? {}),\n error: parsedMessage.error,\n };\n\n break;\n }\n case WebSocketRedisSubscriberEvent.Custom: {\n // Custom logic is being handled in the app\n\n break;\n }\n default: {\n log('Unknown subscriber message received', {\n Channel: channel,\n Message: message,\n });\n }\n }\n\n if (typeof this.applicationConfig.webSocket?.subscriberEventHandler === 'function') {\n // Execute custom application subscriber event handler\n this.applicationConfig.webSocket.subscriberEventHandler({\n channel,\n message: parsedMessage,\n webSocketServer: this,\n databaseInstance: this.databaseInstance,\n });\n }\n };\n\n private handleServerError = (error: Error): void => {\n Logger.error({ error });\n };\n\n private handleServerClientConnection = (\n ws: WebSocket,\n authenticatedUser?: { userId: number; payload: any } | null,\n ): void => {\n const clientId = generateClientId();\n\n const lastActivity = Date.now();\n\n ws.on('message', (message: RawData) => this.handleClientMessage(ws, message));\n\n ws.on('close', () => {\n this.handleServerClientDisconnection(clientId);\n this.clientManager.removeClient(clientId);\n\n // Clean up event listeners to prevent memory leaks\n ws.removeAllListeners();\n });\n\n try {\n this.clientManager.addClient({\n clientId,\n ws,\n lastActivity,\n user: authenticatedUser,\n });\n\n // Let other workers know that the client has connected\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.ClientConnected,\n JSON.stringify({\n clientId,\n lastActivity,\n workerId: this.workerId,\n user: authenticatedUser,\n }),\n );\n\n // Send authentication success message if user is authenticated\n if (authenticatedUser) {\n this.sendClientMessage(ws, {\n type: 'auth',\n action: 'authenticated',\n data: {\n userId: authenticatedUser.userId,\n message: 'Authentication successful',\n },\n });\n }\n } catch (error) {\n logger.error({ error });\n }\n };\n\n public leaveRoom({ ws, roomName }: { ws: WebSocket; roomName: string }): void {\n const clientId = this.clientManager.getClientId({ ws });\n\n if (!clientId) {\n log('Client ID not found when removing client from room');\n\n return;\n }\n\n // Check if client is in room\n const clientInRoom = this.roomManager.isClientInRoom({\n clientId,\n roomName,\n });\n\n if (!clientInRoom) {\n log('Client not in room when removing client from room', {\n 'Client ID': clientId || '-',\n 'Room Name': roomName,\n });\n\n return;\n }\n\n this.roomManager.removeClientFromRoom({\n roomName,\n clientId,\n });\n\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.ClientLeftRoom,\n JSON.stringify({\n clientId,\n room: roomName,\n workerId: this.workerId,\n }),\n );\n\n // Optionally send a message to the client\n this.sendClientMessage(ws, {\n type: 'user',\n action: 'leftRoom',\n data: {\n roomName,\n },\n });\n }\n\n private onClientConnect({\n clientId,\n lastActivity,\n user,\n }: {\n clientId: string;\n lastActivity: number;\n user?: { userId: number; payload: any } | null;\n }): void {\n this.clientManager.addClient({\n clientId,\n ws: null,\n lastActivity,\n user,\n });\n }\n\n private onClientDisconnect({ clientId }: { clientId: string }): void {\n // Set client as disconnected\n this.clientManager.removeClient(clientId);\n\n // Remove client from rooms\n this.roomManager.removeClientFromAllRooms({ clientId });\n }\n\n private handleServerClientDisconnection = (clientId: string): void => {\n const client = this.clientManager.getClient({\n clientId,\n });\n\n if (!client) {\n log('Client not found when handling server client disconnection', {\n 'Client ID': clientId || '-',\n });\n\n return;\n }\n\n this.onClientDisconnect({ clientId });\n\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.ClientDisconnected,\n JSON.stringify({\n clientId,\n workerId: this.workerId,\n }),\n );\n\n // log('Client disconnected', { ID: clientId });\n };\n\n private handleClientMessage = async (ws: WebSocket, message: RawData): Promise<void> => {\n try {\n const clientId = this.clientManager.getClientId({\n ws,\n });\n\n if (!clientId) {\n log('Client ID not found when handling server message');\n\n return;\n }\n\n // Handle server message\n const serverMessageResponse = await this.handleServerMessage(ws, message, clientId);\n\n if (serverMessageResponse) {\n this.sendClientMessage(ws, {\n type: serverMessageResponse.type,\n action: serverMessageResponse.action,\n response: serverMessageResponse?.response,\n });\n\n if (\n serverMessageResponse?.response &&\n typeof serverMessageResponse.response === 'object' &&\n 'error' in serverMessageResponse.response\n ) {\n // throw new Error(serverMessageResponse?.response?.error);\n\n Logger.error({ error: serverMessageResponse.response.error });\n }\n }\n } catch (error) {\n Logger.error({ error });\n\n log('Error handling client message', {\n Error: error,\n });\n }\n };\n\n protected handleMessageError(clientId: string, error: string): void {\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.MessageError,\n JSON.stringify({\n includeSender: true,\n clientId,\n error,\n }),\n );\n }\n\n private checkInactiveClients(): void {\n const now = Date.now();\n\n if (this.options.disconnectInactiveClients?.enabled && this.options.disconnectInactiveClients.log) {\n log('Checking inactive clients...');\n }\n\n if (!this.options.disconnectInactiveClients?.enabled) {\n return;\n }\n\n const maxInactiveTime = this.options.disconnectInactiveClients.inactiveTime;\n\n if (!maxInactiveTime) {\n return;\n }\n\n const clients = this.clientManager.getClients();\n\n clients.forEach(client => {\n const inactiveTime = now - client.lastActivity;\n\n if (inactiveTime > maxInactiveTime) {\n this.clientManager.disconnectClient(client.clientId);\n\n if (this.options.disconnectInactiveClients?.log) {\n log('Disconnected inactive client', {\n 'Client ID': client.clientId,\n 'Inactive Time': `${inactiveTime}ms`,\n });\n }\n }\n });\n }\n\n public broadcastToAllClients({\n data,\n excludeClientId,\n }: {\n data: { [key: string]: any };\n excludeClientId?: string;\n }): void {\n if (!this.server) {\n log('Server not started when broadcasting to all clients');\n\n return;\n }\n\n this.server.clients.forEach(client => {\n let excludeClient = false;\n\n if (excludeClientId) {\n const clientId = this.clientManager.getClientId({\n ws: client,\n });\n\n excludeClient = clientId === excludeClientId;\n }\n\n if (client.readyState === WebSocket.OPEN && !excludeClient) {\n client.send(JSON.stringify(data));\n }\n });\n }\n\n public sendMessageError({ webSocketClientId, error }: { webSocketClientId: string; error: string }): void {\n const client = this.clientManager.getClient({\n clientId: webSocketClientId,\n });\n\n if (!client) {\n log('Client not found when sending message error', {\n 'Client ID': webSocketClientId || '-',\n Error: error,\n });\n\n return;\n } else if (!client.ws) {\n log('Client WebSocket not found when sending message error', {\n 'Client ID': webSocketClientId || '-',\n Error: error,\n });\n\n return;\n }\n\n this.sendClientMessage(client.ws, {\n type: 'error',\n action: 'message',\n data: {\n error,\n },\n });\n }\n\n // private getClientId({\n // client,\n // }: {\n // client: WebSocket;\n // }): string | undefined {\n // return [...this.connectedClients.entries()].find(\n // ([_, value]) => value.ws === client,\n // )?.[0];\n // }\n\n private onJoinRoom({ clientId, roomName, userData }: { clientId: string; roomName: string; userData: any }): void {\n const client = this.clientManager.getClient({\n clientId,\n });\n\n if (!client) {\n log('Client not found when joining room', {\n 'Client ID': clientId || '-',\n 'Room Name': roomName,\n });\n\n return;\n }\n\n // Check if client can join multiple rooms\n const canJoinMultipleRooms = this.options.rooms?.clientCanJoinMultipleRooms ?? true; // Default to true for backward compatibility\n\n if (!canJoinMultipleRooms && client.roomName) {\n // Remove client from current room before joining new one\n this.roomManager.removeClientFromRoom({\n roomName: client.roomName,\n clientId,\n broadcast: false, // Don't broadcast here, will broadcast after adding to new room\n });\n }\n\n // Update client with user in client manager\n this.clientManager.updateClient({\n clientId,\n key: 'user',\n data: userData,\n });\n\n this.roomManager.addClientToRoom({\n clientId,\n user: userData,\n roomName,\n });\n }\n\n public async joinRoom({\n ws,\n userId,\n userType,\n username,\n roomName,\n }: {\n ws: WebSocket;\n userId?: number;\n userType?: string;\n username?: string;\n roomName: string;\n }) {\n const clientId = this.clientManager.getClientId({ ws });\n\n if (!clientId) {\n // throw new Error('Client ID not found when joining room');\n\n logger.warn({\n message: 'Client ID not found when joining room',\n meta: {\n // 'WebSocket ID': ws?.id || '-',\n 'Room Name': roomName,\n },\n });\n\n return;\n }\n\n // Check if client is already in room\n const isClientInRoom = this.roomManager.isClientInRoom({\n clientId,\n roomName,\n });\n\n if (isClientInRoom) {\n // throw new Error('Client already in room when joining');\n\n logger.warn({\n message: 'Client already in room when joining',\n meta: {\n // 'WebSocket ID': ws?. || '-',\n 'Room Name': roomName,\n 'Client ID': clientId,\n },\n });\n\n return;\n }\n\n let userData: any = {};\n\n // // Get WebSocket client ID\n // const webSocketId = this.clientManager.getClientId({ ws });\n\n if (userId) {\n // Get user email from database\n const dbEntityManager = this.databaseInstance.getEntityManager();\n\n const getUserQuery = 'SELECT email FROM users WHERE id = ?';\n const getUserParams = [userId];\n\n const getUserResult = await dbEntityManager.execute(getUserQuery, getUserParams);\n\n if (!getUserResult || getUserResult.length === 0) {\n throw new Error('User not found in database');\n }\n\n const user = getUserResult[0];\n\n userData = {\n id: userId,\n ...user,\n };\n }\n\n // userData.uniqueId = webSocketId;\n\n if (username) {\n userData.username = username;\n }\n\n userData.userType = userType;\n\n // if user with same email is already connected, disconnect the previous connection\n // const existingClient =\n // this.clientManager.getClientByKey({\n // key: 'user.email',\n // value: user.email,\n // });\n\n // if (existingClient) {\n // if (existingClient.ws) {\n // this.clientManager.disconnectClient({\n // clientId: existingClient.clientId,\n // });\n // } else {\n // // Publish to Redis that we should disconnect this client\n // this.redisInstance.publisherClient.publish(\n // WebSocketRedisSubscriberEvent.DisconnectClient,\n // JSON.stringify({\n // clientId,\n // workerId: this.workerId,\n // }),\n // );\n // }\n // }\n\n this.onJoinRoom({\n clientId,\n roomName,\n userData,\n });\n\n // Let other workers know that the client has joined the room\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.ClientJoinedRoom,\n JSON.stringify({\n clientId,\n user: userData,\n roomName,\n workerId: this.workerId,\n }),\n );\n\n return true;\n }\n\n public sendClientMessage = (ws: WebSocket, data: unknown, binary: boolean = false): void => {\n const webSocketMessage = JSON.stringify(data);\n\n ws.send(webSocketMessage, { binary });\n };\n\n public sendMessage = ({ data }: { data: unknown }): void => {\n const formattedData = {\n ...(data as object),\n workerId: this.workerId,\n };\n\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.SendMessage,\n JSON.stringify(formattedData),\n );\n };\n\n public sendMessageToAll = ({ data }: { data: unknown }): void => {\n const formattedData = {\n ...(data as object),\n workerId: this.workerId,\n };\n\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.SendMessageToAll,\n JSON.stringify(formattedData),\n );\n };\n\n public sendCustomMessage = ({ data }: { data: unknown }): void => {\n const formattedData = {\n ...(data as object),\n workerId: this.workerId,\n };\n\n console.log('SEND CUSTOM MESSAGE:', formattedData);\n\n this.redisInstance.publisherClient.publish(WebSocketRedisSubscriberEvent.Custom, JSON.stringify(formattedData));\n };\n\n public getClients({ userType }: { userType?: string }): any[] {\n return this.clientManager.getClients({ userType });\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { type RawData, WebSocketServer as WS, WebSocket } from 'ws';\nimport {\n type WebSocketOptions,\n WebSocketRedisSubscriberEvent,\n type WebSocketRoute,\n type WebSocketType,\n} from './websocket.interface.js';\nimport type RedisInstance from '../redis/instance.js';\nimport type QueueManager from '../queue/manager.js';\nimport type DatabaseInstance from '../database/instance.js';\nimport type { WebSocketServerProps } from './websocket-server.interface.js';\nimport WebSocketClientManager from './websocket-client-manager.js';\nimport { generateClientId, log } from './utils.js';\nimport WebSocketBase from './websocket-base.js';\nimport { Logger } from '../logger/index.js';\nimport path from 'path';\nimport { type WebApplicationConfig, baseDir } from '../index.js';\nimport WebSocketRoomManager from './websocket-room-manager.js';\nimport logger from '../logger/logger.js';\nimport type { FastifyInstance } from 'fastify';\nimport { WebSocketAuthService } from './websocket-auth.js';\n\nexport default class WebSocketServer extends WebSocketBase {\n protected defaultRoutes: WebSocketRoute[] = [\n {\n type: 'system',\n action: 'joinRoom',\n controllerName: 'system',\n },\n {\n type: 'system',\n action: 'leaveRoom',\n controllerName: 'system',\n },\n ];\n\n private server?: WS;\n\n private abortController = new AbortController();\n private workerId: number | null;\n private uniqueInstanceId: string;\n private applicationConfig: WebApplicationConfig;\n private options: WebSocketOptions;\n public clientManager = new WebSocketClientManager();\n private roomManager = new WebSocketRoomManager({\n clientManager: this.clientManager,\n });\n private authService: WebSocketAuthService;\n\n public get rooms() {\n return this.roomManager.rooms;\n }\n private redisInstance: RedisInstance;\n private queueManager: QueueManager;\n private databaseInstance: DatabaseInstance;\n\n /** Redis subscriber events */\n private redisSubscriberEvents: string[] = [\n WebSocketRedisSubscriberEvent.ClientConnected,\n WebSocketRedisSubscriberEvent.ClientJoinedRoom,\n WebSocketRedisSubscriberEvent.ClientLeftRoom,\n WebSocketRedisSubscriberEvent.ClientDisconnected,\n WebSocketRedisSubscriberEvent.DisconnectClient,\n WebSocketRedisSubscriberEvent.SendMessage,\n WebSocketRedisSubscriberEvent.SendMessageToAll,\n WebSocketRedisSubscriberEvent.MessageError,\n WebSocketRedisSubscriberEvent.QueueJobCompleted,\n WebSocketRedisSubscriberEvent.QueueJobError,\n WebSocketRedisSubscriberEvent.Custom,\n ];\n\n constructor(props: WebSocketServerProps) {\n super();\n\n this.uniqueInstanceId = props.uniqueInstanceId;\n this.applicationConfig = props.applicationConfig;\n this.options = props.options;\n this.redisInstance = props.redisInstance;\n this.queueManager = props.queueManager;\n this.databaseInstance = props.databaseInstance;\n this.routes = props.routes;\n this.workerId = props.workerId;\n this.authService = new WebSocketAuthService(props.applicationConfig);\n }\n\n public get type(): WebSocketType {\n return 'server';\n }\n\n private async validateWebSocketAuth(\n url: string,\n ): Promise<{ userId: number; payload: Record<string, unknown> } | null> {\n return this.authService.validateAuth(url);\n }\n\n public async load(): Promise<void> {\n const libraryControllersDirectory = path.join(baseDir, 'websocket', 'controllers', 'server');\n\n // Configure default routes\n await this.configureRoutes(this.defaultRoutes, libraryControllersDirectory);\n\n // Configure custom routes\n await this.configureRoutes(this.routes, this.options.controllersDirectory);\n }\n\n public async start({ fastifyServer }: { fastifyServer: FastifyInstance }): Promise<{ server: WS }> {\n return new Promise(resolve => {\n const server = new WS({\n noServer: true, // We're handling the server externally\n });\n\n this.server = server;\n\n // Ensure this is called after the server has been properly set up\n this.handleServerStart();\n\n fastifyServer.server.on('upgrade', async (request, socket, head) => {\n if (request.url?.startsWith('/ws')) {\n try {\n // Validate authentication token if provided\n const authenticatedUser = await this.validateWebSocketAuth(request.url);\n\n server.handleUpgrade(request, socket, head, ws => {\n server.emit('connection', ws, request, authenticatedUser);\n });\n } catch (error: any) {\n log('WebSocket authentication failed', { error: error.message });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n }\n } else {\n socket.destroy();\n }\n });\n\n server.on('error', this.handleServerError);\n\n server.on(\n 'connection',\n (ws: WebSocket, request: any, authenticatedUser: { userId: number; payload: any } | null) => {\n this.handleServerClientConnection(ws, authenticatedUser);\n },\n );\n\n // Resolve the promise with the server instance\n resolve({ server });\n });\n }\n\n public async stop(): Promise<void> {\n // Abort all ongoing operations (intervals, etc.)\n this.abortController.abort();\n\n // Clean up Redis subscriber listeners\n this.redisInstance.subscriberClient?.removeListener('message', this.handleSubscriberMessage);\n\n // Unsubscribe from all Redis events\n this.redisSubscriberEvents.forEach(subscriberEventName => {\n this.redisInstance.subscriberClient?.unsubscribe(subscriberEventName);\n });\n\n // Close all client connections and clean up\n if (this.server) {\n this.server.clients.forEach(client => {\n client.removeAllListeners();\n client.close();\n });\n\n this.server.removeAllListeners();\n this.server.close();\n }\n\n // Clean up client manager and room manager\n this.clientManager.cleanup();\n this.roomManager.cleanup();\n\n // Reset managers\n this.clientManager = new WebSocketClientManager();\n this.roomManager = new WebSocketRoomManager({\n clientManager: this.clientManager,\n });\n\n // Create new AbortController for potential restart\n this.abortController = new AbortController();\n\n log('Server stopped');\n }\n\n protected getControllerDependencies(): {\n webSocketServer: WebSocketServer;\n redisInstance: RedisInstance;\n queueManager: QueueManager;\n databaseInstance: DatabaseInstance;\n } {\n return {\n webSocketServer: this,\n redisInstance: this.redisInstance,\n queueManager: this.queueManager,\n databaseInstance: this.databaseInstance,\n };\n }\n\n protected shouldPrintRoutes(): boolean {\n return this.options.debug?.printRoutes ?? false;\n }\n\n private handleServerStart = (): void => {\n if (!this.server) {\n throw new Error('WebSocket server not started');\n }\n\n if (this.options.disconnectInactiveClients?.enabled && this.options.disconnectInactiveClients.intervalCheckTime) {\n // Note: setInterval with signal option requires Node.js 15+\n // TypeScript types may not reflect this, so we use type assertion\n (setInterval as (fn: () => void, ms: number, options?: { signal: AbortSignal }) => NodeJS.Timeout)(\n () => this.checkInactiveClients(),\n this.options.disconnectInactiveClients.intervalCheckTime,\n { signal: this.abortController.signal },\n );\n }\n\n // Go through each event and subscribe to it\n this.redisSubscriberEvents.forEach(subscriberEventName => {\n // Subscribe to event\n this.redisInstance.subscriberClient?.subscribe(subscriberEventName);\n });\n\n // Handle subscriber message\n this.redisInstance.subscriberClient.on('message', this.handleSubscriberMessage);\n\n log('Server started', {\n Host: this.options.host,\n URL: this.options.url,\n });\n\n if (this.options.events?.onServerStarted) {\n this.options.events.onServerStarted({\n webSocketServer: this.server,\n });\n }\n };\n\n /**\n * Handle subscriber message.\n */\n private handleSubscriberMessage = async (channel: string, message: string): Promise<void> => {\n let parsedMessage: { [key: string]: any };\n\n try {\n parsedMessage = JSON.parse(message);\n } catch (error) {\n log('Failed to parse subscriber message', {\n Channel: channel,\n Message: message,\n Error: error,\n });\n\n return;\n }\n\n const includeSender = parsedMessage.includeSender === true;\n\n const isSameWorker = parsedMessage.workerId === this.workerId;\n\n // Check if message is from the same worker\n if (includeSender !== true && isSameWorker) {\n // Ignore the message if it's from the same worker\n return;\n }\n\n log('Incoming subscriber message', {\n Channel: channel,\n // 'Run Same Worker': parsedMessage.includeSender ? 'Yes' : 'No',\n 'Client ID': parsedMessage.clientId ?? '-',\n });\n\n switch (channel) {\n case WebSocketRedisSubscriberEvent.ClientConnected: {\n this.onClientConnect({\n clientId: parsedMessage.clientId,\n lastActivity: parsedMessage.lastActivity,\n user: parsedMessage.user,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.ClientDisconnected: {\n this.onClientDisconnect({\n clientId: parsedMessage.clientId,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.DisconnectClient: {\n const clientToDisconnect = this.clientManager.getClient({\n clientId: parsedMessage.clientId,\n // requireWs: true,\n });\n\n if (clientToDisconnect) {\n this.clientManager.disconnectClient({\n clientId: parsedMessage.clientId,\n });\n\n // Remove client from rooms\n this.roomManager.removeClientFromAllRooms({\n clientId: parsedMessage.clientId,\n });\n }\n\n break;\n }\n case WebSocketRedisSubscriberEvent.ClientJoinedRoom: {\n this.onJoinRoom({\n clientId: parsedMessage.clientId,\n roomName: parsedMessage.roomName,\n userData: parsedMessage.user,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.ClientLeftRoom: {\n this.roomManager.removeClientFromRoom({\n roomName: parsedMessage.room,\n clientId: parsedMessage.clientId,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.SendMessage: {\n break;\n }\n case WebSocketRedisSubscriberEvent.SendMessageToAll: {\n this.broadcastToAllClients({ data: parsedMessage });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.MessageError: {\n this.sendMessageError({\n webSocketClientId: parsedMessage.clientId,\n error: parsedMessage.error,\n });\n\n break;\n }\n case WebSocketRedisSubscriberEvent.QueueJobCompleted: {\n // const parsedMessage = JSON.parse(message);\n\n break;\n }\n case WebSocketRedisSubscriberEvent.QueueJobError: {\n // For queue job errors, merge error information into data field\n // This maintains backward compatibility while allowing flexible error data\n parsedMessage.data = {\n ...(parsedMessage.data ?? {}),\n error: parsedMessage.error,\n };\n\n break;\n }\n case WebSocketRedisSubscriberEvent.Custom: {\n // Custom logic is being handled in the app\n\n break;\n }\n default: {\n log('Unknown subscriber message received', {\n Channel: channel,\n Message: message,\n });\n }\n }\n\n if (typeof this.applicationConfig.webSocket?.subscriberEventHandler === 'function') {\n // Execute custom application subscriber event handler\n this.applicationConfig.webSocket.subscriberEventHandler({\n channel,\n message: parsedMessage,\n webSocketServer: this,\n databaseInstance: this.databaseInstance,\n });\n }\n };\n\n private handleServerError = (error: Error): void => {\n Logger.error({ error });\n };\n\n private handleServerClientConnection = (\n ws: WebSocket,\n authenticatedUser?: { userId: number; payload: any } | null,\n ): void => {\n const clientId = generateClientId();\n\n const lastActivity = Date.now();\n\n ws.on('message', (message: RawData) => this.handleClientMessage(ws, message));\n\n ws.on('close', () => {\n this.handleServerClientDisconnection(clientId);\n this.clientManager.removeClient(clientId);\n\n // Clean up event listeners to prevent memory leaks\n ws.removeAllListeners();\n });\n\n try {\n this.clientManager.addClient({\n clientId,\n ws,\n lastActivity,\n user: authenticatedUser,\n });\n\n // Let other workers know that the client has connected\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.ClientConnected,\n JSON.stringify({\n clientId,\n lastActivity,\n workerId: this.workerId,\n user: authenticatedUser,\n }),\n );\n\n // Send authentication success message if user is authenticated\n if (authenticatedUser) {\n this.sendClientMessage(ws, {\n type: 'auth',\n action: 'authenticated',\n data: {\n userId: authenticatedUser.userId,\n message: 'Authentication successful',\n },\n });\n }\n } catch (error) {\n logger.error({ error });\n }\n };\n\n public leaveRoom({ ws, roomName }: { ws: WebSocket; roomName: string }): void {\n const clientId = this.clientManager.getClientId({ ws });\n\n if (!clientId) {\n log('Client ID not found when removing client from room');\n\n return;\n }\n\n // Check if client is in room\n const clientInRoom = this.roomManager.isClientInRoom({\n clientId,\n roomName,\n });\n\n if (!clientInRoom) {\n log('Client not in room when removing client from room', {\n 'Client ID': clientId || '-',\n 'Room Name': roomName,\n });\n\n return;\n }\n\n this.roomManager.removeClientFromRoom({\n roomName,\n clientId,\n });\n\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.ClientLeftRoom,\n JSON.stringify({\n clientId,\n room: roomName,\n workerId: this.workerId,\n }),\n );\n\n // Optionally send a message to the client\n this.sendClientMessage(ws, {\n type: 'user',\n action: 'leftRoom',\n data: {\n roomName,\n },\n });\n }\n\n private onClientConnect({\n clientId,\n lastActivity,\n user,\n }: {\n clientId: string;\n lastActivity: number;\n user?: { userId: number; payload: any } | null;\n }): void {\n this.clientManager.addClient({\n clientId,\n ws: null,\n lastActivity,\n user,\n });\n }\n\n private onClientDisconnect({ clientId }: { clientId: string }): void {\n // Set client as disconnected\n this.clientManager.removeClient(clientId);\n\n // Remove client from rooms\n this.roomManager.removeClientFromAllRooms({ clientId });\n }\n\n private handleServerClientDisconnection = (clientId: string): void => {\n const client = this.clientManager.getClient({\n clientId,\n });\n\n if (!client) {\n log('Client not found when handling server client disconnection', {\n 'Client ID': clientId || '-',\n });\n\n return;\n }\n\n this.onClientDisconnect({ clientId });\n\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.ClientDisconnected,\n JSON.stringify({\n clientId,\n workerId: this.workerId,\n }),\n );\n\n // log('Client disconnected', { ID: clientId });\n };\n\n private handleClientMessage = async (ws: WebSocket, message: RawData): Promise<void> => {\n try {\n const clientId = this.clientManager.getClientId({\n ws,\n });\n\n if (!clientId) {\n log('Client ID not found when handling server message');\n\n return;\n }\n\n // Handle server message\n const serverMessageResponse = await this.handleServerMessage(ws, message, clientId);\n\n if (serverMessageResponse) {\n this.sendClientMessage(ws, {\n type: serverMessageResponse.type,\n action: serverMessageResponse.action,\n response: serverMessageResponse?.response,\n });\n\n if (\n serverMessageResponse?.response &&\n typeof serverMessageResponse.response === 'object' &&\n 'error' in serverMessageResponse.response\n ) {\n // Log error but don't throw to prevent connection disruption\n Logger.error({\n error: serverMessageResponse.response.error,\n meta: {\n clientId,\n type: serverMessageResponse.type,\n action: serverMessageResponse.action,\n },\n });\n }\n }\n } catch (error) {\n Logger.error({ error });\n\n log('Error handling client message', {\n Error: error,\n });\n }\n };\n\n protected handleMessageError(clientId: string, error: string): void {\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.MessageError,\n JSON.stringify({\n includeSender: true,\n clientId,\n error,\n }),\n );\n }\n\n /**\n * Check and disconnect inactive clients based on configuration\n * This helps prevent stale connections from accumulating\n */\n private checkInactiveClients(): void {\n const config = this.options.disconnectInactiveClients;\n\n if (!config?.enabled || !config.inactiveTime) {\n return;\n }\n\n if (config.log) {\n log('Checking inactive clients...');\n }\n\n const now = Date.now();\n const clients = this.clientManager.getClients();\n\n for (const client of clients) {\n const inactiveTime = now - client.lastActivity;\n\n if (inactiveTime > config.inactiveTime) {\n this.clientManager.disconnectClient(client.clientId);\n\n if (config.log) {\n log('Disconnected inactive client', {\n 'Client ID': client.clientId,\n 'Inactive Time': `${inactiveTime}ms`,\n });\n }\n }\n }\n }\n\n /**\n * Broadcast a message to all connected WebSocket clients\n * @param data - The data to broadcast (will be JSON stringified)\n * @param excludeClientId - Optional client ID to exclude from broadcast\n */\n public broadcastToAllClients({\n data,\n excludeClientId,\n }: {\n data: { [key: string]: any };\n excludeClientId?: string;\n }): void {\n if (!this.server) {\n log('Server not started when broadcasting to all clients');\n return;\n }\n\n for (const client of this.server.clients) {\n if (client.readyState !== WebSocket.OPEN) {\n continue;\n }\n\n // Skip excluded client if specified\n if (excludeClientId) {\n const clientId = this.clientManager.getClientId({ ws: client });\n if (clientId === excludeClientId) {\n continue;\n }\n }\n\n client.send(JSON.stringify(data));\n }\n }\n\n public sendMessageError({ webSocketClientId, error }: { webSocketClientId: string; error: string }): void {\n const client = this.clientManager.getClient({\n clientId: webSocketClientId,\n });\n\n if (!client) {\n log('Client not found when sending message error', {\n 'Client ID': webSocketClientId || '-',\n Error: error,\n });\n\n return;\n } else if (!client.ws) {\n log('Client WebSocket not found when sending message error', {\n 'Client ID': webSocketClientId || '-',\n Error: error,\n });\n\n return;\n }\n\n this.sendClientMessage(client.ws, {\n type: 'error',\n action: 'message',\n data: {\n error,\n },\n });\n }\n\n // private getClientId({\n // client,\n // }: {\n // client: WebSocket;\n // }): string | undefined {\n // return [...this.connectedClients.entries()].find(\n // ([_, value]) => value.ws === client,\n // )?.[0];\n // }\n\n private onJoinRoom({ clientId, roomName, userData }: { clientId: string; roomName: string; userData: any }): void {\n const client = this.clientManager.getClient({\n clientId,\n });\n\n if (!client) {\n log('Client not found when joining room', {\n 'Client ID': clientId || '-',\n 'Room Name': roomName,\n });\n\n return;\n }\n\n // Check if client can join multiple rooms\n const canJoinMultipleRooms = this.options.rooms?.clientCanJoinMultipleRooms ?? true; // Default to true for backward compatibility\n\n if (!canJoinMultipleRooms && client.roomName) {\n // Remove client from current room before joining new one\n this.roomManager.removeClientFromRoom({\n roomName: client.roomName,\n clientId,\n broadcast: false, // Don't broadcast here, will broadcast after adding to new room\n });\n }\n\n // Update client with user in client manager\n this.clientManager.updateClient({\n clientId,\n key: 'user',\n data: userData,\n });\n\n this.roomManager.addClientToRoom({\n clientId,\n user: userData,\n roomName,\n });\n }\n\n public async joinRoom({\n ws,\n userId,\n userType,\n username,\n roomName,\n }: {\n ws: WebSocket;\n userId?: number;\n userType?: string;\n username?: string;\n roomName: string;\n }) {\n const clientId = this.clientManager.getClientId({ ws });\n\n if (!clientId) {\n // throw new Error('Client ID not found when joining room');\n\n logger.warn({\n message: 'Client ID not found when joining room',\n meta: {\n // 'WebSocket ID': ws?.id || '-',\n 'Room Name': roomName,\n },\n });\n\n return;\n }\n\n // Check if client is already in room\n const isClientInRoom = this.roomManager.isClientInRoom({\n clientId,\n roomName,\n });\n\n if (isClientInRoom) {\n // throw new Error('Client already in room when joining');\n\n logger.warn({\n message: 'Client already in room when joining',\n meta: {\n // 'WebSocket ID': ws?. || '-',\n 'Room Name': roomName,\n 'Client ID': clientId,\n },\n });\n\n return;\n }\n\n let userData: any = {};\n\n // // Get WebSocket client ID\n // const webSocketId = this.clientManager.getClientId({ ws });\n\n if (userId) {\n // Get user email from database\n const dbEntityManager = this.databaseInstance.getEntityManager();\n\n const getUserQuery = 'SELECT email FROM users WHERE id = ?';\n const getUserParams = [userId];\n\n const getUserResult = await dbEntityManager.execute(getUserQuery, getUserParams);\n\n if (!getUserResult || getUserResult.length === 0) {\n throw new Error('User not found in database');\n }\n\n const user = getUserResult[0];\n\n userData = {\n id: userId,\n ...user,\n };\n }\n\n // userData.uniqueId = webSocketId;\n\n if (username) {\n userData.username = username;\n }\n\n userData.userType = userType;\n\n // if user with same email is already connected, disconnect the previous connection\n // const existingClient =\n // this.clientManager.getClientByKey({\n // key: 'user.email',\n // value: user.email,\n // });\n\n // if (existingClient) {\n // if (existingClient.ws) {\n // this.clientManager.disconnectClient({\n // clientId: existingClient.clientId,\n // });\n // } else {\n // // Publish to Redis that we should disconnect this client\n // this.redisInstance.publisherClient.publish(\n // WebSocketRedisSubscriberEvent.DisconnectClient,\n // JSON.stringify({\n // clientId,\n // workerId: this.workerId,\n // }),\n // );\n // }\n // }\n\n this.onJoinRoom({\n clientId,\n roomName,\n userData,\n });\n\n // Let other workers know that the client has joined the room\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.ClientJoinedRoom,\n JSON.stringify({\n clientId,\n user: userData,\n roomName,\n workerId: this.workerId,\n }),\n );\n\n return true;\n }\n\n public sendClientMessage = (ws: WebSocket, data: unknown, binary: boolean = false): void => {\n const webSocketMessage = JSON.stringify(data);\n\n ws.send(webSocketMessage, { binary });\n };\n\n public sendMessage = ({ data }: { data: unknown }): void => {\n const formattedData = {\n ...(data as object),\n workerId: this.workerId,\n };\n\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.SendMessage,\n JSON.stringify(formattedData),\n );\n };\n\n public sendMessageToAll = ({ data }: { data: unknown }): void => {\n const formattedData = {\n ...(data as object),\n workerId: this.workerId,\n };\n\n this.redisInstance.publisherClient.publish(\n WebSocketRedisSubscriberEvent.SendMessageToAll,\n JSON.stringify(formattedData),\n );\n };\n\n public sendCustomMessage = ({ data }: { data: unknown }): void => {\n const formattedData = {\n ...(data as object),\n workerId: this.workerId,\n };\n\n this.redisInstance.publisherClient.publish(WebSocketRedisSubscriberEvent.Custom, JSON.stringify(formattedData));\n };\n\n public getClients({ userType }: { userType?: string }): any[] {\n return this.clientManager.getClients({ userType });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -42,6 +42,19 @@ export interface WebSocketEventsConfig {
42
42
  queueManager: QueueManager;
43
43
  databaseInstance: DatabaseInstance;
44
44
  }) => void;
45
+ /** Fired when attempting to reconnect */
46
+ onReconnecting?: ({ attempt, delay }: {
47
+ attempt: number;
48
+ delay: number;
49
+ }) => void;
50
+ /** Fired when reconnection is successful */
51
+ onReconnected?: ({ clientId }: {
52
+ clientId?: string;
53
+ }) => void;
54
+ /** Fired when max reconnection attempts are reached */
55
+ onReconnectFailed?: ({ attempts }: {
56
+ attempts: number;
57
+ }) => void;
45
58
  }
46
59
  export interface WebSocketOptions {
47
60
  /** WebSocket type */
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.interface.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket.interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"websocket.interface.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket.interface.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/websocket.interface.ts"],
4
- "sourcesContent": ["import type { WebSocket, WebSocketServer } from 'ws';\nimport type DatabaseInstance from '../database/instance.js';\nimport type QueueManager from '../queue/manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport type { WebSocketServerBaseControllerType } from './controller/server/base.interface.js';\nimport type { WebSocketClientBaseControllerType } from './controller/client/base.interface.js';\n\nexport type WebSocketType = 'server' | 'client';\n\nexport interface WebSocketDebugOptions {\n printRoutes?: boolean;\n printConnectedClients?: 'simple' | 'table';\n}\n\nexport interface WebSocketMessage<TData = unknown> {\n type: string;\n action: string;\n data: TData;\n}\n\nexport interface WebSocketEventsConfig {\n onServerStarted?: ({ webSocketServer }: { webSocketServer: WebSocketServer }) => void;\n onConnected?: ({\n ws,\n clientId,\n joinRoom,\n }: {\n ws: WebSocket;\n clientId: string;\n joinRoom({\n userId,\n userType,\n username,\n roomName,\n }: {\n userId?: string;\n userType?: string;\n username?: string;\n roomName: string;\n }): void;\n }) => void;\n onDisconnected?: ({ clientId }: { clientId?: string }) => void;\n onError?: ({ error }: { error: Error }) => void;\n onMessage?: <TData = unknown>({\n ws,\n clientId,\n data,\n redisInstance,\n queueManager,\n databaseInstance,\n }: {\n ws: WebSocket;\n clientId: string;\n data: WebSocketMessage<TData>;\n redisInstance: RedisInstance;\n queueManager: QueueManager;\n databaseInstance: DatabaseInstance;\n }) => void;\n}\n\nexport interface WebSocketOptions {\n /** WebSocket type */\n type: WebSocketType;\n\n /** WebSocket host */\n host?: string;\n\n /** WebSocket URL */\n url: string;\n\n /** WebSocket controllers directory */\n controllersDirectory: string;\n\n /** Disconnect inactive WebSocket clients configuration */\n disconnectInactiveClients?: {\n /** Whether to enable disconnection of inactive WebSocket clients */\n enabled?: boolean;\n\n /** Interval check time in milliseconds */\n intervalCheckTime?: number;\n\n /** Inactive time in milliseconds */\n inactiveTime?: number;\n\n /** Whether to log disconnection of inactive WebSocket clients */\n log?: boolean;\n };\n\n rooms?: {\n enabled?: boolean;\n clientCanJoinMultipleRooms?: boolean;\n };\n\n /** WebSocket debug options */\n debug?: WebSocketDebugOptions;\n\n /** WebSocket events */\n events?: WebSocketEventsConfig;\n}\n\nexport interface WebSocketRoute {\n /** WebSocket route type */\n type: string;\n\n /** WebSocket route controller name */\n controllerName: string;\n\n /** WebSocket route controller */\n controller?: WebSocketServerBaseControllerType | WebSocketClientBaseControllerType;\n\n /** WebSocket route action */\n action: string;\n}\n\nexport interface WebSocketConstructorParams {\n /** WebSocket options */\n options: WebSocketOptions;\n\n /** WebSocket routes */\n routes: WebSocketRoute[];\n\n /** Redis instance */\n redisInstance: RedisInstance;\n\n /** Queue manager */\n queueManager: QueueManager;\n\n /** Database instance */\n databaseInstance: DatabaseInstance;\n}\n\nexport interface WebSocketConnectedClientData {\n /** WebSocket client */\n ws: WebSocket | null;\n\n /** Last activity time */\n lastActivity: number;\n\n /** Client username */\n username?: string;\n}\n\nexport interface WebSocketMessageResponse {\n error?: string;\n}\n\nexport interface WebSocketMessageHandler<TData = unknown, TResponse = WebSocketMessageResponse> {\n (ws: WebSocket, clientId: string, data: TData): Promise<TResponse> | TResponse;\n}\n\nexport enum WebSocketRedisSubscriberEvent {\n ClientConnected = 'clientConnected',\n ClientDisconnected = 'clientDisconnected',\n DisconnectClient = 'disconnectClient',\n ClientJoinedRoom = 'clientJoinedRoom',\n ClientLeftRoom = 'clientLeftRoom',\n SendMessage = 'sendMessage',\n SendMessageToAll = 'sendMessageToAll',\n MessageError = 'messageError',\n QueueJobCompleted = 'queueJobCompleted',\n QueueJobError = 'queueJobError',\n Custom = 'custom',\n}\n"],
5
- "mappings": "AAsJO,IAAK,gCAAL,kBAAKA,mCAAL;AACL,EAAAA,+BAAA,qBAAkB;AAClB,EAAAA,+BAAA,wBAAqB;AACrB,EAAAA,+BAAA,sBAAmB;AACnB,EAAAA,+BAAA,sBAAmB;AACnB,EAAAA,+BAAA,oBAAiB;AACjB,EAAAA,+BAAA,iBAAc;AACd,EAAAA,+BAAA,sBAAmB;AACnB,EAAAA,+BAAA,kBAAe;AACf,EAAAA,+BAAA,uBAAoB;AACpB,EAAAA,+BAAA,mBAAgB;AAChB,EAAAA,+BAAA,YAAS;AAXC,SAAAA;AAAA,GAAA;",
4
+ "sourcesContent": ["import type { WebSocket, WebSocketServer } from 'ws';\nimport type DatabaseInstance from '../database/instance.js';\nimport type QueueManager from '../queue/manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport type { WebSocketServerBaseControllerType } from './controller/server/base.interface.js';\nimport type { WebSocketClientBaseControllerType } from './controller/client/base.interface.js';\n\nexport type WebSocketType = 'server' | 'client';\n\nexport interface WebSocketDebugOptions {\n printRoutes?: boolean;\n printConnectedClients?: 'simple' | 'table';\n}\n\nexport interface WebSocketMessage<TData = unknown> {\n type: string;\n action: string;\n data: TData;\n}\n\nexport interface WebSocketEventsConfig {\n onServerStarted?: ({ webSocketServer }: { webSocketServer: WebSocketServer }) => void;\n onConnected?: ({\n ws,\n clientId,\n joinRoom,\n }: {\n ws: WebSocket;\n clientId: string;\n joinRoom({\n userId,\n userType,\n username,\n roomName,\n }: {\n userId?: string;\n userType?: string;\n username?: string;\n roomName: string;\n }): void;\n }) => void;\n onDisconnected?: ({ clientId }: { clientId?: string }) => void;\n onError?: ({ error }: { error: Error }) => void;\n onMessage?: <TData = unknown>({\n ws,\n clientId,\n data,\n redisInstance,\n queueManager,\n databaseInstance,\n }: {\n ws: WebSocket;\n clientId: string;\n data: WebSocketMessage<TData>;\n redisInstance: RedisInstance;\n queueManager: QueueManager;\n databaseInstance: DatabaseInstance;\n }) => void;\n /** Fired when attempting to reconnect */\n onReconnecting?: ({ attempt, delay }: { attempt: number; delay: number }) => void;\n /** Fired when reconnection is successful */\n onReconnected?: ({ clientId }: { clientId?: string }) => void;\n /** Fired when max reconnection attempts are reached */\n onReconnectFailed?: ({ attempts }: { attempts: number }) => void;\n}\n\nexport interface WebSocketOptions {\n /** WebSocket type */\n type: WebSocketType;\n\n /** WebSocket host */\n host?: string;\n\n /** WebSocket URL */\n url: string;\n\n /** WebSocket controllers directory */\n controllersDirectory: string;\n\n /** Disconnect inactive WebSocket clients configuration */\n disconnectInactiveClients?: {\n /** Whether to enable disconnection of inactive WebSocket clients */\n enabled?: boolean;\n\n /** Interval check time in milliseconds */\n intervalCheckTime?: number;\n\n /** Inactive time in milliseconds */\n inactiveTime?: number;\n\n /** Whether to log disconnection of inactive WebSocket clients */\n log?: boolean;\n };\n\n rooms?: {\n enabled?: boolean;\n clientCanJoinMultipleRooms?: boolean;\n };\n\n /** WebSocket debug options */\n debug?: WebSocketDebugOptions;\n\n /** WebSocket events */\n events?: WebSocketEventsConfig;\n}\n\nexport interface WebSocketRoute {\n /** WebSocket route type */\n type: string;\n\n /** WebSocket route controller name */\n controllerName: string;\n\n /** WebSocket route controller */\n controller?: WebSocketServerBaseControllerType | WebSocketClientBaseControllerType;\n\n /** WebSocket route action */\n action: string;\n}\n\nexport interface WebSocketConstructorParams {\n /** WebSocket options */\n options: WebSocketOptions;\n\n /** WebSocket routes */\n routes: WebSocketRoute[];\n\n /** Redis instance */\n redisInstance: RedisInstance;\n\n /** Queue manager */\n queueManager: QueueManager;\n\n /** Database instance */\n databaseInstance: DatabaseInstance;\n}\n\nexport interface WebSocketConnectedClientData {\n /** WebSocket client */\n ws: WebSocket | null;\n\n /** Last activity time */\n lastActivity: number;\n\n /** Client username */\n username?: string;\n}\n\nexport interface WebSocketMessageResponse {\n error?: string;\n}\n\nexport interface WebSocketMessageHandler<TData = unknown, TResponse = WebSocketMessageResponse> {\n (ws: WebSocket, clientId: string, data: TData): Promise<TResponse> | TResponse;\n}\n\nexport enum WebSocketRedisSubscriberEvent {\n ClientConnected = 'clientConnected',\n ClientDisconnected = 'clientDisconnected',\n DisconnectClient = 'disconnectClient',\n ClientJoinedRoom = 'clientJoinedRoom',\n ClientLeftRoom = 'clientLeftRoom',\n SendMessage = 'sendMessage',\n SendMessageToAll = 'sendMessageToAll',\n MessageError = 'messageError',\n QueueJobCompleted = 'queueJobCompleted',\n QueueJobError = 'queueJobError',\n Custom = 'custom',\n}\n"],
5
+ "mappings": "AA4JO,IAAK,gCAAL,kBAAKA,mCAAL;AACL,EAAAA,+BAAA,qBAAkB;AAClB,EAAAA,+BAAA,wBAAqB;AACrB,EAAAA,+BAAA,sBAAmB;AACnB,EAAAA,+BAAA,sBAAmB;AACnB,EAAAA,+BAAA,oBAAiB;AACjB,EAAAA,+BAAA,iBAAc;AACd,EAAAA,+BAAA,sBAAmB;AACnB,EAAAA,+BAAA,kBAAe;AACf,EAAAA,+BAAA,uBAAoB;AACpB,EAAAA,+BAAA,mBAAgB;AAChB,EAAAA,+BAAA,YAAS;AAXC,SAAAA;AAAA,GAAA;",
6
6
  "names": ["WebSocketRedisSubscriberEvent"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scpxl/nodejs-framework",
3
- "version": "1.0.24",
3
+ "version": "1.0.25",
4
4
  "description": "PXL Node.js Framework",
5
5
  "engines": {
6
6
  "node": ">=22.0.0"
@@ -83,6 +83,10 @@
83
83
  "./services": {
84
84
  "import": "./dist/services/index.js",
85
85
  "types": "./dist/services/index.d.ts"
86
+ },
87
+ "./schemas": {
88
+ "import": "./dist/schemas/index.js",
89
+ "types": "./dist/schemas/index.d.ts"
86
90
  }
87
91
  },
88
92
  "files": [
@@ -90,12 +94,14 @@
90
94
  "README.md"
91
95
  ],
92
96
  "scripts": {
93
- "dev": "node scripts/hmr-watcher.js",
97
+ "dev": "node scripts/hmr-watcher-enhanced.js",
98
+ "dev:legacy": "node scripts/hmr-watcher.js",
94
99
  "dev:import-map": "tsx src/index.ts",
95
100
  "clean": "del-cli dist",
96
101
  "build": "npm run clean && node esbuild.config.js",
97
102
  "build:tsc": "npm run clean && tsc",
98
103
  "build:local": "npm run clean && node esbuild.config.js && yalc push",
104
+ "build:watch": "node esbuild.config.js --watch",
99
105
  "docs:dev": "vitepress dev docs",
100
106
  "docs:build": "vitepress build docs",
101
107
  "docs:preview": "vitepress preview docs",
@@ -121,15 +127,7 @@
121
127
  "yalc:publish": "yalc publish",
122
128
  "yalc:push": "yalc push",
123
129
  "dev:yalc": "npm run build && npm run yalc:push",
124
- "example:install": "npm install --prefix examples/hello-world/backend && npm install --prefix examples/hello-world/frontend && npm install --prefix examples/commands",
125
- "example:hello-world": "concurrently -n backend,frontend -c blue,magenta \"npm run example:hello-world:backend\" \"npm run example:hello-world:frontend\"",
126
- "example:hello-world:backend": "npm run dev --prefix examples/hello-world/backend",
127
- "example:hello-world:frontend": "npm run dev --prefix examples/hello-world/frontend",
128
- "example:commands:install": "npm install --prefix examples/commands",
129
- "example:commands": "npm run dev --prefix examples/commands --",
130
- "example:commands:hello": "npm run dev --prefix examples/commands -- hello",
131
- "example:commands:seed": "npm run dev --prefix examples/commands -- database-seed",
132
- "example:commands:queue": "npm run dev --prefix examples/commands -- queue-process"
130
+ "example": "npm run --prefix examples/${npm_config_example:-hello-world/backend}"
133
131
  },
134
132
  "keywords": [],
135
133
  "author": "PXL <devops@pxlagency.com>",
@@ -185,7 +183,6 @@
185
183
  "fluent-ffmpeg": "^2.1.3",
186
184
  "http-status-codes": "^2.3.0",
187
185
  "ioredis": "^5.3.2",
188
- "joi": "^18.0.1",
189
186
  "jose": "^6.0.10",
190
187
  "lru-cache": "^11.2.2",
191
188
  "typescript": "^5.8.3",