@morojs/moro 1.6.1 → 1.6.2

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 (404) hide show
  1. package/README.md +74 -256
  2. package/dist/core/auth/morojs-adapter.js +20 -20
  3. package/dist/core/auth/morojs-adapter.js.map +1 -1
  4. package/dist/core/config/config-manager.d.ts +44 -0
  5. package/dist/core/config/config-manager.js +104 -0
  6. package/dist/core/config/config-manager.js.map +1 -0
  7. package/dist/core/config/config-sources.d.ts +21 -0
  8. package/dist/core/config/config-sources.js +503 -0
  9. package/dist/core/config/config-sources.js.map +1 -0
  10. package/dist/core/config/config-validator.d.ts +21 -0
  11. package/dist/core/config/config-validator.js +791 -0
  12. package/dist/core/config/config-validator.js.map +1 -0
  13. package/dist/core/config/file-loader.d.ts +1 -6
  14. package/dist/core/config/file-loader.js +21 -249
  15. package/dist/core/config/file-loader.js.map +1 -1
  16. package/dist/core/config/index.d.ts +41 -12
  17. package/dist/core/config/index.js +65 -54
  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 +55 -44
  21. package/dist/core/config/schema.js.map +1 -1
  22. package/dist/core/config/utils.d.ts +10 -3
  23. package/dist/core/config/utils.js +31 -58
  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 +13 -1
  32. package/dist/core/database/adapters/mongodb.js +46 -10
  33. package/dist/core/database/adapters/mongodb.js.map +1 -1
  34. package/dist/core/database/adapters/mysql.d.ts +14 -1
  35. package/dist/core/database/adapters/mysql.js +19 -9
  36. package/dist/core/database/adapters/mysql.js.map +1 -1
  37. package/dist/core/database/adapters/postgresql.d.ts +12 -2
  38. package/dist/core/database/adapters/postgresql.js +19 -9
  39. package/dist/core/database/adapters/postgresql.js.map +1 -1
  40. package/dist/core/database/adapters/redis.d.ts +12 -1
  41. package/dist/core/database/adapters/redis.js +48 -13
  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 +7 -11
  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 +20 -13
  73. package/dist/core/framework.js +285 -102
  74. package/dist/core/framework.js.map +1 -1
  75. package/dist/core/http/http-server.d.ts +59 -7
  76. package/dist/core/http/http-server.js +190 -176
  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/uws-http-server.d.ts +46 -0
  82. package/dist/core/http/uws-http-server.js +523 -0
  83. package/dist/core/http/uws-http-server.js.map +1 -0
  84. package/dist/core/logger/filters.d.ts +1 -1
  85. package/dist/core/logger/filters.js +20 -23
  86. package/dist/core/logger/filters.js.map +1 -1
  87. package/dist/core/logger/index.d.ts +3 -3
  88. package/dist/core/logger/index.js +2 -24
  89. package/dist/core/logger/index.js.map +1 -1
  90. package/dist/core/logger/logger.d.ts +30 -14
  91. package/dist/core/logger/logger.js +398 -223
  92. package/dist/core/logger/logger.js.map +1 -1
  93. package/dist/core/logger/outputs.d.ts +1 -1
  94. package/dist/core/logger/outputs.js +8 -17
  95. package/dist/core/logger/outputs.js.map +1 -1
  96. package/dist/core/middleware/built-in/adapters/cache/file.d.ts +1 -1
  97. package/dist/core/middleware/built-in/adapters/cache/file.js +10 -47
  98. package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -1
  99. package/dist/core/middleware/built-in/adapters/cache/index.d.ts +4 -4
  100. package/dist/core/middleware/built-in/adapters/cache/index.js +10 -17
  101. package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -1
  102. package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +1 -1
  103. package/dist/core/middleware/built-in/adapters/cache/memory.js +3 -7
  104. package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -1
  105. package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +3 -1
  106. package/dist/core/middleware/built-in/adapters/cache/redis.js +11 -9
  107. package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -1
  108. package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +1 -1
  109. package/dist/core/middleware/built-in/adapters/cdn/azure.js +3 -7
  110. package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -1
  111. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +1 -1
  112. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +3 -7
  113. package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -1
  114. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +3 -1
  115. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +12 -10
  116. package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -1
  117. package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +4 -4
  118. package/dist/core/middleware/built-in/adapters/cdn/index.js +10 -17
  119. package/dist/core/middleware/built-in/adapters/cdn/index.js.map +1 -1
  120. package/dist/core/middleware/built-in/adapters/index.d.ts +4 -4
  121. package/dist/core/middleware/built-in/adapters/index.js +4 -23
  122. package/dist/core/middleware/built-in/adapters/index.js.map +1 -1
  123. package/dist/core/middleware/built-in/auth-helpers.js +11 -22
  124. package/dist/core/middleware/built-in/auth-helpers.js.map +1 -1
  125. package/dist/core/middleware/built-in/auth-providers.d.ts +1 -1
  126. package/dist/core/middleware/built-in/auth-providers.js +4 -9
  127. package/dist/core/middleware/built-in/auth-providers.js.map +1 -1
  128. package/dist/core/middleware/built-in/auth.d.ts +2 -2
  129. package/dist/core/middleware/built-in/auth.js +93 -26
  130. package/dist/core/middleware/built-in/auth.js.map +1 -1
  131. package/dist/core/middleware/built-in/cache.d.ts +2 -2
  132. package/dist/core/middleware/built-in/cache.js +11 -12
  133. package/dist/core/middleware/built-in/cache.js.map +1 -1
  134. package/dist/core/middleware/built-in/cdn.d.ts +2 -2
  135. package/dist/core/middleware/built-in/cdn.js +5 -9
  136. package/dist/core/middleware/built-in/cdn.js.map +1 -1
  137. package/dist/core/middleware/built-in/cookie.d.ts +1 -1
  138. package/dist/core/middleware/built-in/cookie.js +3 -7
  139. package/dist/core/middleware/built-in/cookie.js.map +1 -1
  140. package/dist/core/middleware/built-in/cors.d.ts +1 -1
  141. package/dist/core/middleware/built-in/cors.js +3 -7
  142. package/dist/core/middleware/built-in/cors.js.map +1 -1
  143. package/dist/core/middleware/built-in/csp.d.ts +1 -1
  144. package/dist/core/middleware/built-in/csp.js +5 -8
  145. package/dist/core/middleware/built-in/csp.js.map +1 -1
  146. package/dist/core/middleware/built-in/csrf.d.ts +1 -1
  147. package/dist/core/middleware/built-in/csrf.js +5 -8
  148. package/dist/core/middleware/built-in/csrf.js.map +1 -1
  149. package/dist/core/middleware/built-in/error-tracker.js +3 -7
  150. package/dist/core/middleware/built-in/error-tracker.js.map +1 -1
  151. package/dist/core/middleware/built-in/index.d.ts +28 -27
  152. package/dist/core/middleware/built-in/index.js +48 -78
  153. package/dist/core/middleware/built-in/index.js.map +1 -1
  154. package/dist/core/middleware/built-in/jwt-helpers.d.ts +118 -0
  155. package/dist/core/middleware/built-in/jwt-helpers.js +218 -0
  156. package/dist/core/middleware/built-in/jwt-helpers.js.map +1 -0
  157. package/dist/core/middleware/built-in/performance-monitor.js +3 -7
  158. package/dist/core/middleware/built-in/performance-monitor.js.map +1 -1
  159. package/dist/core/middleware/built-in/rate-limit.d.ts +1 -1
  160. package/dist/core/middleware/built-in/rate-limit.js +3 -7
  161. package/dist/core/middleware/built-in/rate-limit.js.map +1 -1
  162. package/dist/core/middleware/built-in/request-logger.js +5 -8
  163. package/dist/core/middleware/built-in/request-logger.js.map +1 -1
  164. package/dist/core/middleware/built-in/session.d.ts +2 -2
  165. package/dist/core/middleware/built-in/session.js +11 -15
  166. package/dist/core/middleware/built-in/session.js.map +1 -1
  167. package/dist/core/middleware/built-in/sse.d.ts +1 -1
  168. package/dist/core/middleware/built-in/sse.js +12 -14
  169. package/dist/core/middleware/built-in/sse.js.map +1 -1
  170. package/dist/core/middleware/built-in/validation.d.ts +1 -1
  171. package/dist/core/middleware/built-in/validation.js +3 -7
  172. package/dist/core/middleware/built-in/validation.js.map +1 -1
  173. package/dist/core/middleware/index.d.ts +4 -4
  174. package/dist/core/middleware/index.js +8 -28
  175. package/dist/core/middleware/index.js.map +1 -1
  176. package/dist/core/modules/auto-discovery.d.ts +19 -2
  177. package/dist/core/modules/auto-discovery.js +391 -74
  178. package/dist/core/modules/auto-discovery.js.map +1 -1
  179. package/dist/core/modules/index.d.ts +2 -2
  180. package/dist/core/modules/index.js +2 -9
  181. package/dist/core/modules/index.js.map +1 -1
  182. package/dist/core/modules/modules.d.ts +3 -3
  183. package/dist/core/modules/modules.js +23 -54
  184. package/dist/core/modules/modules.js.map +1 -1
  185. package/dist/core/networking/adapters/index.d.ts +4 -3
  186. package/dist/core/networking/adapters/index.js +3 -7
  187. package/dist/core/networking/adapters/index.js.map +1 -1
  188. package/dist/core/networking/adapters/socketio-adapter.d.ts +1 -1
  189. package/dist/core/networking/adapters/socketio-adapter.js +5 -40
  190. package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
  191. package/dist/core/networking/adapters/uws-adapter.d.ts +44 -0
  192. package/dist/core/networking/adapters/uws-adapter.js +513 -0
  193. package/dist/core/networking/adapters/uws-adapter.js.map +1 -0
  194. package/dist/core/networking/adapters/ws-adapter.d.ts +2 -2
  195. package/dist/core/networking/adapters/ws-adapter.js +8 -43
  196. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  197. package/dist/core/networking/index.d.ts +3 -2
  198. package/dist/core/networking/index.js +2 -7
  199. package/dist/core/networking/index.js.map +1 -1
  200. package/dist/core/networking/service-discovery.js +8 -12
  201. package/dist/core/networking/service-discovery.js.map +1 -1
  202. package/dist/core/networking/websocket-adapter.js +1 -2
  203. package/dist/core/networking/websocket-adapter.js.map +1 -1
  204. package/dist/core/networking/websocket-manager.d.ts +3 -3
  205. package/dist/core/networking/websocket-manager.js +9 -11
  206. package/dist/core/networking/websocket-manager.js.map +1 -1
  207. package/dist/core/pooling/object-pool-manager.d.ts +140 -0
  208. package/dist/core/pooling/object-pool-manager.js +502 -0
  209. package/dist/core/pooling/object-pool-manager.js.map +1 -0
  210. package/dist/core/routing/app-integration.d.ts +14 -12
  211. package/dist/core/routing/app-integration.js +49 -85
  212. package/dist/core/routing/app-integration.js.map +1 -1
  213. package/dist/core/routing/index.d.ts +17 -11
  214. package/dist/core/routing/index.js +48 -237
  215. package/dist/core/routing/index.js.map +1 -1
  216. package/dist/core/routing/path-matcher.d.ts +67 -0
  217. package/dist/core/routing/path-matcher.js +182 -0
  218. package/dist/core/routing/path-matcher.js.map +1 -0
  219. package/dist/core/routing/router.d.ts +38 -0
  220. package/dist/core/routing/router.js +68 -0
  221. package/dist/core/routing/router.js.map +1 -0
  222. package/dist/core/routing/unified-router.d.ts +148 -0
  223. package/dist/core/routing/unified-router.js +684 -0
  224. package/dist/core/routing/unified-router.js.map +1 -0
  225. package/dist/core/runtime/aws-lambda-adapter.d.ts +3 -3
  226. package/dist/core/runtime/aws-lambda-adapter.js +2 -6
  227. package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
  228. package/dist/core/runtime/base-adapter.d.ts +2 -2
  229. package/dist/core/runtime/base-adapter.js +3 -7
  230. package/dist/core/runtime/base-adapter.js.map +1 -1
  231. package/dist/core/runtime/cloudflare-workers-adapter.d.ts +3 -3
  232. package/dist/core/runtime/cloudflare-workers-adapter.js +2 -6
  233. package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
  234. package/dist/core/runtime/index.d.ts +12 -12
  235. package/dist/core/runtime/index.js +22 -35
  236. package/dist/core/runtime/index.js.map +1 -1
  237. package/dist/core/runtime/node-adapter.d.ts +4 -4
  238. package/dist/core/runtime/node-adapter.js +18 -49
  239. package/dist/core/runtime/node-adapter.js.map +1 -1
  240. package/dist/core/runtime/vercel-edge-adapter.d.ts +3 -3
  241. package/dist/core/runtime/vercel-edge-adapter.js +2 -6
  242. package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
  243. package/dist/core/utilities/circuit-breaker.js +1 -5
  244. package/dist/core/utilities/circuit-breaker.js.map +1 -1
  245. package/dist/core/utilities/container.js +12 -22
  246. package/dist/core/utilities/container.js.map +1 -1
  247. package/dist/core/utilities/hooks.d.ts +2 -2
  248. package/dist/core/utilities/hooks.js +7 -12
  249. package/dist/core/utilities/hooks.js.map +1 -1
  250. package/dist/core/utilities/index.d.ts +5 -4
  251. package/dist/core/utilities/index.js +5 -19
  252. package/dist/core/utilities/index.js.map +1 -1
  253. package/dist/core/utilities/package-utils.d.ts +38 -0
  254. package/dist/core/utilities/package-utils.js +57 -0
  255. package/dist/core/utilities/package-utils.js.map +1 -0
  256. package/dist/core/validation/adapters.d.ts +1 -1
  257. package/dist/core/validation/adapters.js +15 -26
  258. package/dist/core/validation/adapters.js.map +1 -1
  259. package/dist/core/validation/index.d.ts +6 -4
  260. package/dist/core/validation/index.js +57 -28
  261. package/dist/core/validation/index.js.map +1 -1
  262. package/dist/core/validation/schema-interface.js +3 -9
  263. package/dist/core/validation/schema-interface.js.map +1 -1
  264. package/dist/index.d.ts +51 -52
  265. package/dist/index.js +23 -132
  266. package/dist/index.js.map +1 -1
  267. package/dist/moro.d.ts +70 -16
  268. package/dist/moro.js +658 -271
  269. package/dist/moro.js.map +1 -1
  270. package/dist/types/auth.js +3 -9
  271. package/dist/types/auth.js.map +1 -1
  272. package/dist/types/cache.js +1 -2
  273. package/dist/types/cdn.js +1 -2
  274. package/dist/types/config.d.ts +73 -2
  275. package/dist/types/config.js +1 -2
  276. package/dist/types/config.js.map +1 -1
  277. package/dist/types/core.d.ts +36 -42
  278. package/dist/types/core.js +1 -2
  279. package/dist/types/database.js +1 -2
  280. package/dist/types/discovery.js +1 -2
  281. package/dist/types/events.js +1 -2
  282. package/dist/types/hooks.d.ts +1 -1
  283. package/dist/types/hooks.js +1 -2
  284. package/dist/types/http.d.ts +16 -1
  285. package/dist/types/http.js +1 -2
  286. package/dist/types/logger.d.ts +7 -0
  287. package/dist/types/logger.js +1 -2
  288. package/dist/types/module.d.ts +11 -0
  289. package/dist/types/module.js +1 -2
  290. package/dist/types/runtime.d.ts +1 -1
  291. package/dist/types/runtime.js +1 -2
  292. package/dist/types/session.js +1 -2
  293. package/jest.config.mjs +41 -0
  294. package/package.json +19 -52
  295. package/src/core/auth/morojs-adapter.ts +18 -13
  296. package/src/core/config/config-manager.ts +133 -0
  297. package/src/core/config/config-sources.ts +600 -0
  298. package/src/core/config/config-validator.ts +1116 -0
  299. package/src/core/config/file-loader.ts +16 -273
  300. package/src/core/config/index.ts +83 -34
  301. package/src/core/config/schema.ts +47 -33
  302. package/src/core/config/utils.ts +24 -31
  303. package/src/core/database/README.md +26 -16
  304. package/src/core/database/adapters/drizzle.ts +18 -6
  305. package/src/core/database/adapters/index.ts +13 -13
  306. package/src/core/database/adapters/mongodb.ts +53 -5
  307. package/src/core/database/adapters/mysql.ts +32 -4
  308. package/src/core/database/adapters/postgresql.ts +30 -5
  309. package/src/core/database/adapters/redis.ts +61 -8
  310. package/src/core/database/adapters/sqlite.ts +19 -3
  311. package/src/core/database/index.ts +2 -2
  312. package/src/core/docs/index.ts +8 -8
  313. package/src/core/docs/openapi-generator.ts +4 -4
  314. package/src/core/docs/schema-to-openapi.ts +3 -6
  315. package/src/core/docs/simple-docs.ts +2 -2
  316. package/src/core/docs/swagger-ui.ts +19 -16
  317. package/src/core/docs/zod-to-openapi.ts +34 -34
  318. package/src/core/events/event-bus.ts +3 -3
  319. package/src/core/events/index.ts +2 -2
  320. package/src/core/framework.ts +320 -71
  321. package/src/core/http/http-server.ts +203 -143
  322. package/src/core/http/index.ts +4 -3
  323. package/src/core/http/uws-http-server.ts +591 -0
  324. package/src/core/logger/filters.ts +13 -5
  325. package/src/core/logger/index.ts +4 -3
  326. package/src/core/logger/logger.ts +435 -216
  327. package/src/core/logger/outputs.ts +1 -3
  328. package/src/core/middleware/built-in/adapters/cache/file.ts +3 -3
  329. package/src/core/middleware/built-in/adapters/cache/index.ts +7 -7
  330. package/src/core/middleware/built-in/adapters/cache/memory.ts +2 -2
  331. package/src/core/middleware/built-in/adapters/cache/redis.ts +18 -4
  332. package/src/core/middleware/built-in/adapters/cdn/azure.ts +2 -2
  333. package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +2 -2
  334. package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +16 -5
  335. package/src/core/middleware/built-in/adapters/cdn/index.ts +7 -7
  336. package/src/core/middleware/built-in/adapters/index.ts +4 -4
  337. package/src/core/middleware/built-in/auth-helpers.ts +1 -1
  338. package/src/core/middleware/built-in/auth-providers.ts +1 -1
  339. package/src/core/middleware/built-in/auth.ts +102 -21
  340. package/src/core/middleware/built-in/cache.ts +8 -6
  341. package/src/core/middleware/built-in/cdn.ts +4 -4
  342. package/src/core/middleware/built-in/cookie.ts +2 -2
  343. package/src/core/middleware/built-in/cors.ts +2 -2
  344. package/src/core/middleware/built-in/csp.ts +3 -3
  345. package/src/core/middleware/built-in/csrf.ts +3 -3
  346. package/src/core/middleware/built-in/error-tracker.ts +1 -1
  347. package/src/core/middleware/built-in/index.ts +38 -30
  348. package/src/core/middleware/built-in/jwt-helpers.ts +243 -0
  349. package/src/core/middleware/built-in/performance-monitor.ts +1 -1
  350. package/src/core/middleware/built-in/rate-limit.ts +2 -2
  351. package/src/core/middleware/built-in/request-logger.ts +3 -1
  352. package/src/core/middleware/built-in/session.ts +7 -8
  353. package/src/core/middleware/built-in/sse.ts +11 -9
  354. package/src/core/middleware/built-in/validation.ts +2 -2
  355. package/src/core/middleware/index.ts +6 -6
  356. package/src/core/modules/auto-discovery.ts +478 -15
  357. package/src/core/modules/index.ts +2 -2
  358. package/src/core/modules/modules.ts +23 -12
  359. package/src/core/networking/adapters/index.ts +4 -3
  360. package/src/core/networking/adapters/socketio-adapter.ts +5 -3
  361. package/src/core/networking/adapters/uws-adapter.ts +619 -0
  362. package/src/core/networking/adapters/ws-adapter.ts +8 -9
  363. package/src/core/networking/index.ts +3 -2
  364. package/src/core/networking/service-discovery.ts +6 -7
  365. package/src/core/networking/websocket-manager.ts +7 -7
  366. package/src/core/pooling/object-pool-manager.ts +630 -0
  367. package/src/core/routing/app-integration.ts +60 -112
  368. package/src/core/routing/index.ts +66 -293
  369. package/src/core/routing/path-matcher.ts +222 -0
  370. package/src/core/routing/router.ts +97 -0
  371. package/src/core/routing/unified-router.ts +870 -0
  372. package/src/core/runtime/aws-lambda-adapter.ts +3 -3
  373. package/src/core/runtime/base-adapter.ts +2 -2
  374. package/src/core/runtime/cloudflare-workers-adapter.ts +3 -3
  375. package/src/core/runtime/index.ts +13 -13
  376. package/src/core/runtime/node-adapter.ts +16 -10
  377. package/src/core/runtime/vercel-edge-adapter.ts +3 -3
  378. package/src/core/utilities/hooks.ts +3 -3
  379. package/src/core/utilities/index.ts +5 -4
  380. package/src/core/utilities/package-utils.ts +59 -0
  381. package/src/core/validation/adapters.ts +1 -1
  382. package/src/core/validation/index.ts +68 -16
  383. package/src/index.ts +73 -66
  384. package/src/moro.ts +784 -253
  385. package/src/types/config.ts +74 -2
  386. package/src/types/core.ts +49 -47
  387. package/src/types/hooks.ts +1 -1
  388. package/src/types/http.ts +23 -1
  389. package/src/types/logger.ts +9 -0
  390. package/src/types/module.ts +12 -0
  391. package/src/types/runtime.ts +1 -1
  392. package/tsconfig.json +4 -2
  393. package/dist/core/config/loader.d.ts +0 -7
  394. package/dist/core/config/loader.js +0 -269
  395. package/dist/core/config/loader.js.map +0 -1
  396. package/dist/core/config/validation.d.ts +0 -17
  397. package/dist/core/config/validation.js +0 -131
  398. package/dist/core/config/validation.js.map +0 -1
  399. package/dist/core/http/router.d.ts +0 -14
  400. package/dist/core/http/router.js +0 -109
  401. package/dist/core/http/router.js.map +0 -1
  402. package/src/core/config/loader.ts +0 -633
  403. package/src/core/config/validation.ts +0 -140
  404. package/src/core/http/router.ts +0 -141
