@morojs/moro 1.7.30 → 1.8.1

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 +89 -46
  2. package/dist/core/auth/morojs-adapter.js +95 -45
  3. package/dist/core/auth/morojs-adapter.js.map +1 -1
  4. package/dist/core/config/config-manager.js.map +1 -1
  5. package/dist/core/config/config-sources.js +119 -48
  6. package/dist/core/config/config-sources.js.map +1 -1
  7. package/dist/core/config/config-validator.js +189 -8
  8. package/dist/core/config/config-validator.js.map +1 -1
  9. package/dist/core/config/file-loader.js.map +1 -1
  10. package/dist/core/config/index.js.map +1 -1
  11. package/dist/core/config/schema.js +35 -4
  12. package/dist/core/config/schema.js.map +1 -1
  13. package/dist/core/config/utils.js.map +1 -1
  14. package/dist/core/database/adapters/drizzle.js +2 -2
  15. package/dist/core/database/adapters/drizzle.js.map +1 -1
  16. package/dist/core/database/adapters/index.js.map +1 -1
  17. package/dist/core/database/adapters/mongodb.d.ts +1 -0
  18. package/dist/core/database/adapters/mongodb.js +16 -0
  19. package/dist/core/database/adapters/mongodb.js.map +1 -1
  20. package/dist/core/database/adapters/mysql.d.ts +1 -0
  21. package/dist/core/database/adapters/mysql.js +13 -2
  22. package/dist/core/database/adapters/mysql.js.map +1 -1
  23. package/dist/core/database/adapters/postgresql.js +2 -2
  24. package/dist/core/database/adapters/postgresql.js.map +1 -1
  25. package/dist/core/database/adapters/redis.js.map +1 -1
  26. package/dist/core/database/adapters/sql-safety.js +5 -4
  27. package/dist/core/database/adapters/sql-safety.js.map +1 -1
  28. package/dist/core/database/adapters/sqlite.js.map +1 -1
  29. package/dist/core/database/index.js.map +1 -1
  30. package/dist/core/docs/index.js +11 -7
  31. package/dist/core/docs/index.js.map +1 -1
  32. package/dist/core/docs/openapi-generator.js +8 -6
  33. package/dist/core/docs/openapi-generator.js.map +1 -1
  34. package/dist/core/docs/schema-to-openapi.js +3 -3
  35. package/dist/core/docs/schema-to-openapi.js.map +1 -1
  36. package/dist/core/docs/simple-docs.js.map +1 -1
  37. package/dist/core/docs/swagger-ui.js.map +1 -1
  38. package/dist/core/docs/zod-to-openapi.js +2 -2
  39. package/dist/core/docs/zod-to-openapi.js.map +1 -1
  40. package/dist/core/events/event-bus.js +14 -5
  41. package/dist/core/events/event-bus.js.map +1 -1
  42. package/dist/core/events/index.js.map +1 -1
  43. package/dist/core/framework.d.ts +41 -3
  44. package/dist/core/framework.js +342 -95
  45. package/dist/core/framework.js.map +1 -1
  46. package/dist/core/graphql/adapter.js.map +1 -1
  47. package/dist/core/graphql/adapters/graphql-js-adapter.js.map +1 -1
  48. package/dist/core/graphql/core.js.map +1 -1
  49. package/dist/core/graphql/index.js.map +1 -1
  50. package/dist/core/graphql/loader.js.map +1 -1
  51. package/dist/core/graphql/types.js.map +1 -1
  52. package/dist/core/grpc/adapters/grpc-js-adapter.js +4 -0
  53. package/dist/core/grpc/adapters/grpc-js-adapter.js.map +1 -1
  54. package/dist/core/grpc/adapters/index.js.map +1 -1
  55. package/dist/core/grpc/grpc-adapter.js.map +1 -1
  56. package/dist/core/grpc/grpc-manager.js.map +1 -1
  57. package/dist/core/grpc/index.js.map +1 -1
  58. package/dist/core/grpc/middleware/auth.js +1 -1
  59. package/dist/core/grpc/middleware/auth.js.map +1 -1
  60. package/dist/core/grpc/middleware/logging.js.map +1 -1
  61. package/dist/core/grpc/middleware/validation.js +1 -1
  62. package/dist/core/grpc/middleware/validation.js.map +1 -1
  63. package/dist/core/grpc/types.d.ts +7 -7
  64. package/dist/core/grpc/types.js.map +1 -1
  65. package/dist/core/http/http-server.d.ts +17 -23
  66. package/dist/core/http/http-server.js +109 -249
  67. package/dist/core/http/http-server.js.map +1 -1
  68. package/dist/core/http/http2-server.d.ts +6 -16
  69. package/dist/core/http/http2-server.js +40 -83
  70. package/dist/core/http/http2-server.js.map +1 -1
  71. package/dist/core/http/index.d.ts +1 -0
  72. package/dist/core/http/index.js +3 -0
  73. package/dist/core/http/index.js.map +1 -1
  74. package/dist/core/http/moro-engine-server.d.ts +263 -0
  75. package/dist/core/http/moro-engine-server.js +1962 -0
  76. package/dist/core/http/moro-engine-server.js.map +1 -0
  77. package/dist/core/http/utils/compression.d.ts +47 -0
  78. package/dist/core/http/utils/compression.js +132 -0
  79. package/dist/core/http/utils/compression.js.map +1 -0
  80. package/dist/core/http/utils/lazy-event-emitter.d.ts +11 -0
  81. package/dist/core/http/utils/lazy-event-emitter.js +69 -0
  82. package/dist/core/http/utils/lazy-event-emitter.js.map +1 -0
  83. package/dist/core/http/utils/multipart-parser.d.ts +32 -0
  84. package/dist/core/http/utils/multipart-parser.js +215 -0
  85. package/dist/core/http/utils/multipart-parser.js.map +1 -0
  86. package/dist/core/http/utils/query-parser.d.ts +1 -0
  87. package/dist/core/http/utils/query-parser.js +44 -0
  88. package/dist/core/http/utils/query-parser.js.map +1 -0
  89. package/dist/core/http/utils/size.d.ts +33 -0
  90. package/dist/core/http/utils/size.js +37 -0
  91. package/dist/core/http/utils/size.js.map +1 -0
  92. package/dist/core/http/utils/ssl-config.d.ts +69 -0
  93. package/dist/core/http/utils/ssl-config.js +116 -0
  94. package/dist/core/http/utils/ssl-config.js.map +1 -0
  95. package/dist/core/http/utils/uws-worker-clustering.js +45 -32
  96. package/dist/core/http/utils/uws-worker-clustering.js.map +1 -1
  97. package/dist/core/http/uws-http-server.d.ts +25 -3
  98. package/dist/core/http/uws-http-server.js +465 -86
  99. package/dist/core/http/uws-http-server.js.map +1 -1
  100. package/dist/core/jobs/cron-parser.js +7 -5
  101. package/dist/core/jobs/cron-parser.js.map +1 -1
  102. package/dist/core/jobs/index.js.map +1 -1
  103. package/dist/core/jobs/job-executor.d.ts +1 -1
  104. package/dist/core/jobs/job-executor.js.map +1 -1
  105. package/dist/core/jobs/job-scheduler.d.ts +3 -3
  106. package/dist/core/jobs/job-scheduler.js.map +1 -1
  107. package/dist/core/jobs/job-state-manager.d.ts +3 -3
  108. package/dist/core/jobs/job-state-manager.js +25 -4
  109. package/dist/core/jobs/job-state-manager.js.map +1 -1
  110. package/dist/core/jobs/leader-election.d.ts +15 -0
  111. package/dist/core/jobs/leader-election.js +158 -69
  112. package/dist/core/jobs/leader-election.js.map +1 -1
  113. package/dist/core/jobs/types.d.ts +4 -4
  114. package/dist/core/jobs/types.js.map +1 -1
  115. package/dist/core/jobs/utils.d.ts +1 -1
  116. package/dist/core/jobs/utils.js +7 -3
  117. package/dist/core/jobs/utils.js.map +1 -1
  118. package/dist/core/logger/filters.js +3 -2
  119. package/dist/core/logger/filters.js.map +1 -1
  120. package/dist/core/logger/index.js.map +1 -1
  121. package/dist/core/logger/logger.js +56 -25
  122. package/dist/core/logger/logger.js.map +1 -1
  123. package/dist/core/logger/outputs.js.map +1 -1
  124. package/dist/core/mail/adapters/console-adapter.js.map +1 -1
  125. package/dist/core/mail/adapters/index.js.map +1 -1
  126. package/dist/core/mail/adapters/nodemailer-adapter.js.map +1 -1
  127. package/dist/core/mail/adapters/resend-adapter.js.map +1 -1
  128. package/dist/core/mail/adapters/sendgrid-adapter.js.map +1 -1
  129. package/dist/core/mail/adapters/ses-adapter.js.map +1 -1
  130. package/dist/core/mail/index.js.map +1 -1
  131. package/dist/core/mail/mail-adapter.js.map +1 -1
  132. package/dist/core/mail/mail-manager.d.ts +10 -0
  133. package/dist/core/mail/mail-manager.js +21 -5
  134. package/dist/core/mail/mail-manager.js.map +1 -1
  135. package/dist/core/mail/template-engine.js.map +1 -1
  136. package/dist/core/mail/types.js.map +1 -1
  137. package/dist/core/middleware/built-in/auth/core.js +3 -3
  138. package/dist/core/middleware/built-in/auth/core.js.map +1 -1
  139. package/dist/core/middleware/built-in/auth/helpers.js +4 -4
  140. package/dist/core/middleware/built-in/auth/helpers.js.map +1 -1
  141. package/dist/core/middleware/built-in/auth/hook.js.map +1 -1
  142. package/dist/core/middleware/built-in/auth/index.js.map +1 -1
  143. package/dist/core/middleware/built-in/auth/jwt-helpers.d.ts +4 -4
  144. package/dist/core/middleware/built-in/auth/jwt-helpers.js.map +1 -1
  145. package/dist/core/middleware/built-in/auth/middleware.js.map +1 -1
  146. package/dist/core/middleware/built-in/auth/providers.js.map +1 -1
  147. package/dist/core/middleware/built-in/body-parsers/index.js.map +1 -1
  148. package/dist/core/middleware/built-in/body-size/core.js +2 -2
  149. package/dist/core/middleware/built-in/body-size/core.js.map +1 -1
  150. package/dist/core/middleware/built-in/body-size/hook.js.map +1 -1
  151. package/dist/core/middleware/built-in/body-size/index.js.map +1 -1
  152. package/dist/core/middleware/built-in/body-size/middleware.js.map +1 -1
  153. package/dist/core/middleware/built-in/cache/adapters/cache/file.js +3 -1
  154. package/dist/core/middleware/built-in/cache/adapters/cache/file.js.map +1 -1
  155. package/dist/core/middleware/built-in/cache/adapters/cache/index.js.map +1 -1
  156. package/dist/core/middleware/built-in/cache/adapters/cache/memory.js.map +1 -1
  157. package/dist/core/middleware/built-in/cache/adapters/cache/redis.js.map +1 -1
  158. package/dist/core/middleware/built-in/cache/adapters/index.js.map +1 -1
  159. package/dist/core/middleware/built-in/cache/core.js.map +1 -1
  160. package/dist/core/middleware/built-in/cache/hook.js +3 -3
  161. package/dist/core/middleware/built-in/cache/hook.js.map +1 -1
  162. package/dist/core/middleware/built-in/cache/index.js.map +1 -1
  163. package/dist/core/middleware/built-in/cache/middleware.js.map +1 -1
  164. package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.js.map +1 -1
  165. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.js.map +1 -1
  166. package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudfront.js.map +1 -1
  167. package/dist/core/middleware/built-in/cdn/adapters/cdn/index.js.map +1 -1
  168. package/dist/core/middleware/built-in/cdn/adapters/index.js.map +1 -1
  169. package/dist/core/middleware/built-in/cdn/core.js.map +1 -1
  170. package/dist/core/middleware/built-in/cdn/hook.js.map +1 -1
  171. package/dist/core/middleware/built-in/cdn/index.js.map +1 -1
  172. package/dist/core/middleware/built-in/cdn/middleware.js.map +1 -1
  173. package/dist/core/middleware/built-in/compression/core.d.ts +3 -0
  174. package/dist/core/middleware/built-in/compression/core.js +28 -34
  175. package/dist/core/middleware/built-in/compression/core.js.map +1 -1
  176. package/dist/core/middleware/built-in/compression/hook.js.map +1 -1
  177. package/dist/core/middleware/built-in/compression/index.js.map +1 -1
  178. package/dist/core/middleware/built-in/compression/middleware.js.map +1 -1
  179. package/dist/core/middleware/built-in/cookie/core.js.map +1 -1
  180. package/dist/core/middleware/built-in/cookie/hook.js.map +1 -1
  181. package/dist/core/middleware/built-in/cookie/index.js.map +1 -1
  182. package/dist/core/middleware/built-in/cookie/middleware.js.map +1 -1
  183. package/dist/core/middleware/built-in/cors/core.js.map +1 -1
  184. package/dist/core/middleware/built-in/cors/hook.js.map +1 -1
  185. package/dist/core/middleware/built-in/cors/index.js.map +1 -1
  186. package/dist/core/middleware/built-in/cors/middleware.js.map +1 -1
  187. package/dist/core/middleware/built-in/csp/core.js.map +1 -1
  188. package/dist/core/middleware/built-in/csp/hook.js.map +1 -1
  189. package/dist/core/middleware/built-in/csp/index.js.map +1 -1
  190. package/dist/core/middleware/built-in/csp/middleware.js.map +1 -1
  191. package/dist/core/middleware/built-in/csrf/core.js +1 -1
  192. package/dist/core/middleware/built-in/csrf/core.js.map +1 -1
  193. package/dist/core/middleware/built-in/csrf/hook.js.map +1 -1
  194. package/dist/core/middleware/built-in/csrf/index.js.map +1 -1
  195. package/dist/core/middleware/built-in/csrf/middleware.js.map +1 -1
  196. package/dist/core/middleware/built-in/error-tracker/index.js.map +1 -1
  197. package/dist/core/middleware/built-in/error-tracker/middleware.js.map +1 -1
  198. package/dist/core/middleware/built-in/graphql/core.js.map +1 -1
  199. package/dist/core/middleware/built-in/graphql/helpers.js.map +1 -1
  200. package/dist/core/middleware/built-in/graphql/hook.js.map +1 -1
  201. package/dist/core/middleware/built-in/graphql/index.js.map +1 -1
  202. package/dist/core/middleware/built-in/graphql/middleware.js.map +1 -1
  203. package/dist/core/middleware/built-in/graphql/subscriptions.js.map +1 -1
  204. package/dist/core/middleware/built-in/helmet/core.js.map +1 -1
  205. package/dist/core/middleware/built-in/helmet/hook.js.map +1 -1
  206. package/dist/core/middleware/built-in/helmet/index.js.map +1 -1
  207. package/dist/core/middleware/built-in/helmet/middleware.js.map +1 -1
  208. package/dist/core/middleware/built-in/http2/core.js.map +1 -1
  209. package/dist/core/middleware/built-in/http2/hook.js.map +1 -1
  210. package/dist/core/middleware/built-in/http2/index.js.map +1 -1
  211. package/dist/core/middleware/built-in/http2/middleware.js.map +1 -1
  212. package/dist/core/middleware/built-in/index.js.map +1 -1
  213. package/dist/core/middleware/built-in/performance-monitor/index.js.map +1 -1
  214. package/dist/core/middleware/built-in/performance-monitor/middleware.js.map +1 -1
  215. package/dist/core/middleware/built-in/range/core.js +4 -1
  216. package/dist/core/middleware/built-in/range/core.js.map +1 -1
  217. package/dist/core/middleware/built-in/range/hook.js.map +1 -1
  218. package/dist/core/middleware/built-in/range/index.js.map +1 -1
  219. package/dist/core/middleware/built-in/range/middleware.js.map +1 -1
  220. package/dist/core/middleware/built-in/rate-limit/core.js.map +1 -1
  221. package/dist/core/middleware/built-in/rate-limit/hook.js.map +1 -1
  222. package/dist/core/middleware/built-in/rate-limit/index.js.map +1 -1
  223. package/dist/core/middleware/built-in/rate-limit/middleware.js.map +1 -1
  224. package/dist/core/middleware/built-in/request-logger/index.js.map +1 -1
  225. package/dist/core/middleware/built-in/request-logger/middleware.js.map +1 -1
  226. package/dist/core/middleware/built-in/session/core.js +4 -4
  227. package/dist/core/middleware/built-in/session/core.js.map +1 -1
  228. package/dist/core/middleware/built-in/session/hook.js.map +1 -1
  229. package/dist/core/middleware/built-in/session/index.js.map +1 -1
  230. package/dist/core/middleware/built-in/session/middleware.js.map +1 -1
  231. package/dist/core/middleware/built-in/sse/core.js.map +1 -1
  232. package/dist/core/middleware/built-in/sse/hook.js.map +1 -1
  233. package/dist/core/middleware/built-in/sse/index.js.map +1 -1
  234. package/dist/core/middleware/built-in/sse/middleware.js.map +1 -1
  235. package/dist/core/middleware/built-in/static/core.js.map +1 -1
  236. package/dist/core/middleware/built-in/static/hook.js.map +1 -1
  237. package/dist/core/middleware/built-in/static/index.js.map +1 -1
  238. package/dist/core/middleware/built-in/static/middleware.js.map +1 -1
  239. package/dist/core/middleware/built-in/template/core.js +1 -1
  240. package/dist/core/middleware/built-in/template/core.js.map +1 -1
  241. package/dist/core/middleware/built-in/template/hook.js.map +1 -1
  242. package/dist/core/middleware/built-in/template/index.js.map +1 -1
  243. package/dist/core/middleware/built-in/template/middleware.js.map +1 -1
  244. package/dist/core/middleware/built-in/upload/core.js.map +1 -1
  245. package/dist/core/middleware/built-in/upload/hook.js.map +1 -1
  246. package/dist/core/middleware/built-in/upload/index.js.map +1 -1
  247. package/dist/core/middleware/built-in/upload/middleware.js.map +1 -1
  248. package/dist/core/middleware/built-in/validation/core.js.map +1 -1
  249. package/dist/core/middleware/built-in/validation/hook.js.map +1 -1
  250. package/dist/core/middleware/built-in/validation/index.js.map +1 -1
  251. package/dist/core/middleware/built-in/validation/middleware.js.map +1 -1
  252. package/dist/core/middleware/index.js +2 -2
  253. package/dist/core/middleware/index.js.map +1 -1
  254. package/dist/core/modules/auto-discovery.js +11 -7
  255. package/dist/core/modules/auto-discovery.js.map +1 -1
  256. package/dist/core/modules/index.js.map +1 -1
  257. package/dist/core/modules/modules.js +18 -13
  258. package/dist/core/modules/modules.js.map +1 -1
  259. package/dist/core/networking/adapters/engine-adapter.d.ts +23 -0
  260. package/dist/core/networking/adapters/engine-adapter.js +365 -0
  261. package/dist/core/networking/adapters/engine-adapter.js.map +1 -0
  262. package/dist/core/networking/adapters/index.d.ts +1 -0
  263. package/dist/core/networking/adapters/index.js +1 -0
  264. package/dist/core/networking/adapters/index.js.map +1 -1
  265. package/dist/core/networking/adapters/socketio-adapter.d.ts +1 -0
  266. package/dist/core/networking/adapters/socketio-adapter.js +12 -1
  267. package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
  268. package/dist/core/networking/adapters/uws-adapter.js +27 -16
  269. package/dist/core/networking/adapters/uws-adapter.js.map +1 -1
  270. package/dist/core/networking/adapters/ws-adapter.d.ts +15 -0
  271. package/dist/core/networking/adapters/ws-adapter.js +120 -6
  272. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  273. package/dist/core/networking/index.js.map +1 -1
  274. package/dist/core/networking/service-discovery.js +7 -5
  275. package/dist/core/networking/service-discovery.js.map +1 -1
  276. package/dist/core/networking/websocket-adapter.d.ts +22 -3
  277. package/dist/core/networking/websocket-adapter.js.map +1 -1
  278. package/dist/core/networking/websocket-manager.js +70 -67
  279. package/dist/core/networking/websocket-manager.js.map +1 -1
  280. package/dist/core/pooling/object-pool-manager.js +6 -0
  281. package/dist/core/pooling/object-pool-manager.js.map +1 -1
  282. package/dist/core/queue/adapters/bull-adapter.js.map +1 -1
  283. package/dist/core/queue/adapters/index.js.map +1 -1
  284. package/dist/core/queue/adapters/kafka-adapter.js +2 -2
  285. package/dist/core/queue/adapters/kafka-adapter.js.map +1 -1
  286. package/dist/core/queue/adapters/memory-adapter.js +6 -6
  287. package/dist/core/queue/adapters/memory-adapter.js.map +1 -1
  288. package/dist/core/queue/adapters/rabbitmq-adapter.d.ts +50 -0
  289. package/dist/core/queue/adapters/rabbitmq-adapter.js +176 -20
  290. package/dist/core/queue/adapters/rabbitmq-adapter.js.map +1 -1
  291. package/dist/core/queue/adapters/sqs-adapter.d.ts +12 -2
  292. package/dist/core/queue/adapters/sqs-adapter.js +75 -24
  293. package/dist/core/queue/adapters/sqs-adapter.js.map +1 -1
  294. package/dist/core/queue/index.js.map +1 -1
  295. package/dist/core/queue/middleware/index.js.map +1 -1
  296. package/dist/core/queue/middleware/monitoring.d.ts +1 -1
  297. package/dist/core/queue/middleware/monitoring.js.map +1 -1
  298. package/dist/core/queue/middleware/priority.js +2 -1
  299. package/dist/core/queue/middleware/priority.js.map +1 -1
  300. package/dist/core/queue/middleware/rate-limit.js.map +1 -1
  301. package/dist/core/queue/queue-adapter.js.map +1 -1
  302. package/dist/core/queue/queue-manager.js.map +1 -1
  303. package/dist/core/queue/types.d.ts +8 -8
  304. package/dist/core/queue/types.js.map +1 -1
  305. package/dist/core/routing/app-integration.js.map +1 -1
  306. package/dist/core/routing/create-router.js.map +1 -1
  307. package/dist/core/routing/index.js.map +1 -1
  308. package/dist/core/routing/path-matcher.js.map +1 -1
  309. package/dist/core/routing/radix-tree.js.map +1 -1
  310. package/dist/core/routing/router.js.map +1 -1
  311. package/dist/core/routing/unified-router.js +12 -4
  312. package/dist/core/routing/unified-router.js.map +1 -1
  313. package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
  314. package/dist/core/runtime/base-adapter.js +2 -2
  315. package/dist/core/runtime/base-adapter.js.map +1 -1
  316. package/dist/core/runtime/cloudflare-workers-adapter.js +2 -0
  317. package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
  318. package/dist/core/runtime/index.js.map +1 -1
  319. package/dist/core/runtime/node-adapter.js +19 -17
  320. package/dist/core/runtime/node-adapter.js.map +1 -1
  321. package/dist/core/runtime/vercel-edge-adapter.js +2 -0
  322. package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
  323. package/dist/core/utilities/circuit-breaker.d.ts +1 -0
  324. package/dist/core/utilities/circuit-breaker.js +25 -2
  325. package/dist/core/utilities/circuit-breaker.js.map +1 -1
  326. package/dist/core/utilities/container.js +9 -9
  327. package/dist/core/utilities/container.js.map +1 -1
  328. package/dist/core/utilities/hooks.js +28 -6
  329. package/dist/core/utilities/hooks.js.map +1 -1
  330. package/dist/core/utilities/index.js.map +1 -1
  331. package/dist/core/utilities/module-path.js.map +1 -1
  332. package/dist/core/utilities/package-utils.d.ts +68 -0
  333. package/dist/core/utilities/package-utils.js +198 -1
  334. package/dist/core/utilities/package-utils.js.map +1 -1
  335. package/dist/core/utilities/response-helpers.js +1 -1
  336. package/dist/core/utilities/response-helpers.js.map +1 -1
  337. package/dist/core/validation/adapters.js.map +1 -1
  338. package/dist/core/validation/error-handler.js.map +1 -1
  339. package/dist/core/validation/index.js.map +1 -1
  340. package/dist/core/validation/schema-interface.js.map +1 -1
  341. package/dist/core/workers/facade.js.map +1 -1
  342. package/dist/core/workers/index.js.map +1 -1
  343. package/dist/core/workers/worker-entry.d.ts +1 -0
  344. package/dist/core/workers/worker-entry.js +12 -0
  345. package/dist/core/workers/worker-entry.js.map +1 -0
  346. package/dist/core/workers/worker-manager.d.ts +23 -2
  347. package/dist/core/workers/worker-manager.js +117 -17
  348. package/dist/core/workers/worker-manager.js.map +1 -1
  349. package/dist/core/workers/worker.js +8 -6
  350. package/dist/core/workers/worker.js.map +1 -1
  351. package/dist/index.d.ts +2 -2
  352. package/dist/index.js +5 -2
  353. package/dist/index.js.map +1 -1
  354. package/dist/moro.d.ts +20 -1
  355. package/dist/moro.js +230 -70
  356. package/dist/moro.js.map +1 -1
  357. package/dist/types/auth.d.ts +4 -4
  358. package/dist/types/auth.js.map +1 -1
  359. package/dist/types/cache.js.map +1 -1
  360. package/dist/types/cdn.js.map +1 -1
  361. package/dist/types/config.d.ts +100 -15
  362. package/dist/types/config.js.map +1 -1
  363. package/dist/types/core.js.map +1 -1
  364. package/dist/types/database.js.map +1 -1
  365. package/dist/types/discovery.js.map +1 -1
  366. package/dist/types/events.js.map +1 -1
  367. package/dist/types/hooks.js.map +1 -1
  368. package/dist/types/http.js.map +1 -1
  369. package/dist/types/logger.js.map +1 -1
  370. package/dist/types/module.js.map +1 -1
  371. package/dist/types/runtime.js.map +1 -1
  372. package/dist/types/session.js.map +1 -1
  373. package/package.json +32 -17
