@scpxl/nodejs-framework 1.0.50 → 1.0.57

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 (251) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +14 -9
  3. package/dist/api-requester/api-requester.js +1 -1
  4. package/dist/api-requester/api-requester.js.map +2 -2
  5. package/dist/api-requester/index.d.ts +1 -1
  6. package/dist/api-requester/index.d.ts.map +1 -1
  7. package/dist/api-requester/index.js.map +2 -2
  8. package/dist/application/base-application.d.ts +6 -5
  9. package/dist/application/base-application.d.ts.map +1 -1
  10. package/dist/application/base-application.interface.d.ts +2 -4
  11. package/dist/application/base-application.interface.d.ts.map +1 -1
  12. package/dist/application/base-application.js +17 -14
  13. package/dist/application/base-application.js.map +2 -2
  14. package/dist/application/command-application.d.ts.map +1 -1
  15. package/dist/application/command-application.js +2 -2
  16. package/dist/application/command-application.js.map +2 -2
  17. package/dist/application/index.d.ts +3 -3
  18. package/dist/application/index.d.ts.map +1 -1
  19. package/dist/application/index.js +4 -4
  20. package/dist/application/index.js.map +2 -2
  21. package/dist/application/web-application.d.ts +5 -5
  22. package/dist/application/web-application.d.ts.map +1 -1
  23. package/dist/application/web-application.js +6 -7
  24. package/dist/application/web-application.js.map +2 -2
  25. package/dist/application/worker-application.d.ts +2 -2
  26. package/dist/application/worker-application.d.ts.map +1 -1
  27. package/dist/application/worker-application.js +2 -2
  28. package/dist/application/worker-application.js.map +2 -2
  29. package/dist/auth/jwt.d.ts.map +1 -1
  30. package/dist/auth/jwt.js +2 -2
  31. package/dist/auth/jwt.js.map +2 -2
  32. package/dist/cache/manager.d.ts.map +1 -1
  33. package/dist/cache/manager.js.map +2 -2
  34. package/dist/cli/index.js +192 -7029
  35. package/dist/cli/index.js.map +4 -4
  36. package/dist/cluster/cluster-manager.d.ts.map +1 -1
  37. package/dist/cluster/cluster-manager.js +1 -1
  38. package/dist/cluster/cluster-manager.js.map +2 -2
  39. package/dist/command/command.d.ts +1 -1
  40. package/dist/command/command.d.ts.map +1 -1
  41. package/dist/command/command.js.map +2 -2
  42. package/dist/config/env.d.ts +1 -1
  43. package/dist/config/env.d.ts.map +1 -1
  44. package/dist/config/env.js.map +1 -1
  45. package/dist/config/index.d.ts +1 -1
  46. package/dist/config/index.d.ts.map +1 -1
  47. package/dist/config/index.js +1 -1
  48. package/dist/config/index.js.map +1 -1
  49. package/dist/config/schema.d.ts.map +1 -1
  50. package/dist/config/schema.js +1 -1
  51. package/dist/config/schema.js.map +2 -2
  52. package/dist/database/dynamic-entity.js +9 -9
  53. package/dist/database/dynamic-entity.js.map +2 -2
  54. package/dist/database/index.d.ts +3 -3
  55. package/dist/database/index.d.ts.map +1 -1
  56. package/dist/database/index.js +5 -5
  57. package/dist/database/index.js.map +2 -2
  58. package/dist/database/instance.d.ts +3 -3
  59. package/dist/database/instance.js +3 -3
  60. package/dist/database/instance.js.map +1 -1
  61. package/dist/database/manager.d.ts +1 -0
  62. package/dist/database/manager.d.ts.map +1 -1
  63. package/dist/database/manager.js +16 -3
  64. package/dist/database/manager.js.map +2 -2
  65. package/dist/error/error-reporter.js +1 -1
  66. package/dist/error/error-reporter.js.map +2 -2
  67. package/dist/error/index.d.ts +2 -3
  68. package/dist/error/index.d.ts.map +1 -1
  69. package/dist/error/index.js +8 -9
  70. package/dist/error/index.js.map +2 -2
  71. package/dist/event/controller/base.d.ts +2 -2
  72. package/dist/event/controller/base.d.ts.map +1 -1
  73. package/dist/event/controller/base.js +2 -2
  74. package/dist/event/controller/base.js.map +2 -2
  75. package/dist/event/index.d.ts +3 -3
  76. package/dist/event/index.d.ts.map +1 -1
  77. package/dist/event/index.js +5 -5
  78. package/dist/event/index.js.map +2 -2
  79. package/dist/event/manager.d.ts.map +1 -1
  80. package/dist/event/manager.interface.d.ts +2 -3
  81. package/dist/event/manager.interface.d.ts.map +1 -1
  82. package/dist/event/manager.js.map +2 -2
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +1 -1
  86. package/dist/index.js.map +2 -2
  87. package/dist/lifecycle/index.d.ts +3 -3
  88. package/dist/lifecycle/index.d.ts.map +1 -1
  89. package/dist/lifecycle/index.js +1 -1
  90. package/dist/lifecycle/index.js.map +2 -2
  91. package/dist/logger/logger.d.ts +20 -1
  92. package/dist/logger/logger.d.ts.map +1 -1
  93. package/dist/logger/logger.js +68 -96
  94. package/dist/logger/logger.js.map +2 -2
  95. package/dist/performance/cache-performance.d.ts.map +1 -1
  96. package/dist/performance/cache-performance.js +1 -1
  97. package/dist/performance/cache-performance.js.map +2 -2
  98. package/dist/performance/database-performance.d.ts.map +1 -1
  99. package/dist/performance/database-performance.js +1 -1
  100. package/dist/performance/database-performance.js.map +2 -2
  101. package/dist/performance/index.d.ts +3 -3
  102. package/dist/performance/index.d.ts.map +1 -1
  103. package/dist/performance/index.js +3 -3
  104. package/dist/performance/index.js.map +1 -1
  105. package/dist/performance/performance-monitor.js +2 -2
  106. package/dist/performance/performance-monitor.js.map +2 -2
  107. package/dist/performance/performance-monitor.plugin.d.ts.map +1 -1
  108. package/dist/performance/performance-monitor.plugin.js +1 -1
  109. package/dist/performance/performance-monitor.plugin.js.map +2 -2
  110. package/dist/performance/queue-performance.d.ts.map +1 -1
  111. package/dist/performance/queue-performance.js +1 -1
  112. package/dist/performance/queue-performance.js.map +2 -2
  113. package/dist/performance/webserver-performance.d.ts.map +1 -1
  114. package/dist/performance/webserver-performance.js +1 -1
  115. package/dist/performance/webserver-performance.js.map +2 -2
  116. package/dist/performance/websocket-performance.d.ts.map +1 -1
  117. package/dist/performance/websocket-performance.js +1 -1
  118. package/dist/performance/websocket-performance.js.map +2 -2
  119. package/dist/queue/index.d.ts +2 -2
  120. package/dist/queue/index.d.ts.map +1 -1
  121. package/dist/queue/index.interface.d.ts +1 -1
  122. package/dist/queue/index.interface.d.ts.map +1 -1
  123. package/dist/queue/index.js.map +2 -2
  124. package/dist/queue/manager.d.ts +3 -2
  125. package/dist/queue/manager.d.ts.map +1 -1
  126. package/dist/queue/manager.js +5 -2
  127. package/dist/queue/manager.js.map +2 -2
  128. package/dist/queue/processor/base.d.ts +5 -5
  129. package/dist/queue/processor/base.d.ts.map +1 -1
  130. package/dist/queue/processor/base.js +2 -2
  131. package/dist/queue/processor/base.js.map +2 -2
  132. package/dist/queue/processor/processor.interface.d.ts +3 -3
  133. package/dist/queue/processor/processor.interface.d.ts.map +1 -1
  134. package/dist/queue/worker.d.ts.map +1 -1
  135. package/dist/queue/worker.interface.d.ts +1 -1
  136. package/dist/queue/worker.interface.d.ts.map +1 -1
  137. package/dist/queue/worker.js +1 -1
  138. package/dist/queue/worker.js.map +2 -2
  139. package/dist/redis/index.d.ts +1 -1
  140. package/dist/redis/index.d.ts.map +1 -1
  141. package/dist/redis/index.js +4 -4
  142. package/dist/redis/index.js.map +2 -2
  143. package/dist/redis/manager.d.ts +2 -1
  144. package/dist/redis/manager.d.ts.map +1 -1
  145. package/dist/redis/manager.js +7 -4
  146. package/dist/redis/manager.js.map +2 -2
  147. package/dist/request-context/index.d.ts +1 -1
  148. package/dist/request-context/index.d.ts.map +1 -1
  149. package/dist/request-context/index.js +5 -5
  150. package/dist/request-context/index.js.map +1 -1
  151. package/dist/schemas/entity-builder.d.ts +3 -3
  152. package/dist/schemas/entity-builder.d.ts.map +1 -1
  153. package/dist/schemas/entity-builder.js.map +1 -1
  154. package/dist/services/aws/s3.d.ts.map +1 -1
  155. package/dist/services/aws/s3.js +7 -10
  156. package/dist/services/aws/s3.js.map +2 -2
  157. package/dist/util/file.d.ts +0 -6
  158. package/dist/util/file.d.ts.map +1 -1
  159. package/dist/util/file.js +6 -28
  160. package/dist/util/file.js.map +2 -2
  161. package/dist/util/helper.js +2 -2
  162. package/dist/util/helper.js.map +2 -2
  163. package/dist/util/index.d.ts +2 -2
  164. package/dist/util/index.d.ts.map +1 -1
  165. package/dist/util/index.js +18 -18
  166. package/dist/util/index.js.map +2 -2
  167. package/dist/util/loader.js +3 -3
  168. package/dist/util/loader.js.map +2 -2
  169. package/dist/util/os.js +2 -2
  170. package/dist/util/os.js.map +2 -2
  171. package/dist/webserver/controller/auth-middleware.d.ts +1 -1
  172. package/dist/webserver/controller/auth-middleware.d.ts.map +1 -1
  173. package/dist/webserver/controller/auth-middleware.js +1 -1
  174. package/dist/webserver/controller/auth-middleware.js.map +2 -2
  175. package/dist/webserver/controller/base.d.ts +6 -6
  176. package/dist/webserver/controller/base.d.ts.map +1 -1
  177. package/dist/webserver/controller/base.interface.d.ts +1 -1
  178. package/dist/webserver/controller/base.interface.d.ts.map +1 -1
  179. package/dist/webserver/controller/base.js +4 -4
  180. package/dist/webserver/controller/base.js.map +2 -2
  181. package/dist/webserver/controller/entity.d.ts +3 -3
  182. package/dist/webserver/controller/entity.d.ts.map +1 -1
  183. package/dist/webserver/controller/entity.js +19 -17
  184. package/dist/webserver/controller/entity.js.map +2 -2
  185. package/dist/webserver/controller/example-auth.d.ts.map +1 -1
  186. package/dist/webserver/controller/example-auth.js +1 -1
  187. package/dist/webserver/controller/example-auth.js.map +2 -2
  188. package/dist/webserver/controller/health.d.ts.map +1 -1
  189. package/dist/webserver/controller/health.js +1 -1
  190. package/dist/webserver/controller/health.js.map +2 -2
  191. package/dist/webserver/define-action.d.ts +1 -1
  192. package/dist/webserver/define-action.d.ts.map +1 -1
  193. package/dist/webserver/define-action.js.map +1 -1
  194. package/dist/webserver/define-route.d.ts +1 -1
  195. package/dist/webserver/define-route.d.ts.map +1 -1
  196. package/dist/webserver/define-route.js.map +2 -2
  197. package/dist/webserver/index.d.ts +9 -9
  198. package/dist/webserver/index.d.ts.map +1 -1
  199. package/dist/webserver/index.js +14 -14
  200. package/dist/webserver/index.js.map +2 -2
  201. package/dist/webserver/webserver.d.ts +3 -3
  202. package/dist/webserver/webserver.d.ts.map +1 -1
  203. package/dist/webserver/webserver.interface.d.ts +5 -5
  204. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  205. package/dist/webserver/webserver.interface.js.map +1 -1
  206. package/dist/webserver/webserver.js +9 -9
  207. package/dist/webserver/webserver.js.map +2 -2
  208. package/dist/websocket/controller/server/base.d.ts +2 -2
  209. package/dist/websocket/controller/server/base.js.map +1 -1
  210. package/dist/websocket/controllers/server/system.d.ts.map +1 -1
  211. package/dist/websocket/controllers/server/system.js +1 -1
  212. package/dist/websocket/controllers/server/system.js.map +2 -2
  213. package/dist/websocket/index.d.ts +9 -11
  214. package/dist/websocket/index.d.ts.map +1 -1
  215. package/dist/websocket/index.js +22 -22
  216. package/dist/websocket/index.js.map +2 -2
  217. package/dist/websocket/subscriber-middleware.d.ts.map +1 -1
  218. package/dist/websocket/subscriber-middleware.js.map +2 -2
  219. package/dist/websocket/subscriber-utils.d.ts.map +1 -1
  220. package/dist/websocket/subscriber-utils.js.map +2 -2
  221. package/dist/websocket/utils.d.ts.map +1 -1
  222. package/dist/websocket/utils.js +4 -2
  223. package/dist/websocket/utils.js.map +2 -2
  224. package/dist/websocket/websocket-auth.d.ts.map +1 -1
  225. package/dist/websocket/websocket-auth.js +3 -3
  226. package/dist/websocket/websocket-auth.js.map +2 -2
  227. package/dist/websocket/websocket-base.d.ts +2 -2
  228. package/dist/websocket/websocket-base.d.ts.map +1 -1
  229. package/dist/websocket/websocket-base.js +1 -1
  230. package/dist/websocket/websocket-base.js.map +2 -2
  231. package/dist/websocket/websocket-client-manager.d.ts.map +1 -1
  232. package/dist/websocket/websocket-client-manager.js +3 -3
  233. package/dist/websocket/websocket-client-manager.js.map +2 -2
  234. package/dist/websocket/websocket-client.d.ts +5 -5
  235. package/dist/websocket/websocket-client.d.ts.map +1 -1
  236. package/dist/websocket/websocket-client.js +5 -5
  237. package/dist/websocket/websocket-client.js.map +2 -2
  238. package/dist/websocket/websocket-room-manager.js +1 -1
  239. package/dist/websocket/websocket-room-manager.js.map +1 -1
  240. package/dist/websocket/websocket-server.d.ts +7 -7
  241. package/dist/websocket/websocket-server.d.ts.map +1 -1
  242. package/dist/websocket/websocket-server.js +25 -20
  243. package/dist/websocket/websocket-server.js.map +2 -2
  244. package/dist/websocket/websocket-service.d.ts +2 -2
  245. package/dist/websocket/websocket-service.d.ts.map +1 -1
  246. package/dist/websocket/websocket-service.js +1 -1
  247. package/dist/websocket/websocket-service.js.map +2 -2
  248. package/dist/websocket/websocket.interface.d.ts +3 -5
  249. package/dist/websocket/websocket.interface.d.ts.map +1 -1
  250. package/dist/websocket/websocket.interface.js.map +2 -2
  251. package/package.json +69 -65