@@ -0,0 +1,591 @@
1
+ // uWebSockets.js HTTP Server Implementation for Moro Framework
2
+ // Provides high-performance HTTP and WebSocket server using uWebSockets.js
3
+
4
+ import cluster from 'cluster';
5
+ import { createFrameworkLogger } from '../logger/index.js';
6
+ import { ObjectPoolManager } from '../pooling/object-pool-manager.js';
7
+ import {
8
+ HttpRequest,
9
+ HttpResponse,
10
+ HttpHandler,
11
+ Middleware,
12
+ RouteEntry,
13
+ } from '../../types/http.js';
14
+
15
+ /**
16
+ * uWebSockets HTTP Server Adapter
17
+ * Bridges uWebSockets.js with Moro's HTTP abstractions
18
+ */
19
+ export class UWebSocketsHttpServer {
20
+ private app: any; // uWebSockets app instance
21
+ private uws: any; // uWebSockets module reference (stored to avoid re-importing)
22
+ private listenSocket: any; // uWebSockets listen socket
23
+ private globalMiddleware: Middleware[] = [];
24
+ private logger = createFrameworkLogger('UWSHttpServer');
25
+ private hookManager: any;
26
+ private requestCounter = 0;
27
+ private requestTrackingEnabled = true; // Generate request IDs
28
+ private isListening = false;
29
+ private port?: number;
30
+ private host?: string;
31
+ private initPromise: Promise<void>;
32
+
33
+ // Performance optimizations - shared object pooling
34
+ private poolManager = ObjectPoolManager.getInstance();
35
+
36
+ // String interning for common values
37
+ private static readonly INTERNED_METHODS = new Map([
38
+ ['get', 'GET'],
39
+ ['post', 'POST'],
40
+ ['put', 'PUT'],
41
+ ['delete', 'DELETE'],
42
+ ['patch', 'PATCH'],
43
+ ['head', 'HEAD'],
44
+ ['options', 'OPTIONS'],
45
+ ]);
46
+
47
+ // Pre-compiled response buffers
48
+ private static readonly RESPONSE_BUFFERS = {
49
+ notFound: Buffer.from('{"success":false,"error":"Not found"}'),
50
+ serverError: Buffer.from('{"success":false,"error":"Internal server error"}'),
51
+ };
52
+
53
+ constructor(
54
+ options: {
55
+ ssl?: { key_file_name?: string; cert_file_name?: string; passphrase?: string };
56
+ } = {}
57
+ ) {
58
+ this.initPromise = this.initialize(options);
59
+ }
60
+
61
+ private async initialize(options: {
62
+ ssl?: { key_file_name?: string; cert_file_name?: string; passphrase?: string };
63
+ }): Promise<void> {
64
+ try {
65
+ // Lazy load uWebSockets.js - only when explicitly configured
66
+ // This ensures it's an optional dependency with graceful fallback
67
+ const uwsModule = await import('uWebSockets.js');
68
+ this.uws = uwsModule.default || uwsModule;
69
+
70
+ if (options.ssl && options.ssl.key_file_name && options.ssl.cert_file_name) {
71
+ this.app = this.uws.SSLApp({
72
+ key_file_name: options.ssl.key_file_name,
73
+ cert_file_name: options.ssl.cert_file_name,
74
+ passphrase: options.ssl.passphrase,
75
+ });
76
+ this.logger.info('uWebSockets SSL/TLS HTTP server created', 'Init');
77
+ } else {
78
+ this.app = this.uws.App();
79
+ this.logger.info('uWebSockets HTTP server created', 'Init');
80
+ }
81
+
82
+ // Setup generic route handler for all HTTP methods and paths
83
+ this.setupRouteHandlers();
84
+ } catch (error) {
85
+ // Log helpful error message with installation instructions
86
+ this.logger.error(
87
+ 'Failed to load uWebSockets.js (optional dependency)\n' +
88
+ 'To use uWebSockets, install it with:\n' +
89
+ ' npm install --save-dev github:uNetworking/uWebSockets.js#v20.52.0\n' +
90
+ 'Or set useUWebSockets: false in your config to use the standard HTTP server.\n' +
91
+ 'Error: ' +
92
+ (error instanceof Error ? error.message : String(error)),
93
+ 'Init'
94
+ );
95
+ throw error; // Re-throw so framework.ts can catch and fallback
96
+ }
97
+ }
98
+
99
+ private setupRouteHandlers(): void {
100
+ // Handle all HTTP methods through catchall
101
+ // All requests go through middleware chain (includes UnifiedRouter)
102
+ this.app.any('/*', (res: any, req: any) => {
103
+ this.handleRequest(req, res);
104
+ });
105
+ }
106
+
107
+ private async handleRequest(req: any, res: any): Promise<void> {
108
+ this.requestCounter++;
109
+
110
+ // Declare outside try block for cleanup in finally
111
+ let httpReq: any;
112
+ let httpRes: any;
113
+
114
+ try {
115
+ // Create Moro-compatible request object
116
+ httpReq = this.createMoroRequest(req, res);
117
+ httpRes = this.createMoroResponse(req, res);
118
+
119
+ // Parse body only if there's actually a body (check content-length)
120
+ const method = req.getMethod().toUpperCase();
121
+ const contentLength = req.getHeader('content-length');
122
+ if (
123
+ (method === 'POST' || method === 'PUT' || method === 'PATCH') &&
124
+ contentLength &&
125
+ parseInt(contentLength) > 0
126
+ ) {
127
+ await this.readBody(res, httpReq);
128
+ }
129
+
130
+ // Execute hooks before request processing
131
+ if (this.hookManager) {
132
+ await this.hookManager.execute('request', {
133
+ request: httpReq,
134
+ response: httpRes,
135
+ });
136
+ }
137
+
138
+ // Execute middleware chain (includes UnifiedRouter for routing)
139
+ // The UnifiedRouter will handle route matching, params extraction, and handler execution
140
+ if (this.globalMiddleware.length > 0) {
141
+ await this.executeMiddleware(this.globalMiddleware, httpReq, httpRes);
142
+ } else {
143
+ // No middleware - send 404 (router middleware should be present)
144
+ if (!httpRes.headersSent) {
145
+ httpRes.statusCode = 404;
146
+ httpRes.setHeader('Content-Type', 'application/json');
147
+ httpRes.end('{"success":false,"error":"Not found"}');
148
+ }
149
+ }
150
+ } catch (error) {
151
+ this.logger.error(
152
+ `Request handling error: ${error instanceof Error ? error.message : String(error)}`,
153
+ 'RequestError'
154
+ );
155
+
156
+ // Send error response if not already sent
157
+ if (!res.aborted) {
158
+ try {
159
+ res.cork(() => {
160
+ res.writeStatus('500 Internal Server Error');
161
+ res.writeHeader('Content-Type', 'application/json');
162
+ res.end('{"success":false,"error":"Internal server error"}');
163
+ });
164
+ } catch (writeError) {
165
+ this.logger.error('Failed to send error response', 'ResponseError');
166
+ }
167
+ }
168
+ } finally {
169
+ // CRITICAL: Release pooled objects back to pool
170
+ if (httpReq) {
171
+ const pooledQuery = (httpReq as any)._pooledQuery;
172
+ const pooledHeaders = (httpReq as any)._pooledHeaders;
173
+
174
+ if (pooledQuery && Object.keys(pooledQuery).length > 0) {
175
+ this.poolManager.releaseQuery(pooledQuery);
176
+ }
177
+
178
+ if (pooledHeaders && Object.keys(pooledHeaders).length > 0) {
179
+ this.poolManager.releaseHeaders(pooledHeaders);
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+ private createMoroRequest(req: any, res: any): HttpRequest {
186
+ const url = req.getUrl();
187
+ const queryString = req.getQuery();
188
+ const methodRaw = req.getMethod();
189
+
190
+ // Use interned method string if available
191
+ const method = UWebSocketsHttpServer.INTERNED_METHODS.get(methodRaw) || methodRaw.toUpperCase();
192
+
193
+ // Optimized query parsing with pooled object
194
+ let queryParams: Record<string, string>;
195
+ if (queryString) {
196
+ queryParams = this.poolManager.acquireQuery();
197
+ // Query parsing without URLSearchParams overhead
198
+ const pairs = queryString.split('&');
199
+ for (let i = 0; i < pairs.length; i++) {
200
+ const pair = pairs[i];
201
+ const eqIdx = pair.indexOf('=');
202
+ if (eqIdx > 0) {
203
+ const key = pair.substring(0, eqIdx);
204
+ const value = pair.substring(eqIdx + 1);
205
+ queryParams[decodeURIComponent(key)] = decodeURIComponent(value);
206
+ }
207
+ }
208
+ } else {
209
+ queryParams = {};
210
+ }
211
+
212
+ // Optimized header parsing with pooled object
213
+ const headers = this.poolManager.acquireHeaders();
214
+ req.forEach((key: string, value: string) => {
215
+ const lowerKey = key.toLowerCase();
216
+ headers[lowerKey] = value;
217
+ });
218
+
219
+ const httpReq = {
220
+ method,
221
+ path: url,
222
+ url: url,
223
+ query: queryParams,
224
+ params: {}, // Will be filled by route matching
225
+ headers,
226
+ body: null,
227
+ ip: '', // Lazy - only compute if accessed
228
+ requestId: this.requestTrackingEnabled ? this.poolManager.generateRequestId() : '', // ID generation (if enabled)
229
+ } as HttpRequest;
230
+
231
+ // Store pooled objects for cleanup
232
+ (httpReq as any)._pooledQuery = queryParams;
233
+ (httpReq as any)._pooledHeaders = headers;
234
+
235
+ return httpReq;
236
+ }
237
+
238
+ private createMoroResponse(req: any, res: any): HttpResponse {
239
+ let headersSent = false;
240
+ let statusCode = 200;
241
+ const responseHeaders: Record<string, string | string[]> = {};
242
+ //eslint-disable-next-line @typescript-eslint/no-this-alias
243
+ const self = this;
244
+
245
+ const httpRes = {
246
+ statusCode,
247
+ get headersSent() {
248
+ return headersSent;
249
+ },
250
+
251
+ status(code: number) {
252
+ statusCode = code;
253
+ (httpRes as any).statusCode = code;
254
+ return httpRes as HttpResponse;
255
+ },
256
+
257
+ setHeader(name: string, value: string | string[]) {
258
+ responseHeaders[name.toLowerCase()] = value;
259
+ return httpRes as HttpResponse;
260
+ },
261
+
262
+ getHeader(name: string) {
263
+ return responseHeaders[name.toLowerCase()];
264
+ },
265
+
266
+ removeHeader(name: string) {
267
+ delete responseHeaders[name.toLowerCase()];
268
+ return httpRes as HttpResponse;
269
+ },
270
+
271
+ json(data: any) {
272
+ if (headersSent || res.aborted) return;
273
+
274
+ const body = JSON.stringify(data);
275
+ responseHeaders['content-type'] = 'application/json';
276
+
277
+ try {
278
+ res.cork(() => {
279
+ res.writeStatus(`${statusCode} OK`);
280
+ Object.entries(responseHeaders).forEach(([key, value]) => {
281
+ res.writeHeader(key, Array.isArray(value) ? value.join(', ') : String(value));
282
+ });
283
+ res.end(body);
284
+ });
285
+ headersSent = true;
286
+ } catch (error) {
287
+ self.logger.error('Failed to send JSON response', 'ResponseError');
288
+ }
289
+ },
290
+
291
+ send(data: string | Buffer) {
292
+ if (headersSent || res.aborted) return;
293
+
294
+ const body = typeof data === 'string' ? data : data.toString();
295
+
296
+ try {
297
+ res.cork(() => {
298
+ res.writeStatus(`${statusCode} OK`);
299
+ Object.entries(responseHeaders).forEach(([key, value]) => {
300
+ res.writeHeader(key, Array.isArray(value) ? value.join(', ') : String(value));
301
+ });
302
+ res.end(body);
303
+ });
304
+ headersSent = true;
305
+ } catch (error) {
306
+ self.logger.error('Failed to send response', 'ResponseError');
307
+ }
308
+ },
309
+
310
+ end(data?: any, encoding?: any, callback?: any) {
311
+ if (headersSent || res.aborted) {
312
+ if (typeof callback === 'function') callback();
313
+ return httpRes as HttpResponse;
314
+ }
315
+
316
+ try {
317
+ res.cork(() => {
318
+ res.writeStatus(`${statusCode} OK`);
319
+ Object.entries(responseHeaders).forEach(([key, value]) => {
320
+ res.writeHeader(key, Array.isArray(value) ? value.join(', ') : String(value));
321
+ });
322
+ res.end(data || '');
323
+ });
324
+ headersSent = true;
325
+ if (typeof callback === 'function') callback();
326
+ } catch (error) {
327
+ self.logger.error('Failed to end response', 'ResponseError');
328
+ if (typeof callback === 'function') callback();
329
+ }
330
+
331
+ return httpRes as HttpResponse;
332
+ },
333
+
334
+ redirect(url: string, code?: number) {
335
+ if (headersSent || res.aborted) return;
336
+
337
+ const redirectCode = code || 302;
338
+ statusCode = redirectCode;
339
+
340
+ try {
341
+ res.cork(() => {
342
+ res.writeStatus(`${redirectCode} Found`);
343
+ res.writeHeader('Location', url);
344
+ res.end();
345
+ });
346
+ headersSent = true;
347
+ } catch (error) {
348
+ self.logger.error('Failed to send redirect', 'ResponseError');
349
+ }
350
+ },
351
+
352
+ // EventEmitter compatibility - stub implementations for middleware
353
+ on(event: string, callback: Function) {
354
+ // uWebSockets doesn't use events like Node.js, but middleware might try to listen
355
+ // Only implement 'finish' and 'close' events as stubs
356
+ return httpRes;
357
+ },
358
+
359
+ once(event: string, callback: Function) {
360
+ return httpRes;
361
+ },
362
+
363
+ emit(event: string, ...args: any[]) {
364
+ return true;
365
+ },
366
+
367
+ removeListener(event: string, callback: Function) {
368
+ return httpRes;
369
+ },
370
+
371
+ cookie(name: string, value: string, options?: any) {
372
+ let cookie = `${name}=${value}`;
373
+
374
+ if (options) {
375
+ if (options.maxAge) cookie += `; Max-Age=${options.maxAge}`;
376
+ if (options.domain) cookie += `; Domain=${options.domain}`;
377
+ if (options.path) cookie += `; Path=${options.path}`;
378
+ if (options.secure) cookie += '; Secure';
379
+ if (options.httpOnly) cookie += '; HttpOnly';
380
+ if (options.sameSite) cookie += `; SameSite=${options.sameSite}`;
381
+ }
382
+
383
+ const existing = responseHeaders['set-cookie'];
384
+ if (existing) {
385
+ if (Array.isArray(existing)) {
386
+ responseHeaders['set-cookie'] = [...existing, cookie];
387
+ } else {
388
+ responseHeaders['set-cookie'] = [existing as string, cookie];
389
+ }
390
+ } else {
391
+ responseHeaders['set-cookie'] = cookie;
392
+ }
393
+
394
+ return httpRes as HttpResponse;
395
+ },
396
+ } as any;
397
+
398
+ return httpRes as HttpResponse;
399
+ }
400
+
401
+ private async readBody(res: any, httpReq: HttpRequest): Promise<void> {
402
+ return new Promise((resolve, reject) => {
403
+ let buffer: Buffer;
404
+
405
+ res.onData((chunk: ArrayBuffer, isLast: boolean) => {
406
+ const chunkBuffer = Buffer.from(chunk);
407
+
408
+ if (isLast) {
409
+ if (buffer) {
410
+ buffer = Buffer.concat([buffer, chunkBuffer]);
411
+ } else {
412
+ buffer = chunkBuffer;
413
+ }
414
+
415
+ try {
416
+ const contentType = httpReq.headers['content-type'] || '';
417
+
418
+ if (contentType.includes('application/json')) {
419
+ httpReq.body = JSON.parse(buffer.toString('utf-8'));
420
+ } else if (contentType.includes('application/x-www-form-urlencoded')) {
421
+ const params = new URLSearchParams(buffer.toString('utf-8'));
422
+ const body: Record<string, any> = {};
423
+ params.forEach((value, key) => {
424
+ body[key] = value;
425
+ });
426
+ httpReq.body = body;
427
+ } else {
428
+ httpReq.body = buffer.toString('utf-8');
429
+ }
430
+
431
+ resolve();
432
+ } catch (error) {
433
+ this.logger.error('Failed to parse request body', 'BodyParseError');
434
+ httpReq.body = null;
435
+ resolve();
436
+ }
437
+ } else {
438
+ if (buffer) {
439
+ buffer = Buffer.concat([buffer, chunkBuffer]);
440
+ } else {
441
+ buffer = chunkBuffer;
442
+ }
443
+ }
444
+ });
445
+
446
+ res.onAborted(() => {
447
+ this.logger.debug('Request aborted', 'RequestAborted');
448
+ resolve();
449
+ });
450
+ });
451
+ }
452
+
453
+ private async executeMiddleware(
454
+ middleware: Middleware[],
455
+ req: HttpRequest,
456
+ res: HttpResponse
457
+ ): Promise<void> {
458
+ for (const mw of middleware) {
459
+ if (res.headersSent) break;
460
+
461
+ await new Promise<void>((resolve, reject) => {
462
+ try {
463
+ const result = mw(req, res, (err?: Error) => {
464
+ if (err) reject(err);
465
+ else resolve();
466
+ });
467
+
468
+ // Handle async middleware
469
+ if (result && typeof result.then === 'function') {
470
+ result.then(() => resolve()).catch(reject);
471
+ }
472
+ } catch (error) {
473
+ reject(error);
474
+ }
475
+ });
476
+ }
477
+ }
478
+
479
+ // Public API - matches MoroHttpServer interface
480
+
481
+ use(middleware: Middleware): void {
482
+ this.globalMiddleware.push(middleware);
483
+ }
484
+
485
+ // Configure request tracking (ID generation)
486
+ setRequestTracking(enabled: boolean): void {
487
+ this.requestTrackingEnabled = enabled;
488
+ }
489
+
490
+ // Note: Route registration methods (get, post, etc.) are not used by uWebSockets adapter
491
+ // All routing is handled by UnifiedRouter through the middleware chain
492
+
493
+ setHookManager(hookManager: any): void {
494
+ this.hookManager = hookManager;
495
+ }
496
+
497
+ configurePerformance(config: any): void {
498
+ // uWebSockets is already highly optimized
499
+ // This method exists for API compatibility
500
+ this.logger.debug('Performance configuration noted (uWebSockets is pre-optimized)', 'Config');
501
+ }
502
+
503
+ listen(port: number, callback?: () => void): void;
504
+ listen(port: number, host: string, callback?: () => void): void;
505
+ listen(port: number, hostOrCallback?: string | (() => void), callback?: () => void): void {
506
+ // Wrap in async to await init
507
+ this.initPromise
508
+ .then(() => {
509
+ if (this.isListening) {
510
+ this.logger.warn('Server is already listening', 'Listen');
511
+ return;
512
+ }
513
+
514
+ const host = typeof hostOrCallback === 'string' ? hostOrCallback : '0.0.0.0';
515
+ const cb = typeof hostOrCallback === 'function' ? hostOrCallback : callback;
516
+
517
+ this.port = port;
518
+ this.host = host;
519
+
520
+ // Check if we're in a cluster environment
521
+ const isClusterWorker = cluster.isWorker;
522
+ const isClusterPrimary = cluster.isPrimary;
523
+
524
+ // ALWAYS use LIBUS_LISTEN_EXCLUSIVE_PORT when clustering
525
+ // This enables SO_REUSEPORT at the OS level, allowing multiple processes to bind to the same port
526
+ // NOTE: uWebSockets.js API doesn't have listen(host, port, options, cb)
527
+ // We must use listen(port, options, cb) which binds to 0.0.0.0
528
+ const listenOptions = 1; // ALWAYS use LIBUS_LISTEN_EXCLUSIVE_PORT for clustering support
529
+
530
+ this.app.listen(port, listenOptions, (token: any) => {
531
+ if (token) {
532
+ this.listenSocket = token;
533
+ this.isListening = true;
534
+ const clusterInfo = isClusterWorker ? ` (worker ${process.pid})` : '';
535
+ this.logger.info(
536
+ `uWebSockets HTTP server listening on 0.0.0.0:${port}${clusterInfo}`,
537
+ 'Listen'
538
+ );
539
+ if (cb) cb();
540
+ } else {
541
+ const clusterInfo = isClusterWorker ? ` (worker ${process.pid})` : '';
542
+ this.logger.error(`Failed to listen on port ${port}${clusterInfo}`, 'Listen');
543
+ // Don't throw in cluster workers - let them fail gracefully
544
+ if (!isClusterWorker) {
545
+ throw new Error(`Failed to bind to port ${port}`);
546
+ }
547
+ }
548
+ });
549
+ })
550
+ .catch(error => {
551
+ this.logger.error('Failed to initialize server before listen', 'Listen', {
552
+ error: error instanceof Error ? error.message : String(error),
553
+ });
554
+ });
555
+ }
556
+
557
+ async close(callback?: () => void): Promise<void> {
558
+ if (!this.isListening) {
559
+ if (callback) callback();
560
+ return;
561
+ }
562
+
563
+ try {
564
+ // Use stored module reference instead of re-importing
565
+ if (this.listenSocket && this.uws) {
566
+ this.uws.us_listen_socket_close(this.listenSocket);
567
+ this.listenSocket = null;
568
+ this.isListening = false;
569
+ this.logger.info('uWebSockets HTTP server closed', 'Close');
570
+ }
571
+ if (callback) callback();
572
+ } catch (error) {
573
+ this.logger.error('Error closing server', 'Close');
574
+ if (callback) callback();
575
+ }
576
+ }
577
+
578
+ getServer(): any {
579
+ // Return the uWebSockets app for direct access if needed
580
+ return this.app;
581
+ }
582
+
583
+ getApp(): any {
584
+ return this.app;
585
+ }
586
+
587
+ forceCleanup(): void {
588
+ // Cleanup method for compatibility
589
+ this.logger.debug('Force cleanup called', 'Cleanup');
590
+ }
591
+ }
@@ -1,5 +1,5 @@
1
1
  // Advanced Logger Filters
2
- import { LogEntry, LogFilter } from '../../types/logger';
2
+ import { LogEntry, LogFilter } from '../../types/logger.js';
3
3
 
4
4
  // Level-based filter
5
5
  export const levelFilter = (minLevel: string): LogFilter => ({
@@ -22,16 +22,24 @@ export const contextFilter = (allowedContexts: string[]): LogFilter => ({
22
22
  // Rate limiting filter
23
23
  export const rateLimitFilter = (maxPerSecond: number): LogFilter => {
24
24
  const timestamps: number[] = [];
25
+ let lastCleanup = 0;
25
26
 
26
27
  return {
27
28
  name: 'rate-limit',
28
29
  filter: (entry: LogEntry) => {
29
30
  const now = Date.now();
30
- const oneSecondAgo = now - 1000;
31
31
 
32
- // Remove old timestamps
33
- while (timestamps.length > 0 && timestamps[0] < oneSecondAgo) {
34
- timestamps.shift();
32
+ // Batch cleanup for better performance and thread safety
33
+ if (now - lastCleanup > 1000) {
34
+ const cutoff = now - 1000;
35
+ let keepIndex = 0;
36
+ for (let i = 0; i < timestamps.length; i++) {
37
+ if (timestamps[i] >= cutoff) {
38
+ timestamps[keepIndex++] = timestamps[i];
39
+ }
40
+ }
41
+ timestamps.length = keepIndex;
42
+ lastCleanup = now;
35
43
  }
36
44
 
37
45
  // Check rate limit
@@ -5,8 +5,9 @@ export {
5
5
  createFrameworkLogger,
6
6
  configureGlobalLogger,
7
7
  applyLoggingConfiguration,
8
- } from './logger';
9
- export * from './filters';
8
+ destroyGlobalLogger,
9
+ } from './logger.js';
10
+ export * from './filters.js';
10
11
 
11
12
  export type {
12
13
  LogLevel,
@@ -17,4 +18,4 @@ export type {
17
18
  LogFilter,
18
19
  LogMetrics,
19
20
  ColorScheme,
20
- } from '../../types/logger';
21
+ } from '../../types/logger.js';