@@ -2,13 +2,16 @@ import crypto from 'crypto';
2
2
  import { EventEmitter } from 'events';
3
3
  import { MoroHttpServer } from './http/index.js';
4
4
  import { UWebSocketsHttpServer } from './http/uws-http-server.js';
5
+ import { MoroEngineServer } from './http/moro-engine-server.js';
5
6
  import { MoroHttp2Server } from './http/http2-server.js';
6
7
  import { Router } from './routing/router.js';
7
8
  import { Container, buildModuleBasePath } from './utilities/index.js';
8
9
  import { ModuleLoader } from './modules/index.js';
9
10
  import { WebSocketManager } from './networking/websocket-manager.js';
10
11
  import { CircuitBreaker } from './utilities/circuit-breaker.js';
11
- import { isPackageAvailable, createUserRequire } from './utilities/package-utils.js';
12
+ import { isPackageAvailable, loadNativeEngine, getNativeEngineLoadErrors, } from './utilities/package-utils.js';
13
+ import { parseSizeToBytes } from './http/utils/size.js';
14
+ import { normalizeSSLConfig, sslForNode, sslForUws, sslIsComplete, } from './http/utils/ssl-config.js';
12
15
  import { MoroEventBus } from './events/index.js';
13
16
  import { createFrameworkLogger, logger as globalLogger } from './logger/index.js';