@@ -1 +1 @@
1
- {"version":3,"file":"subscriber-utils.d.ts","sourceRoot":"","sources":["../../src/websocket/subscriber-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,iCAAiC,EACjC,0BAA0B,EAC3B,MAAM,0BAA0B,CAAC;AAGlC;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,0BAA0B,CASvF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,GAAG,OAAO,EACnD,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GACrC,0BAA0B,CAS5B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAajE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAG,GAAG,EAC7C,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,iCAAiC,CAAC,QAAQ,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACtG,WAAW,UAAQ,GAClB,0BAA0B,CAAC,QAAQ,CAAC,CAuBtC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,GAAG,GAAG,EACxC,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,WAAW,SAAuB,GACjC,0BAA0B,CAAC,QAAQ,CAAC,CAoCtC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,GAAG,GAAG,EAC1C,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,iCAAiC,CAAC,QAAQ,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC7F,0BAA0B,CAAC,QAAQ,CAAC,CAqBtC;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,QAAQ,GAAG,GAAG,EACtC,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,iBAAiB,SAAI,GACpB,0BAA0B,CAAC,QAAQ,CAAC,CAoBtC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAG,GAAG,EAC5C,QAAQ,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAAE,GAC/C,0BAA0B,CAAC,QAAQ,CAAC,CAMtC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,GAAG,GAAG,EACvC,SAAS,EAAE,CAAC,OAAO,EAAE,iCAAiC,CAAC,QAAQ,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EAC/F,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC5C,0BAA0B,CAAC,QAAQ,CAAC,CAOtC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAG,GAAG,EAC3C,SAAS,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACtD,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC5C,0BAA0B,CAAC,QAAQ,CAAC,CAgBtC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,GAAG,GAAG,EACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC5C,0BAA0B,CAAC,QAAQ,CAAC,CAStC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,GAAG,GAAG,EACzC,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,OAAO,EAAE,MAAM,GACd,0BAA0B,CAAC,QAAQ,CAAC,CA0BtC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,GAAG,GAAG,EACzC,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,UAAU,EAAE,MAAM,GACjB,0BAA0B,CAAC,QAAQ,CAAC,CAatC"}
1
+ {"version":3,"file":"subscriber-utils.d.ts","sourceRoot":"","sources":["../../src/websocket/subscriber-utils.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/subscriber-utils.ts"],
4
- "sourcesContent": ["import type {\n WebSocketSubscriberHandler,\n WebSocketSubscriberHandlerContext,\n WebSocketSubscriberMatcher,\n} from './websocket.interface.js';\nimport { Logger } from '../logger/index.js';\n\n/**\n * Utility functions for building and composing WebSocket subscriber handlers\n */\n\n/**\n * Create a predicate matcher for message properties\n * @param key - The property key to check\n * @param value - The expected value\n */\nexport function matchByProperty(key: string, value: unknown): WebSocketSubscriberMatcher {\n return (context: WebSocketSubscriberHandlerContext) => {\n try {\n const messageValue = getNestedProperty(context.message, key);\n return messageValue === value;\n } catch {\n return false;\n }\n };\n}\n\n/**\n * Create a predicate matcher for message property patterns\n * @param key - The property key to check\n * @param predicate - Function to test the value\n */\nexport function matchByPropertyPredicate<_T = unknown>(\n key: string,\n predicate: (value: unknown) => boolean,\n): WebSocketSubscriberMatcher {\n return (context: WebSocketSubscriberHandlerContext) => {\n try {\n const messageValue = getNestedProperty(context.message, key);\n return predicate(messageValue);\n } catch {\n return false;\n }\n };\n}\n\n/**\n * Safely get nested property from an object\n * @param obj - The object to search\n * @param path - Dot-notation path (e.g., 'user.id' or 'data.items.0.name')\n */\nexport function getNestedProperty(obj: any, path: string): unknown {\n const keys = path.split('.');\n let current = obj;\n\n for (const key of keys) {\n if (current == null) {\n return undefined;\n }\n // eslint-disable-next-line security/detect-object-injection\n current = current[key];\n }\n\n return current;\n}\n\n/**\n * Wrap a handler with error handling\n * @param handler - The handler to wrap\n * @param onError - Error handler callback\n * @param throwError - Whether to rethrow the error after handling\n */\nexport function withErrorHandler<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n onError?: (error: Error, context: WebSocketSubscriberHandlerContext<TMessage>) => void | Promise<void>,\n _throwError = false,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n try {\n return await handler(context);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n\n if (onError) {\n try {\n await onError(err, context);\n } catch (callbackError) {\n Logger.error({\n message: 'Error handler callback failed',\n meta: { originalError: err.message, callbackError },\n });\n }\n }\n\n if (_throwError) {\n throw err;\n }\n }\n };\n}\n\n/**\n * Wrap a handler with logging\n * @param handler - The handler to wrap\n * @param handlerName - Name for logging purposes\n */\nexport function withLogging<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n handlerName = 'subscriber-handler',\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const startTime = Date.now();\n const messageKeys =\n context.message && typeof context.message === 'object'\n ? Object.keys(context.message as Record<string, unknown>).slice(0, 5)\n : [];\n Logger.info({\n message: `${handlerName}: Starting handler execution`,\n meta: {\n channel: context.channel,\n messageKeys,\n },\n });\n\n try {\n const result = await handler(context);\n const duration = Date.now() - startTime;\n Logger.info({\n message: `${handlerName}: Handler completed successfully`,\n meta: { channel: context.channel, durationMs: duration },\n });\n return result;\n } catch (error) {\n const duration = Date.now() - startTime;\n Logger.error({\n message: `${handlerName}: Handler failed`,\n meta: {\n channel: context.channel,\n error: error instanceof Error ? error.message : String(error),\n durationMs: duration,\n },\n });\n throw error;\n }\n };\n}\n\n/**\n * Wrap a handler with rate limiting\n * @param handler - The handler to wrap\n * @param maxExecutions - Max executions allowed\n * @param windowMs - Time window in milliseconds\n * @param onRateLimited - Optional callback when rate limited\n */\nexport function withRateLimit<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n maxExecutions: number,\n windowMs: number,\n onRateLimited?: (context: WebSocketSubscriberHandlerContext<TMessage>) => void | Promise<void>,\n): WebSocketSubscriberHandler<TMessage> {\n const executionTimes: number[] = [];\n\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const now = Date.now();\n\n // Remove old entries outside the window\n while (executionTimes.length > 0 && executionTimes[0] < now - windowMs) {\n executionTimes.shift();\n }\n\n if (executionTimes.length >= maxExecutions) {\n if (onRateLimited) {\n await onRateLimited(context);\n }\n return;\n }\n\n executionTimes.push(now);\n return await handler(context);\n };\n}\n\n/**\n * Wrap a handler with retry logic\n * @param handler - The handler to wrap\n * @param maxRetries - Maximum number of retries\n * @param delayMs - Delay between retries in milliseconds\n * @param backoffMultiplier - Multiplier for exponential backoff (default: 1, no backoff)\n */\nexport function withRetry<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n maxRetries: number,\n delayMs: number,\n backoffMultiplier = 1,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n let lastError: Error | null = null;\n let currentDelay = delayMs;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await handler(context);\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, currentDelay));\n currentDelay = Math.floor(currentDelay * backoffMultiplier);\n }\n }\n }\n\n throw lastError;\n };\n}\n\n/**\n * Compose multiple handlers into a single handler\n * Executes handlers sequentially, passing context through each one\n * @param handlers - Array of handlers to compose\n */\nexport function composeHandlers<TMessage = any>(\n handlers: WebSocketSubscriberHandler<TMessage>[],\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n for (const handler of handlers) {\n await handler(context);\n }\n };\n}\n\n/**\n * Create a filter handler that conditionally executes based on a predicate\n * @param predicate - Function that returns true if handler should execute\n * @param handler - The handler to execute conditionally\n */\nexport function withFilter<TMessage = any>(\n predicate: (context: WebSocketSubscriberHandlerContext<TMessage>) => boolean | Promise<boolean>,\n handler: WebSocketSubscriberHandler<TMessage>,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const shouldExecute = await predicate(context);\n if (shouldExecute) {\n return await handler(context);\n }\n };\n}\n\n/**\n * Validate message structure before execution\n * @param validator - Function that validates the message and throws if invalid\n * @param handler - The handler to wrap\n */\nexport function withValidation<TMessage = any>(\n validator: (message: TMessage) => void | Promise<void>,\n handler: WebSocketSubscriberHandler<TMessage>,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n try {\n await validator(context.message);\n return await handler(context);\n } catch (error) {\n Logger.warn({\n message: 'Message validation failed',\n meta: {\n channel: context.channel,\n error: error instanceof Error ? error.message : String(error),\n },\n });\n throw error;\n }\n };\n}\n\n/**\n * Add metadata/context to a handler execution\n * @param metadata - Metadata to add to context\n * @param handler - The handler to wrap\n */\nexport function withMetadata<TMessage = any>(\n metadata: Record<string, unknown>,\n handler: WebSocketSubscriberHandler<TMessage>,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const enrichedContext = {\n ...context,\n metadata,\n } as any;\n\n return await handler(enrichedContext);\n };\n}\n\n/**\n * Debounce handler execution by channel\n * @param handler - The handler to wrap\n * @param delayMs - Debounce delay in milliseconds\n */\nexport function withDebounce<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n delayMs: number,\n): WebSocketSubscriberHandler<TMessage> {\n const timers = new Map<string, NodeJS.Timeout>();\n\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const channel = context.channel;\n\n // Cancel previous timer for this channel\n const existingTimer = timers.get(channel);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Set new timer\n return new Promise<void>(resolve => {\n const timer = setTimeout(async () => {\n try {\n await handler(context);\n } finally {\n timers.delete(channel);\n resolve();\n }\n }, delayMs);\n\n timers.set(channel, timer);\n });\n };\n}\n\n/**\n * Throttle handler execution by channel\n * @param handler - The handler to wrap\n * @param intervalMs - Throttle interval in milliseconds\n */\nexport function withThrottle<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n intervalMs: number,\n): WebSocketSubscriberHandler<TMessage> {\n const lastExecutionTime = new Map<string, number>();\n\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const channel = context.channel;\n const now = Date.now();\n const lastTime = lastExecutionTime.get(channel) ?? 0;\n\n if (now - lastTime >= intervalMs) {\n lastExecutionTime.set(channel, now);\n return await handler(context);\n }\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Logger } from '../logger/index.js';\nimport type {\n WebSocketSubscriberHandler,\n WebSocketSubscriberHandlerContext,\n WebSocketSubscriberMatcher,\n} from './websocket.interface.js';\n\n/**\n * Utility functions for building and composing WebSocket subscriber handlers\n */\n\n/**\n * Create a predicate matcher for message properties\n * @param key - The property key to check\n * @param value - The expected value\n */\nexport function matchByProperty(key: string, value: unknown): WebSocketSubscriberMatcher {\n return (context: WebSocketSubscriberHandlerContext) => {\n try {\n const messageValue = getNestedProperty(context.message, key);\n return messageValue === value;\n } catch {\n return false;\n }\n };\n}\n\n/**\n * Create a predicate matcher for message property patterns\n * @param key - The property key to check\n * @param predicate - Function to test the value\n */\nexport function matchByPropertyPredicate<_T = unknown>(\n key: string,\n predicate: (value: unknown) => boolean,\n): WebSocketSubscriberMatcher {\n return (context: WebSocketSubscriberHandlerContext) => {\n try {\n const messageValue = getNestedProperty(context.message, key);\n return predicate(messageValue);\n } catch {\n return false;\n }\n };\n}\n\n/**\n * Safely get nested property from an object\n * @param obj - The object to search\n * @param path - Dot-notation path (e.g., 'user.id' or 'data.items.0.name')\n */\nexport function getNestedProperty(obj: any, path: string): unknown {\n const keys = path.split('.');\n let current = obj;\n\n for (const key of keys) {\n if (current == null) {\n return undefined;\n }\n // eslint-disable-next-line security/detect-object-injection\n current = current[key];\n }\n\n return current;\n}\n\n/**\n * Wrap a handler with error handling\n * @param handler - The handler to wrap\n * @param onError - Error handler callback\n * @param throwError - Whether to rethrow the error after handling\n */\nexport function withErrorHandler<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n onError?: (error: Error, context: WebSocketSubscriberHandlerContext<TMessage>) => void | Promise<void>,\n _throwError = false,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n try {\n return await handler(context);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n\n if (onError) {\n try {\n await onError(err, context);\n } catch (callbackError) {\n Logger.error({\n message: 'Error handler callback failed',\n meta: { originalError: err.message, callbackError },\n });\n }\n }\n\n if (_throwError) {\n throw err;\n }\n }\n };\n}\n\n/**\n * Wrap a handler with logging\n * @param handler - The handler to wrap\n * @param handlerName - Name for logging purposes\n */\nexport function withLogging<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n handlerName = 'subscriber-handler',\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const startTime = Date.now();\n const messageKeys =\n context.message && typeof context.message === 'object'\n ? Object.keys(context.message as Record<string, unknown>).slice(0, 5)\n : [];\n Logger.info({\n message: `${handlerName}: Starting handler execution`,\n meta: {\n channel: context.channel,\n messageKeys,\n },\n });\n\n try {\n const result = await handler(context);\n const duration = Date.now() - startTime;\n Logger.info({\n message: `${handlerName}: Handler completed successfully`,\n meta: { channel: context.channel, durationMs: duration },\n });\n return result;\n } catch (error) {\n const duration = Date.now() - startTime;\n Logger.error({\n message: `${handlerName}: Handler failed`,\n meta: {\n channel: context.channel,\n error: error instanceof Error ? error.message : String(error),\n durationMs: duration,\n },\n });\n throw error;\n }\n };\n}\n\n/**\n * Wrap a handler with rate limiting\n * @param handler - The handler to wrap\n * @param maxExecutions - Max executions allowed\n * @param windowMs - Time window in milliseconds\n * @param onRateLimited - Optional callback when rate limited\n */\nexport function withRateLimit<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n maxExecutions: number,\n windowMs: number,\n onRateLimited?: (context: WebSocketSubscriberHandlerContext<TMessage>) => void | Promise<void>,\n): WebSocketSubscriberHandler<TMessage> {\n const executionTimes: number[] = [];\n\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const now = Date.now();\n\n // Remove old entries outside the window\n while (executionTimes.length > 0 && executionTimes[0] < now - windowMs) {\n executionTimes.shift();\n }\n\n if (executionTimes.length >= maxExecutions) {\n if (onRateLimited) {\n await onRateLimited(context);\n }\n return;\n }\n\n executionTimes.push(now);\n return await handler(context);\n };\n}\n\n/**\n * Wrap a handler with retry logic\n * @param handler - The handler to wrap\n * @param maxRetries - Maximum number of retries\n * @param delayMs - Delay between retries in milliseconds\n * @param backoffMultiplier - Multiplier for exponential backoff (default: 1, no backoff)\n */\nexport function withRetry<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n maxRetries: number,\n delayMs: number,\n backoffMultiplier = 1,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n let lastError: Error | null = null;\n let currentDelay = delayMs;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await handler(context);\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, currentDelay));\n currentDelay = Math.floor(currentDelay * backoffMultiplier);\n }\n }\n }\n\n throw lastError;\n };\n}\n\n/**\n * Compose multiple handlers into a single handler\n * Executes handlers sequentially, passing context through each one\n * @param handlers - Array of handlers to compose\n */\nexport function composeHandlers<TMessage = any>(\n handlers: WebSocketSubscriberHandler<TMessage>[],\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n for (const handler of handlers) {\n await handler(context);\n }\n };\n}\n\n/**\n * Create a filter handler that conditionally executes based on a predicate\n * @param predicate - Function that returns true if handler should execute\n * @param handler - The handler to execute conditionally\n */\nexport function withFilter<TMessage = any>(\n predicate: (context: WebSocketSubscriberHandlerContext<TMessage>) => boolean | Promise<boolean>,\n handler: WebSocketSubscriberHandler<TMessage>,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const shouldExecute = await predicate(context);\n if (shouldExecute) {\n return await handler(context);\n }\n };\n}\n\n/**\n * Validate message structure before execution\n * @param validator - Function that validates the message and throws if invalid\n * @param handler - The handler to wrap\n */\nexport function withValidation<TMessage = any>(\n validator: (message: TMessage) => void | Promise<void>,\n handler: WebSocketSubscriberHandler<TMessage>,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n try {\n await validator(context.message);\n return await handler(context);\n } catch (error) {\n Logger.warn({\n message: 'Message validation failed',\n meta: {\n channel: context.channel,\n error: error instanceof Error ? error.message : String(error),\n },\n });\n throw error;\n }\n };\n}\n\n/**\n * Add metadata/context to a handler execution\n * @param metadata - Metadata to add to context\n * @param handler - The handler to wrap\n */\nexport function withMetadata<TMessage = any>(\n metadata: Record<string, unknown>,\n handler: WebSocketSubscriberHandler<TMessage>,\n): WebSocketSubscriberHandler<TMessage> {\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const enrichedContext = {\n ...context,\n metadata,\n } as any;\n\n return await handler(enrichedContext);\n };\n}\n\n/**\n * Debounce handler execution by channel\n * @param handler - The handler to wrap\n * @param delayMs - Debounce delay in milliseconds\n */\nexport function withDebounce<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n delayMs: number,\n): WebSocketSubscriberHandler<TMessage> {\n const timers = new Map<string, NodeJS.Timeout>();\n\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const channel = context.channel;\n\n // Cancel previous timer for this channel\n const existingTimer = timers.get(channel);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Set new timer\n return new Promise<void>(resolve => {\n const timer = setTimeout(async () => {\n try {\n await handler(context);\n } finally {\n timers.delete(channel);\n resolve();\n }\n }, delayMs);\n\n timers.set(channel, timer);\n });\n };\n}\n\n/**\n * Throttle handler execution by channel\n * @param handler - The handler to wrap\n * @param intervalMs - Throttle interval in milliseconds\n */\nexport function withThrottle<TMessage = any>(\n handler: WebSocketSubscriberHandler<TMessage>,\n intervalMs: number,\n): WebSocketSubscriberHandler<TMessage> {\n const lastExecutionTime = new Map<string, number>();\n\n return async (context: WebSocketSubscriberHandlerContext<TMessage>) => {\n const channel = context.channel;\n const now = Date.now();\n const lastTime = lastExecutionTime.get(channel) ?? 0;\n\n if (now - lastTime >= intervalMs) {\n lastExecutionTime.set(channel, now);\n return await handler(context);\n }\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/websocket/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAGhC,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAE/F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBnF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/websocket/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAGhC,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAE/F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoBnF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhE"}
@@ -22,9 +22,11 @@ function parseServerMessage(message) {
22
22
  }
23
23
  if (!parsedMessage) {
24
24
  throw new Error("Invalid WebSocket message");
25
- } else if (!parsedMessage.type) {
25
+ }
26
+ if (!parsedMessage.type) {
26
27
  throw new Error("Missing WebSocket message type");
27
- } else if (!parsedMessage.action) {
28
+ }
29
+ if (!parsedMessage.action) {
28
30
  throw new Error("Missing WebSocket message action");
29
31
  }
30
32
  return parsedMessage;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/utils.ts"],
4
- "sourcesContent": ["import crypto from 'node:crypto';\nimport type WebSocket from 'ws';\nimport { Logger } from '../logger/index.js';\n\nexport interface LogOptions {\n muteWorker?: boolean;\n}\n\nexport function generateClientId(): string {\n if (typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID().replace(/-/g, '');\n }\n\n return crypto.randomBytes(16).toString('hex');\n}\n\nexport function log(message: string, meta?: Record<string, unknown>, options?: LogOptions): void {\n Logger.custom({ level: 'webSocket', message, meta, options });\n}\n\nexport function parseServerMessage(message: WebSocket.Data): Record<string, unknown> {\n let parsedMessage;\n\n try {\n parsedMessage = JSON.parse(message.toString());\n } catch {\n throw new Error('Failed to parse JSON');\n }\n\n if (!parsedMessage) {\n throw new Error('Invalid WebSocket message');\n } else if (!parsedMessage.type) {\n throw new Error('Missing WebSocket message type');\n } else if (!parsedMessage.action) {\n throw new Error('Missing WebSocket message action');\n }\n\n return parsedMessage;\n}\n\nexport function getRouteKey(type: string, action: string): string {\n return `${type}:${action}`;\n}\n"],
5
- "mappings": ";;AAAA,OAAO,YAAY;AAEnB,SAAS,cAAc;AAMhB,SAAS,mBAA2B;AACzC,MAAI,OAAO,OAAO,eAAe,YAAY;AAC3C,WAAO,OAAO,WAAW,EAAE,QAAQ,MAAM,EAAE;AAAA,EAC7C;AAEA,SAAO,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAC9C;AANgB;AAQT,SAAS,IAAI,SAAiB,MAAgC,SAA4B;AAC/F,SAAO,OAAO,EAAE,OAAO,aAAa,SAAS,MAAM,QAAQ,CAAC;AAC9D;AAFgB;AAIT,SAAS,mBAAmB,SAAkD;AACnF,MAAI;AAEJ,MAAI;AACF,oBAAgB,KAAK,MAAM,QAAQ,SAAS,CAAC;AAAA,EAC/C,QAAQ;AACN,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AAEA,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C,WAAW,CAAC,cAAc,MAAM;AAC9B,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD,WAAW,CAAC,cAAc,QAAQ;AAChC,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAEA,SAAO;AACT;AAlBgB;AAoBT,SAAS,YAAY,MAAc,QAAwB;AAChE,SAAO,GAAG,IAAI,IAAI,MAAM;AAC1B;AAFgB;",
4
+ "sourcesContent": ["import crypto from 'node:crypto';\nimport type WebSocket from 'ws';\nimport { Logger } from '../logger/index.js';\n\nexport interface LogOptions {\n muteWorker?: boolean;\n}\n\nexport function generateClientId(): string {\n if (typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID().replace(/-/g, '');\n }\n\n return crypto.randomBytes(16).toString('hex');\n}\n\nexport function log(message: string, meta?: Record<string, unknown>, options?: LogOptions): void {\n Logger.custom({ level: 'webSocket', message, meta, options });\n}\n\nexport function parseServerMessage(message: WebSocket.Data): Record<string, unknown> {\n let parsedMessage: Record<string, unknown>;\n\n try {\n parsedMessage = JSON.parse(message.toString());\n } catch {\n throw new Error('Failed to parse JSON');\n }\n\n if (!parsedMessage) {\n throw new Error('Invalid WebSocket message');\n }\n if (!parsedMessage.type) {\n throw new Error('Missing WebSocket message type');\n }\n if (!parsedMessage.action) {\n throw new Error('Missing WebSocket message action');\n }\n\n return parsedMessage;\n}\n\nexport function getRouteKey(type: string, action: string): string {\n return `${type}:${action}`;\n}\n"],
5
+ "mappings": ";;AAAA,OAAO,YAAY;AAEnB,SAAS,cAAc;AAMhB,SAAS,mBAA2B;AACzC,MAAI,OAAO,OAAO,eAAe,YAAY;AAC3C,WAAO,OAAO,WAAW,EAAE,QAAQ,MAAM,EAAE;AAAA,EAC7C;AAEA,SAAO,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAC9C;AANgB;AAQT,SAAS,IAAI,SAAiB,MAAgC,SAA4B;AAC/F,SAAO,OAAO,EAAE,OAAO,aAAa,SAAS,MAAM,QAAQ,CAAC;AAC9D;AAFgB;AAIT,SAAS,mBAAmB,SAAkD;AACnF,MAAI;AAEJ,MAAI;AACF,oBAAgB,KAAK,MAAM,QAAQ,SAAS,CAAC;AAAA,EAC/C,QAAQ;AACN,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AAEA,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C;AACA,MAAI,CAAC,cAAc,MAAM;AACvB,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACA,MAAI,CAAC,cAAc,QAAQ;AACzB,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAEA,SAAO;AACT;AApBgB;AAsBT,SAAS,YAAY,MAAc,QAAwB;AAChE,SAAO,GAAG,IAAI,IAAI,MAAM;AAC1B;AAFgB;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-auth.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AAExF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAAjB,iBAAiB,EAAE,oBAAoB;IAEpE;;;;;OAKG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;CAmCrE"}
1
+ {"version":3,"file":"websocket-auth.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AAGxF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAAjB,iBAAiB,EAAE,oBAAoB;IAEpE;;;;;OAKG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;CAmCrE"}
@@ -1,6 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- import { URL } from "url";
3
+ import { URL } from "node:url";
4
4
  import Jwt from "../auth/jwt.js";
5
5
  class WebSocketAuthService {
6
6
  constructor(applicationConfig) {
@@ -30,8 +30,8 @@ class WebSocketAuthService {
30
30
  jwtSecretKey
31
31
  });
32
32
  const { payload } = await Jwt.jwtVerify(token, importedJwtSecretKey);
33
- const userId = parseInt(payload.sub);
34
- if (isNaN(userId)) {
33
+ const userId = parseInt(payload.sub, 10);
34
+ if (Number.isNaN(userId)) {
35
35
  throw new Error("Invalid user ID in token");
36
36
  }
37
37
  return { userId, payload };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/websocket-auth.ts"],
4
- "sourcesContent": ["import { URL } from 'url';\nimport Jwt from '../auth/jwt.js';\nimport type { WebApplicationConfig } from '../application/web-application.interface.js';\n\nexport interface WebSocketAuthResult {\n userId: number;\n payload: Record<string, unknown>;\n}\n\nexport class WebSocketAuthService {\n constructor(private readonly applicationConfig: WebApplicationConfig) {}\n\n /**\n * Validates WebSocket authentication token from URL query parameters\n * @param url - The WebSocket connection URL\n * @returns Authentication result with userId and payload, or null if no token provided\n * @throws Error if authentication fails\n */\n async validateAuth(url: string): Promise<WebSocketAuthResult | 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"],
5
- "mappings": ";;AAAA,SAAS,WAAW;AACpB,OAAO,SAAS;AAQT,MAAM,qBAAqB;AAAA,EAChC,YAA6B,mBAAyC;AAAzC;AAAA,EAA0C;AAAA,EAVzE,OASkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShC,MAAM,aAAa,KAAkD;AACnE,QAAI;AACF,YAAM,YAAY,IAAI,IAAI,KAAK,gBAAgB;AAC/C,YAAM,QAAQ,UAAU,aAAa,IAAI,OAAO;AAEhD,UAAI,CAAC,OAAO;AACV,eAAO;AAAA,MACT;AAGA,YAAM,eAAe,KAAK,kBAAkB,MAAM;AAElD,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AAGA,YAAM,uBAAuB,MAAM,IAAI,mBAAmB;AAAA,QACxD;AAAA,MACF,CAAC;AAGD,YAAM,EAAE,QAAQ,IAAI,MAAM,IAAI,UAAU,OAAO,oBAAoB;AAEnE,YAAM,SAAS,SAAS,QAAQ,GAAa;AAE7C,UAAI,MAAM,MAAM,GAAG;AACjB,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AAEA,aAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B,SAAS,OAAY;AACnB,YAAM,IAAI,MAAM,4BAA4B,MAAM,OAAO,EAAE;AAAA,IAC7D;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { URL } from 'node:url';\nimport type { WebApplicationConfig } from '../application/web-application.interface.js';\nimport Jwt from '../auth/jwt.js';\n\nexport interface WebSocketAuthResult {\n userId: number;\n payload: Record<string, unknown>;\n}\n\nexport class WebSocketAuthService {\n constructor(private readonly applicationConfig: WebApplicationConfig) {}\n\n /**\n * Validates WebSocket authentication token from URL query parameters\n * @param url - The WebSocket connection URL\n * @returns Authentication result with userId and payload, or null if no token provided\n * @throws Error if authentication fails\n */\n async validateAuth(url: string): Promise<WebSocketAuthResult | 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, 10);\n\n if (Number.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"],
5
+ "mappings": ";;AAAA,SAAS,WAAW;AAEpB,OAAO,SAAS;AAOT,MAAM,qBAAqB;AAAA,EAChC,YAA6B,mBAAyC;AAAzC;AAAA,EAA0C;AAAA,EAVzE,OASkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShC,MAAM,aAAa,KAAkD;AACnE,QAAI;AACF,YAAM,YAAY,IAAI,IAAI,KAAK,gBAAgB;AAC/C,YAAM,QAAQ,UAAU,aAAa,IAAI,OAAO;AAEhD,UAAI,CAAC,OAAO;AACV,eAAO;AAAA,MACT;AAGA,YAAM,eAAe,KAAK,kBAAkB,MAAM;AAElD,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AAGA,YAAM,uBAAuB,MAAM,IAAI,mBAAmB;AAAA,QACxD;AAAA,MACF,CAAC;AAGD,YAAM,EAAE,QAAQ,IAAI,MAAM,IAAI,UAAU,OAAO,oBAAoB;AAEnE,YAAM,SAAS,SAAS,QAAQ,KAAe,EAAE;AAEjD,UAAI,OAAO,MAAM,MAAM,GAAG;AACxB,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AAEA,aAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B,SAAS,OAAY;AACnB,YAAM,IAAI,MAAM,4BAA4B,MAAM,OAAO,EAAE;AAAA,IAC7D;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,5 @@
1
- import type { WebSocketMessageHandler, WebSocketRoute, WebSocketType } from './websocket.interface.js';
2
1
  import type WebSocket from 'ws';
2
+ import type { WebSocketMessageHandler, WebSocketRoute, WebSocketType } from './websocket.interface.js';
3
3
  export default abstract class WebSocketBase {
4
4
  protected routes: WebSocketRoute[];
5
5
  protected routeHandlers: Map<string, WebSocketMessageHandler>;
@@ -13,7 +13,7 @@ export default abstract class WebSocketBase {
13
13
  type: unknown;
14
14
  action: unknown;
15
15
  response: unknown;
16
- } | void>;
16
+ } | undefined>;
17
17
  protected printRoutes(): void;
18
18
  }
19
19
  //# sourceMappingURL=websocket-base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-base.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAIvG,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAGhC,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,aAAa;IACzC,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,CAAM;IACxC,SAAS,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAa;IAE1E,SAAS,CAAC,aAAa,EAAE,cAAc,EAAE,CAAM;IAE/C,aAAoB,IAAI,IAAI,aAAa,CAAC;IAE1C,SAAS,CAAC,QAAQ,CAAC,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvE,SAAS,CAAC,QAAQ,CAAC,iBAAiB,IAAI,OAAO;IAC/C,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;cAE5D,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAiFtF,mBAAmB,CACjC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,SAAS,CAAC,IAAI,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAuDxE,SAAS,CAAC,WAAW,IAAI,IAAI;CAiB9B"}
1
+ {"version":3,"file":"websocket-base.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAKhC,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEvG,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,aAAa;IACzC,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,CAAM;IACxC,SAAS,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAa;IAE1E,SAAS,CAAC,aAAa,EAAE,cAAc,EAAE,CAAM;IAE/C,aAAoB,IAAI,IAAI,aAAa,CAAC;IAE1C,SAAS,CAAC,QAAQ,CAAC,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvE,SAAS,CAAC,QAAQ,CAAC,iBAAiB,IAAI,OAAO;IAC/C,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;cAE5D,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAiFtF,mBAAmB,CACjC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,SAAS,CAAC,IAAI,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IAuD7E,SAAS,CAAC,WAAW,IAAI,IAAI;CAiB9B"}
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- import { getRouteKey, log, parseServerMessage } from "./utils.js";
4
3
  import { File, Helper, Loader } from "../util/index.js";
4
+ import { getRouteKey, log, parseServerMessage } from "./utils.js";
5
5
  class WebSocketBase {
6
6
  static {
7
7
  __name(this, "WebSocketBase");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/websocket-base.ts"],
4
- "sourcesContent": ["import type { WebSocketMessageHandler, WebSocketRoute, WebSocketType } from './websocket.interface.js';\nimport { getRouteKey, log, parseServerMessage } from './utils.js';\nimport type { WebSocketServerBaseControllerType } from './controller/server/base.interface.js';\nimport type { WebSocketClientBaseControllerType } from './controller/client/base.interface.js';\nimport type WebSocket from 'ws';\nimport { File, Helper, Loader } from '../util/index.js';\n\nexport default abstract class WebSocketBase {\n protected routes: WebSocketRoute[] = [];\n protected routeHandlers: Map<string, WebSocketMessageHandler> = new Map();\n\n protected defaultRoutes: WebSocketRoute[] = [];\n\n public abstract get type(): WebSocketType;\n\n protected abstract getControllerDependencies(): Record<string, unknown>;\n protected abstract shouldPrintRoutes(): boolean;\n protected abstract handleMessageError(clientId: string, error: string): void;\n\n protected async configureRoutes(routes: WebSocketRoute[], controllersDirectory: string): Promise<void> {\n // log ('Configuring routes', { Type: this.type, 'Controllers Directory': controllersDirectory });\n\n const controllersDirectoryExists = await File.pathExists(controllersDirectory);\n\n if (!controllersDirectoryExists) {\n log('Controllers directory not found', {\n Directory: controllersDirectory,\n });\n\n return;\n }\n\n const scriptFileExtension = Helper.getScriptFileExtension();\n\n // Load controllers\n const controllers = await Loader.loadModulesInDirectory({\n directory: controllersDirectory,\n // NOTE:\n // When getting \"system\", it gets /app/node_modules/@scpxl/nodejs-framework/dist/websocket/controllers/server\n // Therefor .js is needed also\n // Fix so only .ts vs .js is needed\n extensions: ['.ts', '.js'],\n });\n\n for (const route of routes) {\n let ControllerClass: WebSocketServerBaseControllerType | WebSocketClientBaseControllerType;\n\n // log('Registering route', {\n // Type: route.type,\n // Controller: route.controller ? route.controller.toString() : route.controllerName,\n // Action: route.action,\n // });\n\n if (route.controller) {\n ControllerClass = route.controller;\n } else if (route.controllerName) {\n ControllerClass = controllers[route.controllerName] as\n | WebSocketServerBaseControllerType\n | WebSocketClientBaseControllerType;\n } else {\n throw new Error('WebSocket controller config not found');\n }\n\n if (typeof ControllerClass !== 'function') {\n log('Controller not found', {\n Controller: route.controllerName,\n Path: `${controllersDirectory}/${route.controllerName}.${scriptFileExtension}`,\n });\n\n continue;\n }\n\n const controllerDependencies = this.getControllerDependencies();\n\n const controllerInstance = new ControllerClass(controllerDependencies as any);\n\n const controllerHandler = controllerInstance[route.action as keyof typeof controllerInstance] as\n | WebSocketMessageHandler\n | undefined;\n const routeKey = getRouteKey(route.type, route.action);\n\n if (typeof controllerHandler !== 'function') {\n log('Controller action not found', {\n Controller: route.controllerName ?? ControllerClass.name,\n Action: route.action,\n RouteKey: routeKey,\n });\n continue;\n }\n\n this.routeHandlers.set(routeKey, controllerHandler.bind(controllerInstance));\n }\n\n if (this.shouldPrintRoutes()) {\n log('Routes:', { Type: this.type });\n\n this.printRoutes();\n }\n }\n\n protected async handleServerMessage(\n ws: WebSocket,\n message: WebSocket.Data,\n clientId: string,\n ): Promise<{ type: unknown; action: unknown; response: unknown } | void> {\n try {\n const parsedMessage = parseServerMessage(message);\n const type = parsedMessage.type;\n const action = parsedMessage.action;\n\n log('Incoming message', {\n 'Client ID': clientId,\n Type: type ?? '-',\n Action: action ?? '-',\n });\n\n const routeKey = getRouteKey(parsedMessage.type as string, parsedMessage.action as string);\n\n const messageHandler = this.routeHandlers.get(routeKey);\n\n if (messageHandler) {\n const messageResponse = await messageHandler(ws, clientId, parsedMessage.data);\n\n return {\n type,\n action,\n response: messageResponse,\n };\n }\n // throw new Error(`Route handler not found (Route Key: ${routeKey} | Type: ${type} | Action: ${action})`);\n\n log('Route handler not found', {\n RouteKey: routeKey,\n Type: type,\n Action: action,\n });\n\n // if (\n // typeof this.applicationConfig.webSocket\n // ?.serverMessageHandler === 'function'\n // ) {\n // // Execute custom application subscriber event handler\n // this.applicationConfig.webSocket.serverMessageHandler(\n // {\n // ws,\n // clientId,\n // parsedMessage,\n // },\n // );\n // }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n log(errorMessage);\n\n this.handleMessageError(clientId, errorMessage);\n }\n }\n\n protected printRoutes(): void {\n let routesString = '';\n\n const routeKeys = Array.from(this.routeHandlers.keys());\n\n routeKeys.forEach((routeKey, index) => {\n const [type, action] = routeKey.split(':');\n\n routesString += `Type: ${type} -> Action: ${action}`;\n\n if (index !== routeKeys.length - 1) {\n routesString += '\\n';\n }\n });\n\n log(routesString);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type WebSocket from 'ws';\nimport { File, Helper, Loader } from '../util/index.js';\nimport type { WebSocketClientBaseControllerType } from './controller/client/base.interface.js';\nimport type { WebSocketServerBaseControllerType } from './controller/server/base.interface.js';\nimport { getRouteKey, log, parseServerMessage } from './utils.js';\nimport type { WebSocketMessageHandler, WebSocketRoute, WebSocketType } from './websocket.interface.js';\n\nexport default abstract class WebSocketBase {\n protected routes: WebSocketRoute[] = [];\n protected routeHandlers: Map<string, WebSocketMessageHandler> = new Map();\n\n protected defaultRoutes: WebSocketRoute[] = [];\n\n public abstract get type(): WebSocketType;\n\n protected abstract getControllerDependencies(): Record<string, unknown>;\n protected abstract shouldPrintRoutes(): boolean;\n protected abstract handleMessageError(clientId: string, error: string): void;\n\n protected async configureRoutes(routes: WebSocketRoute[], controllersDirectory: string): Promise<void> {\n // log ('Configuring routes', { Type: this.type, 'Controllers Directory': controllersDirectory });\n\n const controllersDirectoryExists = await File.pathExists(controllersDirectory);\n\n if (!controllersDirectoryExists) {\n log('Controllers directory not found', {\n Directory: controllersDirectory,\n });\n\n return;\n }\n\n const scriptFileExtension = Helper.getScriptFileExtension();\n\n // Load controllers\n const controllers = await Loader.loadModulesInDirectory({\n directory: controllersDirectory,\n // NOTE:\n // When getting \"system\", it gets /app/node_modules/@scpxl/nodejs-framework/dist/websocket/controllers/server\n // Therefor .js is needed also\n // Fix so only .ts vs .js is needed\n extensions: ['.ts', '.js'],\n });\n\n for (const route of routes) {\n let ControllerClass: WebSocketServerBaseControllerType | WebSocketClientBaseControllerType;\n\n // log('Registering route', {\n // Type: route.type,\n // Controller: route.controller ? route.controller.toString() : route.controllerName,\n // Action: route.action,\n // });\n\n if (route.controller) {\n ControllerClass = route.controller;\n } else if (route.controllerName) {\n ControllerClass = controllers[route.controllerName] as\n | WebSocketServerBaseControllerType\n | WebSocketClientBaseControllerType;\n } else {\n throw new Error('WebSocket controller config not found');\n }\n\n if (typeof ControllerClass !== 'function') {\n log('Controller not found', {\n Controller: route.controllerName,\n Path: `${controllersDirectory}/${route.controllerName}.${scriptFileExtension}`,\n });\n\n continue;\n }\n\n const controllerDependencies = this.getControllerDependencies();\n\n const controllerInstance = new ControllerClass(controllerDependencies as any);\n\n const controllerHandler = controllerInstance[route.action as keyof typeof controllerInstance] as\n | WebSocketMessageHandler\n | undefined;\n const routeKey = getRouteKey(route.type, route.action);\n\n if (typeof controllerHandler !== 'function') {\n log('Controller action not found', {\n Controller: route.controllerName ?? ControllerClass.name,\n Action: route.action,\n RouteKey: routeKey,\n });\n continue;\n }\n\n this.routeHandlers.set(routeKey, controllerHandler.bind(controllerInstance));\n }\n\n if (this.shouldPrintRoutes()) {\n log('Routes:', { Type: this.type });\n\n this.printRoutes();\n }\n }\n\n protected async handleServerMessage(\n ws: WebSocket,\n message: WebSocket.Data,\n clientId: string,\n ): Promise<{ type: unknown; action: unknown; response: unknown } | undefined> {\n try {\n const parsedMessage = parseServerMessage(message);\n const type = parsedMessage.type;\n const action = parsedMessage.action;\n\n log('Incoming message', {\n 'Client ID': clientId,\n Type: type ?? '-',\n Action: action ?? '-',\n });\n\n const routeKey = getRouteKey(parsedMessage.type as string, parsedMessage.action as string);\n\n const messageHandler = this.routeHandlers.get(routeKey);\n\n if (messageHandler) {\n const messageResponse = await messageHandler(ws, clientId, parsedMessage.data);\n\n return {\n type,\n action,\n response: messageResponse,\n };\n }\n // throw new Error(`Route handler not found (Route Key: ${routeKey} | Type: ${type} | Action: ${action})`);\n\n log('Route handler not found', {\n RouteKey: routeKey,\n Type: type,\n Action: action,\n });\n\n // if (\n // typeof this.applicationConfig.webSocket\n // ?.serverMessageHandler === 'function'\n // ) {\n // // Execute custom application subscriber event handler\n // this.applicationConfig.webSocket.serverMessageHandler(\n // {\n // ws,\n // clientId,\n // parsedMessage,\n // },\n // );\n // }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n log(errorMessage);\n\n this.handleMessageError(clientId, errorMessage);\n }\n }\n\n protected printRoutes(): void {\n let routesString = '';\n\n const routeKeys = Array.from(this.routeHandlers.keys());\n\n routeKeys.forEach((routeKey, index) => {\n const [type, action] = routeKey.split(':');\n\n routesString += `Type: ${type} -> Action: ${action}`;\n\n if (index !== routeKeys.length - 1) {\n routesString += '\\n';\n }\n });\n\n log(routesString);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-client-manager.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-client-manager.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAE3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAKnF,MAAM,CAAC,OAAO,OAAO,sBAAsB;IACzC,OAAO,CAAC,OAAO,CAA+C;IAC9D,wEAAwE;IACxE,OAAO,CAAC,YAAY,CAAqC;IAElD,SAAS,CAAC,EACf,QAAQ,EACR,EAAE,EACF,YAAY,EACZ,IAAI,GACL,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,EAAE,EAAE,SAAS,GAAG,IAAI,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,GAAG,CAAA;SAAE,GAAG,IAAI,CAAC;KAChD;IAsBM,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE;QAAE,EAAE,EAAE,SAAS,CAAA;KAAE,GAAG,MAAM,GAAG,SAAS;IAK1D,SAAS,CAAC,EACf,QAAQ,EACR,SAAS,GACV,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,GAAG,mBAAmB,GAAG,SAAS;IAU5B,YAAY,CAAC,EAClB,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,mBAAmB,GACpB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,GAAG,CAAC;QACV,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B;IA2CM,YAAY,CAAC,QAAQ,EAAE,MAAM;IAyB7B,aAAa;;kBAEN,MAAM;;IAcb,cAAc,CAAC,EACpB,GAAG,EACH,KAAK,EACL,SAAS,EACT,QAAQ,GACT,EAAE;QACD,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;;;;;;IA6BM,UAAU,CAAC,EAAE,QAAQ,EAAE,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO;IAgBnD,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE;IAwBnD,YAAY;IAwBZ,mBAAmB,CAAC,IAAI,EAAE,MAAM;IA0BhC,OAAO,IAAI,IAAI;CAuBvB"}
1
+ {"version":3,"file":"websocket-client-manager.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-client-manager.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,IAAI,CAAC;AAI3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAEnF,MAAM,CAAC,OAAO,OAAO,sBAAsB;IACzC,OAAO,CAAC,OAAO,CAA+C;IAC9D,wEAAwE;IACxE,OAAO,CAAC,YAAY,CAAqC;IAElD,SAAS,CAAC,EACf,QAAQ,EACR,EAAE,EACF,YAAY,EACZ,IAAI,GACL,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,EAAE,EAAE,SAAS,GAAG,IAAI,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,GAAG,CAAA;SAAE,GAAG,IAAI,CAAC;KAChD;IAsBM,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE;QAAE,EAAE,EAAE,SAAS,CAAA;KAAE,GAAG,MAAM,GAAG,SAAS;IAK1D,SAAS,CAAC,EACf,QAAQ,EACR,SAAS,GACV,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,GAAG,mBAAmB,GAAG,SAAS;IAU5B,YAAY,CAAC,EAClB,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,mBAAmB,GACpB,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,GAAG,CAAC;QACV,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B;IA2CM,YAAY,CAAC,QAAQ,EAAE,MAAM;IAyB7B,aAAa;;kBAEN,MAAM;;IAcb,cAAc,CAAC,EACpB,GAAG,EACH,KAAK,EACL,SAAS,EACT,QAAQ,GACT,EAAE;QACD,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;;;;;;IA6BM,UAAU,CAAC,EAAE,QAAQ,EAAE,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO;IAgBnD,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE;IAwBnD,YAAY;IAwBZ,mBAAmB,CAAC,IAAI,EAAE,MAAM;IA0BhC,OAAO,IAAI,IAAI;CAuBvB"}
@@ -1,10 +1,10 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ import cluster from "node:cluster";
3
4
  import WebSocket from "ws";
4
- import { log } from "./utils.js";
5
- import { Helper, Time } from "../util/index.js";
6
- import cluster from "cluster";
7
5
  import { safeSerializeError } from "../error/error-reporter.js";
6
+ import { Helper, Time } from "../util/index.js";
7
+ import { log } from "./utils.js";
8
8
  class WebSocketClientManager {
9
9
  static {
10
10
  __name(this, "WebSocketClientManager");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/websocket-client-manager.ts"],
4
- "sourcesContent": ["import WebSocket from 'ws';\nimport { log } from './utils.js';\nimport type { WebSocketClientData } from './websocket-client-manager.interface.js';\nimport { Helper, Time } from '../util/index.js';\nimport cluster from 'cluster';\nimport { safeSerializeError } from '../error/error-reporter.js';\n\nexport default class WebSocketClientManager {\n private clients: Map<string, WebSocketClientData> = new Map();\n /** Reverse lookup map for O(1) clientId lookup by WebSocket instance */\n private wsToClientId: Map<WebSocket, string> = new Map();\n\n public addClient({\n clientId,\n ws,\n lastActivity,\n user,\n }: {\n clientId: string;\n ws: WebSocket | null;\n lastActivity: number;\n user?: { userId: number; payload: any } | null;\n }) {\n this.clients.set(clientId, {\n ws,\n lastActivity,\n user,\n });\n\n // Maintain reverse lookup map for O(1) clientId lookups\n if (ws) {\n this.wsToClientId.set(ws, clientId);\n }\n\n this.broadcastClientList('addClient');\n\n log('Client connected', {\n ID: clientId,\n UserId: user?.userId ?? 'unauthenticated',\n });\n\n this.printClients();\n }\n\n public getClientId({ ws }: { ws: WebSocket }): string | undefined {\n // O(1) lookup using reverse map instead of O(n) iteration\n return this.wsToClientId.get(ws);\n }\n\n public getClient({\n clientId,\n requireWs,\n }: {\n clientId: string;\n requireWs?: boolean;\n }): WebSocketClientData | undefined {\n const client = this.clients.get(clientId);\n\n if (requireWs && !client?.ws) {\n return undefined;\n }\n\n return client;\n }\n\n public updateClient({\n clientId,\n key,\n data,\n broadcastClientList,\n }: {\n clientId: string;\n key: string;\n data: any;\n broadcastClientList?: boolean;\n }) {\n const client = this.clients.get(clientId);\n\n if (!client) {\n return;\n }\n\n // Prevent prototype pollution attacks\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n log('Blocked attempt to modify dangerous property', { Property: key });\n return;\n }\n\n // Define allowed client properties to prevent unauthorized modifications\n const allowedClientProperties = [\n 'id',\n 'ws',\n 'room',\n 'userId',\n 'username',\n 'metadata',\n 'connectedAt',\n 'lastActivity',\n 'status',\n 'permissions',\n ];\n\n if (!allowedClientProperties.includes(key)) {\n log('Blocked attempt to modify unauthorized property', { Property: key });\n return;\n }\n\n Reflect.set(client, key, data);\n\n this.clients.set(clientId, client);\n\n if (broadcastClientList !== false) {\n this.broadcastClientList('updateClient');\n }\n\n this.printClients();\n }\n\n public removeClient(clientId: string) {\n const client = this.clients.get(clientId);\n\n // Clean up WebSocket connection if it exists\n if (client?.ws) {\n // Remove from reverse lookup map\n this.wsToClientId.delete(client.ws);\n\n try {\n client.ws.removeAllListeners();\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.close();\n }\n } catch (error) {\n log('Error cleaning up WebSocket connection', {\n error: error instanceof Error ? error.message : safeSerializeError(error),\n });\n }\n }\n\n this.clients.delete(clientId);\n this.broadcastClientList('removeClient');\n this.printClients();\n }\n\n public getClientList() {\n const clientList: {\n clientId: string;\n [key: string]: any;\n }[] = [];\n\n this.clients.forEach((clientData, clientId) => {\n clientList.push({\n clientId,\n ...clientData,\n });\n });\n\n return clientList;\n }\n\n public getClientByKey({\n key,\n value,\n requireWs,\n userType,\n }: {\n key: string;\n value: string;\n requireWs?: boolean;\n userType?: string;\n }) {\n const clients = [...this.clients.entries()];\n\n const client = clients.find(([_, clientData]) => {\n const deepKeyValue = Helper.getValueFromObject(clientData, key);\n\n const isValueMatching = deepKeyValue === value;\n\n if (userType && clientData.user?.userType !== userType) {\n return false;\n }\n\n return isValueMatching;\n });\n\n const formattedClient = client\n ? {\n clientId: client[0],\n ...client[1],\n }\n : undefined;\n\n if (requireWs && !formattedClient?.ws) {\n return undefined;\n }\n\n return formattedClient;\n }\n\n public getClients({ userType }: { userType?: string } = {}) {\n const clients: WebSocketClientData[] = [];\n\n this.clients.forEach((clientData, clientId) => {\n if (userType && clientData.user?.userType !== userType) {\n return;\n }\n\n clientData.clientId = clientId;\n\n clients.push(clientData);\n });\n\n return clients;\n }\n\n public disconnectClient({ clientId }: { clientId: string }) {\n const clientInfo = this.clients.get(clientId);\n\n if (clientInfo?.ws) {\n const connectedTime = Date.now() - clientInfo.lastActivity;\n\n clientInfo.ws.close();\n\n log('WebSocket client was disconnected due to inactivity', {\n ID: clientId,\n 'Time Connected': Time.formatTime({\n time: connectedTime,\n format: 's',\n }),\n });\n }\n\n this.removeClient(clientId);\n\n log('Client disconnected', { ID: clientId });\n\n this.printClients();\n }\n\n public printClients() {\n const numClients = this.clients.size;\n\n const workerId = cluster.isWorker && cluster.worker ? cluster.worker.id : null;\n\n let logOutput = '\\n-------------------------------------------------------\\n';\n logOutput += `Connected clients (Count: ${numClients}${workerId ? ` | Worker: ${workerId}` : ''}):\\n`;\n logOutput += '-------------------------------------------------------\\n';\n\n if (numClients > 0) {\n this.clients.forEach((client, clientId) => {\n logOutput += `ID: ${clientId} | Username: ${client?.user?.username ?? '-'} | User Type: ${client?.user?.userType ?? '-'} | Email: ${client.user?.email ?? '-'}\\n`;\n });\n } else {\n logOutput += 'No clients';\n }\n\n logOutput += '\\n';\n\n log(logOutput, undefined, {\n muteWorker: true,\n });\n }\n\n public broadcastClientList(type: string) {\n const clientList = this.getClientList();\n\n this.clients.forEach(({ ws }) => {\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n return;\n }\n\n try {\n ws.send(\n JSON.stringify({\n type: 'system',\n action: 'clientList',\n clientListType: type,\n data: clientList,\n }),\n );\n } catch (error) {\n // Handle send errors (e.g., connection closed)\n log('Error broadcasting client list', {\n error: error instanceof Error ? error.message : safeSerializeError(error),\n });\n }\n });\n }\n\n public cleanup(): void {\n // Clean up all client connections\n this.clients.forEach((client, clientId) => {\n if (client.ws) {\n try {\n client.ws.removeAllListeners();\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.close();\n }\n } catch (error) {\n log('Error cleaning up client connection', {\n clientId,\n error: error instanceof Error ? error.message : safeSerializeError(error),\n });\n }\n }\n });\n\n // Clear all maps\n this.clients.clear();\n this.wsToClientId.clear();\n log('WebSocket client manager cleaned up');\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import cluster from 'node:cluster';\nimport WebSocket from 'ws';\nimport { safeSerializeError } from '../error/error-reporter.js';\nimport { Helper, Time } from '../util/index.js';\nimport { log } from './utils.js';\nimport type { WebSocketClientData } from './websocket-client-manager.interface.js';\n\nexport default class WebSocketClientManager {\n private clients: Map<string, WebSocketClientData> = new Map();\n /** Reverse lookup map for O(1) clientId lookup by WebSocket instance */\n private wsToClientId: Map<WebSocket, string> = new Map();\n\n public addClient({\n clientId,\n ws,\n lastActivity,\n user,\n }: {\n clientId: string;\n ws: WebSocket | null;\n lastActivity: number;\n user?: { userId: number; payload: any } | null;\n }) {\n this.clients.set(clientId, {\n ws,\n lastActivity,\n user,\n });\n\n // Maintain reverse lookup map for O(1) clientId lookups\n if (ws) {\n this.wsToClientId.set(ws, clientId);\n }\n\n this.broadcastClientList('addClient');\n\n log('Client connected', {\n ID: clientId,\n UserId: user?.userId ?? 'unauthenticated',\n });\n\n this.printClients();\n }\n\n public getClientId({ ws }: { ws: WebSocket }): string | undefined {\n // O(1) lookup using reverse map instead of O(n) iteration\n return this.wsToClientId.get(ws);\n }\n\n public getClient({\n clientId,\n requireWs,\n }: {\n clientId: string;\n requireWs?: boolean;\n }): WebSocketClientData | undefined {\n const client = this.clients.get(clientId);\n\n if (requireWs && !client?.ws) {\n return undefined;\n }\n\n return client;\n }\n\n public updateClient({\n clientId,\n key,\n data,\n broadcastClientList,\n }: {\n clientId: string;\n key: string;\n data: any;\n broadcastClientList?: boolean;\n }) {\n const client = this.clients.get(clientId);\n\n if (!client) {\n return;\n }\n\n // Prevent prototype pollution attacks\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n log('Blocked attempt to modify dangerous property', { Property: key });\n return;\n }\n\n // Define allowed client properties to prevent unauthorized modifications\n const allowedClientProperties = [\n 'id',\n 'ws',\n 'room',\n 'userId',\n 'username',\n 'metadata',\n 'connectedAt',\n 'lastActivity',\n 'status',\n 'permissions',\n ];\n\n if (!allowedClientProperties.includes(key)) {\n log('Blocked attempt to modify unauthorized property', { Property: key });\n return;\n }\n\n Reflect.set(client, key, data);\n\n this.clients.set(clientId, client);\n\n if (broadcastClientList !== false) {\n this.broadcastClientList('updateClient');\n }\n\n this.printClients();\n }\n\n public removeClient(clientId: string) {\n const client = this.clients.get(clientId);\n\n // Clean up WebSocket connection if it exists\n if (client?.ws) {\n // Remove from reverse lookup map\n this.wsToClientId.delete(client.ws);\n\n try {\n client.ws.removeAllListeners();\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.close();\n }\n } catch (error) {\n log('Error cleaning up WebSocket connection', {\n error: error instanceof Error ? error.message : safeSerializeError(error),\n });\n }\n }\n\n this.clients.delete(clientId);\n this.broadcastClientList('removeClient');\n this.printClients();\n }\n\n public getClientList() {\n const clientList: {\n clientId: string;\n [key: string]: any;\n }[] = [];\n\n this.clients.forEach((clientData, clientId) => {\n clientList.push({\n clientId,\n ...clientData,\n });\n });\n\n return clientList;\n }\n\n public getClientByKey({\n key,\n value,\n requireWs,\n userType,\n }: {\n key: string;\n value: string;\n requireWs?: boolean;\n userType?: string;\n }) {\n const clients = [...this.clients.entries()];\n\n const client = clients.find(([_, clientData]) => {\n const deepKeyValue = Helper.getValueFromObject(clientData, key);\n\n const isValueMatching = deepKeyValue === value;\n\n if (userType && clientData.user?.userType !== userType) {\n return false;\n }\n\n return isValueMatching;\n });\n\n const formattedClient = client\n ? {\n clientId: client[0],\n ...client[1],\n }\n : undefined;\n\n if (requireWs && !formattedClient?.ws) {\n return undefined;\n }\n\n return formattedClient;\n }\n\n public getClients({ userType }: { userType?: string } = {}) {\n const clients: WebSocketClientData[] = [];\n\n this.clients.forEach((clientData, clientId) => {\n if (userType && clientData.user?.userType !== userType) {\n return;\n }\n\n clientData.clientId = clientId;\n\n clients.push(clientData);\n });\n\n return clients;\n }\n\n public disconnectClient({ clientId }: { clientId: string }) {\n const clientInfo = this.clients.get(clientId);\n\n if (clientInfo?.ws) {\n const connectedTime = Date.now() - clientInfo.lastActivity;\n\n clientInfo.ws.close();\n\n log('WebSocket client was disconnected due to inactivity', {\n ID: clientId,\n 'Time Connected': Time.formatTime({\n time: connectedTime,\n format: 's',\n }),\n });\n }\n\n this.removeClient(clientId);\n\n log('Client disconnected', { ID: clientId });\n\n this.printClients();\n }\n\n public printClients() {\n const numClients = this.clients.size;\n\n const workerId = cluster.isWorker && cluster.worker ? cluster.worker.id : null;\n\n let logOutput = '\\n-------------------------------------------------------\\n';\n logOutput += `Connected clients (Count: ${numClients}${workerId ? ` | Worker: ${workerId}` : ''}):\\n`;\n logOutput += '-------------------------------------------------------\\n';\n\n if (numClients > 0) {\n this.clients.forEach((client, clientId) => {\n logOutput += `ID: ${clientId} | Username: ${client?.user?.username ?? '-'} | User Type: ${client?.user?.userType ?? '-'} | Email: ${client.user?.email ?? '-'}\\n`;\n });\n } else {\n logOutput += 'No clients';\n }\n\n logOutput += '\\n';\n\n log(logOutput, undefined, {\n muteWorker: true,\n });\n }\n\n public broadcastClientList(type: string) {\n const clientList = this.getClientList();\n\n this.clients.forEach(({ ws }) => {\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n return;\n }\n\n try {\n ws.send(\n JSON.stringify({\n type: 'system',\n action: 'clientList',\n clientListType: type,\n data: clientList,\n }),\n );\n } catch (error) {\n // Handle send errors (e.g., connection closed)\n log('Error broadcasting client list', {\n error: error instanceof Error ? error.message : safeSerializeError(error),\n });\n }\n });\n }\n\n public cleanup(): void {\n // Clean up all client connections\n this.clients.forEach((client, clientId) => {\n if (client.ws) {\n try {\n client.ws.removeAllListeners();\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.close();\n }\n } catch (error) {\n log('Error cleaning up client connection', {\n clientId,\n error: error instanceof Error ? error.message : safeSerializeError(error),\n });\n }\n }\n });\n\n // Clear all maps\n this.clients.clear();\n this.wsToClientId.clear();\n log('WebSocket client manager cleaned up');\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,9 +1,9 @@
1
- import type { WebSocketRoute, WebSocketType } from './websocket.interface.js';
2
- import type RedisInstance from '../redis/instance.js';
3
- import type QueueManager from '../queue/manager.js';
4
1
  import type DatabaseInstance from '../database/instance.js';
5
- import type { WebSocketClientProps } from './websocket-client.interface.js';
2
+ import type QueueManager from '../queue/manager.js';
3
+ import type RedisInstance from '../redis/instance.js';
4
+ import type { WebSocketRoute, WebSocketType } from './websocket.interface.js';
6
5
  import WebSocketBase from './websocket-base.js';
6
+ import type { WebSocketClientProps } from './websocket-client.interface.js';
7
7
  export default class WebSocketClient extends WebSocketBase {
8
8
  protected defaultRoutes: WebSocketRoute[];
9
9
  private applicationConfig;
@@ -31,7 +31,7 @@ export default class WebSocketClient extends WebSocketBase {
31
31
  };
32
32
  protected shouldPrintRoutes(): boolean;
33
33
  private handleIncomingMessage;
34
- protected handleMessageError(clientId: string, error: string): void;
34
+ protected handleMessageError(_clientId: string, error: string): void;
35
35
  sendClientMessage: (data: unknown, binary?: boolean) => void;
36
36
  sendMessage: (data: unknown) => void;
37
37
  disconnect(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-client.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAE5E,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAMhD,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,aAAa;IACxD,SAAS,CAAC,aAAa,EAAE,cAAc,EAAE,CAMvC;IAEF,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,EAAE,CAAC,CAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,oBAAoB,CAAc;IAC1C,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,eAAe,CAAiB;gBAE5B,KAAK,EAAE,oBAAoB;IAWvC,IAAW,IAAI,IAAI,aAAa,CAE/B;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IA+E7C,SAAS,CAAC,yBAAyB,IAAI;QACrC,WAAW,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;QACrC,aAAa,EAAE,aAAa,CAAC;QAC7B,YAAY,EAAE,YAAY,CAAC;QAC3B,gBAAgB,EAAE,gBAAgB,CAAC;KACpC;IAQD,SAAS,CAAC,iBAAiB,IAAI,OAAO;IAItC,OAAO,CAAC,qBAAqB,CAqB3B;IAEF,SAAS,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI5D,iBAAiB,GAAI,MAAM,OAAO,EAAE,SAAQ,OAAe,KAAG,IAAI,CAUvE;IAEK,WAAW,GAAI,MAAM,OAAO,KAAG,IAAI,CAExC;IAEK,UAAU,IAAI,IAAI;IAoBlB,iBAAiB,IAAI,OAAO;IAInC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAqCzB;;OAEG;YACW,gBAAgB;IA4B9B;;OAEG;IACI,mBAAmB,IAAI,IAAI;IAIlC;;OAEG;IACI,oBAAoB,IAAI,IAAI;IASnC;;OAEG;IACI,mBAAmB,IAAI;QAC5B,WAAW,EAAE,OAAO,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,oBAAoB,EAAE,OAAO,CAAC;KAC/B;IAQD;;;OAGG;IACI,OAAO,IAAI,IAAI;CAyBvB"}
1
+ {"version":3,"file":"websocket-client.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAG5D,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAoB,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAE5E,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,aAAa;IACxD,SAAS,CAAC,aAAa,EAAE,cAAc,EAAE,CAMvC;IAEF,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,EAAE,CAAC,CAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,oBAAoB,CAAc;IAC1C,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,eAAe,CAAiB;gBAE5B,KAAK,EAAE,oBAAoB;IAWvC,IAAW,IAAI,IAAI,aAAa,CAE/B;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IA+E7C,SAAS,CAAC,yBAAyB,IAAI;QACrC,WAAW,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;QACrC,aAAa,EAAE,aAAa,CAAC;QAC7B,YAAY,EAAE,YAAY,CAAC;QAC3B,gBAAgB,EAAE,gBAAgB,CAAC;KACpC;IAQD,SAAS,CAAC,iBAAiB,IAAI,OAAO;IAItC,OAAO,CAAC,qBAAqB,CAqB3B;IAEF,SAAS,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7D,iBAAiB,GAAI,MAAM,OAAO,EAAE,SAAQ,OAAe,KAAG,IAAI,CAUvE;IAEK,WAAW,GAAI,MAAM,OAAO,KAAG,IAAI,CAExC;IAEK,UAAU,IAAI,IAAI;IAoBlB,iBAAiB,IAAI,OAAO;IAInC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAqCzB;;OAEG;YACW,gBAAgB;IA4B9B;;OAEG;IACI,mBAAmB,IAAI,IAAI;IAIlC;;OAEG;IACI,oBAAoB,IAAI,IAAI;IASnC;;OAEG;IACI,mBAAmB,IAAI;QAC5B,WAAW,EAAE,OAAO,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,oBAAoB,EAAE,OAAO,CAAC;KAC/B;IAQD;;;OAGG;IACI,OAAO,IAAI,IAAI;CAyBvB"}
@@ -1,11 +1,11 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ import path from "node:path";
3
4
  import WebSocket from "ws";
4
- import { generateClientId, log, parseServerMessage } from "./utils.js";
5
- import WebSocketBase from "./websocket-base.js";
6
- import path from "path";
7
5
  import { safeSerializeError } from "../error/error-reporter.js";
8
6
  import { baseDir } from "../index.js";
7
+ import { generateClientId, log, parseServerMessage } from "./utils.js";
8
+ import WebSocketBase from "./websocket-base.js";
9
9
  class WebSocketClient extends WebSocketBase {
10
10
  static {
11
11
  __name(this, "WebSocketClient");
@@ -133,7 +133,7 @@ class WebSocketClient extends WebSocketBase {
133
133
  }
134
134
  await this.handleServerMessage(this.ws, message, this.clientId);
135
135
  }, "handleIncomingMessage");
136
- handleMessageError(clientId, error) {
136
+ handleMessageError(_clientId, error) {
137
137
  log(error);
138
138
  }
139
139
  sendClientMessage = /* @__PURE__ */ __name((data, binary = false) => {
@@ -180,7 +180,7 @@ class WebSocketClient extends WebSocketBase {
180
180
  }
181
181
  return;
182
182
  }
183
- const delay = Math.min(this.reconnectDelay * Math.pow(2, this.reconnectAttempts), 3e4);
183
+ const delay = Math.min(this.reconnectDelay * 2 ** this.reconnectAttempts, 3e4);
184
184
  this.reconnectAttempts++;
185
185
  log("Scheduling reconnection", {
186
186
  Attempt: this.reconnectAttempts,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/websocket-client.ts"],
4
- "sourcesContent": ["import WebSocket, { type RawData } from 'ws';\nimport type { WebSocketOptions, WebSocketRoute, WebSocketType } 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 { WebSocketClientProps } from './websocket-client.interface.js';\nimport { generateClientId, log, parseServerMessage } from './utils.js';\nimport WebSocketBase from './websocket-base.js';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport path from 'path';\nimport { safeSerializeError } from '../error/error-reporter.js';\nimport { baseDir } from '../index.js';\n\nexport default class WebSocketClient extends WebSocketBase {\n protected defaultRoutes: WebSocketRoute[] = [\n {\n type: 'system',\n action: 'clientList',\n controllerName: 'system',\n },\n ];\n\n private applicationConfig: ApplicationConfig;\n private options: WebSocketOptions;\n private redisInstance: RedisInstance;\n private queueManager: QueueManager;\n private databaseInstance: DatabaseInstance;\n private ws?: WebSocket;\n private clientId?: string;\n private isConnected: boolean = false;\n private reconnectAttempts: number = 0;\n private maxReconnectAttempts: number = 10;\n private reconnectDelay: number = 1000; // Start with 1 second\n private reconnectTimer?: NodeJS.Timeout;\n private shouldReconnect: boolean = true;\n\n constructor(props: WebSocketClientProps) {\n super();\n\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 }\n\n public get type(): WebSocketType {\n return 'client';\n }\n\n public async load(): Promise<void> {\n const libraryControllersDirectory = path.join(baseDir, 'websocket', 'controllers', 'client');\n\n await this.configureRoutes(this.defaultRoutes, libraryControllersDirectory);\n\n await this.configureRoutes(this.routes, this.options.controllersDirectory);\n }\n\n public async connectToServer(): Promise<void> {\n const url = this.options.url;\n // const host = this.options.host;\n // const port = this.options.port;\n\n return new Promise(resolve => {\n const ws = new WebSocket(url);\n\n ws.on('open', () => {\n this.clientId = generateClientId();\n this.isConnected = true;\n\n log('Connected to server', { ID: this.clientId });\n\n if (this.options.events?.onConnected) {\n this.options.events.onConnected({\n ws,\n clientId: this.clientId,\n joinRoom: ({\n userId,\n userType,\n username,\n roomName,\n }: {\n userId?: string;\n userType?: string;\n username: string;\n roomName: string;\n }) => {\n this.sendClientMessage({\n type: 'system',\n action: 'joinRoom',\n data: {\n userId,\n userType,\n username,\n roomName,\n },\n });\n },\n });\n }\n\n resolve();\n });\n\n ws.on('message', this.handleIncomingMessage);\n\n ws.on('close', code => {\n this.isConnected = false;\n log('Connection to server closed', { Code: code });\n\n if (this.options.events?.onDisconnected) {\n this.options.events.onDisconnected({ clientId: this.clientId });\n }\n\n // Clean up event listeners to prevent memory leaks\n ws.removeAllListeners();\n this.ws = undefined;\n this.clientId = undefined;\n\n // Attempt to reconnect if not manually disconnected\n if (this.shouldReconnect) {\n this.scheduleReconnect();\n }\n });\n\n ws.on('error', error => {\n log('WebSocket error', { error: error.message });\n\n if (this.options.events?.onError) {\n this.options.events.onError({ error });\n }\n });\n\n this.ws = ws;\n });\n }\n\n protected getControllerDependencies(): {\n sendMessage: (data: unknown) => void;\n redisInstance: RedisInstance;\n queueManager: QueueManager;\n databaseInstance: DatabaseInstance;\n } {\n return {\n sendMessage: this.sendMessage,\n redisInstance: this.redisInstance,\n queueManager: this.queueManager,\n databaseInstance: this.databaseInstance,\n };\n }\n protected shouldPrintRoutes(): boolean {\n return this.options.debug?.printRoutes ?? false;\n }\n\n private handleIncomingMessage = async (message: RawData): Promise<void> => {\n if (!this.ws || !this.clientId) {\n log('WebSocket not initialized or client ID not set');\n\n return;\n }\n\n if (this.options.events?.onMessage) {\n const parsedMessage = parseServerMessage(message);\n\n this.options.events.onMessage({\n ws: this.ws,\n clientId: this.clientId,\n data: parsedMessage as { type: string; action: string; data: unknown },\n redisInstance: this.redisInstance,\n queueManager: this.queueManager,\n databaseInstance: this.databaseInstance,\n });\n }\n\n await this.handleServerMessage(this.ws, message, this.clientId);\n };\n\n protected handleMessageError(clientId: string, error: string): void {\n log(error);\n }\n\n public sendClientMessage = (data: unknown, binary: boolean = false): void => {\n if (!this.ws) {\n log('WebSocket not initialized');\n\n return;\n }\n\n const webSocketMessage = JSON.stringify(data);\n\n this.ws.send(webSocketMessage, { binary });\n };\n\n public sendMessage = (data: unknown): void => {\n this.sendClientMessage(data);\n };\n\n public disconnect(): void {\n // Disable auto-reconnect on manual disconnect\n this.shouldReconnect = false;\n\n // Clear any pending reconnect timer\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n if (this.ws && this.isConnected) {\n this.ws.removeAllListeners();\n this.ws.close();\n this.ws = undefined;\n this.clientId = undefined;\n this.isConnected = false;\n log('WebSocket client disconnected');\n }\n }\n\n public isClientConnected(): boolean {\n return this.isConnected && this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Schedule a reconnection attempt with exponential backoff\n */\n private scheduleReconnect(): void {\n // Don't reconnect if we've exceeded max attempts\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n log('Max reconnection attempts reached', {\n Attempts: this.reconnectAttempts,\n });\n\n if (this.options.events?.onReconnectFailed) {\n this.options.events.onReconnectFailed({\n attempts: this.reconnectAttempts,\n });\n }\n\n return;\n }\n\n // Calculate delay with exponential backoff (max 30 seconds)\n const delay = Math.min(this.reconnectDelay * Math.pow(2, this.reconnectAttempts), 30000);\n this.reconnectAttempts++;\n\n log('Scheduling reconnection', {\n Attempt: this.reconnectAttempts,\n Delay: `${delay}ms`,\n });\n\n if (this.options.events?.onReconnecting) {\n this.options.events.onReconnecting({\n attempt: this.reconnectAttempts,\n delay,\n });\n }\n\n this.reconnectTimer = setTimeout(() => {\n this.attemptReconnect();\n }, delay);\n }\n\n /**\n * Attempt to reconnect to the server\n */\n private async attemptReconnect(): Promise<void> {\n try {\n log('Attempting to reconnect...', {\n Attempt: this.reconnectAttempts,\n });\n\n await this.connectToServer();\n\n // Reset reconnect attempts on successful connection\n this.reconnectAttempts = 0;\n\n log('Reconnection successful');\n\n if (this.options.events?.onReconnected) {\n this.options.events.onReconnected({\n clientId: this.clientId,\n });\n }\n } catch (error) {\n log('Reconnection failed', {\n Error: error instanceof Error ? error.message : safeSerializeError(error),\n });\n\n // Schedule next attempt\n this.scheduleReconnect();\n }\n }\n\n /**\n * Enable auto-reconnection\n */\n public enableAutoReconnect(): void {\n this.shouldReconnect = true;\n }\n\n /**\n * Disable auto-reconnection\n */\n public disableAutoReconnect(): void {\n this.shouldReconnect = false;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n }\n\n /**\n * Get connection status\n */\n public getConnectionStatus(): {\n isConnected: boolean;\n reconnectAttempts: number;\n autoReconnectEnabled: boolean;\n } {\n return {\n isConnected: this.isConnected,\n reconnectAttempts: this.reconnectAttempts,\n autoReconnectEnabled: this.shouldReconnect,\n };\n }\n\n /**\n * Destroy the client and clean up all resources.\n * This should be called when the client is no longer needed to prevent memory leaks.\n */\n public destroy(): void {\n // Ensure all timers are cleared\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n // Disable reconnection\n this.shouldReconnect = false;\n\n // Clean up WebSocket connection\n if (this.ws) {\n this.ws.removeAllListeners();\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close();\n }\n this.ws = undefined;\n }\n\n this.clientId = undefined;\n this.isConnected = false;\n this.reconnectAttempts = 0;\n\n log('WebSocket client destroyed');\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'node:path';\nimport WebSocket, { type RawData } from 'ws';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type DatabaseInstance from '../database/instance.js';\nimport { safeSerializeError } from '../error/error-reporter.js';\nimport { baseDir } from '../index.js';\nimport type QueueManager from '../queue/manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport { generateClientId, log, parseServerMessage } from './utils.js';\nimport type { WebSocketOptions, WebSocketRoute, WebSocketType } from './websocket.interface.js';\nimport WebSocketBase from './websocket-base.js';\nimport type { WebSocketClientProps } from './websocket-client.interface.js';\n\nexport default class WebSocketClient extends WebSocketBase {\n protected defaultRoutes: WebSocketRoute[] = [\n {\n type: 'system',\n action: 'clientList',\n controllerName: 'system',\n },\n ];\n\n private applicationConfig: ApplicationConfig;\n private options: WebSocketOptions;\n private redisInstance: RedisInstance;\n private queueManager: QueueManager;\n private databaseInstance: DatabaseInstance;\n private ws?: WebSocket;\n private clientId?: string;\n private isConnected: boolean = false;\n private reconnectAttempts: number = 0;\n private maxReconnectAttempts: number = 10;\n private reconnectDelay: number = 1000; // Start with 1 second\n private reconnectTimer?: NodeJS.Timeout;\n private shouldReconnect: boolean = true;\n\n constructor(props: WebSocketClientProps) {\n super();\n\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 }\n\n public get type(): WebSocketType {\n return 'client';\n }\n\n public async load(): Promise<void> {\n const libraryControllersDirectory = path.join(baseDir, 'websocket', 'controllers', 'client');\n\n await this.configureRoutes(this.defaultRoutes, libraryControllersDirectory);\n\n await this.configureRoutes(this.routes, this.options.controllersDirectory);\n }\n\n public async connectToServer(): Promise<void> {\n const url = this.options.url;\n // const host = this.options.host;\n // const port = this.options.port;\n\n return new Promise(resolve => {\n const ws = new WebSocket(url);\n\n ws.on('open', () => {\n this.clientId = generateClientId();\n this.isConnected = true;\n\n log('Connected to server', { ID: this.clientId });\n\n if (this.options.events?.onConnected) {\n this.options.events.onConnected({\n ws,\n clientId: this.clientId,\n joinRoom: ({\n userId,\n userType,\n username,\n roomName,\n }: {\n userId?: string;\n userType?: string;\n username: string;\n roomName: string;\n }) => {\n this.sendClientMessage({\n type: 'system',\n action: 'joinRoom',\n data: {\n userId,\n userType,\n username,\n roomName,\n },\n });\n },\n });\n }\n\n resolve();\n });\n\n ws.on('message', this.handleIncomingMessage);\n\n ws.on('close', code => {\n this.isConnected = false;\n log('Connection to server closed', { Code: code });\n\n if (this.options.events?.onDisconnected) {\n this.options.events.onDisconnected({ clientId: this.clientId });\n }\n\n // Clean up event listeners to prevent memory leaks\n ws.removeAllListeners();\n this.ws = undefined;\n this.clientId = undefined;\n\n // Attempt to reconnect if not manually disconnected\n if (this.shouldReconnect) {\n this.scheduleReconnect();\n }\n });\n\n ws.on('error', error => {\n log('WebSocket error', { error: error.message });\n\n if (this.options.events?.onError) {\n this.options.events.onError({ error });\n }\n });\n\n this.ws = ws;\n });\n }\n\n protected getControllerDependencies(): {\n sendMessage: (data: unknown) => void;\n redisInstance: RedisInstance;\n queueManager: QueueManager;\n databaseInstance: DatabaseInstance;\n } {\n return {\n sendMessage: this.sendMessage,\n redisInstance: this.redisInstance,\n queueManager: this.queueManager,\n databaseInstance: this.databaseInstance,\n };\n }\n protected shouldPrintRoutes(): boolean {\n return this.options.debug?.printRoutes ?? false;\n }\n\n private handleIncomingMessage = async (message: RawData): Promise<void> => {\n if (!this.ws || !this.clientId) {\n log('WebSocket not initialized or client ID not set');\n\n return;\n }\n\n if (this.options.events?.onMessage) {\n const parsedMessage = parseServerMessage(message);\n\n this.options.events.onMessage({\n ws: this.ws,\n clientId: this.clientId,\n data: parsedMessage as { type: string; action: string; data: unknown },\n redisInstance: this.redisInstance,\n queueManager: this.queueManager,\n databaseInstance: this.databaseInstance,\n });\n }\n\n await this.handleServerMessage(this.ws, message, this.clientId);\n };\n\n protected handleMessageError(_clientId: string, error: string): void {\n log(error);\n }\n\n public sendClientMessage = (data: unknown, binary: boolean = false): void => {\n if (!this.ws) {\n log('WebSocket not initialized');\n\n return;\n }\n\n const webSocketMessage = JSON.stringify(data);\n\n this.ws.send(webSocketMessage, { binary });\n };\n\n public sendMessage = (data: unknown): void => {\n this.sendClientMessage(data);\n };\n\n public disconnect(): void {\n // Disable auto-reconnect on manual disconnect\n this.shouldReconnect = false;\n\n // Clear any pending reconnect timer\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n if (this.ws && this.isConnected) {\n this.ws.removeAllListeners();\n this.ws.close();\n this.ws = undefined;\n this.clientId = undefined;\n this.isConnected = false;\n log('WebSocket client disconnected');\n }\n }\n\n public isClientConnected(): boolean {\n return this.isConnected && this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Schedule a reconnection attempt with exponential backoff\n */\n private scheduleReconnect(): void {\n // Don't reconnect if we've exceeded max attempts\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n log('Max reconnection attempts reached', {\n Attempts: this.reconnectAttempts,\n });\n\n if (this.options.events?.onReconnectFailed) {\n this.options.events.onReconnectFailed({\n attempts: this.reconnectAttempts,\n });\n }\n\n return;\n }\n\n // Calculate delay with exponential backoff (max 30 seconds)\n const delay = Math.min(this.reconnectDelay * 2 ** this.reconnectAttempts, 30000);\n this.reconnectAttempts++;\n\n log('Scheduling reconnection', {\n Attempt: this.reconnectAttempts,\n Delay: `${delay}ms`,\n });\n\n if (this.options.events?.onReconnecting) {\n this.options.events.onReconnecting({\n attempt: this.reconnectAttempts,\n delay,\n });\n }\n\n this.reconnectTimer = setTimeout(() => {\n this.attemptReconnect();\n }, delay);\n }\n\n /**\n * Attempt to reconnect to the server\n */\n private async attemptReconnect(): Promise<void> {\n try {\n log('Attempting to reconnect...', {\n Attempt: this.reconnectAttempts,\n });\n\n await this.connectToServer();\n\n // Reset reconnect attempts on successful connection\n this.reconnectAttempts = 0;\n\n log('Reconnection successful');\n\n if (this.options.events?.onReconnected) {\n this.options.events.onReconnected({\n clientId: this.clientId,\n });\n }\n } catch (error) {\n log('Reconnection failed', {\n Error: error instanceof Error ? error.message : safeSerializeError(error),\n });\n\n // Schedule next attempt\n this.scheduleReconnect();\n }\n }\n\n /**\n * Enable auto-reconnection\n */\n public enableAutoReconnect(): void {\n this.shouldReconnect = true;\n }\n\n /**\n * Disable auto-reconnection\n */\n public disableAutoReconnect(): void {\n this.shouldReconnect = false;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n }\n\n /**\n * Get connection status\n */\n public getConnectionStatus(): {\n isConnected: boolean;\n reconnectAttempts: number;\n autoReconnectEnabled: boolean;\n } {\n return {\n isConnected: this.isConnected,\n reconnectAttempts: this.reconnectAttempts,\n autoReconnectEnabled: this.shouldReconnect,\n };\n }\n\n /**\n * Destroy the client and clean up all resources.\n * This should be called when the client is no longer needed to prevent memory leaks.\n */\n public destroy(): void {\n // Ensure all timers are cleared\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n\n // Disable reconnection\n this.shouldReconnect = false;\n\n // Clean up WebSocket connection\n if (this.ws) {\n this.ws.removeAllListeners();\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close();\n }\n this.ws = undefined;\n }\n\n this.clientId = undefined;\n this.isConnected = false;\n this.reconnectAttempts = 0;\n\n log('WebSocket client destroyed');\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- import cluster from "cluster";
3
+ import cluster from "node:cluster";
4
4
  import { log } from "./utils.js";
5
5
  class WebSocketRoomManager {
6
6
  static {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/websocket-room-manager.ts"],
4
- "sourcesContent": ["import cluster from 'cluster';\nimport { log } from './utils.js';\nimport type WebSocketClientManager from './websocket-client-manager.js';\n\nexport default class WebSocketRoomManager {\n private clientManager: WebSocketClientManager;\n\n public rooms: Map<string, Set<string>> = new Map();\n\n constructor({ clientManager }: { clientManager: WebSocketClientManager }) {\n this.clientManager = clientManager;\n }\n\n public addClientToRoom({\n clientId,\n user,\n roomName,\n broadcast,\n }: {\n clientId: string;\n user: any;\n roomName: string;\n broadcast?: boolean;\n }) {\n // Check if room exists\n if (!this.rooms.has(roomName)) {\n // Create room\n this.rooms.set(roomName, new Set());\n }\n\n // Get room from room name\n const room = this.rooms.get(roomName);\n\n if (!room) {\n log('Room not found when adding client', { Name: roomName });\n\n return;\n }\n\n // Add client to room\n room.add(clientId);\n\n // Set room name in client manager\n this.clientManager.updateClient({\n clientId,\n key: 'roomName',\n data: roomName,\n });\n\n if (broadcast !== false) {\n this.clientManager.broadcastClientList('clientAddedToRoom');\n }\n\n this.printRooms();\n\n log('Client joined room', {\n 'User Type': user?.userType ?? '-',\n Room: roomName,\n ID: clientId,\n Email: user.email ?? '-',\n });\n }\n\n public removeClientFromRoom({\n roomName,\n clientId,\n broadcast,\n }: {\n roomName: string;\n clientId: string;\n broadcast?: boolean;\n }) {\n // Get room from room name\n const room = this.rooms.get(roomName);\n\n if (!room) {\n log('Room not found when removing client', { Name: roomName });\n\n return;\n }\n\n // Get clients in room\n const clientsInRoom = this.rooms.get(roomName);\n\n if (!clientsInRoom) {\n return;\n }\n\n // Remove client from room list\n clientsInRoom.delete(clientId);\n\n // Check if there are no clients in the room\n if (clientsInRoom.size === 0) {\n // Delete room\n this.rooms.delete(roomName);\n }\n\n // Set room name in client manager\n this.clientManager.updateClient({\n clientId,\n key: 'roomName',\n data: null,\n });\n\n if (broadcast !== false) {\n this.clientManager.broadcastClientList('clientRemovedFromRoom');\n }\n\n this.printRooms();\n\n log('Client left room', { Room: roomName, ID: clientId });\n }\n\n public removeClientFromAllRooms({ clientId }: { clientId: string }) {\n this.rooms.forEach((clientsInRoom, room) => {\n if (!clientsInRoom.has(clientId)) {\n return;\n }\n\n this.removeClientFromRoom({ roomName: room, clientId, broadcast: false });\n });\n\n this.clientManager.broadcastClientList('clientRemovedFromAllRooms');\n\n this.printRooms();\n }\n\n public isClientInRoom({ clientId, roomName }: { clientId: string; roomName: string }) {\n // Get clients in room\n const clientsInRoom = this.rooms.get(roomName);\n\n if (!clientsInRoom) {\n return false;\n }\n\n // Check if client is in room\n return clientsInRoom.has(clientId);\n }\n\n public printRooms() {\n const numRooms = this.rooms.size;\n\n let logOutput = '\\n-------------------------------------------------------\\n';\n logOutput += `Rooms (Count: ${numRooms}):\\n`;\n logOutput += '-------------------------------------------------------\\n';\n\n if (numRooms > 0) {\n const workerId = cluster.isWorker && cluster.worker ? cluster.worker.id : null;\n\n // Loop through all rooms\n let roomNumber = 1;\n\n this.rooms.forEach((clientsInRoom, room) => {\n const numClientsInRoom = clientsInRoom.size;\n\n logOutput += `Room ${roomNumber} (Name: ${room} | Clients: ${numClientsInRoom}${workerId ? ` | Worker: ${workerId}` : ''}):\\n`;\n logOutput += ' Clients:\\n';\n\n // Loop through all clients in room\n clientsInRoom.forEach(clientId => {\n const client = this.clientManager.getClient({ clientId });\n\n logOutput += ` Client (ID: ${clientId} | Username: ${client?.user?.username ?? '-'} | User Type: ${client?.user?.userType ?? '-'} | Email: ${client?.user?.email ?? '-'})\\n`;\n });\n\n roomNumber++;\n });\n } else {\n logOutput += 'No rooms\\n';\n }\n\n logOutput += '\\n';\n\n log(logOutput);\n }\n\n public getRoomClients({ roomName }: { roomName: string }): string[] {\n const room = this.rooms.get(roomName);\n return room ? Array.from(room) : [];\n }\n\n public cleanup(): void {\n // Clear all rooms\n this.rooms.clear();\n log('WebSocket room manager cleaned up');\n }\n}\n"],
4
+ "sourcesContent": ["import cluster from 'node:cluster';\nimport { log } from './utils.js';\nimport type WebSocketClientManager from './websocket-client-manager.js';\n\nexport default class WebSocketRoomManager {\n private clientManager: WebSocketClientManager;\n\n public rooms: Map<string, Set<string>> = new Map();\n\n constructor({ clientManager }: { clientManager: WebSocketClientManager }) {\n this.clientManager = clientManager;\n }\n\n public addClientToRoom({\n clientId,\n user,\n roomName,\n broadcast,\n }: {\n clientId: string;\n user: any;\n roomName: string;\n broadcast?: boolean;\n }) {\n // Check if room exists\n if (!this.rooms.has(roomName)) {\n // Create room\n this.rooms.set(roomName, new Set());\n }\n\n // Get room from room name\n const room = this.rooms.get(roomName);\n\n if (!room) {\n log('Room not found when adding client', { Name: roomName });\n\n return;\n }\n\n // Add client to room\n room.add(clientId);\n\n // Set room name in client manager\n this.clientManager.updateClient({\n clientId,\n key: 'roomName',\n data: roomName,\n });\n\n if (broadcast !== false) {\n this.clientManager.broadcastClientList('clientAddedToRoom');\n }\n\n this.printRooms();\n\n log('Client joined room', {\n 'User Type': user?.userType ?? '-',\n Room: roomName,\n ID: clientId,\n Email: user.email ?? '-',\n });\n }\n\n public removeClientFromRoom({\n roomName,\n clientId,\n broadcast,\n }: {\n roomName: string;\n clientId: string;\n broadcast?: boolean;\n }) {\n // Get room from room name\n const room = this.rooms.get(roomName);\n\n if (!room) {\n log('Room not found when removing client', { Name: roomName });\n\n return;\n }\n\n // Get clients in room\n const clientsInRoom = this.rooms.get(roomName);\n\n if (!clientsInRoom) {\n return;\n }\n\n // Remove client from room list\n clientsInRoom.delete(clientId);\n\n // Check if there are no clients in the room\n if (clientsInRoom.size === 0) {\n // Delete room\n this.rooms.delete(roomName);\n }\n\n // Set room name in client manager\n this.clientManager.updateClient({\n clientId,\n key: 'roomName',\n data: null,\n });\n\n if (broadcast !== false) {\n this.clientManager.broadcastClientList('clientRemovedFromRoom');\n }\n\n this.printRooms();\n\n log('Client left room', { Room: roomName, ID: clientId });\n }\n\n public removeClientFromAllRooms({ clientId }: { clientId: string }) {\n this.rooms.forEach((clientsInRoom, room) => {\n if (!clientsInRoom.has(clientId)) {\n return;\n }\n\n this.removeClientFromRoom({ roomName: room, clientId, broadcast: false });\n });\n\n this.clientManager.broadcastClientList('clientRemovedFromAllRooms');\n\n this.printRooms();\n }\n\n public isClientInRoom({ clientId, roomName }: { clientId: string; roomName: string }) {\n // Get clients in room\n const clientsInRoom = this.rooms.get(roomName);\n\n if (!clientsInRoom) {\n return false;\n }\n\n // Check if client is in room\n return clientsInRoom.has(clientId);\n }\n\n public printRooms() {\n const numRooms = this.rooms.size;\n\n let logOutput = '\\n-------------------------------------------------------\\n';\n logOutput += `Rooms (Count: ${numRooms}):\\n`;\n logOutput += '-------------------------------------------------------\\n';\n\n if (numRooms > 0) {\n const workerId = cluster.isWorker && cluster.worker ? cluster.worker.id : null;\n\n // Loop through all rooms\n let roomNumber = 1;\n\n this.rooms.forEach((clientsInRoom, room) => {\n const numClientsInRoom = clientsInRoom.size;\n\n logOutput += `Room ${roomNumber} (Name: ${room} | Clients: ${numClientsInRoom}${workerId ? ` | Worker: ${workerId}` : ''}):\\n`;\n logOutput += ' Clients:\\n';\n\n // Loop through all clients in room\n clientsInRoom.forEach(clientId => {\n const client = this.clientManager.getClient({ clientId });\n\n logOutput += ` Client (ID: ${clientId} | Username: ${client?.user?.username ?? '-'} | User Type: ${client?.user?.userType ?? '-'} | Email: ${client?.user?.email ?? '-'})\\n`;\n });\n\n roomNumber++;\n });\n } else {\n logOutput += 'No rooms\\n';\n }\n\n logOutput += '\\n';\n\n log(logOutput);\n }\n\n public getRoomClients({ roomName }: { roomName: string }): string[] {\n const room = this.rooms.get(roomName);\n return room ? Array.from(room) : [];\n }\n\n public cleanup(): void {\n // Clear all rooms\n this.rooms.clear();\n log('WebSocket room manager cleaned up');\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,12 +1,12 @@
1
- import { WebSocketServer as WS, WebSocket } from 'ws';
2
- import { type WebSocketRoute, type WebSocketType } from './websocket.interface.js';
3
- import type RedisInstance from '../redis/instance.js';
4
- import type QueueManager from '../queue/manager.js';
1
+ import type { FastifyInstance } from 'fastify';
2
+ import { WebSocket, WebSocketServer as WS } from 'ws';
5
3
  import type DatabaseInstance from '../database/instance.js';
6
- import type { WebSocketServerProps } from './websocket-server.interface.js';
7
- import WebSocketClientManager from './websocket-client-manager.js';
4
+ import type QueueManager from '../queue/manager.js';
5
+ import type RedisInstance from '../redis/instance.js';
6
+ import { type WebSocketRoute, type WebSocketType } from './websocket.interface.js';
8
7
  import WebSocketBase from './websocket-base.js';
9
- import type { FastifyInstance } from 'fastify';
8
+ import WebSocketClientManager from './websocket-client-manager.js';
9
+ import type { WebSocketServerProps } from './websocket-server.interface.js';
10
10
  export default class WebSocketServer extends WebSocketBase {
11
11
  protected defaultRoutes: WebSocketRoute[];
12
12
  private server?;