@morojs/moro 1.5.17 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/README.md +70 -269
  2. package/dist/core/auth/morojs-adapter.js +5 -9
  3. package/dist/core/auth/morojs-adapter.js.map +1 -1
  4. package/dist/core/config/config-manager.d.ts +1 -1
  5. package/dist/core/config/config-manager.js +10 -20
  6. package/dist/core/config/config-manager.js.map +1 -1
  7. package/dist/core/config/config-sources.d.ts +2 -2
  8. package/dist/core/config/config-sources.js +17 -20
  9. package/dist/core/config/config-sources.js.map +1 -1
  10. package/dist/core/config/config-validator.d.ts +1 -1
  11. package/dist/core/config/config-validator.js +33 -10
  12. package/dist/core/config/config-validator.js.map +1 -1
  13. package/dist/core/config/file-loader.d.ts +1 -1
  14. package/dist/core/config/file-loader.js +19 -78
  15. package/dist/core/config/file-loader.js.map +1 -1
  16. package/dist/core/config/index.d.ts +8 -8
  17. package/dist/core/config/index.js +25 -51
  18. package/dist/core/config/index.js.map +1 -1
  19. package/dist/core/config/schema.d.ts +2 -2
  20. package/dist/core/config/schema.js +11 -13
  21. package/dist/core/config/schema.js.map +1 -1
  22. package/dist/core/config/utils.d.ts +1 -1
  23. package/dist/core/config/utils.js +18 -32
  24. package/dist/core/config/utils.js.map +1 -1
  25. package/dist/core/database/adapters/drizzle.d.ts +1 -1
  26. package/dist/core/database/adapters/drizzle.js +18 -11
  27. package/dist/core/database/adapters/drizzle.js.map +1 -1
  28. package/dist/core/database/adapters/index.d.ts +7 -7
  29. package/dist/core/database/adapters/index.js +19 -29
  30. package/dist/core/database/adapters/index.js.map +1 -1
  31. package/dist/core/database/adapters/mongodb.d.ts +3 -1
  32. package/dist/core/database/adapters/mongodb.js +23 -8
  33. package/dist/core/database/adapters/mongodb.js.map +1 -1
  34. package/dist/core/database/adapters/mysql.d.ts +3 -1
  35. package/dist/core/database/adapters/mysql.js +18 -9
  36. package/dist/core/database/adapters/mysql.js.map +1 -1
  37. package/dist/core/database/adapters/postgresql.d.ts +3 -1
  38. package/dist/core/database/adapters/postgresql.js +18 -8
  39. package/dist/core/database/adapters/postgresql.js.map +1 -1
  40. package/dist/core/database/adapters/redis.d.ts +3 -1
  41. package/dist/core/database/adapters/redis.js +34 -9
  42. package/dist/core/database/adapters/redis.js.map +1 -1
  43. package/dist/core/database/adapters/sqlite.d.ts +3 -1
  44. package/dist/core/database/adapters/sqlite.js +19 -8
  45. package/dist/core/database/adapters/sqlite.js.map +1 -1
  46. package/dist/core/database/index.d.ts +2 -2
  47. package/dist/core/database/index.js +2 -18
  48. package/dist/core/database/index.js.map +1 -1
  49. package/dist/core/docs/index.d.ts +9 -9
  50. package/dist/core/docs/index.js +14 -35
  51. package/dist/core/docs/index.js.map +1 -1
  52. package/dist/core/docs/openapi-generator.d.ts +2 -2
  53. package/dist/core/docs/openapi-generator.js +11 -16
  54. package/dist/core/docs/openapi-generator.js.map +1 -1
  55. package/dist/core/docs/schema-to-openapi.d.ts +2 -2
  56. package/dist/core/docs/schema-to-openapi.js +5 -11
  57. package/dist/core/docs/schema-to-openapi.js.map +1 -1
  58. package/dist/core/docs/simple-docs.d.ts +1 -1
  59. package/dist/core/docs/simple-docs.js +4 -9
  60. package/dist/core/docs/simple-docs.js.map +1 -1
  61. package/dist/core/docs/swagger-ui.d.ts +2 -2
  62. package/dist/core/docs/swagger-ui.js +26 -29
  63. package/dist/core/docs/swagger-ui.js.map +1 -1
  64. package/dist/core/docs/zod-to-openapi.js +31 -28
  65. package/dist/core/docs/zod-to-openapi.js.map +1 -1
  66. package/dist/core/events/event-bus.d.ts +1 -1
  67. package/dist/core/events/event-bus.js +6 -10
  68. package/dist/core/events/event-bus.js.map +1 -1
  69. package/dist/core/events/index.d.ts +2 -2
  70. package/dist/core/events/index.js +1 -5
  71. package/dist/core/events/index.js.map +1 -1
  72. package/dist/core/framework.d.ts +14 -6
  73. package/dist/core/framework.js +150 -88
  74. package/dist/core/framework.js.map +1 -1
  75. package/dist/core/http/http-server.d.ts +1 -1
  76. package/dist/core/http/http-server.js +24 -62
  77. package/dist/core/http/http-server.js.map +1 -1
  78. package/dist/core/http/index.d.ts +4 -3
  79. package/dist/core/http/index.js +3 -8
  80. package/dist/core/http/index.js.map +1 -1
  81. package/dist/core/http/router.d.ts +1 -1
  82. package/dist/core/http/router.js +3 -7
  83. package/dist/core/http/router.js.map +1 -1
  84. package/dist/core/http/uws-http-server.d.ts +64 -0
  85. package/dist/core/http/uws-http-server.js +688 -0
  86. package/dist/core/http/uws-http-server.js.map +1 -0
  87. package/dist/core/logger/filters.d.ts +1 -1
  88. package/dist/core/logger/filters.js +8 -19
  89. package/dist/core/logger/filters.js.map +1 -1
  90. package/dist/core/logger/index.d.ts +3 -3
  91. package/dist/core/logger/index.js +2 -25
  92. package/dist/core/logger/index.js.map +1 -1
  93. package/dist/core/logger/logger.d.ts +1 -1
  94. package/dist/core/logger/logger.js +21 -23
  95. package/dist/core/logger/logger.js.map +1 -1
  96. package/dist/core/logger/outputs.d.ts +1 -1
  97. package/dist/core/logger/outputs.js +8 -15
  98. package/dist/core/logger/outputs.js.map +1 -1
  99. package/dist/core/middleware/built-in/adapters/cache/file.d.ts +1 -1
  100. package/dist/core/middleware/built-in/adapters/cache/file.js +10 -47
  101. package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -1
  102. package/dist/core/middleware/built-in/adapters/cache/index.d.ts +4 -4
  103. package/dist/core/middleware/built-in/adapters/cache/index.js +10 -17
  104. package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -1
  105. package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +1 -1
  106. package/dist/core/middleware/built-in/adapters/cache/memory.js +3 -7
  107. package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -1
  108. package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +3 -1
  109. package/dist/core/middleware/built-in/adapters/cache/redis.js +11 -9
  110. package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -1
  111. package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +1 -1
  112. package/dist/core/middleware/built-in/adapters/cdn/azure.js +3 -7
  113. package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -1
  114. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +1 -1
  115. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +3 -7
  116. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -1
  117. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +3 -1
  118. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +12 -10
  119. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -1
  120. package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +4 -4
  121. package/dist/core/middleware/built-in/adapters/cdn/index.js +10 -17
  122. package/dist/core/middleware/built-in/adapters/cdn/index.js.map +1 -1
  123. package/dist/core/middleware/built-in/adapters/index.d.ts +4 -4
  124. package/dist/core/middleware/built-in/adapters/index.js +4 -23
  125. package/dist/core/middleware/built-in/adapters/index.js.map +1 -1
  126. package/dist/core/middleware/built-in/auth-helpers.js +11 -22
  127. package/dist/core/middleware/built-in/auth-helpers.js.map +1 -1
  128. package/dist/core/middleware/built-in/auth-providers.d.ts +1 -1
  129. package/dist/core/middleware/built-in/auth-providers.js +4 -9
  130. package/dist/core/middleware/built-in/auth-providers.js.map +1 -1
  131. package/dist/core/middleware/built-in/auth.d.ts +2 -2
  132. package/dist/core/middleware/built-in/auth.js +10 -14
  133. package/dist/core/middleware/built-in/auth.js.map +1 -1
  134. package/dist/core/middleware/built-in/cache.d.ts +2 -2
  135. package/dist/core/middleware/built-in/cache.js +8 -11
  136. package/dist/core/middleware/built-in/cache.js.map +1 -1
  137. package/dist/core/middleware/built-in/cdn.d.ts +2 -2
  138. package/dist/core/middleware/built-in/cdn.js +5 -9
  139. package/dist/core/middleware/built-in/cdn.js.map +1 -1
  140. package/dist/core/middleware/built-in/cookie.d.ts +1 -1
  141. package/dist/core/middleware/built-in/cookie.js +3 -7
  142. package/dist/core/middleware/built-in/cookie.js.map +1 -1
  143. package/dist/core/middleware/built-in/cors.d.ts +1 -1
  144. package/dist/core/middleware/built-in/cors.js +3 -7
  145. package/dist/core/middleware/built-in/cors.js.map +1 -1
  146. package/dist/core/middleware/built-in/csp.d.ts +1 -1
  147. package/dist/core/middleware/built-in/csp.js +5 -8
  148. package/dist/core/middleware/built-in/csp.js.map +1 -1
  149. package/dist/core/middleware/built-in/csrf.d.ts +1 -1
  150. package/dist/core/middleware/built-in/csrf.js +5 -8
  151. package/dist/core/middleware/built-in/csrf.js.map +1 -1
  152. package/dist/core/middleware/built-in/error-tracker.js +3 -7
  153. package/dist/core/middleware/built-in/error-tracker.js.map +1 -1
  154. package/dist/core/middleware/built-in/index.d.ts +28 -28
  155. package/dist/core/middleware/built-in/index.js +47 -82
  156. package/dist/core/middleware/built-in/index.js.map +1 -1
  157. package/dist/core/middleware/built-in/jwt-helpers.d.ts +1 -1
  158. package/dist/core/middleware/built-in/jwt-helpers.js +6 -9
  159. package/dist/core/middleware/built-in/jwt-helpers.js.map +1 -1
  160. package/dist/core/middleware/built-in/performance-monitor.js +3 -7
  161. package/dist/core/middleware/built-in/performance-monitor.js.map +1 -1
  162. package/dist/core/middleware/built-in/rate-limit.d.ts +1 -1
  163. package/dist/core/middleware/built-in/rate-limit.js +3 -7
  164. package/dist/core/middleware/built-in/rate-limit.js.map +1 -1
  165. package/dist/core/middleware/built-in/request-logger.js +3 -7
  166. package/dist/core/middleware/built-in/request-logger.js.map +1 -1
  167. package/dist/core/middleware/built-in/session.d.ts +2 -2
  168. package/dist/core/middleware/built-in/session.js +11 -15
  169. package/dist/core/middleware/built-in/session.js.map +1 -1
  170. package/dist/core/middleware/built-in/sse.d.ts +1 -1
  171. package/dist/core/middleware/built-in/sse.js +3 -7
  172. package/dist/core/middleware/built-in/sse.js.map +1 -1
  173. package/dist/core/middleware/built-in/validation.d.ts +1 -1
  174. package/dist/core/middleware/built-in/validation.js +3 -7
  175. package/dist/core/middleware/built-in/validation.js.map +1 -1
  176. package/dist/core/middleware/index.d.ts +4 -4
  177. package/dist/core/middleware/index.js +8 -28
  178. package/dist/core/middleware/index.js.map +1 -1
  179. package/dist/core/modules/auto-discovery.d.ts +3 -3
  180. package/dist/core/modules/auto-discovery.js +43 -81
  181. package/dist/core/modules/auto-discovery.js.map +1 -1
  182. package/dist/core/modules/index.d.ts +2 -2
  183. package/dist/core/modules/index.js +2 -9
  184. package/dist/core/modules/index.js.map +1 -1
  185. package/dist/core/modules/modules.d.ts +3 -3
  186. package/dist/core/modules/modules.js +11 -52
  187. package/dist/core/modules/modules.js.map +1 -1
  188. package/dist/core/networking/adapters/index.d.ts +4 -3
  189. package/dist/core/networking/adapters/index.js +3 -7
  190. package/dist/core/networking/adapters/index.js.map +1 -1
  191. package/dist/core/networking/adapters/socketio-adapter.d.ts +1 -1
  192. package/dist/core/networking/adapters/socketio-adapter.js +5 -40
  193. package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
  194. package/dist/core/networking/adapters/uws-adapter.d.ts +44 -0
  195. package/dist/core/networking/adapters/uws-adapter.js +513 -0
  196. package/dist/core/networking/adapters/uws-adapter.js.map +1 -0
  197. package/dist/core/networking/adapters/ws-adapter.d.ts +1 -1
  198. package/dist/core/networking/adapters/ws-adapter.js +7 -42
  199. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  200. package/dist/core/networking/index.d.ts +3 -2
  201. package/dist/core/networking/index.js +2 -7
  202. package/dist/core/networking/index.js.map +1 -1
  203. package/dist/core/networking/service-discovery.js +3 -7
  204. package/dist/core/networking/service-discovery.js.map +1 -1
  205. package/dist/core/networking/websocket-adapter.js +1 -2
  206. package/dist/core/networking/websocket-adapter.js.map +1 -1
  207. package/dist/core/networking/websocket-manager.d.ts +3 -3
  208. package/dist/core/networking/websocket-manager.js +9 -11
  209. package/dist/core/networking/websocket-manager.js.map +1 -1
  210. package/dist/core/routing/app-integration.d.ts +2 -2
  211. package/dist/core/routing/app-integration.js +7 -12
  212. package/dist/core/routing/app-integration.js.map +1 -1
  213. package/dist/core/routing/index.d.ts +2 -2
  214. package/dist/core/routing/index.js +7 -14
  215. package/dist/core/routing/index.js.map +1 -1
  216. package/dist/core/runtime/aws-lambda-adapter.d.ts +3 -3
  217. package/dist/core/runtime/aws-lambda-adapter.js +2 -6
  218. package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
  219. package/dist/core/runtime/base-adapter.d.ts +2 -2
  220. package/dist/core/runtime/base-adapter.js +3 -7
  221. package/dist/core/runtime/base-adapter.js.map +1 -1
  222. package/dist/core/runtime/cloudflare-workers-adapter.d.ts +3 -3
  223. package/dist/core/runtime/cloudflare-workers-adapter.js +2 -6
  224. package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
  225. package/dist/core/runtime/index.d.ts +12 -12
  226. package/dist/core/runtime/index.js +22 -35
  227. package/dist/core/runtime/index.js.map +1 -1
  228. package/dist/core/runtime/node-adapter.d.ts +4 -4
  229. package/dist/core/runtime/node-adapter.js +6 -43
  230. package/dist/core/runtime/node-adapter.js.map +1 -1
  231. package/dist/core/runtime/vercel-edge-adapter.d.ts +3 -3
  232. package/dist/core/runtime/vercel-edge-adapter.js +2 -6
  233. package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
  234. package/dist/core/utilities/circuit-breaker.js +1 -5
  235. package/dist/core/utilities/circuit-breaker.js.map +1 -1
  236. package/dist/core/utilities/container.js +12 -22
  237. package/dist/core/utilities/container.js.map +1 -1
  238. package/dist/core/utilities/hooks.d.ts +2 -2
  239. package/dist/core/utilities/hooks.js +7 -12
  240. package/dist/core/utilities/hooks.js.map +1 -1
  241. package/dist/core/utilities/index.d.ts +5 -4
  242. package/dist/core/utilities/index.js +5 -19
  243. package/dist/core/utilities/index.js.map +1 -1
  244. package/dist/core/utilities/package-utils.d.ts +38 -0
  245. package/dist/core/utilities/package-utils.js +57 -0
  246. package/dist/core/utilities/package-utils.js.map +1 -0
  247. package/dist/core/validation/adapters.d.ts +1 -1
  248. package/dist/core/validation/adapters.js +15 -26
  249. package/dist/core/validation/adapters.js.map +1 -1
  250. package/dist/core/validation/index.d.ts +6 -4
  251. package/dist/core/validation/index.js +57 -28
  252. package/dist/core/validation/index.js.map +1 -1
  253. package/dist/core/validation/schema-interface.js +3 -9
  254. package/dist/core/validation/schema-interface.js.map +1 -1
  255. package/dist/index.d.ts +51 -52
  256. package/dist/index.js +23 -132
  257. package/dist/index.js.map +1 -1
  258. package/dist/moro.d.ts +13 -10
  259. package/dist/moro.js +132 -102
  260. package/dist/moro.js.map +1 -1
  261. package/dist/types/auth.js +3 -9
  262. package/dist/types/auth.js.map +1 -1
  263. package/dist/types/cache.js +1 -2
  264. package/dist/types/cdn.js +1 -2
  265. package/dist/types/config.d.ts +13 -1
  266. package/dist/types/config.js +1 -2
  267. package/dist/types/config.js.map +1 -1
  268. package/dist/types/core.d.ts +3 -3
  269. package/dist/types/core.js +1 -2
  270. package/dist/types/database.js +1 -2
  271. package/dist/types/discovery.js +1 -2
  272. package/dist/types/events.js +1 -2
  273. package/dist/types/hooks.d.ts +1 -1
  274. package/dist/types/hooks.js +1 -2
  275. package/dist/types/http.js +1 -2
  276. package/dist/types/logger.js +1 -2
  277. package/dist/types/module.js +1 -2
  278. package/dist/types/runtime.d.ts +1 -1
  279. package/dist/types/runtime.js +1 -2
  280. package/dist/types/session.js +1 -2
  281. package/jest.config.mjs +41 -0
  282. package/package.json +18 -51
  283. package/src/core/auth/morojs-adapter.ts +1 -1
  284. package/src/core/config/config-manager.ts +2 -2
  285. package/src/core/config/config-sources.ts +6 -6
  286. package/src/core/config/config-validator.ts +38 -3
  287. package/src/core/config/file-loader.ts +13 -40
  288. package/src/core/config/index.ts +15 -11
  289. package/src/core/config/schema.ts +3 -2
  290. package/src/core/config/utils.ts +3 -3
  291. package/src/core/database/adapters/drizzle.ts +18 -6
  292. package/src/core/database/adapters/index.ts +13 -13
  293. package/src/core/database/adapters/mongodb.ts +23 -3
  294. package/src/core/database/adapters/mysql.ts +18 -4
  295. package/src/core/database/adapters/postgresql.ts +18 -3
  296. package/src/core/database/adapters/redis.ts +34 -4
  297. package/src/core/database/adapters/sqlite.ts +19 -3
  298. package/src/core/database/index.ts +2 -2
  299. package/src/core/docs/index.ts +8 -8
  300. package/src/core/docs/openapi-generator.ts +4 -4
  301. package/src/core/docs/schema-to-openapi.ts +3 -6
  302. package/src/core/docs/simple-docs.ts +2 -2
  303. package/src/core/docs/swagger-ui.ts +19 -16
  304. package/src/core/docs/zod-to-openapi.ts +34 -34
  305. package/src/core/events/event-bus.ts +2 -2
  306. package/src/core/events/index.ts +2 -2
  307. package/src/core/framework.ts +148 -44
  308. package/src/core/http/http-server.ts +14 -9
  309. package/src/core/http/index.ts +4 -3
  310. package/src/core/http/router.ts +2 -2
  311. package/src/core/http/uws-http-server.ts +794 -0
  312. package/src/core/logger/filters.ts +1 -1
  313. package/src/core/logger/index.ts +3 -3
  314. package/src/core/logger/logger.ts +9 -1
  315. package/src/core/logger/outputs.ts +1 -1
  316. package/src/core/middleware/built-in/adapters/cache/file.ts +3 -3
  317. package/src/core/middleware/built-in/adapters/cache/index.ts +7 -7
  318. package/src/core/middleware/built-in/adapters/cache/memory.ts +2 -2
  319. package/src/core/middleware/built-in/adapters/cache/redis.ts +18 -4
  320. package/src/core/middleware/built-in/adapters/cdn/azure.ts +2 -2
  321. package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +2 -2
  322. package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +16 -5
  323. package/src/core/middleware/built-in/adapters/cdn/index.ts +7 -7
  324. package/src/core/middleware/built-in/adapters/index.ts +4 -4
  325. package/src/core/middleware/built-in/auth-helpers.ts +1 -1
  326. package/src/core/middleware/built-in/auth-providers.ts +1 -1
  327. package/src/core/middleware/built-in/auth.ts +6 -6
  328. package/src/core/middleware/built-in/cache.ts +5 -5
  329. package/src/core/middleware/built-in/cdn.ts +4 -4
  330. package/src/core/middleware/built-in/cookie.ts +2 -2
  331. package/src/core/middleware/built-in/cors.ts +2 -2
  332. package/src/core/middleware/built-in/csp.ts +3 -3
  333. package/src/core/middleware/built-in/csrf.ts +3 -3
  334. package/src/core/middleware/built-in/error-tracker.ts +1 -1
  335. package/src/core/middleware/built-in/index.ts +31 -31
  336. package/src/core/middleware/built-in/jwt-helpers.ts +6 -3
  337. package/src/core/middleware/built-in/performance-monitor.ts +1 -1
  338. package/src/core/middleware/built-in/rate-limit.ts +2 -2
  339. package/src/core/middleware/built-in/request-logger.ts +1 -1
  340. package/src/core/middleware/built-in/session.ts +7 -8
  341. package/src/core/middleware/built-in/sse.ts +2 -2
  342. package/src/core/middleware/built-in/validation.ts +2 -2
  343. package/src/core/middleware/index.ts +6 -6
  344. package/src/core/modules/auto-discovery.ts +4 -4
  345. package/src/core/modules/index.ts +2 -2
  346. package/src/core/modules/modules.ts +4 -4
  347. package/src/core/networking/adapters/index.ts +4 -3
  348. package/src/core/networking/adapters/socketio-adapter.ts +5 -3
  349. package/src/core/networking/adapters/uws-adapter.ts +619 -0
  350. package/src/core/networking/adapters/ws-adapter.ts +6 -4
  351. package/src/core/networking/index.ts +3 -2
  352. package/src/core/networking/service-discovery.ts +1 -1
  353. package/src/core/networking/websocket-manager.ts +7 -7
  354. package/src/core/routing/app-integration.ts +3 -3
  355. package/src/core/routing/index.ts +3 -3
  356. package/src/core/runtime/aws-lambda-adapter.ts +3 -3
  357. package/src/core/runtime/base-adapter.ts +2 -2
  358. package/src/core/runtime/cloudflare-workers-adapter.ts +3 -3
  359. package/src/core/runtime/index.ts +13 -13
  360. package/src/core/runtime/node-adapter.ts +4 -4
  361. package/src/core/runtime/vercel-edge-adapter.ts +3 -3
  362. package/src/core/utilities/hooks.ts +3 -3
  363. package/src/core/utilities/index.ts +5 -4
  364. package/src/core/utilities/package-utils.ts +59 -0
  365. package/src/core/validation/adapters.ts +1 -1
  366. package/src/core/validation/index.ts +68 -16
  367. package/src/index.ts +73 -66
  368. package/src/moro.ts +144 -51
  369. package/src/types/config.ts +13 -1
  370. package/src/types/core.ts +3 -3
  371. package/src/types/hooks.ts +1 -1
  372. package/src/types/runtime.ts +1 -1
  373. package/tsconfig.json +4 -2