14
17
  import { mergeWebSocketConfig, } from './networking/websocket-adapter.js';
@@ -29,7 +32,12 @@ export class Moro extends EventEmitter {
29
32
  options;
30
33
  config;
31
34
  usingUWebSockets = false;
35
+ // True when the Moro-shaped @morojs/engine backs this app (usingUWebSockets
36
+ // stays reserved for the legacy uWS-API-shaped engine)
37
+ usingEngine = false;
32
38
  usingHttp2 = false;
39
+ // Which server actually booted (engine = native uWS-style engine)
40
+ engineInfo = { server: 'node' };
33
41
  // WebSocket initialization promise to handle async adapter detection
34
42
  websocketSetupPromise = null;
35
43
  constructor(options = {}) {
@@ -53,71 +61,127 @@ export class Moro extends EventEmitter {
53
61
  }
54
62
  // Initialize framework logger after global configuration
55
63
  this.logger = createFrameworkLogger('Core');
56
- // Check if uWebSockets should be used for HTTP and WebSocket.
57
- // IMPORTANT: uWS is a native optional dependency loaded ASYNCHRONOUSLY by
58
- // UWebSocketsHttpServer's constructor, so a load failure (package missing,
59
- // or no prebuilt binary for this Node ABI - e.g. Node 25 with uWS v20.52)
60
- // does NOT throw here and the catch-based fallback below would never fire;
61
- // the app would hang at listen() bound to nothing. Preflight the require
62
- // synchronously so the fallback can actually happen.
63
- const useUWebSockets = (this.config.server?.useUWebSockets || false) && this.preflightUws();
64
- if (useUWebSockets) {
64
+ // Resolve which HTTP server backs this app: the native engine
65
+ // (@morojs/engine, or a legacy user-installed uWebSockets.js), Node's
66
+ // http server, or the http2 server. The engine module is loaded
67
+ // SYNCHRONOUSLY here - UWebSocketsHttpServer finishes initialization
68
+ // asynchronously, so a load failure (package missing, or no prebuilt
69
+ // binary for this Node ABI) surfacing there would never hit the fallback
70
+ // and the app would hang at listen() bound to nothing.
71
+ const engineChoice = this.resolveEngineMode(options);
72
+ // One normalized SSL config + one flattened limits object, built here and
73
+ // projected per-runtime, so a single server.ssl / server.limits flows
74
+ // everywhere regardless of which server boots.
75
+ const ssl = normalizeSSLConfig(this.config.server?.ssl, options.https, this.logger);
76
+ const rt = this.buildRuntimeLimits();
77
+ if (engineChoice.kind === 'engine') {
65
78
  try {
66
- // Try to use uWebSockets for high performance HTTP and WebSocket
67
- const sslOptions = this.config.server?.ssl || options.https;
68
- this.httpServer = new UWebSocketsHttpServer({
69
- ssl: sslOptions,
70
- maxBodySize: this.parseSizeToBytes(this.config.server.bodySizeLimit),
71
- maxUploadSize: this.parseSizeToBytes(this.config.server.maxUploadSize),
72
- });
73
- this.server = this.httpServer.getApp();
74
- this.usingUWebSockets = true;
75
- this.logger.info('uWebSockets HTTP+WebSocket server created', 'ServerInit');
79
+ // The two native engines expose different APIs: @morojs/engine is
80
+ // Moro-shaped (serve/respond, one JS crossing each way), the legacy
81
+ // uWS peer is App()-shaped. Pick the adapter by capability.
82
+ const engineSurface = engineChoice.engine.module?.default || engineChoice.engine.module;
83
+ const caps = engineChoice.engine.capabilities;
84
+ if (typeof engineSurface?.serve === 'function' &&
85
+ typeof engineSurface?.respond === 'function') {
86
+ this.httpServer = new MoroEngineServer({
87
+ ssl,
88
+ limits: rt,
89
+ maxBodySize: rt.maxBodySize,
90
+ maxUploadSize: rt.maxUploadSize,
91
+ engineModule: engineChoice.engine.module,
92
+ // Cluster workers each bind the port; SO_REUSEPORT lets the kernel
93
+ // balance accepts across them (Windows is gated to Node earlier).
94
+ reusePort: this.config.performance?.clustering?.enabled === true,
95
+ ...(caps ? { capabilities: caps } : {}),
96
+ ...(engineChoice.h2 ? { http2Settings: this.resolveH2Settings(options) } : {}),
97
+ });
98
+ this.server = this.httpServer.getServer();
99
+ this.usingEngine = true;
100
+ }
101
+ else {
102
+ this.httpServer = new UWebSocketsHttpServer({
103
+ sslInlineOnly: ssl ? !sslForUws(ssl) : false,
104
+ limits: rt,
105
+ maxBodySize: rt.maxBodySize,
106
+ maxUploadSize: rt.maxUploadSize,
107
+ engineModule: engineChoice.engine.module,
108
+ ...(ssl ? { ssl: sslForUws(ssl) } : {}),
109
+ });
110
+ this.server = this.httpServer.getApp();
111
+ this.usingUWebSockets = true;
112
+ }
113
+ this.engineInfo = {
114
+ server: 'engine',
115
+ enginePackage: engineChoice.engine.source,
116
+ engineVersion: engineChoice.engine.version,
117
+ protocols: engineChoice.h2 && caps?.http2 ? ['h2', 'http/1.1'] : ['http/1.1'],
118
+ };
119
+ this.logger.info(`HTTP engine: ${engineChoice.engine.source}` +
120
+ (engineChoice.engine.version ? ` v${engineChoice.engine.version}` : '') +
121
+ ` (native, Node ABI ${process.versions.modules})`, 'ServerInit');
76
122
  }
77
123
  catch (error) {
78
- // Fallback to standard HTTP/1.1 if uWebSockets fails to load
79
- this.logger.warn('uWebSockets failed to initialize, falling back to Node.js http.Server. ' +
80
- 'Error: ' +
81
- (error instanceof Error ? error.message : String(error)), 'ServerInit');
124
+ // Construction failed after a successful module load - unexpected, but
125
+ // never boot nothing: fall back to the Node.js http server.
126
+ const reason = error instanceof Error ? error.message : String(error);
127
+ this.logger.warn(`Native engine (${engineChoice.requested}) failed to initialize, falling back to Node.js http.Server. Error: ${reason}`, 'ServerInit');
82
128
  this.usingUWebSockets = false;
129
+ this.usingEngine = false;
130
+ this.engineInfo = { server: 'node', fallbackReason: reason };
83
131
  this.httpServer = new MoroHttpServer({
84
- maxBodySize: this.parseSizeToBytes(this.config.server.bodySizeLimit),
85
- maxUploadSize: this.parseSizeToBytes(this.config.server.maxUploadSize),
132
+ limits: rt,
133
+ maxBodySize: rt.maxBodySize,
134
+ maxUploadSize: rt.maxUploadSize,
135
+ ...(ssl && sslIsComplete(ssl) ? { ssl: sslForNode(ssl) } : {}),
86
136
  });
87
137
  this.server = this.httpServer.getServer();
88
138
  }
89
139
  }
90
- else if (options.http2) {
140
+ else if (engineChoice.kind === 'http2') {
91
141
  // Use HTTP/2 with proper adapter
92
- const http2Options = {};
93
- if (typeof options.http2 === 'object') {
94
- // Advanced HTTP/2 configuration
95
- Object.assign(http2Options, options.http2);
96
- }
97
- // Add SSL configuration if provided
98
- if (options.https) {
99
- http2Options.key = options.https.key;
100
- http2Options.cert = options.https.cert;
101
- if (options.https.ca) {
102
- http2Options.ca = options.https.ca;
103
- }
142
+ const http2Options = this.resolveH2Settings(options);
143
+ // SSL now flows from the unified config (either shape) as well as the
144
+ // legacy options.https, via the normalizer.
145
+ if (ssl) {
146
+ const nodeSsl = sslForNode(ssl);
147
+ http2Options.key = nodeSsl.key;
148
+ http2Options.cert = nodeSsl.cert;
149
+ if (nodeSsl.ca)
150
+ http2Options.ca = nodeSsl.ca;
104
151
  }
105
152
  this.httpServer = new MoroHttp2Server({
106
153
  ...http2Options,
107
- maxBodySize: this.parseSizeToBytes(this.config.server.bodySizeLimit),
108
- maxUploadSize: this.parseSizeToBytes(this.config.server.maxUploadSize),
154
+ limits: rt,
155
+ maxBodySize: rt.maxBodySize,
156
+ maxUploadSize: rt.maxUploadSize,
109
157
  });
110
158
  this.server = this.httpServer.getServer();
111
159
  this.usingHttp2 = true;
160
+ this.engineInfo = { server: 'http2', protocols: ['h2', 'http/1.1'] };
112
161
  this.logger.info('HTTP/2 server created with native adapter', 'ServerInit');
113
162
  }
114
163
  else {
115
- // Use standard HTTP/1.1
164
+ // Use standard HTTP/1.1 (Node), now with optional in-process HTTPS.
116
165
  this.httpServer = new MoroHttpServer({
117
- maxBodySize: this.parseSizeToBytes(this.config.server.bodySizeLimit),
118
- maxUploadSize: this.parseSizeToBytes(this.config.server.maxUploadSize),
166
+ limits: rt,
167
+ maxBodySize: rt.maxBodySize,
168
+ maxUploadSize: rt.maxUploadSize,
169
+ ...(ssl && sslIsComplete(ssl) ? { ssl: sslForNode(ssl) } : {}),
119
170
  });
120
171
  this.server = this.httpServer.getServer();
172
+ this.engineInfo = { server: 'node', fallbackReason: engineChoice.fallbackReason };
173
+ if (engineChoice.fallbackReason) {
174
+ // The default engine simply not being installed is expected (it is an
175
+ // optional dependency) - only an EXPLICIT engine choice that cannot be
176
+ // honored deserves warn-level noise on every boot.
177
+ const message = `Native engine unavailable, using Node.js http.Server - ${engineChoice.fallbackReason}`;
178
+ if (engineChoice.explicitEngine) {
179
+ this.logger.warn(message, 'ServerInit');
180
+ }
181
+ else {
182
+ this.logger.info(message, 'ServerInit');
183
+ }
184
+ }
121
185
  }
122
186
  this.container = new Container();
123
187
  this.moduleLoader = new ModuleLoader(this.container);
@@ -188,6 +252,21 @@ export class Moro extends EventEmitter {
188
252
  */
189
253
  async setupWebSockets(wsConfig) {
190
254
  try {
255
+ // The Moro-shaped @morojs/engine has native RFC 6455 WebSocket support:
256
+ // upgrades share the HTTP listen socket, driven by the engine's C++ WS
257
+ // path via the EngineWebSocketAdapter.
258
+ if (this.usingEngine) {
259
+ const { EngineWebSocketAdapter } = await import('./networking/adapters/engine-adapter.js');
260
+ this.websocketAdapter = new EngineWebSocketAdapter();
261
+ await this.websocketAdapter.initialize(this.httpServer, wsConfig.options);
262
+ this.websocketManager = new WebSocketManager(this.websocketAdapter, this.container);
263
+ if (wsConfig.compression)
264
+ this.websocketAdapter.setCompression(true);
265
+ if (wsConfig.customIdGenerator)
266
+ this.websocketAdapter.setCustomIdGenerator(wsConfig.customIdGenerator);
267
+ this.logger.info('Engine WebSocket adapter initialized (integrated with @morojs/engine)', 'WebSocketSetup');
268
+ return;
269
+ }
191
270
  // If using uWebSockets HTTP server, automatically use uWebSockets for WebSocket too
192
271
  if (this.usingUWebSockets) {
193
272
  const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
@@ -233,14 +312,13 @@ export class Moro extends EventEmitter {
233
312
  // Check if adapter is specified in config
234
313
  if (this.config.websocket?.adapter) {
235
314
  const adapterType = this.config.websocket.adapter;
236
- if (adapterType === 'uws' && isPackageAvailable('uWebSockets.js')) {
237
- try {
238
- const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
239
- return new UWebSocketsAdapter();
240
- }
241
- catch {
242
- this.logger.warn('uWebSockets.js specified but failed to load', 'AdapterDetection');
243
- }
315
+ if (adapterType === 'uws') {
316
+ // The uws adapter only works integrated with the native engine's own
317
+ // app (setupWebSockets handles that path before detection runs).
318
+ // Standalone it would register routes on a second, never-listening
319
+ // uWS app - fall through to the Node-compatible adapters instead.
320
+ this.logger.warn("websocket adapter 'uws' requires a native engine HTTP server " +
321
+ "(engine: 'moro' or 'uws') - falling back to socket.io/ws detection", 'AdapterDetection');
244
322
  }
245
323
  else if (adapterType === 'socket.io' && isPackageAvailable('socket.io')) {
246
324
  try {
@@ -261,18 +339,11 @@ export class Moro extends EventEmitter {
261
339
  }
262
340
  }
263
341
  }
264
- // Auto-detect: Try uWebSockets.js first (highest performance)
265
- if (isPackageAvailable('uWebSockets.js')) {
266
- try {
267
- const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
268
- this.logger.debug('uWebSockets.js detected and loaded', 'AdapterDetection');
269
- return new UWebSocketsAdapter();
270
- }
271
- catch {
272
- // Failed to load adapter
273
- }
274
- }
275
- // Try socket.io second
342
+ // Auto-detect. The uws adapter is deliberately NOT probed here: it only
343
+ // works integrated with the native engine's app (the usingUWebSockets
344
+ // branch of setupWebSockets), and with the engine installed by default a
345
+ // resolvable package no longer implies the engine is serving HTTP.
346
+ // Try socket.io first
276
347
  if (isPackageAvailable('socket.io')) {
277
348
  try {
278
349
  const { SocketIOAdapter } = await import('./networking/adapters/index.js');
@@ -845,44 +916,220 @@ export class Moro extends EventEmitter {
845
916
  limit.count++;
846
917
  return true;
847
918
  }
848
- // Synchronously verify that uWebSockets.js can actually load on this
849
- // runtime: the package must be present AND ship a prebuilt binary for this
850
- // Node ABI (e.g. uWS v20.52 has no binary for Node 25 / ABI 141). Loading
851
- // it here is not wasted work - the CJS module cache shares the instance
852
- // with the server's own import.
853
- preflightUws() {
854
- try {
855
- // cwd-based require (the repo's standard optional-dependency resolution,
856
- // and safe under both ESM and the CJS test transform - import.meta is not)
857
- createUserRequire()('uWebSockets.js');
858
- return true;
919
+ /**
920
+ * Which HTTP server backs this app, which package provides it, and the
921
+ * fallback reason when the native engine was requested but unavailable.
922
+ */
923
+ getServerKind() {
924
+ return { ...this.engineInfo };
925
+ }
926
+ // Decide which HTTP server to construct. Engine values:
927
+ // 'moro' (default) - Moro's own native engine (@morojs/engine)
928
+ // 'uws' - opt in to uWebSockets.js
929
+ // 'node' - the Node.js http server (no native engine)
930
+ // A chosen native engine that cannot load on this platform/Node ABI (e.g.
931
+ // no prebuilt binary) silently degrades to the Node.js http server and logs
932
+ // why - the app never fails to boot. The engine load happens here,
933
+ // synchronously; the CJS module cache shares the instance with the server.
934
+ resolveEngineMode(options) {
935
+ const server = this.config.server || {};
936
+ // Explicit engine wins. The deprecated useUWebSockets:true counts as an
937
+ // explicit 'uws' choice - it always beat http2 before the engine option
938
+ // existed, and silently changing that transport on upgrade would break
939
+ // existing apps.
940
+ let engineExplicit = server.engine !== undefined || server.useUWebSockets === true;
941
+ let mode = server.engine ?? (server.useUWebSockets ? 'uws' : 'moro');
942
+ // A user-provided uWS adapter INSTANCE implies the uWS engine when the
943
+ // engine wasn't chosen explicitly - otherwise the instance would be
944
+ // silently discarded in favor of the default engine's WS bridge.
945
+ const wsAdapterOption = options.websocket && typeof options.websocket === 'object'
946
+ ? options.websocket.adapter
947
+ : undefined;
948
+ const isUwsAdapterInstance = wsAdapterOption &&
949
+ typeof wsAdapterOption.getAdapterName === 'function' &&
950
+ wsAdapterOption.getAdapterName() === 'uWebSockets.js';
951
+ if (isUwsAdapterInstance) {
952
+ if (!engineExplicit && mode === 'moro') {
953
+ mode = 'uws';
954
+ engineExplicit = true;
955
+ }
956
+ else if (mode === 'moro') {
957
+ this.logger.warn("A uWebSockets.js adapter instance was provided but engine: 'moro' is set - " +
958
+ 'the instance is superseded by the Moro engine WebSocket bridge', 'ServerInit');
959
+ }
859
960
  }
860
- catch (error) {
861
- this.logger.warn('useUWebSockets is enabled but uWebSockets.js cannot load on this runtime - ' +
862
- 'falling back to Node.js http.Server. ' +
863
- (error instanceof Error ? error.message.split('\n')[0] : String(error)), 'ServerInit');
864
- return false;
961
+ // HTTP/2 is wanted via either the top-level option or server.http2 config.
962
+ const wantH2 = Boolean(options.http2 ?? this.config.server?.http2);
963
+ if (mode === 'node') {
964
+ // The Node runtime serves HTTP/2 via the separate MoroHttp2Server.
965
+ return wantH2 ? { kind: 'http2' } : { kind: 'node' };
966
+ }
967
+ // Clustering forks workers that each bind the port themselves; the native
968
+ // engines rely on SO_REUSEPORT for that, which Windows lacks. The Node
969
+ // server shares the listener over cluster IPC instead, so fall back there
970
+ // rather than letting workers 2..N crash with EADDRINUSE.
971
+ if (this.config.performance?.clustering?.enabled === true && process.platform === 'win32') {
972
+ return {
973
+ kind: 'node',
974
+ fallbackReason: 'clustering on Windows requires the Node.js http server (SO_REUSEPORT is unavailable)',
975
+ explicitEngine: engineExplicit,
976
+ };
977
+ }
978
+ // Environments where a native engine cannot apply (edge runtime, an
979
+ // explicit ws/socket.io adapter that needs a Node http.Server)
980
+ const gate = this.nativeEngineGate(options);
981
+ if (gate) {
982
+ // The native engine can't apply here - but http2 still can, and works
983
+ // fine with the ws/socket.io adapters that trigger the gate, so honor an
984
+ // explicit http2 opt-in rather than silently dropping it.
985
+ return wantH2 ? { kind: 'http2' } : { kind: 'node', fallbackReason: gate };
865
986
  }
987
+ // Load the specific package for the chosen engine - 'moro' never silently
988
+ // uses uWS and vice-versa; each falls back only to Node. The load happens
989
+ // BEFORE the http2 decision so we can feature-detect native ALPN h2.
990
+ const pkg = mode === 'uws' ? 'uWebSockets.js' : '@morojs/engine';
991
+ const loadErrors = [];
992
+ const engine = loadNativeEngine({ candidates: [pkg], collectErrors: loadErrors });
993
+ if (!engine) {
994
+ // Prefer this load's own failure detail (missing prebuilt binary, ABI
995
+ // mismatch, ...); only degrade to "not installed" when there is none.
996
+ const detail = (loadErrors.length ? loadErrors : getNativeEngineLoadErrors())
997
+ .map(e => e.split('\n')[0])
998
+ .join('; ') || `${pkg} is not installed`;
999
+ // An explicit http2 opt-in survives the engine's absence - falling all
1000
+ // the way to plain HTTP/1.1 would silently drop the user's choice.
1001
+ if (wantH2) {
1002
+ this.logger.warn(`Native engine (${mode}) unavailable (${detail}) - using the configured http2 server`, 'ServerInit');
1003
+ return { kind: 'http2' };
1004
+ }
1005
+ return { kind: 'node', fallbackReason: detail, explicitEngine: engineExplicit };
1006
+ }
1007
+ // HTTP/2 decision, now that the engine is loaded and its capabilities known.
1008
+ if (wantH2) {
1009
+ const canH2 = engine.capabilities?.http2 === true;
1010
+ if (mode === 'uws') {
1011
+ // uWebSockets.js does not serve HTTP/2 through this integration.
1012
+ this.logger.warn("engine: 'uws' does not serve HTTP/2 - serving HTTP/1.1 (use engine: " +
1013
+ "'moro' with an h2-capable build, or engine: 'node' for the http2 server)", 'ServerInit');
1014
+ return { kind: 'engine', engine, requested: mode };
1015
+ }
1016
+ if (canH2) {
1017
+ // The Moro engine speaks ALPN h2 + http/1.1 on one TLS port.
1018
+ return { kind: 'engine', engine, requested: mode, h2: true };
1019
+ }
1020
+ // Engine can't do h2. An explicit engine choice keeps the engine (h1);
1021
+ // the default engine yields to the dedicated MoroHttp2Server.
1022
+ if (engineExplicit) {
1023
+ this.logger.warn(`engine: '${mode}' (build ${engine.version ?? 'unknown'}) does not support ` +
1024
+ 'HTTP/2 - serving HTTP/1.1. Upgrade @morojs/engine or use engine: ' +
1025
+ "'node' for the http2 server.", 'ServerInit');
1026
+ return { kind: 'engine', engine, requested: mode };
1027
+ }
1028
+ return { kind: 'http2' };
1029
+ }
1030
+ return { kind: 'engine', engine, requested: mode };
1031
+ }
1032
+ // Reasons the native engine should not back this app even when loadable:
1033
+ // edge/serverless runtimes never use a listening server, and the ws /
1034
+ // socket.io adapters attach to a real Node http.Server for upgrades.
1035
+ nativeEngineGate(options) {
1036
+ const runtimeType = options.runtime?.type;
1037
+ if (runtimeType && runtimeType !== 'node') {
1038
+ return `runtime '${runtimeType}' does not use a Node listening server`;
1039
+ }
1040
+ const optionsAdapter = options.websocket && typeof options.websocket === 'object'
1041
+ ? options.websocket.adapter
1042
+ : undefined;
1043
+ if (optionsAdapter && typeof optionsAdapter.getAdapterName === 'function') {
1044
+ const name = optionsAdapter.getAdapterName();
1045
+ if (name && name !== 'uWebSockets.js') {
1046
+ return `websocket adapter '${name}' requires the Node.js http server`;
1047
+ }
1048
+ }
1049
+ const configuredAdapter = this.config.websocket?.adapter;
1050
+ if (typeof configuredAdapter === 'string' && configuredAdapter !== 'uws') {
1051
+ return `websocket adapter '${configuredAdapter}' requires the Node.js http server`;
1052
+ }
1053
+ return null;
866
1054
  }
867
1055
  /**
868
- * Parse size string (e.g., "10mb", "5gb") to bytes
1056
+ * Parse size string (e.g., "10mb", "5gb") to bytes.
1057
+ * Delegates to the shared utility so every server + config path agrees.
869
1058
  */
870
1059
  parseSizeToBytes(size) {
871
- if (typeof size === 'number') {
872
- return size;
873
- }
874
- const units = {
875
- b: 1,
876
- kb: 1024,
877
- mb: 1024 * 1024,
878
- gb: 1024 * 1024 * 1024,
1060
+ return parseSizeToBytes(size);
1061
+ }
1062
+ /**
1063
+ * Merge HTTP/2 settings from config.server.http2 and the top-level
1064
+ * options.http2 (options win — the highest-precedence, back-compat path)
1065
+ * into one Http2ServerOptions used by both the engine (ALPN h2) and the
1066
+ * MoroHttp2Server fallback.
1067
+ */
1068
+ resolveH2Settings(options) {
1069
+ const out = {};
1070
+ const cfg = this.config.server?.http2;
1071
+ if (cfg && typeof cfg === 'object') {
1072
+ if (cfg.allowHTTP1 !== undefined)
1073
+ out.allowHTTP1 = cfg.allowHTTP1;
1074
+ if (cfg.maxSessionMemory !== undefined)
1075
+ out.maxSessionMemory = cfg.maxSessionMemory;
1076
+ if (cfg.settings)
1077
+ out.settings = { ...cfg.settings };
1078
+ }
1079
+ if (typeof options.http2 === 'object') {
1080
+ Object.assign(out, options.http2);
1081
+ if (options.http2.settings) {
1082
+ out.settings = { ...(out.settings ?? {}), ...options.http2.settings };
1083
+ }
1084
+ }
1085
+ if (out.allowHTTP1 === undefined)
1086
+ out.allowHTTP1 = true;
1087
+ return out;
1088
+ }
1089
+ /**
1090
+ * Resolve every size string in server.limits/timeouts/backlog into one flat
1091
+ * object of bytes/ms, built once and passed to whichever server boots. A
1092
+ * value left undefined means "use the server's own documented default".
1093
+ */
1094
+ buildRuntimeLimits() {
1095
+ const s = this.config.server ?? {};
1096
+ const limits = s.limits ?? {};
1097
+ const timeouts = s.timeouts ?? {};
1098
+ const size = (v) => v === undefined ? undefined : parseSizeToBytes(v);
1099
+ const multipart = limits.multipart ?? {};
1100
+ const maxPartHeaderBytes = size(multipart.maxPartHeaderBytes);
1101
+ const maxFileSize = size(multipart.maxFileSize);
1102
+ // undefined = use that server's own documented default, so omit the key
1103
+ // entirely rather than pass an explicit undefined (exactOptionalPropertyTypes).
1104
+ const maxHeaderSize = size(limits.maxHeaderSize);
1105
+ const wsMaxMessageSize = size(limits.wsMaxMessageSize ?? this.config.websocket?.options?.maxPayloadLength);
1106
+ const wsBackpressureLimit = size(limits.wsBackpressureLimit);
1107
+ const writeHighWaterMark = size(limits.writeHighWaterMark);
1108
+ const maxPendingBytes = size(limits.maxPendingBytes);
1109
+ return {
1110
+ maxBodySize: parseSizeToBytes(s.bodySizeLimit ?? '10mb'),
1111
+ maxUploadSize: parseSizeToBytes(s.maxUploadSize ?? '100mb'),
1112
+ maxConnections: typeof s.maxConnections === 'number' ? s.maxConnections : 0,
1113
+ backlog: s.backlog,
1114
+ timeouts: {
1115
+ request: timeouts.request,
1116
+ idle: timeouts.idle,
1117
+ keepAlive: timeouts.keepAlive,
1118
+ headers: timeouts.headers,
1119
+ },
1120
+ maxHeaders: limits.maxHeaders,
1121
+ ...(maxHeaderSize !== undefined ? { maxHeaderSize } : {}),
1122
+ ...(wsMaxMessageSize !== undefined ? { wsMaxMessageSize } : {}),
1123
+ ...(wsBackpressureLimit !== undefined ? { wsBackpressureLimit } : {}),
1124
+ ...(writeHighWaterMark !== undefined ? { writeHighWaterMark } : {}),
1125
+ ...(maxPendingBytes !== undefined ? { maxPendingBytes } : {}),
1126
+ multipart: {
1127
+ maxParts: multipart.maxParts,
1128
+ maxFiles: multipart.maxFiles,
1129
+ ...(maxPartHeaderBytes !== undefined ? { maxPartHeaderBytes } : {}),
1130
+ ...(maxFileSize !== undefined ? { maxFileSize } : {}),
1131
+ },
879
1132
  };
880
- const match = size.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/);
881
- if (!match)
882
- return 10 * 1024 * 1024; // Default 10MB
883
- const value = parseFloat(match[1]);
884
- const unit = match[2] || 'b';
885
- return Math.round(value * units[unit]);
886
1133
  }
887
1134
  getCircuitBreaker(key) {
888
1135
  if (!this.circuitBreakers.has(key)) {