@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
@@ -0,0 +1,688 @@
1
+ // uWebSockets.js HTTP Server Implementation for Moro Framework
2
+ // Provides ultra-high-performance HTTP and WebSocket server using uWebSockets.js
3
+ import cluster from 'cluster';
4
+ import { createFrameworkLogger } from '../logger/index.js';
5
+ /**
6
+ * uWebSockets HTTP Server Adapter
7
+ * Bridges uWebSockets.js with Moro's HTTP abstractions
8
+ */
9
+ export class UWebSocketsHttpServer {
10
+ app; // uWebSockets app instance
11
+ uws; // uWebSockets module reference (stored to avoid re-importing)
12
+ listenSocket; // uWebSockets listen socket
13
+ routes = [];
14
+ globalMiddleware = [];
15
+ logger = createFrameworkLogger('UWSHttpServer');
16
+ hookManager;
17
+ requestCounter = 0;
18
+ isListening = false;
19
+ port;
20
+ host;
21
+ initPromise;
22
+ // Route caching for performance
23
+ staticRoutes = new Map();
24
+ dynamicRoutes = [];
25
+ // Performance optimizations - object pooling
26
+ paramObjectPool = [];
27
+ queryObjectPool = [];
28
+ maxPoolSize = 100;
29
+ // String interning for common values
30
+ static INTERNED_METHODS = new Map([
31
+ ['get', 'GET'],
32
+ ['post', 'POST'],
33
+ ['put', 'PUT'],
34
+ ['delete', 'DELETE'],
35
+ ['patch', 'PATCH'],
36
+ ['head', 'HEAD'],
37
+ ['options', 'OPTIONS'],
38
+ ]);
39
+ // Pre-compiled response buffers
40
+ static RESPONSE_BUFFERS = {
41
+ notFound: Buffer.from('{"success":false,"error":"Not found"}'),
42
+ serverError: Buffer.from('{"success":false,"error":"Internal server error"}'),
43
+ };
44
+ constructor(options = {}) {
45
+ this.initPromise = this.initialize(options);
46
+ }
47
+ async initialize(options) {
48
+ try {
49
+ // Lazy load uWebSockets.js - only when explicitly configured
50
+ // This ensures it's an optional dependency with graceful fallback
51
+ const uwsModule = await import('uWebSockets.js');
52
+ this.uws = uwsModule.default || uwsModule;
53
+ if (options.ssl && options.ssl.key_file_name && options.ssl.cert_file_name) {
54
+ this.app = this.uws.SSLApp({
55
+ key_file_name: options.ssl.key_file_name,
56
+ cert_file_name: options.ssl.cert_file_name,
57
+ passphrase: options.ssl.passphrase,
58
+ });
59
+ this.logger.info('uWebSockets SSL/TLS HTTP server created', 'Init');
60
+ }
61
+ else {
62
+ this.app = this.uws.App();
63
+ this.logger.info('uWebSockets HTTP server created', 'Init');
64
+ }
65
+ // Setup generic route handler for all HTTP methods and paths
66
+ this.setupRouteHandlers();
67
+ }
68
+ catch (error) {
69
+ // Log helpful error message with installation instructions
70
+ this.logger.error('Failed to load uWebSockets.js (optional dependency)\n' +
71
+ 'To use uWebSockets, install it with:\n' +
72
+ ' npm install --save-dev github:uNetworking/uWebSockets.js#v20.52.0\n' +
73
+ 'Or set useUWebSockets: false in your config to use the standard HTTP server.\n' +
74
+ 'Error: ' +
75
+ (error instanceof Error ? error.message : String(error)), 'Init');
76
+ throw error; // Re-throw so framework.ts can catch and fallback
77
+ }
78
+ }
79
+ setupRouteHandlers() {
80
+ // Handle all HTTP methods through catchall for proper routing
81
+ this.app.any('/*', (res, req) => {
82
+ // Try fast synchronous path first
83
+ const method = req.getMethod().toUpperCase();
84
+ const path = req.getUrl();
85
+ // Fast path: No body, no global middleware
86
+ if (this.globalMiddleware.length === 0 && method === 'GET') {
87
+ const route = this.findRoute(method, path);
88
+ if (route && (!route.middleware || route.middleware.length === 0)) {
89
+ this.handleRequestSync(req, res, route, method, path);
90
+ return;
91
+ }
92
+ }
93
+ // Slow path: Has middleware or body or other complexity
94
+ this.handleRequest(req, res);
95
+ });
96
+ }
97
+ // Fast synchronous handler for simple GET requests
98
+ handleRequestSync(req, res, route, method, path) {
99
+ this.requestCounter++;
100
+ let httpReq;
101
+ try {
102
+ httpReq = this.createMoroRequest(req, res);
103
+ const httpRes = this.createMoroResponse(req, res);
104
+ // Extract params if needed
105
+ if (route.paramNames.length > 0) {
106
+ const matches = path.match(route.pattern);
107
+ if (matches) {
108
+ httpReq.params = this.acquireParamObject();
109
+ route.paramNames.forEach((name, index) => {
110
+ httpReq.params[name] = matches[index + 1];
111
+ });
112
+ httpReq._pooledParams = httpReq.params;
113
+ }
114
+ }
115
+ // Execute handler synchronously
116
+ const result = route.handler(httpReq, httpRes);
117
+ // Handle return value
118
+ if (result && typeof result.then === 'function') {
119
+ // Oops, handler is async - handle it
120
+ result
121
+ .then((data) => {
122
+ if (data !== undefined && data !== null && !httpRes.headersSent) {
123
+ httpRes.json(data);
124
+ }
125
+ })
126
+ .catch(() => {
127
+ if (!res.aborted) {
128
+ res.cork(() => {
129
+ res.writeStatus('500 Internal Server Error');
130
+ res.end('{"success":false,"error":"Internal server error"}');
131
+ });
132
+ }
133
+ });
134
+ }
135
+ else if (result !== undefined && result !== null && !httpRes.headersSent) {
136
+ httpRes.json(result);
137
+ }
138
+ }
139
+ finally {
140
+ const pooledParams = httpReq?._pooledParams;
141
+ if (pooledParams)
142
+ this.releaseParamObject(pooledParams);
143
+ const pooledQuery = httpReq?._pooledQuery;
144
+ if (pooledQuery)
145
+ this.releaseQueryObject(pooledQuery);
146
+ }
147
+ }
148
+ // Object pooling methods for performance
149
+ acquireParamObject() {
150
+ return this.paramObjectPool.pop() || {};
151
+ }
152
+ releaseParamObject(obj) {
153
+ if (this.paramObjectPool.length < this.maxPoolSize) {
154
+ for (const key in obj)
155
+ delete obj[key];
156
+ this.paramObjectPool.push(obj);
157
+ }
158
+ }
159
+ acquireQueryObject() {
160
+ return this.queryObjectPool.pop() || {};
161
+ }
162
+ releaseQueryObject(obj) {
163
+ if (this.queryObjectPool.length < this.maxPoolSize) {
164
+ for (const key in obj)
165
+ delete obj[key];
166
+ this.queryObjectPool.push(obj);
167
+ }
168
+ }
169
+ async handleRequest(req, res) {
170
+ this.requestCounter++;
171
+ // Declare outside try block for cleanup in finally
172
+ let httpReq;
173
+ try {
174
+ // Create Moro-compatible request object
175
+ httpReq = this.createMoroRequest(req, res);
176
+ const httpRes = this.createMoroResponse(req, res);
177
+ // Parse body only if there's actually a body (check content-length)
178
+ const method = req.getMethod().toUpperCase();
179
+ const contentLength = req.getHeader('content-length');
180
+ if ((method === 'POST' || method === 'PUT' || method === 'PATCH') &&
181
+ contentLength &&
182
+ parseInt(contentLength) > 0) {
183
+ await this.readBody(res, httpReq);
184
+ }
185
+ // Execute hooks before request processing
186
+ if (this.hookManager) {
187
+ await this.hookManager.execute('request', {
188
+ request: httpReq,
189
+ response: httpRes,
190
+ });
191
+ }
192
+ // Find route first (before middleware)
193
+ const route = this.findRoute(httpReq.method, httpReq.path);
194
+ if (!route) {
195
+ // 404 Not Found - fast path
196
+ if (!httpRes.headersSent) {
197
+ httpRes.statusCode = 404;
198
+ httpRes.setHeader('Content-Type', 'application/json');
199
+ httpRes.end('{"success":false,"error":"Not found"}');
200
+ }
201
+ return;
202
+ }
203
+ // Extract path parameters early - use pooled object
204
+ const matches = httpReq.path.match(route.pattern);
205
+ if (matches) {
206
+ httpReq.params = this.acquireParamObject();
207
+ route.paramNames.forEach((name, index) => {
208
+ httpReq.params[name] = matches[index + 1];
209
+ });
210
+ // Store for cleanup
211
+ httpReq._pooledParams = httpReq.params;
212
+ }
213
+ // Execute ALL middleware in one pass (global + route)
214
+ if (this.globalMiddleware.length > 0 || (route.middleware && route.middleware.length > 0)) {
215
+ const allMiddleware = route.middleware && route.middleware.length > 0
216
+ ? [...this.globalMiddleware, ...route.middleware]
217
+ : this.globalMiddleware;
218
+ await this.executeMiddleware(allMiddleware, httpReq, httpRes);
219
+ if (httpRes.headersSent)
220
+ return;
221
+ }
222
+ // Execute route handler
223
+ const result = await route.handler(httpReq, httpRes);
224
+ // If handler returns data and response hasn't been sent, send it
225
+ if (result !== undefined && result !== null && !httpRes.headersSent) {
226
+ httpRes.json(result);
227
+ }
228
+ }
229
+ catch (error) {
230
+ this.logger.error(`Request handling error: ${error instanceof Error ? error.message : String(error)}`, 'RequestError');
231
+ // Send error response if not already sent
232
+ if (!res.aborted) {
233
+ try {
234
+ res.cork(() => {
235
+ res.writeStatus('500 Internal Server Error');
236
+ res.writeHeader('Content-Type', 'application/json');
237
+ res.end('{"success":false,"error":"Internal server error"}');
238
+ });
239
+ }
240
+ catch (writeError) {
241
+ this.logger.error('Failed to send error response', 'ResponseError');
242
+ }
243
+ }
244
+ }
245
+ finally {
246
+ // Cleanup: Release pooled objects back to pool for reuse
247
+ const pooledParams = httpReq._pooledParams;
248
+ if (pooledParams) {
249
+ this.releaseParamObject(pooledParams);
250
+ }
251
+ const pooledQuery = httpReq._pooledQuery;
252
+ if (pooledQuery) {
253
+ this.releaseQueryObject(pooledQuery);
254
+ }
255
+ }
256
+ }
257
+ createMoroRequest(req, res) {
258
+ const url = req.getUrl();
259
+ const queryString = req.getQuery();
260
+ const methodRaw = req.getMethod();
261
+ // Use interned method string if available
262
+ const method = UWebSocketsHttpServer.INTERNED_METHODS.get(methodRaw) || methodRaw.toUpperCase();
263
+ // Lazy query parsing - use pooled object
264
+ let queryParams;
265
+ if (queryString) {
266
+ queryParams = this.acquireQueryObject();
267
+ // Fast query parsing without URLSearchParams overhead
268
+ const pairs = queryString.split('&');
269
+ for (let i = 0; i < pairs.length; i++) {
270
+ const pair = pairs[i];
271
+ const eqIdx = pair.indexOf('=');
272
+ if (eqIdx > 0) {
273
+ const key = pair.substring(0, eqIdx);
274
+ const value = pair.substring(eqIdx + 1);
275
+ queryParams[decodeURIComponent(key)] = decodeURIComponent(value);
276
+ }
277
+ }
278
+ }
279
+ // Lazy header parsing - only parse headers that exist
280
+ const headers = {};
281
+ req.forEach((key, value) => {
282
+ const lowerKey = key.toLowerCase();
283
+ headers[lowerKey] = value;
284
+ });
285
+ const httpReq = {
286
+ method,
287
+ path: url,
288
+ url: url,
289
+ query: queryParams || {},
290
+ params: {}, // Will be filled by route matching
291
+ headers,
292
+ body: null,
293
+ ip: '', // Lazy - only compute if accessed
294
+ requestId: '', // Lazy - only generate if accessed
295
+ };
296
+ // Store original query object for cleanup
297
+ httpReq._pooledQuery = queryParams;
298
+ return httpReq;
299
+ }
300
+ createMoroResponse(req, res) {
301
+ let headersSent = false;
302
+ let statusCode = 200;
303
+ const responseHeaders = {};
304
+ //eslint-disable-next-line @typescript-eslint/no-this-alias
305
+ const self = this;
306
+ const httpRes = {
307
+ statusCode,
308
+ get headersSent() {
309
+ return headersSent;
310
+ },
311
+ status(code) {
312
+ statusCode = code;
313
+ httpRes.statusCode = code;
314
+ return httpRes;
315
+ },
316
+ setHeader(name, value) {
317
+ responseHeaders[name.toLowerCase()] = value;
318
+ return httpRes;
319
+ },
320
+ getHeader(name) {
321
+ return responseHeaders[name.toLowerCase()];
322
+ },
323
+ removeHeader(name) {
324
+ delete responseHeaders[name.toLowerCase()];
325
+ return httpRes;
326
+ },
327
+ json(data) {
328
+ if (headersSent || res.aborted)
329
+ return;
330
+ const body = JSON.stringify(data);
331
+ responseHeaders['content-type'] = 'application/json';
332
+ try {
333
+ res.cork(() => {
334
+ res.writeStatus(`${statusCode} OK`);
335
+ Object.entries(responseHeaders).forEach(([key, value]) => {
336
+ res.writeHeader(key, Array.isArray(value) ? value.join(', ') : String(value));
337
+ });
338
+ res.end(body);
339
+ });
340
+ headersSent = true;
341
+ }
342
+ catch (error) {
343
+ self.logger.error('Failed to send JSON response', 'ResponseError');
344
+ }
345
+ },
346
+ send(data) {
347
+ if (headersSent || res.aborted)
348
+ return;
349
+ const body = typeof data === 'string' ? data : data.toString();
350
+ try {
351
+ res.cork(() => {
352
+ res.writeStatus(`${statusCode} OK`);
353
+ Object.entries(responseHeaders).forEach(([key, value]) => {
354
+ res.writeHeader(key, Array.isArray(value) ? value.join(', ') : String(value));
355
+ });
356
+ res.end(body);
357
+ });
358
+ headersSent = true;
359
+ }
360
+ catch (error) {
361
+ self.logger.error('Failed to send response', 'ResponseError');
362
+ }
363
+ },
364
+ end(data, encoding, callback) {
365
+ if (headersSent || res.aborted) {
366
+ if (typeof callback === 'function')
367
+ callback();
368
+ return httpRes;
369
+ }
370
+ try {
371
+ res.cork(() => {
372
+ res.writeStatus(`${statusCode} OK`);
373
+ Object.entries(responseHeaders).forEach(([key, value]) => {
374
+ res.writeHeader(key, Array.isArray(value) ? value.join(', ') : String(value));
375
+ });
376
+ res.end(data || '');
377
+ });
378
+ headersSent = true;
379
+ if (typeof callback === 'function')
380
+ callback();
381
+ }
382
+ catch (error) {
383
+ self.logger.error('Failed to end response', 'ResponseError');
384
+ if (typeof callback === 'function')
385
+ callback();
386
+ }
387
+ return httpRes;
388
+ },
389
+ redirect(url, code) {
390
+ if (headersSent || res.aborted)
391
+ return;
392
+ const redirectCode = code || 302;
393
+ statusCode = redirectCode;
394
+ try {
395
+ res.cork(() => {
396
+ res.writeStatus(`${redirectCode} Found`);
397
+ res.writeHeader('Location', url);
398
+ res.end();
399
+ });
400
+ headersSent = true;
401
+ }
402
+ catch (error) {
403
+ self.logger.error('Failed to send redirect', 'ResponseError');
404
+ }
405
+ },
406
+ // EventEmitter compatibility - stub implementations for middleware
407
+ on(event, callback) {
408
+ // uWebSockets doesn't use events like Node.js, but middleware might try to listen
409
+ // Only implement 'finish' and 'close' events as stubs
410
+ return httpRes;
411
+ },
412
+ once(event, callback) {
413
+ return httpRes;
414
+ },
415
+ emit(event, ...args) {
416
+ return true;
417
+ },
418
+ removeListener(event, callback) {
419
+ return httpRes;
420
+ },
421
+ cookie(name, value, options) {
422
+ let cookie = `${name}=${value}`;
423
+ if (options) {
424
+ if (options.maxAge)
425
+ cookie += `; Max-Age=${options.maxAge}`;
426
+ if (options.domain)
427
+ cookie += `; Domain=${options.domain}`;
428
+ if (options.path)
429
+ cookie += `; Path=${options.path}`;
430
+ if (options.secure)
431
+ cookie += '; Secure';
432
+ if (options.httpOnly)
433
+ cookie += '; HttpOnly';
434
+ if (options.sameSite)
435
+ cookie += `; SameSite=${options.sameSite}`;
436
+ }
437
+ const existing = responseHeaders['set-cookie'];
438
+ if (existing) {
439
+ if (Array.isArray(existing)) {
440
+ responseHeaders['set-cookie'] = [...existing, cookie];
441
+ }
442
+ else {
443
+ responseHeaders['set-cookie'] = [existing, cookie];
444
+ }
445
+ }
446
+ else {
447
+ responseHeaders['set-cookie'] = cookie;
448
+ }
449
+ return httpRes;
450
+ },
451
+ };
452
+ return httpRes;
453
+ }
454
+ async readBody(res, httpReq) {
455
+ return new Promise((resolve, reject) => {
456
+ let buffer;
457
+ res.onData((chunk, isLast) => {
458
+ const chunkBuffer = Buffer.from(chunk);
459
+ if (isLast) {
460
+ if (buffer) {
461
+ buffer = Buffer.concat([buffer, chunkBuffer]);
462
+ }
463
+ else {
464
+ buffer = chunkBuffer;
465
+ }
466
+ try {
467
+ const contentType = httpReq.headers['content-type'] || '';
468
+ if (contentType.includes('application/json')) {
469
+ httpReq.body = JSON.parse(buffer.toString('utf-8'));
470
+ }
471
+ else if (contentType.includes('application/x-www-form-urlencoded')) {
472
+ const params = new URLSearchParams(buffer.toString('utf-8'));
473
+ const body = {};
474
+ params.forEach((value, key) => {
475
+ body[key] = value;
476
+ });
477
+ httpReq.body = body;
478
+ }
479
+ else {
480
+ httpReq.body = buffer.toString('utf-8');
481
+ }
482
+ resolve();
483
+ }
484
+ catch (error) {
485
+ this.logger.error('Failed to parse request body', 'BodyParseError');
486
+ httpReq.body = null;
487
+ resolve();
488
+ }
489
+ }
490
+ else {
491
+ if (buffer) {
492
+ buffer = Buffer.concat([buffer, chunkBuffer]);
493
+ }
494
+ else {
495
+ buffer = chunkBuffer;
496
+ }
497
+ }
498
+ });
499
+ res.onAborted(() => {
500
+ this.logger.debug('Request aborted', 'RequestAborted');
501
+ resolve();
502
+ });
503
+ });
504
+ }
505
+ async executeMiddleware(middleware, req, res) {
506
+ for (const mw of middleware) {
507
+ if (res.headersSent)
508
+ break;
509
+ await new Promise((resolve, reject) => {
510
+ try {
511
+ const result = mw(req, res, (err) => {
512
+ if (err)
513
+ reject(err);
514
+ else
515
+ resolve();
516
+ });
517
+ // Handle async middleware
518
+ if (result && typeof result.then === 'function') {
519
+ result.then(() => resolve()).catch(reject);
520
+ }
521
+ }
522
+ catch (error) {
523
+ reject(error);
524
+ }
525
+ });
526
+ }
527
+ }
528
+ findRoute(method, path) {
529
+ // Fast path: static route lookup
530
+ const staticKey = `${method}:${path}`;
531
+ const staticRoute = this.staticRoutes.get(staticKey);
532
+ if (staticRoute)
533
+ return staticRoute;
534
+ // Dynamic route matching
535
+ for (const route of this.dynamicRoutes) {
536
+ if (route.method === method && route.pattern.test(path)) {
537
+ return route;
538
+ }
539
+ }
540
+ return null;
541
+ }
542
+ // Public API - matches MoroHttpServer interface
543
+ use(middleware) {
544
+ this.globalMiddleware.push(middleware);
545
+ }
546
+ get(path, handler, middleware) {
547
+ this.addRoute('GET', path, handler, middleware);
548
+ }
549
+ post(path, handler, middleware) {
550
+ this.addRoute('POST', path, handler, middleware);
551
+ }
552
+ put(path, handler, middleware) {
553
+ this.addRoute('PUT', path, handler, middleware);
554
+ }
555
+ delete(path, handler, middleware) {
556
+ this.addRoute('DELETE', path, handler, middleware);
557
+ }
558
+ patch(path, handler, middleware) {
559
+ this.addRoute('PATCH', path, handler, middleware);
560
+ }
561
+ options(path, handler, middleware) {
562
+ this.addRoute('OPTIONS', path, handler, middleware);
563
+ }
564
+ head(path, handler, middleware) {
565
+ this.addRoute('HEAD', path, handler, middleware);
566
+ }
567
+ addRoute(method, path, handler, middleware) {
568
+ const { pattern, paramNames } = this.pathToRegex(path);
569
+ const route = {
570
+ method,
571
+ path,
572
+ pattern,
573
+ paramNames,
574
+ handler,
575
+ middleware: middleware || [],
576
+ };
577
+ this.routes.push(route);
578
+ // Optimize route lookup
579
+ if (paramNames.length === 0) {
580
+ // Static route
581
+ this.staticRoutes.set(`${method}:${path}`, route);
582
+ }
583
+ else {
584
+ // Dynamic route
585
+ this.dynamicRoutes.push(route);
586
+ }
587
+ this.logger.debug(`Route registered: ${method} ${path}`, 'RouteRegistration');
588
+ }
589
+ pathToRegex(path) {
590
+ const paramNames = [];
591
+ const regexPath = path.replace(/\//g, '\\/').replace(/:([^/]+)/g, (match, paramName) => {
592
+ paramNames.push(paramName);
593
+ return '([^/]+)';
594
+ });
595
+ return {
596
+ pattern: new RegExp(`^${regexPath}$`),
597
+ paramNames,
598
+ };
599
+ }
600
+ setHookManager(hookManager) {
601
+ this.hookManager = hookManager;
602
+ }
603
+ configurePerformance(config) {
604
+ // uWebSockets is already highly optimized
605
+ // This method exists for API compatibility
606
+ this.logger.debug('Performance configuration noted (uWebSockets is pre-optimized)', 'Config');
607
+ }
608
+ listen(port, hostOrCallback, callback) {
609
+ // Wrap in async to await init
610
+ this.initPromise
611
+ .then(() => {
612
+ if (this.isListening) {
613
+ this.logger.warn('Server is already listening', 'Listen');
614
+ return;
615
+ }
616
+ const host = typeof hostOrCallback === 'string' ? hostOrCallback : '0.0.0.0';
617
+ const cb = typeof hostOrCallback === 'function' ? hostOrCallback : callback;
618
+ this.port = port;
619
+ this.host = host;
620
+ // Check if we're in a cluster environment
621
+ const isClusterWorker = cluster.isWorker;
622
+ const isClusterPrimary = cluster.isPrimary;
623
+ // ALWAYS use LIBUS_LISTEN_EXCLUSIVE_PORT when clustering
624
+ // This enables SO_REUSEPORT at the OS level, allowing multiple processes to bind to the same port
625
+ // NOTE: uWebSockets.js API doesn't have listen(host, port, options, cb)
626
+ // We must use listen(port, options, cb) which binds to 0.0.0.0
627
+ const listenOptions = 1; // ALWAYS use LIBUS_LISTEN_EXCLUSIVE_PORT for clustering support
628
+ this.app.listen(port, listenOptions, (token) => {
629
+ if (token) {
630
+ this.listenSocket = token;
631
+ this.isListening = true;
632
+ const clusterInfo = isClusterWorker ? ` (worker ${process.pid})` : '';
633
+ this.logger.info(`uWebSockets HTTP server listening on 0.0.0.0:${port}${clusterInfo}`, 'Listen');
634
+ if (cb)
635
+ cb();
636
+ }
637
+ else {
638
+ const clusterInfo = isClusterWorker ? ` (worker ${process.pid})` : '';
639
+ this.logger.error(`Failed to listen on port ${port}${clusterInfo}`, 'Listen');
640
+ // Don't throw in cluster workers - let them fail gracefully
641
+ if (!isClusterWorker) {
642
+ throw new Error(`Failed to bind to port ${port}`);
643
+ }
644
+ }
645
+ });
646
+ })
647
+ .catch(error => {
648
+ this.logger.error('Failed to initialize server before listen', 'Listen', {
649
+ error: error instanceof Error ? error.message : String(error),
650
+ });
651
+ });
652
+ }
653
+ async close(callback) {
654
+ if (!this.isListening) {
655
+ if (callback)
656
+ callback();
657
+ return;
658
+ }
659
+ try {
660
+ // Use stored module reference instead of re-importing
661
+ if (this.listenSocket && this.uws) {
662
+ this.uws.us_listen_socket_close(this.listenSocket);
663
+ this.listenSocket = null;
664
+ this.isListening = false;
665
+ this.logger.info('uWebSockets HTTP server closed', 'Close');
666
+ }
667
+ if (callback)
668
+ callback();
669
+ }
670
+ catch (error) {
671
+ this.logger.error('Error closing server', 'Close');
672
+ if (callback)
673
+ callback();
674
+ }
675
+ }
676
+ getServer() {
677
+ // Return the uWebSockets app for direct access if needed
678
+ return this.app;
679
+ }
680
+ getApp() {
681
+ return this.app;
682
+ }
683
+ forceCleanup() {
684
+ // Cleanup method for compatibility
685
+ this.logger.debug('Force cleanup called', 'Cleanup');
686
+ }
687
+ }
688
+ //# sourceMappingURL=uws-http-server.js.map