@@ -1,10 +1,10 @@
1
1
  // Auto-discovery system for Moro modules
2
2
  import { readdirSync, statSync } from 'fs';
3
3
  import { join, extname, relative, isAbsolute } from 'path';
4
- import { ModuleConfig } from '../../types/module';
5
- import { DiscoveryOptions } from '../../types/discovery';
6
- import { ModuleDefaultsConfig } from '../../types/config';
7
- import { createFrameworkLogger } from '../logger';
4
+ import { ModuleConfig } from '../../types/module.js';
5
+ import { DiscoveryOptions } from '../../types/discovery.js';
6
+ import { ModuleDefaultsConfig } from '../../types/config.js';
7
+ import { createFrameworkLogger } from '../logger/index.js';
8
8
 
9
9
  export class ModuleDiscovery {
10
10
  private baseDir: string;
@@ -1,3 +1,3 @@
1
1
  // Module System - Centralized Exports
2
- export { defineModule, ModuleLoader } from './modules';
3
- export { ModuleDiscovery, autoDiscoverModuleDirectories } from './auto-discovery';
2
+ export { defineModule, ModuleLoader } from './modules.js';
3
+ export { ModuleDiscovery, autoDiscoverModuleDirectories } from './auto-discovery.js';
@@ -1,10 +1,10 @@
1
1
  // Module System - Definition and Loading
2
2
  import { promises as fs } from 'fs';
3
3
  import path from 'path';
4
- import { Container } from '../utilities';
5
- import { ModuleConfig } from '../../types/module';
6
- import { ModuleDefinition, ModuleRoute, ModuleSocket } from '../../types/module';
7
- import { createFrameworkLogger } from '../logger';
4
+ import { Container } from '../utilities/index.js';
5
+ import { ModuleConfig } from '../../types/module.js';
6
+ import { ModuleDefinition, ModuleRoute, ModuleSocket } from '../../types/module.js';
7
+ import { createFrameworkLogger } from '../logger/index.js';
8
8
 
9
9
  // Module Definition Function
10
10
  export function defineModule(definition: ModuleDefinition): ModuleConfig {
@@ -1,8 +1,9 @@
1
1
  // WebSocket Adapters for Moro Framework
2
2
  // Export all available adapters from this centralized location
3
3
 
4
- export { SocketIOAdapter } from './socketio-adapter';
5
- export { WSAdapter } from './ws-adapter';
4
+ export { SocketIOAdapter } from './socketio-adapter.js';
5
+ export { WSAdapter } from './ws-adapter.js';
6
+ export { UWebSocketsAdapter } from './uws-adapter.js';
6
7
 
7
8
  // Re-export the adapter interface for convenience
8
9
  export type {
@@ -13,4 +14,4 @@ export type {
13
14
  WebSocketEmitter,
14
15
  WebSocketMiddleware,
15
16
  WebSocketEventHandler,
16
- } from '../websocket-adapter';
17
+ } from '../websocket-adapter.js';
@@ -1,6 +1,7 @@
1
1
  // Socket.IO WebSocket Adapter for Moro Framework
2
2
  // Implements the WebSocket adapter interface using Socket.IO
3
3
 
4
+ import { resolveUserPackage } from '../../utilities/package-utils.js';
4
5
  import {
5
6
  WebSocketAdapter,
6
7
  WebSocketAdapterOptions,
@@ -8,7 +9,7 @@ import {
8
9
  WebSocketConnection,
9
10
  WebSocketEmitter,
10
11
  WebSocketMiddleware,
11
- } from '../websocket-adapter';
12
+ } from '../websocket-adapter.js';
12
13
 
13
14
  /**
14
15
  * Socket.IO adapter implementation
@@ -19,8 +20,9 @@ export class SocketIOAdapter implements WebSocketAdapter {
19
20
 
20
21
  async initialize(httpServer: any, options: WebSocketAdapterOptions = {}): Promise<void> {
21
22
  try {
22
- // Dynamic import to avoid requiring socket.io as a hard dependency
23
- const { Server } = await import('socket.io');
23
+ // Dynamic import from user's context to find their installed socket.io
24
+ const socketIOPath = resolveUserPackage('socket.io');
25
+ const { Server } = await import(socketIOPath);
24
26
 
25
27
  this.io = new Server(httpServer, {
26
28
  cors: options.cors || { origin: '*' },
@@ -0,0 +1,619 @@
1
+ // uWebSockets Adapter for Moro Framework
2
+ // Implements the WebSocket adapter interface using uWebSockets.js
3
+ // High-performance C++ WebSocket implementation with native Node.js bindings
4
+
5
+ import { resolveUserPackage } from '../../utilities/package-utils.js';
6
+ import {
7
+ WebSocketAdapter,
8
+ WebSocketAdapterOptions,
9
+ WebSocketNamespace,
10
+ WebSocketConnection,
11
+ WebSocketEmitter,
12
+ WebSocketMiddleware,
13
+ } from '../websocket-adapter.js';
14
+ import { createFrameworkLogger } from '../../logger/index.js';
15
+
16
+ /**
17
+ * uWebSockets adapter implementation
18
+ * Provides ultra-high-performance WebSocket support using uWebSockets.js
19
+ */
20
+ export class UWebSocketsAdapter implements WebSocketAdapter {
21
+ private app: any; // uWebSockets app instance
22
+ private uws: any; // uWebSockets module reference (stored to avoid re-importing)
23
+ private listenSocket: any; // uWebSockets listen socket
24
+ private namespaces = new Map<string, UWSNamespaceWrapper>();
25
+ private connections = new Map<string, UWSConnectionWrapper>();
26
+ private logger = createFrameworkLogger('UWS_ADAPTER');
27
+ private customIdGenerator?: () => string;
28
+ private connectionCounter = 0;
29
+ private compressionEnabled = false;
30
+ private compressionOptions: any = {};
31
+ private httpServer: any; // Reference to Node.js HTTP server for compatibility
32
+
33
+ async initialize(httpServer: any, options: WebSocketAdapterOptions = {}): Promise<void> {
34
+ try {
35
+ // Lazy load uWebSockets.js from user's context
36
+ // This ensures it's an optional dependency with graceful fallback
37
+ const uwsPath = resolveUserPackage('uWebSockets.js');
38
+ this.uws = await import(uwsPath);
39
+
40
+ // Store HTTP server reference for compatibility
41
+ this.httpServer = httpServer;
42
+
43
+ // uWebSockets.js doesn't integrate with Node's http.Server
44
+ // Instead, it creates its own server, so we'll need to handle this carefully
45
+ // We'll create a uWebSockets app that can coexist with the HTTP server
46
+
47
+ // Check if SSL/TLS options are provided
48
+ const sslOptions = (options as any).ssl;
49
+
50
+ if (sslOptions && sslOptions.key_file_name && sslOptions.cert_file_name) {
51
+ // Create SSL app
52
+ this.app = this.uws.SSLApp({
53
+ key_file_name: sslOptions.key_file_name,
54
+ cert_file_name: sslOptions.cert_file_name,
55
+ passphrase: sslOptions.passphrase,
56
+ ...sslOptions,
57
+ });
58
+ this.logger.info('uWebSockets SSL/TLS app created', 'Init');
59
+ } else {
60
+ // Create regular app
61
+ this.app = this.uws.App();
62
+ this.logger.info('uWebSockets app created', 'Init');
63
+ }
64
+
65
+ // Setup WebSocket route with configurable path
66
+ const wsPath = options.path || '/*';
67
+ const maxPayloadLength = options.maxPayloadLength || 100 * 1024 * 1024; // 100MB default
68
+ const idleTimeout = options.idleTimeout || 120; // 2 minutes default
69
+
70
+ // Configure compression if enabled
71
+ const compression = options.compression !== false;
72
+
73
+ this.app.ws(wsPath, {
74
+ // Compression settings - uWebSockets.js has built-in compression
75
+ compression: compression ? 1 : 0, // 0 = disabled, 1 = shared compressor, 2 = dedicated compressor
76
+ maxPayloadLength,
77
+ idleTimeout,
78
+ maxBackpressure: 1024 * 1024, // 1MB backpressure limit
79
+
80
+ // Connection opened
81
+ open: (ws: any) => {
82
+ this.handleConnection(ws);
83
+ },
84
+
85
+ // Message received
86
+ message: (ws: any, message: ArrayBuffer, isBinary: boolean) => {
87
+ this.handleMessage(ws, message, isBinary);
88
+ },
89
+
90
+ // Connection closed
91
+ close: (ws: any, code: number, message: ArrayBuffer) => {
92
+ this.handleClose(ws, code, message);
93
+ },
94
+
95
+ // Drain handler for backpressure management
96
+ drain: (ws: any) => {
97
+ this.handleDrain(ws);
98
+ },
99
+ });
100
+
101
+ // Setup default namespace
102
+ this.createNamespace('/');
103
+
104
+ this.logger.info('uWebSockets adapter initialized', 'Init');
105
+ } catch (error) {
106
+ // Throw helpful error with installation instructions
107
+ throw new Error(
108
+ 'Failed to load uWebSockets.js (optional dependency)\n' +
109
+ 'To use the uWebSockets adapter, install it with:\n' +
110
+ ' npm install --save-dev github:uNetworking/uWebSockets.js#v20.52.0\n' +
111
+ 'Or use a different WebSocket adapter (socket.io or ws) in your config.\n' +
112
+ 'Error: ' +
113
+ (error instanceof Error ? error.message : String(error))
114
+ );
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Start listening on a specific port
120
+ * This is necessary because uWebSockets.js manages its own server
121
+ */
122
+ listen(port: number, callback?: (token: any) => void): void {
123
+ if (!this.app) {
124
+ throw new Error('uWebSockets app not initialized. Call initialize() first.');
125
+ }
126
+
127
+ this.app.listen(port, (token: any) => {
128
+ if (token) {
129
+ this.listenSocket = token;
130
+ this.logger.info(`uWebSockets listening on port ${port}`, 'Listen');
131
+ if (callback) callback(token);
132
+ } else {
133
+ this.logger.error(`Failed to listen on port ${port}`, 'Listen');
134
+ }
135
+ });
136
+ }
137
+
138
+ /**
139
+ * Start listening on host and port
140
+ */
141
+ listenWithHost(host: string, port: number, callback?: (token: any) => void): void {
142
+ if (!this.app) {
143
+ throw new Error('uWebSockets app not initialized. Call initialize() first.');
144
+ }
145
+
146
+ this.app.listen(host, port, (token: any) => {
147
+ if (token) {
148
+ this.listenSocket = token;
149
+ this.logger.info(`uWebSockets listening on ${host}:${port}`, 'Listen');
150
+ if (callback) callback(token);
151
+ } else {
152
+ this.logger.error(`Failed to listen on ${host}:${port}`, 'Listen');
153
+ }
154
+ });
155
+ }
156
+
157
+ private handleConnection(ws: any): void {
158
+ const id = this.generateId();
159
+
160
+ // Extract connection info
161
+ const ip = Buffer.from(ws.getRemoteAddressAsText()).toString();
162
+
163
+ // Create connection wrapper
164
+ const connection = new UWSConnectionWrapper(ws, id, ip, this.namespaces);
165
+ this.connections.set(id, connection);
166
+
167
+ // Store connection ID on the WebSocket for later retrieval
168
+ ws.connectionId = id;
169
+
170
+ // Notify default namespace of new connection
171
+ const defaultNamespace = this.namespaces.get('/');
172
+ if (defaultNamespace) {
173
+ defaultNamespace.handleConnection(connection);
174
+ }
175
+
176
+ this.logger.debug(`WebSocket connection opened: ${id} from ${ip}`, 'Connection');
177
+ }
178
+
179
+ private handleMessage(ws: any, message: ArrayBuffer, isBinary: boolean): void {
180
+ const connectionId = ws.connectionId;
181
+ const connection = this.connections.get(connectionId);
182
+
183
+ if (!connection) {
184
+ this.logger.warn(`Message received for unknown connection: ${connectionId}`, 'Message');
185
+ return;
186
+ }
187
+
188
+ try {
189
+ // Parse message - expect JSON format for compatibility with socket.io-like behavior
190
+ const messageStr = Buffer.from(message).toString('utf-8');
191
+ const data = JSON.parse(messageStr);
192
+
193
+ // Handle message in connection wrapper
194
+ connection.handleMessage(data);
195
+ } catch (error) {
196
+ this.logger.error(
197
+ `Failed to parse message from ${connectionId}: ${error instanceof Error ? error.message : String(error)}`,
198
+ 'Message'
199
+ );
200
+ }
201
+ }
202
+
203
+ private handleClose(ws: any, code: number, message: ArrayBuffer): void {
204
+ const connectionId = ws.connectionId;
205
+ const connection = this.connections.get(connectionId);
206
+
207
+ if (connection) {
208
+ connection.handleClose(code, message);
209
+ this.connections.delete(connectionId);
210
+ this.logger.debug(`WebSocket connection closed: ${connectionId}`, 'Connection');
211
+ }
212
+ }
213
+
214
+ private handleDrain(ws: any): void {
215
+ // Handle backpressure drain event
216
+ const connectionId = ws.connectionId;
217
+ const connection = this.connections.get(connectionId);
218
+
219
+ if (connection) {
220
+ connection.handleDrain();
221
+ }
222
+ }
223
+
224
+ private generateId(): string {
225
+ if (this.customIdGenerator) {
226
+ return this.customIdGenerator();
227
+ }
228
+ return `uws_${++this.connectionCounter}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
229
+ }
230
+
231
+ createNamespace(namespace: string): WebSocketNamespace {
232
+ if (!this.namespaces.has(namespace)) {
233
+ const ns = new UWSNamespaceWrapper(namespace, this.connections);
234
+ this.namespaces.set(namespace, ns);
235
+ this.logger.debug(`Created namespace: ${namespace}`, 'Namespace');
236
+ }
237
+ return this.namespaces.get(namespace)!;
238
+ }
239
+
240
+ getDefaultNamespace(): WebSocketNamespace {
241
+ return this.createNamespace('/');
242
+ }
243
+
244
+ async close(): Promise<void> {
245
+ // Close all connections
246
+ for (const [id, connection] of this.connections) {
247
+ connection.disconnect(true);
248
+ }
249
+ this.connections.clear();
250
+ this.namespaces.clear();
251
+
252
+ // Close the uWebSockets listen socket
253
+ if (this.listenSocket && this.uws) {
254
+ // Use stored module reference instead of re-importing
255
+ this.uws.us_listen_socket_close(this.listenSocket);
256
+ this.listenSocket = null;
257
+ }
258
+
259
+ this.logger.info('uWebSockets adapter closed', 'Close');
260
+ }
261
+
262
+ setCompression(enabled: boolean, options?: any): void {
263
+ this.compressionEnabled = enabled;
264
+ this.compressionOptions = options || {};
265
+ this.logger.debug(`Compression ${enabled ? 'enabled' : 'disabled'}`, 'Compression');
266
+ }
267
+
268
+ setCustomIdGenerator(generator: () => string): void {
269
+ this.customIdGenerator = generator;
270
+ this.logger.debug('Custom ID generator set', 'Config');
271
+ }
272
+
273
+ getAdapterName(): string {
274
+ return 'uWebSockets.js';
275
+ }
276
+
277
+ getConnectionCount(): number {
278
+ return this.connections.size;
279
+ }
280
+
281
+ /**
282
+ * Get the underlying uWebSockets app for advanced usage
283
+ */
284
+ getApp(): any {
285
+ return this.app;
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Namespace wrapper for uWebSockets
291
+ */
292
+ class UWSNamespaceWrapper implements WebSocketNamespace {
293
+ private connectionHandlers: ((socket: WebSocketConnection) => void)[] = [];
294
+ private middlewares: WebSocketMiddleware[] = [];
295
+
296
+ constructor(
297
+ private namespace: string,
298
+ private connections: Map<string, UWSConnectionWrapper>
299
+ ) {}
300
+
301
+ on(event: 'connection', handler: (socket: WebSocketConnection) => void): void {
302
+ if (event === 'connection') {
303
+ this.connectionHandlers.push(handler);
304
+ }
305
+ }
306
+
307
+ handleConnection(connection: UWSConnectionWrapper): void {
308
+ // Run middlewares
309
+ this.runMiddlewares(connection, err => {
310
+ if (err) {
311
+ connection.disconnect(true);
312
+ return;
313
+ }
314
+
315
+ // Notify all connection handlers
316
+ for (const handler of this.connectionHandlers) {
317
+ handler(connection);
318
+ }
319
+ });
320
+ }
321
+
322
+ private runMiddlewares(
323
+ connection: UWSConnectionWrapper,
324
+ finalCallback: (err?: Error) => void
325
+ ): void {
326
+ let index = 0;
327
+
328
+ const next = (err?: Error) => {
329
+ if (err) {
330
+ finalCallback(err);
331
+ return;
332
+ }
333
+
334
+ if (index >= this.middlewares.length) {
335
+ finalCallback();
336
+ return;
337
+ }
338
+
339
+ const middleware = this.middlewares[index++];
340
+ middleware(connection, next);
341
+ };
342
+
343
+ next();
344
+ }
345
+
346
+ emit(event: string, data: any): void {
347
+ for (const [id, connection] of this.connections) {
348
+ if (connection.connected) {
349
+ connection.emit(event, data);
350
+ }
351
+ }
352
+ }
353
+
354
+ to(room: string | string[]): WebSocketEmitter {
355
+ return new UWSEmitterWrapper(this.connections, { rooms: Array.isArray(room) ? room : [room] });
356
+ }
357
+
358
+ except(room: string | string[]): WebSocketEmitter {
359
+ return new UWSEmitterWrapper(this.connections, {
360
+ exceptRooms: Array.isArray(room) ? room : [room],
361
+ });
362
+ }
363
+
364
+ getSockets(): WebSocketConnection[] {
365
+ return Array.from(this.connections.values()).filter(conn => conn.connected);
366
+ }
367
+
368
+ getConnectionCount(): number {
369
+ return Array.from(this.connections.values()).filter(conn => conn.connected).length;
370
+ }
371
+
372
+ use(middleware: WebSocketMiddleware): void {
373
+ this.middlewares.push(middleware);
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Connection wrapper for uWebSockets
379
+ */
380
+ class UWSConnectionWrapper implements WebSocketConnection {
381
+ public data: Record<string, any> = {};
382
+ public connected = true;
383
+ private rooms = new Set<string>();
384
+ private eventHandlers = new Map<
385
+ string,
386
+ Array<(data: any, callback?: (response?: any) => void) => void>
387
+ >();
388
+ private anyHandlers: Array<(event: string, ...args: any[]) => void> = [];
389
+ private logger = createFrameworkLogger('UWS_CONNECTION');
390
+
391
+ constructor(
392
+ private ws: any,
393
+ public readonly id: string,
394
+ public readonly ip: string,
395
+ private namespaces: Map<string, UWSNamespaceWrapper>
396
+ ) {
397
+ this.headers = this.parseHeaders();
398
+ }
399
+
400
+ public readonly headers: Record<string, string>;
401
+
402
+ private parseHeaders(): Record<string, string> {
403
+ // uWebSockets doesn't provide easy header access
404
+ // We'll return empty headers for now, but this could be enhanced
405
+ return {};
406
+ }
407
+
408
+ on(event: string, handler: (data: any, callback?: (response?: any) => void) => void): void {
409
+ if (!this.eventHandlers.has(event)) {
410
+ this.eventHandlers.set(event, []);
411
+ }
412
+ this.eventHandlers.get(event)!.push(handler);
413
+ }
414
+
415
+ onAny(handler: (event: string, ...args: any[]) => void): void {
416
+ this.anyHandlers.push(handler);
417
+ }
418
+
419
+ emit(event: string, data: any): void {
420
+ if (!this.connected) return;
421
+
422
+ try {
423
+ const message = JSON.stringify({ event, data });
424
+ const buffer = Buffer.from(message);
425
+
426
+ // Send message with backpressure handling
427
+ const sent = this.ws.send(buffer, false); // false = not binary
428
+
429
+ if (!sent) {
430
+ this.logger.warn(`Backpressure detected for connection ${this.id}`, 'Backpressure');
431
+ }
432
+ } catch (error) {
433
+ this.logger.error(
434
+ `Failed to emit event ${event}: ${error instanceof Error ? error.message : String(error)}`,
435
+ 'Emit'
436
+ );
437
+ }
438
+ }
439
+
440
+ compressedEmit(event: string, data: any): void {
441
+ // uWebSockets.js handles compression automatically based on app configuration
442
+ // So this is the same as regular emit
443
+ this.emit(event, data);
444
+ }
445
+
446
+ handleMessage(data: any): void {
447
+ if (!data || typeof data !== 'object') {
448
+ this.logger.warn(`Invalid message format from ${this.id}`, 'Message');
449
+ return;
450
+ }
451
+
452
+ const { event, data: eventData, callback: hasCallback } = data;
453
+
454
+ if (!event) {
455
+ this.logger.warn(`Message without event from ${this.id}`, 'Message');
456
+ return;
457
+ }
458
+
459
+ // Create callback function if client expects response
460
+ const callback = hasCallback
461
+ ? (response?: any) => {
462
+ this.emit(`${event}:response`, response);
463
+ }
464
+ : undefined;
465
+
466
+ // Notify any handlers
467
+ for (const handler of this.anyHandlers) {
468
+ handler(event, eventData);
469
+ }
470
+
471
+ // Notify specific event handlers
472
+ const handlers = this.eventHandlers.get(event);
473
+ if (handlers) {
474
+ for (const handler of handlers) {
475
+ try {
476
+ handler(eventData, callback);
477
+ } catch (error) {
478
+ this.logger.error(
479
+ `Error in event handler for ${event}: ${error instanceof Error ? error.message : String(error)}`,
480
+ 'Handler'
481
+ );
482
+ }
483
+ }
484
+ }
485
+ }
486
+
487
+ handleClose(code: number, message: ArrayBuffer): void {
488
+ this.connected = false;
489
+ this.logger.debug(`Connection ${this.id} closed with code ${code}`, 'Close');
490
+ }
491
+
492
+ handleDrain(): void {
493
+ // Backpressure has been relieved
494
+ this.logger.debug(`Connection ${this.id} drained`, 'Drain');
495
+ }
496
+
497
+ join(room: string | string[]): void {
498
+ const roomsToJoin = Array.isArray(room) ? room : [room];
499
+ for (const r of roomsToJoin) {
500
+ this.rooms.add(r);
501
+ this.logger.debug(`Connection ${this.id} joined room ${r}`, 'Room');
502
+ }
503
+ }
504
+
505
+ leave(room: string | string[]): void {
506
+ const roomsToLeave = Array.isArray(room) ? room : [room];
507
+ for (const r of roomsToLeave) {
508
+ this.rooms.delete(r);
509
+ this.logger.debug(`Connection ${this.id} left room ${r}`, 'Room');
510
+ }
511
+ }
512
+
513
+ to(room: string | string[]): WebSocketEmitter {
514
+ return new UWSEmitterWrapper(new Map([[this.id, this]]), {
515
+ rooms: Array.isArray(room) ? room : [room],
516
+ });
517
+ }
518
+
519
+ get broadcast(): WebSocketEmitter {
520
+ return new UWSEmitterWrapper(
521
+ this.namespaces
522
+ .get('/')
523
+ ?.getSockets()
524
+ .filter(s => s.id !== this.id)
525
+ .reduce((map, conn) => {
526
+ map.set(conn.id, conn as UWSConnectionWrapper);
527
+ return map;
528
+ }, new Map<string, UWSConnectionWrapper>()) || new Map(),
529
+ {}
530
+ );
531
+ }
532
+
533
+ getRooms(): Set<string> {
534
+ return new Set(this.rooms);
535
+ }
536
+
537
+ disconnect(close = false): void {
538
+ if (!this.connected) return;
539
+
540
+ this.connected = false;
541
+
542
+ if (close && this.ws) {
543
+ try {
544
+ this.ws.end(1000, 'Normal closure');
545
+ } catch (error) {
546
+ this.logger.error(
547
+ `Error closing WebSocket: ${error instanceof Error ? error.message : String(error)}`,
548
+ 'Disconnect'
549
+ );
550
+ }
551
+ }
552
+ }
553
+ }
554
+
555
+ /**
556
+ * Emitter wrapper for room-based broadcasting
557
+ */
558
+ class UWSEmitterWrapper implements WebSocketEmitter {
559
+ private targetRooms: string[] = [];
560
+ private excludedRooms: string[] = [];
561
+ private useCompression = false;
562
+
563
+ constructor(
564
+ private connections: Map<string, UWSConnectionWrapper>,
565
+ private options: { rooms?: string[]; exceptRooms?: string[] } = {}
566
+ ) {
567
+ this.targetRooms = options.rooms || [];
568
+ this.excludedRooms = options.exceptRooms || [];
569
+ }
570
+
571
+ emit(event: string, data: any): void {
572
+ for (const [id, connection] of this.connections) {
573
+ if (!connection.connected) continue;
574
+
575
+ // Check room filtering
576
+ const connectionRooms = connection.getRooms();
577
+
578
+ // If target rooms specified, connection must be in at least one
579
+ if (this.targetRooms.length > 0) {
580
+ const inTargetRoom = this.targetRooms.some(room => connectionRooms.has(room));
581
+ if (!inTargetRoom) continue;
582
+ }
583
+
584
+ // If excluded rooms specified, connection must not be in any
585
+ if (this.excludedRooms.length > 0) {
586
+ const inExcludedRoom = this.excludedRooms.some(room => connectionRooms.has(room));
587
+ if (inExcludedRoom) continue;
588
+ }
589
+
590
+ // Emit to connection
591
+ if (this.useCompression && connection.compressedEmit) {
592
+ connection.compressedEmit(event, data);
593
+ } else {
594
+ connection.emit(event, data);
595
+ }
596
+ }
597
+ }
598
+
599
+ to(room: string | string[]): WebSocketEmitter {
600
+ const rooms = Array.isArray(room) ? room : [room];
601
+ return new UWSEmitterWrapper(this.connections, {
602
+ rooms: [...this.targetRooms, ...rooms],
603
+ exceptRooms: this.excludedRooms,
604
+ });
605
+ }
606
+
607
+ except(room: string | string[]): WebSocketEmitter {
608
+ const rooms = Array.isArray(room) ? room : [room];
609
+ return new UWSEmitterWrapper(this.connections, {
610
+ rooms: this.targetRooms,
611
+ exceptRooms: [...this.excludedRooms, ...rooms],
612
+ });
613
+ }
614
+
615
+ compress(compress: boolean): WebSocketEmitter {
616
+ this.useCompression = compress;
617
+ return this;
618
+ }
619
+ }