@morojs/moro 1.6.1 → 1.6.3
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.
- package/README.md +74 -256
- package/dist/core/auth/morojs-adapter.js +20 -20
- package/dist/core/auth/morojs-adapter.js.map +1 -1
- package/dist/core/config/config-manager.d.ts +44 -0
- package/dist/core/config/config-manager.js +104 -0
- package/dist/core/config/config-manager.js.map +1 -0
- package/dist/core/config/config-sources.d.ts +21 -0
- package/dist/core/config/config-sources.js +503 -0
- package/dist/core/config/config-sources.js.map +1 -0
- package/dist/core/config/config-validator.d.ts +21 -0
- package/dist/core/config/config-validator.js +791 -0
- package/dist/core/config/config-validator.js.map +1 -0
- package/dist/core/config/file-loader.d.ts +1 -6
- package/dist/core/config/file-loader.js +21 -249
- package/dist/core/config/file-loader.js.map +1 -1
- package/dist/core/config/index.d.ts +41 -12
- package/dist/core/config/index.js +65 -54
- package/dist/core/config/index.js.map +1 -1
- package/dist/core/config/schema.d.ts +2 -2
- package/dist/core/config/schema.js +55 -44
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/config/utils.d.ts +10 -3
- package/dist/core/config/utils.js +31 -58
- package/dist/core/config/utils.js.map +1 -1
- package/dist/core/database/adapters/drizzle.d.ts +1 -1
- package/dist/core/database/adapters/drizzle.js +18 -11
- package/dist/core/database/adapters/drizzle.js.map +1 -1
- package/dist/core/database/adapters/index.d.ts +7 -7
- package/dist/core/database/adapters/index.js +19 -29
- package/dist/core/database/adapters/index.js.map +1 -1
- package/dist/core/database/adapters/mongodb.d.ts +13 -1
- package/dist/core/database/adapters/mongodb.js +46 -10
- package/dist/core/database/adapters/mongodb.js.map +1 -1
- package/dist/core/database/adapters/mysql.d.ts +14 -1
- package/dist/core/database/adapters/mysql.js +19 -9
- package/dist/core/database/adapters/mysql.js.map +1 -1
- package/dist/core/database/adapters/postgresql.d.ts +12 -2
- package/dist/core/database/adapters/postgresql.js +19 -9
- package/dist/core/database/adapters/postgresql.js.map +1 -1
- package/dist/core/database/adapters/redis.d.ts +12 -1
- package/dist/core/database/adapters/redis.js +48 -13
- package/dist/core/database/adapters/redis.js.map +1 -1
- package/dist/core/database/adapters/sqlite.d.ts +3 -1
- package/dist/core/database/adapters/sqlite.js +19 -8
- package/dist/core/database/adapters/sqlite.js.map +1 -1
- package/dist/core/database/index.d.ts +2 -2
- package/dist/core/database/index.js +2 -18
- package/dist/core/database/index.js.map +1 -1
- package/dist/core/docs/index.d.ts +9 -9
- package/dist/core/docs/index.js +14 -35
- package/dist/core/docs/index.js.map +1 -1
- package/dist/core/docs/openapi-generator.d.ts +2 -2
- package/dist/core/docs/openapi-generator.js +11 -16
- package/dist/core/docs/openapi-generator.js.map +1 -1
- package/dist/core/docs/schema-to-openapi.d.ts +2 -2
- package/dist/core/docs/schema-to-openapi.js +5 -11
- package/dist/core/docs/schema-to-openapi.js.map +1 -1
- package/dist/core/docs/simple-docs.d.ts +1 -1
- package/dist/core/docs/simple-docs.js +4 -9
- package/dist/core/docs/simple-docs.js.map +1 -1
- package/dist/core/docs/swagger-ui.d.ts +2 -2
- package/dist/core/docs/swagger-ui.js +26 -29
- package/dist/core/docs/swagger-ui.js.map +1 -1
- package/dist/core/docs/zod-to-openapi.js +31 -28
- package/dist/core/docs/zod-to-openapi.js.map +1 -1
- package/dist/core/events/event-bus.d.ts +1 -1
- package/dist/core/events/event-bus.js +7 -11
- package/dist/core/events/event-bus.js.map +1 -1
- package/dist/core/events/index.d.ts +2 -2
- package/dist/core/events/index.js +1 -5
- package/dist/core/events/index.js.map +1 -1
- package/dist/core/framework.d.ts +20 -13
- package/dist/core/framework.js +285 -102
- package/dist/core/framework.js.map +1 -1
- package/dist/core/http/http-server.d.ts +59 -7
- package/dist/core/http/http-server.js +202 -185
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/index.d.ts +4 -3
- package/dist/core/http/index.js +3 -8
- package/dist/core/http/index.js.map +1 -1
- package/dist/core/http/uws-http-server.d.ts +46 -0
- package/dist/core/http/uws-http-server.js +523 -0
- package/dist/core/http/uws-http-server.js.map +1 -0
- package/dist/core/logger/filters.d.ts +1 -1
- package/dist/core/logger/filters.js +20 -23
- package/dist/core/logger/filters.js.map +1 -1
- package/dist/core/logger/index.d.ts +3 -3
- package/dist/core/logger/index.js +2 -24
- package/dist/core/logger/index.js.map +1 -1
- package/dist/core/logger/logger.d.ts +30 -14
- package/dist/core/logger/logger.js +398 -223
- package/dist/core/logger/logger.js.map +1 -1
- package/dist/core/logger/outputs.d.ts +1 -1
- package/dist/core/logger/outputs.js +8 -17
- package/dist/core/logger/outputs.js.map +1 -1
- package/dist/core/middleware/built-in/auth/core.d.ts +78 -0
- package/dist/core/middleware/built-in/auth/core.js +358 -0
- package/dist/core/middleware/built-in/auth/core.js.map +1 -0
- package/dist/core/middleware/built-in/{auth-helpers.js → auth/helpers.js} +12 -23
- package/dist/core/middleware/built-in/auth/helpers.js.map +1 -0
- package/dist/core/middleware/built-in/auth/hook.d.ts +30 -0
- package/dist/core/middleware/built-in/auth/hook.js +99 -0
- package/dist/core/middleware/built-in/auth/hook.js.map +1 -0
- package/dist/core/middleware/built-in/auth/index.d.ts +7 -0
- package/dist/core/middleware/built-in/auth/index.js +15 -0
- package/dist/core/middleware/built-in/auth/index.js.map +1 -0
- package/dist/core/middleware/built-in/auth/jwt-helpers.d.ts +118 -0
- package/dist/core/middleware/built-in/auth/jwt-helpers.js +218 -0
- package/dist/core/middleware/built-in/auth/jwt-helpers.js.map +1 -0
- package/dist/core/middleware/built-in/auth/middleware.d.ts +23 -0
- package/dist/core/middleware/built-in/auth/middleware.js +71 -0
- package/dist/core/middleware/built-in/auth/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/{auth-providers.d.ts → auth/providers.d.ts} +1 -1
- package/dist/core/middleware/built-in/{auth-providers.js → auth/providers.js} +5 -10
- package/dist/core/middleware/built-in/auth/providers.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/file.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/file.js +10 -47
- package/dist/core/middleware/built-in/cache/adapters/cache/file.js.map +1 -0
- package/dist/core/middleware/built-in/cache/adapters/cache/index.d.ts +5 -0
- package/dist/core/middleware/built-in/cache/adapters/cache/index.js +21 -0
- package/dist/core/middleware/built-in/cache/adapters/cache/index.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/memory.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/memory.js +3 -7
- package/dist/core/middleware/built-in/cache/adapters/cache/memory.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/redis.d.ts +3 -1
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/redis.js +11 -9
- package/dist/core/middleware/built-in/cache/adapters/cache/redis.js.map +1 -0
- package/dist/core/middleware/built-in/cache/adapters/index.d.ts +2 -0
- package/dist/core/middleware/built-in/cache/adapters/index.js +5 -0
- package/dist/core/middleware/built-in/cache/adapters/index.js.map +1 -0
- package/dist/core/middleware/built-in/cache/core.d.ts +37 -0
- package/dist/core/middleware/built-in/cache/core.js +87 -0
- package/dist/core/middleware/built-in/cache/core.js.map +1 -0
- package/dist/core/middleware/built-in/cache/hook.d.ts +20 -0
- package/dist/core/middleware/built-in/{cache.js → cache/hook.js} +30 -14
- package/dist/core/middleware/built-in/cache/hook.js.map +1 -0
- package/dist/core/middleware/built-in/cache/index.d.ts +3 -0
- package/dist/core/middleware/built-in/cache/index.js +9 -0
- package/dist/core/middleware/built-in/cache/index.js.map +1 -0
- package/dist/core/middleware/built-in/cache/middleware.d.ts +17 -0
- package/dist/core/middleware/built-in/cache/middleware.js +44 -0
- package/dist/core/middleware/built-in/cache/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/azure.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/azure.js +3 -7
- package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/cloudflare.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/cloudflare.js +3 -7
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/cloudfront.d.ts +3 -1
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/cloudfront.js +12 -10
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudfront.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/adapters/cdn/index.d.ts +5 -0
- package/dist/core/middleware/built-in/cdn/adapters/cdn/index.js +21 -0
- package/dist/core/middleware/built-in/cdn/adapters/cdn/index.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/adapters/index.d.ts +2 -0
- package/dist/core/middleware/built-in/cdn/adapters/index.js +5 -0
- package/dist/core/middleware/built-in/cdn/adapters/index.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/core.d.ts +43 -0
- package/dist/core/middleware/built-in/cdn/core.js +144 -0
- package/dist/core/middleware/built-in/cdn/core.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/hook.d.ts +22 -0
- package/dist/core/middleware/built-in/cdn/hook.js +70 -0
- package/dist/core/middleware/built-in/cdn/hook.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/index.d.ts +5 -0
- package/dist/core/middleware/built-in/cdn/index.js +11 -0
- package/dist/core/middleware/built-in/cdn/index.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/middleware.d.ts +21 -0
- package/dist/core/middleware/built-in/cdn/middleware.js +52 -0
- package/dist/core/middleware/built-in/cdn/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/cookie/core.d.ts +37 -0
- package/dist/core/middleware/built-in/cookie/core.js +83 -0
- package/dist/core/middleware/built-in/cookie/core.js.map +1 -0
- package/dist/core/middleware/built-in/cookie/hook.d.ts +20 -0
- package/dist/core/middleware/built-in/cookie/hook.js +47 -0
- package/dist/core/middleware/built-in/cookie/hook.js.map +1 -0
- package/dist/core/middleware/built-in/cookie/index.d.ts +3 -0
- package/dist/core/middleware/built-in/cookie/index.js +9 -0
- package/dist/core/middleware/built-in/cookie/index.js.map +1 -0
- package/dist/core/middleware/built-in/cookie/middleware.d.ts +17 -0
- package/dist/core/middleware/built-in/cookie/middleware.js +36 -0
- package/dist/core/middleware/built-in/cookie/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/cors/core.d.ts +23 -0
- package/dist/core/middleware/built-in/cors/core.js +51 -0
- package/dist/core/middleware/built-in/cors/core.js.map +1 -0
- package/dist/core/middleware/built-in/cors/hook.d.ts +17 -0
- package/dist/core/middleware/built-in/cors/hook.js +37 -0
- package/dist/core/middleware/built-in/cors/hook.js.map +1 -0
- package/dist/core/middleware/built-in/cors/index.d.ts +3 -0
- package/dist/core/middleware/built-in/cors/index.js +9 -0
- package/dist/core/middleware/built-in/cors/index.js.map +1 -0
- package/dist/core/middleware/built-in/cors/middleware.d.ts +16 -0
- package/dist/core/middleware/built-in/cors/middleware.js +22 -0
- package/dist/core/middleware/built-in/cors/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/csp/core.d.ts +45 -0
- package/dist/core/middleware/built-in/csp/core.js +88 -0
- package/dist/core/middleware/built-in/csp/core.js.map +1 -0
- package/dist/core/middleware/built-in/csp/hook.d.ts +22 -0
- package/dist/core/middleware/built-in/csp/hook.js +47 -0
- package/dist/core/middleware/built-in/csp/hook.js.map +1 -0
- package/dist/core/middleware/built-in/csp/index.d.ts +3 -0
- package/dist/core/middleware/built-in/csp/index.js +9 -0
- package/dist/core/middleware/built-in/csp/index.js.map +1 -0
- package/dist/core/middleware/built-in/csp/middleware.d.ts +19 -0
- package/dist/core/middleware/built-in/csp/middleware.js +29 -0
- package/dist/core/middleware/built-in/csp/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/csrf/core.d.ts +28 -0
- package/dist/core/middleware/built-in/csrf/core.js +69 -0
- package/dist/core/middleware/built-in/csrf/core.js.map +1 -0
- package/dist/core/middleware/built-in/csrf/hook.d.ts +17 -0
- package/dist/core/middleware/built-in/csrf/hook.js +45 -0
- package/dist/core/middleware/built-in/csrf/hook.js.map +1 -0
- package/dist/core/middleware/built-in/csrf/index.d.ts +3 -0
- package/dist/core/middleware/built-in/csrf/index.js +9 -0
- package/dist/core/middleware/built-in/csrf/index.js.map +1 -0
- package/dist/core/middleware/built-in/csrf/middleware.d.ts +16 -0
- package/dist/core/middleware/built-in/csrf/middleware.js +34 -0
- package/dist/core/middleware/built-in/csrf/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/error-tracker/index.d.ts +1 -0
- package/dist/core/middleware/built-in/error-tracker/index.js +4 -0
- package/dist/core/middleware/built-in/error-tracker/index.js.map +1 -0
- package/dist/core/middleware/built-in/error-tracker/middleware.d.ts +12 -0
- package/dist/core/middleware/built-in/error-tracker/middleware.js +26 -0
- package/dist/core/middleware/built-in/error-tracker/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/index.d.ts +28 -61
- package/dist/core/middleware/built-in/index.js +48 -78
- package/dist/core/middleware/built-in/index.js.map +1 -1
- package/dist/core/middleware/built-in/performance-monitor/index.d.ts +1 -0
- package/dist/core/middleware/built-in/performance-monitor/index.js +4 -0
- package/dist/core/middleware/built-in/performance-monitor/index.js.map +1 -0
- package/dist/core/middleware/built-in/performance-monitor/middleware.d.ts +12 -0
- package/dist/core/middleware/built-in/performance-monitor/middleware.js +29 -0
- package/dist/core/middleware/built-in/performance-monitor/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit/core.d.ts +33 -0
- package/dist/core/middleware/built-in/rate-limit/core.js +86 -0
- package/dist/core/middleware/built-in/rate-limit/core.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit/hook.d.ts +20 -0
- package/dist/core/middleware/built-in/{rate-limit.js → rate-limit/hook.js} +24 -22
- package/dist/core/middleware/built-in/rate-limit/hook.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit/index.d.ts +3 -0
- package/dist/core/middleware/built-in/rate-limit/index.js +9 -0
- package/dist/core/middleware/built-in/rate-limit/index.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit/middleware.d.ts +16 -0
- package/dist/core/middleware/built-in/rate-limit/middleware.js +35 -0
- package/dist/core/middleware/built-in/rate-limit/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/request-logger/index.d.ts +1 -0
- package/dist/core/middleware/built-in/request-logger/index.js +4 -0
- package/dist/core/middleware/built-in/request-logger/index.js.map +1 -0
- package/dist/core/middleware/built-in/request-logger/middleware.d.ts +12 -0
- package/dist/core/middleware/built-in/request-logger/middleware.js +24 -0
- package/dist/core/middleware/built-in/request-logger/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/session/core.d.ts +73 -0
- package/dist/core/middleware/built-in/session/core.js +227 -0
- package/dist/core/middleware/built-in/session/core.js.map +1 -0
- package/dist/core/middleware/built-in/session/hook.d.ts +17 -0
- package/dist/core/middleware/built-in/session/hook.js +53 -0
- package/dist/core/middleware/built-in/session/hook.js.map +1 -0
- package/dist/core/middleware/built-in/session/index.d.ts +3 -0
- package/dist/core/middleware/built-in/session/index.js +9 -0
- package/dist/core/middleware/built-in/session/index.js.map +1 -0
- package/dist/core/middleware/built-in/session/middleware.d.ts +17 -0
- package/dist/core/middleware/built-in/session/middleware.js +38 -0
- package/dist/core/middleware/built-in/session/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/sse/core.d.ts +44 -0
- package/dist/core/middleware/built-in/sse/core.js +117 -0
- package/dist/core/middleware/built-in/sse/core.js.map +1 -0
- package/dist/core/middleware/built-in/sse/hook.d.ts +18 -0
- package/dist/core/middleware/built-in/sse/hook.js +60 -0
- package/dist/core/middleware/built-in/sse/hook.js.map +1 -0
- package/dist/core/middleware/built-in/sse/index.d.ts +3 -0
- package/dist/core/middleware/built-in/sse/index.js +9 -0
- package/dist/core/middleware/built-in/sse/index.js.map +1 -0
- package/dist/core/middleware/built-in/sse/middleware.d.ts +18 -0
- package/dist/core/middleware/built-in/sse/middleware.js +43 -0
- package/dist/core/middleware/built-in/sse/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/validation/core.d.ts +23 -0
- package/dist/core/middleware/built-in/validation/core.js +93 -0
- package/dist/core/middleware/built-in/validation/core.js.map +1 -0
- package/dist/core/middleware/built-in/validation/hook.d.ts +13 -0
- package/dist/core/middleware/built-in/{validation.js → validation/hook.js} +16 -9
- package/dist/core/middleware/built-in/validation/hook.js.map +1 -0
- package/dist/core/middleware/built-in/validation/index.d.ts +3 -0
- package/dist/core/middleware/built-in/validation/index.js +9 -0
- package/dist/core/middleware/built-in/validation/index.js.map +1 -0
- package/dist/core/middleware/built-in/validation/middleware.d.ts +16 -0
- package/dist/core/middleware/built-in/validation/middleware.js +27 -0
- package/dist/core/middleware/built-in/validation/middleware.js.map +1 -0
- package/dist/core/middleware/index.d.ts +4 -4
- package/dist/core/middleware/index.js +14 -28
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/core/modules/auto-discovery.d.ts +19 -2
- package/dist/core/modules/auto-discovery.js +391 -74
- package/dist/core/modules/auto-discovery.js.map +1 -1
- package/dist/core/modules/index.d.ts +2 -2
- package/dist/core/modules/index.js +2 -9
- package/dist/core/modules/index.js.map +1 -1
- package/dist/core/modules/modules.d.ts +3 -3
- package/dist/core/modules/modules.js +23 -54
- package/dist/core/modules/modules.js.map +1 -1
- package/dist/core/networking/adapters/index.d.ts +4 -3
- package/dist/core/networking/adapters/index.js +3 -7
- package/dist/core/networking/adapters/index.js.map +1 -1
- package/dist/core/networking/adapters/socketio-adapter.d.ts +1 -1
- package/dist/core/networking/adapters/socketio-adapter.js +5 -40
- package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
- package/dist/core/networking/adapters/uws-adapter.d.ts +44 -0
- package/dist/core/networking/adapters/uws-adapter.js +513 -0
- package/dist/core/networking/adapters/uws-adapter.js.map +1 -0
- package/dist/core/networking/adapters/ws-adapter.d.ts +2 -2
- package/dist/core/networking/adapters/ws-adapter.js +8 -43
- package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
- package/dist/core/networking/index.d.ts +3 -2
- package/dist/core/networking/index.js +2 -7
- package/dist/core/networking/index.js.map +1 -1
- package/dist/core/networking/service-discovery.js +8 -12
- package/dist/core/networking/service-discovery.js.map +1 -1
- package/dist/core/networking/websocket-adapter.js +1 -2
- package/dist/core/networking/websocket-adapter.js.map +1 -1
- package/dist/core/networking/websocket-manager.d.ts +3 -3
- package/dist/core/networking/websocket-manager.js +9 -11
- package/dist/core/networking/websocket-manager.js.map +1 -1
- package/dist/core/pooling/object-pool-manager.d.ts +140 -0
- package/dist/core/pooling/object-pool-manager.js +502 -0
- package/dist/core/pooling/object-pool-manager.js.map +1 -0
- package/dist/core/routing/app-integration.d.ts +14 -12
- package/dist/core/routing/app-integration.js +49 -85
- package/dist/core/routing/app-integration.js.map +1 -1
- package/dist/core/routing/index.d.ts +17 -11
- package/dist/core/routing/index.js +48 -237
- package/dist/core/routing/index.js.map +1 -1
- package/dist/core/routing/path-matcher.d.ts +67 -0
- package/dist/core/routing/path-matcher.js +182 -0
- package/dist/core/routing/path-matcher.js.map +1 -0
- package/dist/core/routing/router.d.ts +38 -0
- package/dist/core/routing/router.js +68 -0
- package/dist/core/routing/router.js.map +1 -0
- package/dist/core/routing/unified-router.d.ts +132 -0
- package/dist/core/routing/unified-router.js +639 -0
- package/dist/core/routing/unified-router.js.map +1 -0
- package/dist/core/runtime/aws-lambda-adapter.d.ts +3 -3
- package/dist/core/runtime/aws-lambda-adapter.js +2 -6
- package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
- package/dist/core/runtime/base-adapter.d.ts +2 -2
- package/dist/core/runtime/base-adapter.js +3 -7
- package/dist/core/runtime/base-adapter.js.map +1 -1
- package/dist/core/runtime/cloudflare-workers-adapter.d.ts +3 -3
- package/dist/core/runtime/cloudflare-workers-adapter.js +2 -6
- package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
- package/dist/core/runtime/index.d.ts +12 -12
- package/dist/core/runtime/index.js +22 -35
- package/dist/core/runtime/index.js.map +1 -1
- package/dist/core/runtime/node-adapter.d.ts +4 -4
- package/dist/core/runtime/node-adapter.js +18 -49
- package/dist/core/runtime/node-adapter.js.map +1 -1
- package/dist/core/runtime/vercel-edge-adapter.d.ts +3 -3
- package/dist/core/runtime/vercel-edge-adapter.js +2 -6
- package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
- package/dist/core/utilities/circuit-breaker.js +1 -5
- package/dist/core/utilities/circuit-breaker.js.map +1 -1
- package/dist/core/utilities/container.js +12 -22
- package/dist/core/utilities/container.js.map +1 -1
- package/dist/core/utilities/hooks.d.ts +2 -2
- package/dist/core/utilities/hooks.js +7 -12
- package/dist/core/utilities/hooks.js.map +1 -1
- package/dist/core/utilities/index.d.ts +5 -4
- package/dist/core/utilities/index.js +5 -19
- package/dist/core/utilities/index.js.map +1 -1
- package/dist/core/utilities/package-utils.d.ts +38 -0
- package/dist/core/utilities/package-utils.js +57 -0
- package/dist/core/utilities/package-utils.js.map +1 -0
- package/dist/core/validation/adapters.d.ts +1 -1
- package/dist/core/validation/adapters.js +15 -26
- package/dist/core/validation/adapters.js.map +1 -1
- package/dist/core/validation/index.d.ts +6 -4
- package/dist/core/validation/index.js +57 -28
- package/dist/core/validation/index.js.map +1 -1
- package/dist/core/validation/schema-interface.js +3 -9
- package/dist/core/validation/schema-interface.js.map +1 -1
- package/dist/index.d.ts +52 -52
- package/dist/index.js +24 -132
- package/dist/index.js.map +1 -1
- package/dist/moro.d.ts +70 -16
- package/dist/moro.js +650 -269
- package/dist/moro.js.map +1 -1
- package/dist/types/auth.js +3 -9
- package/dist/types/auth.js.map +1 -1
- package/dist/types/cache.js +1 -2
- package/dist/types/cdn.js +1 -2
- package/dist/types/config.d.ts +73 -2
- package/dist/types/config.js +1 -2
- package/dist/types/config.js.map +1 -1
- package/dist/types/core.d.ts +36 -42
- package/dist/types/core.js +1 -2
- package/dist/types/database.js +1 -2
- package/dist/types/discovery.js +1 -2
- package/dist/types/events.js +1 -2
- package/dist/types/hooks.d.ts +4 -1
- package/dist/types/hooks.js +1 -2
- package/dist/types/http.d.ts +16 -1
- package/dist/types/http.js +1 -2
- package/dist/types/logger.d.ts +7 -0
- package/dist/types/logger.js +1 -2
- package/dist/types/module.d.ts +11 -0
- package/dist/types/module.js +1 -2
- package/dist/types/runtime.d.ts +1 -1
- package/dist/types/runtime.js +1 -2
- package/dist/types/session.js +1 -2
- package/package.json +18 -55
- package/dist/core/config/loader.d.ts +0 -7
- package/dist/core/config/loader.js +0 -269
- package/dist/core/config/loader.js.map +0 -1
- package/dist/core/config/validation.d.ts +0 -17
- package/dist/core/config/validation.js +0 -131
- package/dist/core/config/validation.js.map +0 -1
- package/dist/core/http/router.d.ts +0 -14
- package/dist/core/http/router.js +0 -109
- package/dist/core/http/router.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cache/file.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cache/index.d.ts +0 -5
- package/dist/core/middleware/built-in/adapters/cache/index.js +0 -28
- package/dist/core/middleware/built-in/adapters/cache/index.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cache/memory.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cache/redis.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +0 -5
- package/dist/core/middleware/built-in/adapters/cdn/index.js +0 -28
- package/dist/core/middleware/built-in/adapters/cdn/index.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/index.d.ts +0 -4
- package/dist/core/middleware/built-in/adapters/index.js +0 -26
- package/dist/core/middleware/built-in/adapters/index.js.map +0 -1
- package/dist/core/middleware/built-in/auth-helpers.js.map +0 -1
- package/dist/core/middleware/built-in/auth-providers.js.map +0 -1
- package/dist/core/middleware/built-in/auth.d.ts +0 -30
- package/dist/core/middleware/built-in/auth.js +0 -281
- package/dist/core/middleware/built-in/auth.js.map +0 -1
- package/dist/core/middleware/built-in/cache.d.ts +0 -3
- package/dist/core/middleware/built-in/cache.js.map +0 -1
- package/dist/core/middleware/built-in/cdn.d.ts +0 -3
- package/dist/core/middleware/built-in/cdn.js +0 -113
- package/dist/core/middleware/built-in/cdn.js.map +0 -1
- package/dist/core/middleware/built-in/cookie.d.ts +0 -14
- package/dist/core/middleware/built-in/cookie.js +0 -68
- package/dist/core/middleware/built-in/cookie.js.map +0 -1
- package/dist/core/middleware/built-in/cors.d.ts +0 -2
- package/dist/core/middleware/built-in/cors.js +0 -29
- package/dist/core/middleware/built-in/cors.js.map +0 -1
- package/dist/core/middleware/built-in/csp.d.ts +0 -22
- package/dist/core/middleware/built-in/csp.js +0 -71
- package/dist/core/middleware/built-in/csp.js.map +0 -1
- package/dist/core/middleware/built-in/csrf.d.ts +0 -9
- package/dist/core/middleware/built-in/csrf.js +0 -63
- package/dist/core/middleware/built-in/csrf.js.map +0 -1
- package/dist/core/middleware/built-in/error-tracker.d.ts +0 -1
- package/dist/core/middleware/built-in/error-tracker.js +0 -19
- package/dist/core/middleware/built-in/error-tracker.js.map +0 -1
- package/dist/core/middleware/built-in/performance-monitor.d.ts +0 -1
- package/dist/core/middleware/built-in/performance-monitor.js +0 -22
- package/dist/core/middleware/built-in/performance-monitor.js.map +0 -1
- package/dist/core/middleware/built-in/rate-limit.d.ts +0 -6
- package/dist/core/middleware/built-in/rate-limit.js.map +0 -1
- package/dist/core/middleware/built-in/request-logger.d.ts +0 -1
- package/dist/core/middleware/built-in/request-logger.js +0 -16
- package/dist/core/middleware/built-in/request-logger.js.map +0 -1
- package/dist/core/middleware/built-in/session.d.ts +0 -41
- package/dist/core/middleware/built-in/session.js +0 -209
- package/dist/core/middleware/built-in/session.js.map +0 -1
- package/dist/core/middleware/built-in/sse.d.ts +0 -6
- package/dist/core/middleware/built-in/sse.js +0 -71
- package/dist/core/middleware/built-in/sse.js.map +0 -1
- package/dist/core/middleware/built-in/validation.d.ts +0 -2
- package/dist/core/middleware/built-in/validation.js.map +0 -1
- package/src/core/auth/README.md +0 -339
- package/src/core/auth/morojs-adapter.ts +0 -410
- package/src/core/config/file-loader.ts +0 -407
- package/src/core/config/index.ts +0 -60
- package/src/core/config/loader.ts +0 -633
- package/src/core/config/schema.ts +0 -150
- package/src/core/config/utils.ts +0 -251
- package/src/core/config/validation.ts +0 -140
- package/src/core/database/README.md +0 -228
- package/src/core/database/adapters/drizzle.ts +0 -403
- package/src/core/database/adapters/index.ts +0 -42
- package/src/core/database/adapters/mongodb.ts +0 -269
- package/src/core/database/adapters/mysql.ts +0 -207
- package/src/core/database/adapters/postgresql.ts +0 -201
- package/src/core/database/adapters/redis.ts +0 -326
- package/src/core/database/adapters/sqlite.ts +0 -247
- package/src/core/database/index.ts +0 -3
- package/src/core/docs/index.ts +0 -231
- package/src/core/docs/openapi-generator.ts +0 -576
- package/src/core/docs/schema-to-openapi.ts +0 -148
- package/src/core/docs/simple-docs.ts +0 -295
- package/src/core/docs/swagger-ui.ts +0 -351
- package/src/core/docs/zod-to-openapi.ts +0 -532
- package/src/core/events/event-bus.ts +0 -231
- package/src/core/events/index.ts +0 -12
- package/src/core/framework.ts +0 -636
- package/src/core/http/http-server.ts +0 -1787
- package/src/core/http/index.ts +0 -6
- package/src/core/http/router.ts +0 -141
- package/src/core/logger/filters.ts +0 -145
- package/src/core/logger/index.ts +0 -20
- package/src/core/logger/logger.ts +0 -814
- package/src/core/logger/outputs.ts +0 -134
- package/src/core/middleware/built-in/adapters/cache/file.ts +0 -104
- package/src/core/middleware/built-in/adapters/cache/index.ts +0 -23
- package/src/core/middleware/built-in/adapters/cache/memory.ts +0 -73
- package/src/core/middleware/built-in/adapters/cache/redis.ts +0 -100
- package/src/core/middleware/built-in/adapters/cdn/azure.ts +0 -60
- package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +0 -83
- package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +0 -83
- package/src/core/middleware/built-in/adapters/cdn/index.ts +0 -23
- package/src/core/middleware/built-in/adapters/index.ts +0 -7
- package/src/core/middleware/built-in/auth-helpers.ts +0 -401
- package/src/core/middleware/built-in/auth-providers.ts +0 -480
- package/src/core/middleware/built-in/auth.ts +0 -329
- package/src/core/middleware/built-in/cache.ts +0 -211
- package/src/core/middleware/built-in/cdn.ts +0 -124
- package/src/core/middleware/built-in/cookie.ts +0 -85
- package/src/core/middleware/built-in/cors.ts +0 -38
- package/src/core/middleware/built-in/csp.ts +0 -101
- package/src/core/middleware/built-in/csrf.ts +0 -82
- package/src/core/middleware/built-in/error-tracker.ts +0 -16
- package/src/core/middleware/built-in/index.ts +0 -79
- package/src/core/middleware/built-in/performance-monitor.ts +0 -25
- package/src/core/middleware/built-in/rate-limit.ts +0 -60
- package/src/core/middleware/built-in/request-logger.ts +0 -14
- package/src/core/middleware/built-in/session.ts +0 -288
- package/src/core/middleware/built-in/sse.ts +0 -86
- package/src/core/middleware/built-in/validation.ts +0 -33
- package/src/core/middleware/index.ts +0 -177
- package/src/core/modules/auto-discovery.ts +0 -263
- package/src/core/modules/index.ts +0 -3
- package/src/core/modules/modules.ts +0 -124
- package/src/core/networking/adapters/index.ts +0 -16
- package/src/core/networking/adapters/socketio-adapter.ts +0 -252
- package/src/core/networking/adapters/ws-adapter.ts +0 -430
- package/src/core/networking/index.ts +0 -3
- package/src/core/networking/service-discovery.ts +0 -304
- package/src/core/networking/websocket-adapter.ts +0 -217
- package/src/core/networking/websocket-manager.ts +0 -308
- package/src/core/routing/app-integration.ts +0 -216
- package/src/core/routing/index.ts +0 -488
- package/src/core/runtime/aws-lambda-adapter.ts +0 -147
- package/src/core/runtime/base-adapter.ts +0 -130
- package/src/core/runtime/cloudflare-workers-adapter.ts +0 -152
- package/src/core/runtime/index.ts +0 -62
- package/src/core/runtime/node-adapter.ts +0 -196
- package/src/core/runtime/vercel-edge-adapter.ts +0 -114
- package/src/core/utilities/circuit-breaker.ts +0 -46
- package/src/core/utilities/container.ts +0 -736
- package/src/core/utilities/hooks.ts +0 -142
- package/src/core/utilities/index.ts +0 -16
- package/src/core/validation/adapters.ts +0 -147
- package/src/core/validation/index.ts +0 -206
- package/src/core/validation/schema-interface.ts +0 -100
- package/src/index.ts +0 -226
- package/src/moro.ts +0 -1197
- package/src/types/auth.ts +0 -440
- package/src/types/cache.ts +0 -38
- package/src/types/cdn.ts +0 -22
- package/src/types/config.ts +0 -157
- package/src/types/core.ts +0 -56
- package/src/types/database.ts +0 -32
- package/src/types/discovery.ts +0 -7
- package/src/types/events.ts +0 -82
- package/src/types/hooks.ts +0 -47
- package/src/types/http.ts +0 -67
- package/src/types/logger.ts +0 -93
- package/src/types/module.ts +0 -87
- package/src/types/runtime.ts +0 -76
- package/src/types/session.ts +0 -89
- package/tsconfig.json +0 -21
- /package/dist/core/middleware/built-in/{auth-helpers.d.ts → auth/helpers.d.ts} +0 -0
package/dist/moro.js
CHANGED
|
@@ -1,154 +1,99 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.Moro = void 0;
|
|
37
|
-
exports.createApp = createApp;
|
|
38
|
-
exports.createAppNode = createAppNode;
|
|
39
|
-
exports.createAppEdge = createAppEdge;
|
|
40
|
-
exports.createAppLambda = createAppLambda;
|
|
41
|
-
exports.createAppWorker = createAppWorker;
|
|
42
1
|
// Moro Framework - Modern TypeScript API Framework
|
|
43
2
|
// Built for developers who demand performance, elegance, and zero compromises
|
|
44
3
|
// Event-driven • Modular • Enterprise-ready • Developer-first
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
4
|
+
import { Moro as MoroCore } from './core/framework.js';
|
|
5
|
+
import { middleware } from './core/http/index.js';
|
|
6
|
+
import { createFrameworkLogger, applyLoggingConfiguration } from './core/logger/index.js';
|
|
7
|
+
import { MiddlewareManager } from './core/middleware/index.js';
|
|
8
|
+
import { IntelligentRoutingManager } from './core/routing/app-integration.js';
|
|
9
|
+
import { UnifiedRouter, } from './core/routing/unified-router.js';
|
|
10
|
+
import { AppDocumentationManager } from './core/docs/index.js';
|
|
11
|
+
import { EventEmitter } from 'events';
|
|
12
|
+
import cluster from 'cluster';
|
|
13
|
+
import os from 'os';
|
|
14
|
+
import { normalizeValidationError } from './core/validation/schema-interface.js';
|
|
54
15
|
// Configuration System Integration
|
|
55
|
-
|
|
16
|
+
import { initializeConfig } from './core/config/index.js';
|
|
56
17
|
// Runtime System Integration
|
|
57
|
-
|
|
58
|
-
class Moro extends
|
|
18
|
+
import { createRuntimeAdapter } from './core/runtime/index.js';
|
|
19
|
+
export class Moro extends EventEmitter {
|
|
59
20
|
coreFramework;
|
|
60
21
|
routes = [];
|
|
61
22
|
moduleCounter = 0;
|
|
62
23
|
loadedModules = new Set();
|
|
24
|
+
lazyModules = new Map();
|
|
63
25
|
routeHandlers = {};
|
|
26
|
+
moduleDiscovery; // Store for cleanup
|
|
27
|
+
autoDiscoveryOptions = null;
|
|
28
|
+
autoDiscoveryInitialized = false;
|
|
29
|
+
autoDiscoveryPromise = null;
|
|
64
30
|
// Enterprise event system integration
|
|
65
31
|
eventBus;
|
|
66
32
|
// Application logger
|
|
67
|
-
logger
|
|
68
|
-
//
|
|
69
|
-
|
|
33
|
+
logger;
|
|
34
|
+
// Unified routing system (singleton - shared across all routers)
|
|
35
|
+
unifiedRouter;
|
|
36
|
+
// Legacy intelligent routing (kept for backward compatibility, now a facade)
|
|
37
|
+
intelligentRouting;
|
|
70
38
|
// Documentation system
|
|
71
|
-
documentation = new
|
|
39
|
+
documentation = new AppDocumentationManager();
|
|
72
40
|
// Configuration system
|
|
73
41
|
config;
|
|
42
|
+
// Track if user explicitly set logger options (for worker log level handling)
|
|
43
|
+
userSetLogger = false;
|
|
74
44
|
// Runtime system
|
|
75
45
|
runtimeAdapter;
|
|
76
46
|
runtimeType;
|
|
77
47
|
// Middleware system
|
|
78
48
|
middlewareManager;
|
|
49
|
+
// Queued WebSocket registrations (for async adapter detection)
|
|
50
|
+
queuedWebSocketRegistrations = [];
|
|
79
51
|
constructor(options = {}) {
|
|
80
52
|
super(); // Call EventEmitter constructor
|
|
81
|
-
//
|
|
82
|
-
|
|
53
|
+
// Track if user explicitly set logger/logging options
|
|
54
|
+
this.userSetLogger = !!(options.logger || options.logging);
|
|
55
|
+
// Apply logging configuration BEFORE config loading to avoid DEBUG spam
|
|
56
|
+
// 1. Environment variables (base level)
|
|
83
57
|
const envLogLevel = process.env.LOG_LEVEL || process.env.MORO_LOG_LEVEL;
|
|
84
58
|
if (envLogLevel) {
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
// Initialize configuration system - create a deep copy for this instance
|
|
88
|
-
this.config = JSON.parse(JSON.stringify((0, config_1.initializeConfig)()));
|
|
89
|
-
// Apply logging configuration from the loaded config (this happens after config file processing)
|
|
90
|
-
if (this.config.logging) {
|
|
91
|
-
(0, logger_1.applyLoggingConfiguration)(this.config.logging, undefined);
|
|
59
|
+
applyLoggingConfiguration({ level: envLogLevel }, undefined);
|
|
92
60
|
}
|
|
93
|
-
//
|
|
61
|
+
// 2. createApp logger options (highest precedence)
|
|
94
62
|
if (options.logger !== undefined) {
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
// Apply performance configuration from createApp options (takes precedence)
|
|
98
|
-
if (options.performance) {
|
|
99
|
-
if (options.performance.clustering) {
|
|
100
|
-
this.config.performance.clustering = {
|
|
101
|
-
...this.config.performance.clustering,
|
|
102
|
-
...options.performance.clustering,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
if (options.performance.compression) {
|
|
106
|
-
this.config.performance.compression = {
|
|
107
|
-
...this.config.performance.compression,
|
|
108
|
-
...options.performance.compression,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
if (options.performance.circuitBreaker) {
|
|
112
|
-
this.config.performance.circuitBreaker = {
|
|
113
|
-
...this.config.performance.circuitBreaker,
|
|
114
|
-
...options.performance.circuitBreaker,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
63
|
+
applyLoggingConfiguration(undefined, options.logger);
|
|
117
64
|
}
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
...this.config.modules.rateLimit,
|
|
129
|
-
...options.modules.rateLimit,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
if (options.modules.validation) {
|
|
133
|
-
this.config.modules.validation = {
|
|
134
|
-
...this.config.modules.validation,
|
|
135
|
-
...options.modules.validation,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
65
|
+
// Create logger AFTER initial configuration
|
|
66
|
+
this.logger = createFrameworkLogger('App');
|
|
67
|
+
// Use simplified global configuration system
|
|
68
|
+
this.config = initializeConfig(options);
|
|
69
|
+
// Apply final config logging (this includes normalized logger → logging conversion)
|
|
70
|
+
// Always apply this as it's the authoritative merged config
|
|
71
|
+
if (this.config.logging) {
|
|
72
|
+
applyLoggingConfiguration(this.config.logging, undefined);
|
|
73
|
+
// Recreate logger with updated config
|
|
74
|
+
this.logger = createFrameworkLogger('App');
|
|
138
75
|
}
|
|
139
|
-
|
|
76
|
+
// NOW initialize routing systems AFTER logger is configured
|
|
77
|
+
this.unifiedRouter = UnifiedRouter.getInstance();
|
|
78
|
+
this.intelligentRouting = new IntelligentRoutingManager();
|
|
79
|
+
this.logger.info(`Configuration system initialized: ${process.env.NODE_ENV || 'development'}:${this.config.server.port}`);
|
|
140
80
|
// Initialize runtime system
|
|
141
81
|
this.runtimeType = options.runtime?.type || 'node';
|
|
142
|
-
this.runtimeAdapter = options.runtime?.adapter ||
|
|
82
|
+
this.runtimeAdapter = options.runtime?.adapter || createRuntimeAdapter(this.runtimeType);
|
|
143
83
|
this.logger.info(`Runtime system initialized: ${this.runtimeType}`, 'Runtime');
|
|
144
|
-
// Pass
|
|
84
|
+
// Pass configuration from config to framework
|
|
145
85
|
const frameworkOptions = {
|
|
146
86
|
...options,
|
|
147
87
|
logger: this.config.logging,
|
|
88
|
+
// Enable websockets if either config has it enabled OR user passed websocket options
|
|
89
|
+
websocket: this.config.websocket.enabled || options.websocket
|
|
90
|
+
? options.websocket || this.config.websocket || {}
|
|
91
|
+
: false,
|
|
92
|
+
config: this.config,
|
|
148
93
|
};
|
|
149
|
-
this.coreFramework = new
|
|
94
|
+
this.coreFramework = new MoroCore(frameworkOptions);
|
|
150
95
|
// Initialize middleware system
|
|
151
|
-
this.middlewareManager = new
|
|
96
|
+
this.middlewareManager = new MiddlewareManager();
|
|
152
97
|
// Integrate hooks system with HTTP server
|
|
153
98
|
const httpServer = this.coreFramework.httpServer;
|
|
154
99
|
if (httpServer && httpServer.setHookManager) {
|
|
@@ -169,10 +114,10 @@ class Moro extends events_1.EventEmitter {
|
|
|
169
114
|
...this.getDefaultOptionsFromConfig(),
|
|
170
115
|
...options,
|
|
171
116
|
});
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
117
|
+
// Store auto-discovery options for later initialization
|
|
118
|
+
// IMPORTANT: Auto-discovery is deferred to ensure user middleware (like auth)
|
|
119
|
+
// is registered before module middleware that might bypass it
|
|
120
|
+
this.autoDiscoveryOptions = options.autoDiscover !== false ? options : null;
|
|
176
121
|
// Emit initialization event through enterprise event bus
|
|
177
122
|
this.eventBus.emit('framework:initialized', {
|
|
178
123
|
options,
|
|
@@ -213,44 +158,45 @@ class Moro extends events_1.EventEmitter {
|
|
|
213
158
|
// Direct route registration
|
|
214
159
|
return this.addRoute('GET', path, handler, options);
|
|
215
160
|
}
|
|
216
|
-
//
|
|
217
|
-
return this.
|
|
161
|
+
// Use unified router for chainable API
|
|
162
|
+
return this.unifiedRouter.get(path);
|
|
218
163
|
}
|
|
219
164
|
post(path, handler, options) {
|
|
220
165
|
if (handler) {
|
|
221
166
|
// Direct route registration
|
|
222
167
|
return this.addRoute('POST', path, handler, options);
|
|
223
168
|
}
|
|
224
|
-
//
|
|
225
|
-
return this.
|
|
169
|
+
// Use unified router for chainable API
|
|
170
|
+
return this.unifiedRouter.post(path);
|
|
226
171
|
}
|
|
227
172
|
put(path, handler, options) {
|
|
228
173
|
if (handler) {
|
|
229
174
|
// Direct route registration
|
|
230
175
|
return this.addRoute('PUT', path, handler, options);
|
|
231
176
|
}
|
|
232
|
-
//
|
|
233
|
-
return this.
|
|
177
|
+
// Use unified router for chainable API
|
|
178
|
+
return this.unifiedRouter.put(path);
|
|
234
179
|
}
|
|
235
180
|
delete(path, handler, options) {
|
|
236
181
|
if (handler) {
|
|
237
182
|
// Direct route registration
|
|
238
183
|
return this.addRoute('DELETE', path, handler, options);
|
|
239
184
|
}
|
|
240
|
-
//
|
|
241
|
-
return this.
|
|
185
|
+
// Use unified router for chainable API
|
|
186
|
+
return this.unifiedRouter.delete(path);
|
|
242
187
|
}
|
|
243
188
|
patch(path, handler, options) {
|
|
244
189
|
if (handler) {
|
|
245
190
|
// Direct route registration
|
|
246
191
|
return this.addRoute('PATCH', path, handler, options);
|
|
247
192
|
}
|
|
248
|
-
//
|
|
249
|
-
return this.
|
|
193
|
+
// Use unified router for chainable API
|
|
194
|
+
return this.unifiedRouter.patch(path);
|
|
250
195
|
}
|
|
251
196
|
// Schema-first route method
|
|
252
197
|
route(schema) {
|
|
253
|
-
|
|
198
|
+
// Use unified router for schema-first registration
|
|
199
|
+
this.unifiedRouter.route(schema);
|
|
254
200
|
}
|
|
255
201
|
// Enable automatic API documentation
|
|
256
202
|
enableDocs(config) {
|
|
@@ -338,6 +284,11 @@ class Moro extends events_1.EventEmitter {
|
|
|
338
284
|
version: moduleOrPath.version || '1.0.0',
|
|
339
285
|
});
|
|
340
286
|
}
|
|
287
|
+
// IMPORTANT: If modules are loaded manually after auto-discovery,
|
|
288
|
+
// ensure the final module handler is set up to maintain middleware order
|
|
289
|
+
if (this.autoDiscoveryInitialized) {
|
|
290
|
+
this.coreFramework.setupFinalModuleHandler();
|
|
291
|
+
}
|
|
341
292
|
return this;
|
|
342
293
|
}
|
|
343
294
|
// Database helper with events
|
|
@@ -351,29 +302,36 @@ class Moro extends events_1.EventEmitter {
|
|
|
351
302
|
}
|
|
352
303
|
// WebSocket helper with events
|
|
353
304
|
websocket(namespace, handlers) {
|
|
305
|
+
// Queue the registration to be processed after adapter initialization
|
|
306
|
+
const registration = { namespace, handlers, processed: false };
|
|
307
|
+
this.queuedWebSocketRegistrations.push(registration);
|
|
308
|
+
// Try to process immediately if adapter is already ready
|
|
354
309
|
const adapter = this.coreFramework.getWebSocketAdapter();
|
|
355
|
-
if (!
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
'new Moro({ websocket: { adapter: new SocketIOAdapter() } })');
|
|
310
|
+
if (adapter && !registration.processed) {
|
|
311
|
+
// Adapter is ready, process immediately
|
|
312
|
+
this.processWebSocketRegistration(namespace, handlers, adapter);
|
|
313
|
+
registration.processed = true;
|
|
360
314
|
}
|
|
315
|
+
// Otherwise, it will be processed when the server starts
|
|
316
|
+
return this;
|
|
317
|
+
}
|
|
318
|
+
processWebSocketRegistration(namespace, handlers, adapter) {
|
|
361
319
|
this.emit('websocket:registering', { namespace, handlers });
|
|
362
320
|
const ns = adapter.createNamespace(namespace);
|
|
363
321
|
Object.entries(handlers).forEach(([event, handler]) => {
|
|
364
|
-
ns.on('connection', socket => {
|
|
322
|
+
ns.on('connection', (socket) => {
|
|
365
323
|
this.emit('websocket:connection', { namespace, event, socket });
|
|
366
324
|
socket.on(event, (data, callback) => {
|
|
367
325
|
this.emit('websocket:event', { namespace, event, data });
|
|
368
326
|
Promise.resolve(handler(socket, data))
|
|
369
|
-
.then(result => {
|
|
327
|
+
.then((result) => {
|
|
370
328
|
this.emit('websocket:response', { namespace, event, result });
|
|
371
329
|
if (callback)
|
|
372
330
|
callback(result);
|
|
373
331
|
else if (result)
|
|
374
332
|
socket.emit(`${event}:response`, result);
|
|
375
333
|
})
|
|
376
|
-
.catch(error => {
|
|
334
|
+
.catch((error) => {
|
|
377
335
|
this.emit('websocket:error', { namespace, event, error });
|
|
378
336
|
const errorResponse = { success: false, error: error.message };
|
|
379
337
|
if (callback)
|
|
@@ -385,7 +343,33 @@ class Moro extends events_1.EventEmitter {
|
|
|
385
343
|
});
|
|
386
344
|
});
|
|
387
345
|
this.emit('websocket:registered', { namespace, handlers });
|
|
388
|
-
|
|
346
|
+
}
|
|
347
|
+
async processQueuedWebSocketRegistrations() {
|
|
348
|
+
// Wait for WebSocket adapter to be ready
|
|
349
|
+
await this.coreFramework.ensureWebSocketReady();
|
|
350
|
+
const adapter = this.coreFramework.getWebSocketAdapter();
|
|
351
|
+
// Check if any unprocessed registrations exist
|
|
352
|
+
const unprocessedRegistrations = this.queuedWebSocketRegistrations.filter(r => !r.processed);
|
|
353
|
+
if (!adapter && unprocessedRegistrations.length > 0) {
|
|
354
|
+
throw new Error('WebSocket features require a WebSocket adapter.\n\n' +
|
|
355
|
+
'Option 1: Install socket.io (auto-detected):\n' +
|
|
356
|
+
' npm install socket.io\n' +
|
|
357
|
+
' const app = new Moro({ websocket: {} });\n\n' +
|
|
358
|
+
'Option 2: Configure a specific adapter:\n' +
|
|
359
|
+
" import { SocketIOAdapter } from '@morojs/moro';\n" +
|
|
360
|
+
' const app = new Moro({ websocket: { adapter: new SocketIOAdapter() } });\n\n' +
|
|
361
|
+
'Option 3: Enable in config file (moro.config.js):\n' +
|
|
362
|
+
' export default { websocket: { enabled: true } };');
|
|
363
|
+
}
|
|
364
|
+
if (adapter) {
|
|
365
|
+
// Process all unprocessed registrations
|
|
366
|
+
for (const registration of this.queuedWebSocketRegistrations) {
|
|
367
|
+
if (!registration.processed) {
|
|
368
|
+
this.processWebSocketRegistration(registration.namespace, registration.handlers, adapter);
|
|
369
|
+
registration.processed = true;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
389
373
|
}
|
|
390
374
|
listen(portOrCallback, hostOrCallback, callback) {
|
|
391
375
|
// Only available for Node.js runtime
|
|
@@ -427,9 +411,18 @@ class Moro extends events_1.EventEmitter {
|
|
|
427
411
|
throw new Error('Port not specified and not found in configuration. Please provide a port number or configure it in moro.config.js/ts');
|
|
428
412
|
}
|
|
429
413
|
// Check if clustering is enabled for massive performance gains
|
|
414
|
+
// NOTE: uWebSockets.js does NOT support Node.js clustering - it's single-threaded only
|
|
415
|
+
const usingUWebSockets = this.config.server?.useUWebSockets || false;
|
|
430
416
|
if (this.config.performance?.clustering?.enabled) {
|
|
431
|
-
|
|
432
|
-
|
|
417
|
+
if (usingUWebSockets) {
|
|
418
|
+
this.logger.warn('Clustering is not supported with uWebSockets.js - running in single-threaded mode. ' +
|
|
419
|
+
'uWebSockets is so fast that single-threaded performance often exceeds multi-threaded Node.js!', 'Cluster');
|
|
420
|
+
// Continue without clustering
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
this.startWithClustering(port, host, callback);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
433
426
|
}
|
|
434
427
|
this.eventBus.emit('server:starting', { port, runtime: this.runtimeType });
|
|
435
428
|
// Add documentation middleware first (if enabled)
|
|
@@ -442,44 +435,165 @@ class Moro extends events_1.EventEmitter {
|
|
|
442
435
|
// Documentation not enabled, that's fine
|
|
443
436
|
this.logger.debug('Documentation not enabled', 'Documentation');
|
|
444
437
|
}
|
|
445
|
-
// Add
|
|
438
|
+
// Add unified routing middleware (handles both chainable and direct routes)
|
|
439
|
+
// Optimized: call router without extra async wrapper when possible
|
|
446
440
|
this.coreFramework.addMiddleware(async (req, res, next) => {
|
|
447
|
-
// Try
|
|
448
|
-
const handled =
|
|
449
|
-
if (
|
|
450
|
-
|
|
441
|
+
// Try unified router first (handles all route types)
|
|
442
|
+
const handled = this.unifiedRouter.handleRequest(req, res);
|
|
443
|
+
// Check if it's a promise (async route) or sync (fast-path)
|
|
444
|
+
if (handled && typeof handled.then === 'function') {
|
|
445
|
+
// Async - await the result
|
|
446
|
+
const isHandled = await handled;
|
|
447
|
+
if (!isHandled) {
|
|
448
|
+
next();
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
// Sync - check immediately
|
|
453
|
+
if (!handled) {
|
|
454
|
+
next();
|
|
455
|
+
}
|
|
451
456
|
}
|
|
452
457
|
});
|
|
453
|
-
// Register direct routes with the HTTP server
|
|
458
|
+
// Register legacy direct routes with the HTTP server (for backward compatibility)
|
|
454
459
|
if (this.routes.length > 0) {
|
|
455
460
|
this.registerDirectRoutes();
|
|
456
461
|
}
|
|
457
|
-
const
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
this.
|
|
462
|
+
const startServer = () => {
|
|
463
|
+
const actualCallback = () => {
|
|
464
|
+
const displayHost = host || 'localhost';
|
|
465
|
+
this.logger.info('Moro Server Started', 'Server');
|
|
466
|
+
this.logger.info(`Runtime: ${this.runtimeType}`, 'Server');
|
|
467
|
+
this.logger.info(`HTTP API: http://${displayHost}:${port}`, 'Server');
|
|
468
|
+
if (this.config.websocket.enabled) {
|
|
469
|
+
this.logger.info(`WebSocket: ws://${displayHost}:${port}`, 'Server');
|
|
470
|
+
}
|
|
471
|
+
this.logger.info('Learn more at https://morojs.com', 'Server');
|
|
472
|
+
// Log unified router stats
|
|
473
|
+
const routeCount = this.unifiedRouter.getRouteCount();
|
|
474
|
+
if (routeCount > 0) {
|
|
475
|
+
this.logger.info(`Unified Router: ${routeCount} routes registered`, 'Server');
|
|
476
|
+
// Log performance stats
|
|
477
|
+
this.unifiedRouter.logPerformanceStats();
|
|
478
|
+
}
|
|
479
|
+
this.eventBus.emit('server:started', { port, runtime: this.runtimeType });
|
|
480
|
+
if (callback)
|
|
481
|
+
callback();
|
|
482
|
+
};
|
|
483
|
+
if (host && typeof host === 'string') {
|
|
484
|
+
this.coreFramework.listen(port, host, actualCallback);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
this.coreFramework.listen(port, actualCallback);
|
|
469
488
|
}
|
|
470
|
-
this.eventBus.emit('server:started', { port, runtime: this.runtimeType });
|
|
471
|
-
if (callback)
|
|
472
|
-
callback();
|
|
473
489
|
};
|
|
474
|
-
|
|
475
|
-
|
|
490
|
+
// Ensure auto-discovery and WebSocket setup is complete before starting server
|
|
491
|
+
Promise.all([this.ensureAutoDiscoveryComplete(), this.processQueuedWebSocketRegistrations()])
|
|
492
|
+
.then(() => {
|
|
493
|
+
startServer();
|
|
494
|
+
})
|
|
495
|
+
.catch(error => {
|
|
496
|
+
this.logger.error('Initialization failed during server start', 'Framework', {
|
|
497
|
+
error: error instanceof Error ? error.message : String(error),
|
|
498
|
+
});
|
|
499
|
+
// For auto-discovery failures, start server anyway
|
|
500
|
+
// For WebSocket failures with queued registrations, error will propagate
|
|
501
|
+
if (error instanceof Error &&
|
|
502
|
+
error.message.includes('WebSocket features require a WebSocket adapter')) {
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
startServer();
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
// Public method to manually initialize auto-discovery
|
|
509
|
+
// Useful for ensuring auth middleware is registered before auto-discovery
|
|
510
|
+
async initializeAutoDiscoveryNow() {
|
|
511
|
+
return this.ensureAutoDiscoveryComplete();
|
|
512
|
+
}
|
|
513
|
+
// Public API: Initialize modules explicitly after middleware setup
|
|
514
|
+
// This provides users with explicit control over module loading timing
|
|
515
|
+
// IMPORTANT: This forces module loading even if autoDiscovery.enabled is false
|
|
516
|
+
// Usage: app.initModules() or app.initModules({ paths: ['./my-modules'] })
|
|
517
|
+
initModules(options) {
|
|
518
|
+
this.logger.info('User-requested module initialization', 'ModuleSystem');
|
|
519
|
+
// If already initialized, do nothing
|
|
520
|
+
if (this.autoDiscoveryInitialized) {
|
|
521
|
+
this.logger.debug('Auto-discovery already completed, skipping', 'ModuleSystem');
|
|
522
|
+
return;
|
|
476
523
|
}
|
|
477
|
-
|
|
478
|
-
|
|
524
|
+
// Store the options and mark that we want to force initialization
|
|
525
|
+
this.autoDiscoveryOptions = {
|
|
526
|
+
autoDiscover: {
|
|
527
|
+
enabled: true, // Force enabled regardless of original config
|
|
528
|
+
paths: options?.paths || ['./modules', './src/modules'],
|
|
529
|
+
patterns: options?.patterns || [
|
|
530
|
+
'**/*.module.{ts,js}',
|
|
531
|
+
'**/index.{ts,js}',
|
|
532
|
+
'**/*.config.{ts,js}',
|
|
533
|
+
],
|
|
534
|
+
recursive: options?.recursive ?? true,
|
|
535
|
+
loadingStrategy: options?.loadingStrategy || 'eager',
|
|
536
|
+
watchForChanges: options?.watchForChanges ?? false,
|
|
537
|
+
ignorePatterns: options?.ignorePatterns || [
|
|
538
|
+
'**/*.test.{ts,js}',
|
|
539
|
+
'**/*.spec.{ts,js}',
|
|
540
|
+
'**/node_modules/**',
|
|
541
|
+
],
|
|
542
|
+
loadOrder: options?.loadOrder || 'dependency',
|
|
543
|
+
failOnError: options?.failOnError ?? false,
|
|
544
|
+
maxDepth: options?.maxDepth ?? 5,
|
|
545
|
+
},
|
|
546
|
+
};
|
|
547
|
+
this.logger.debug('Module initialization options stored, will execute on next listen/getHandler call', 'ModuleSystem');
|
|
548
|
+
}
|
|
549
|
+
// Robust method to ensure auto-discovery is complete, handling race conditions
|
|
550
|
+
async ensureAutoDiscoveryComplete() {
|
|
551
|
+
// If already initialized, nothing to do
|
|
552
|
+
if (this.autoDiscoveryInitialized) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
// If auto-discovery is disabled, mark as initialized
|
|
556
|
+
if (!this.autoDiscoveryOptions) {
|
|
557
|
+
this.autoDiscoveryInitialized = true;
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
// If already in progress, wait for it to complete
|
|
561
|
+
if (this.autoDiscoveryPromise) {
|
|
562
|
+
return this.autoDiscoveryPromise;
|
|
563
|
+
}
|
|
564
|
+
// Start auto-discovery
|
|
565
|
+
this.autoDiscoveryPromise = this.performAutoDiscovery();
|
|
566
|
+
try {
|
|
567
|
+
await this.autoDiscoveryPromise;
|
|
568
|
+
this.autoDiscoveryInitialized = true;
|
|
569
|
+
}
|
|
570
|
+
catch (error) {
|
|
571
|
+
// Reset promise on error so it can be retried
|
|
572
|
+
this.autoDiscoveryPromise = null;
|
|
573
|
+
throw error;
|
|
574
|
+
}
|
|
575
|
+
finally {
|
|
576
|
+
this.autoDiscoveryOptions = null; // Clear after attempt
|
|
479
577
|
}
|
|
480
578
|
}
|
|
579
|
+
// Perform the actual auto-discovery work
|
|
580
|
+
async performAutoDiscovery(optionsOverride) {
|
|
581
|
+
const optionsToUse = optionsOverride || this.autoDiscoveryOptions;
|
|
582
|
+
if (!optionsToUse)
|
|
583
|
+
return;
|
|
584
|
+
this.logger.debug('Starting auto-discovery initialization', 'AutoDiscovery');
|
|
585
|
+
await this.initializeAutoDiscovery(optionsToUse);
|
|
586
|
+
this.logger.debug('Auto-discovery initialization completed', 'AutoDiscovery');
|
|
587
|
+
}
|
|
481
588
|
// Get handler for non-Node.js runtimes
|
|
482
589
|
getHandler() {
|
|
590
|
+
// Ensure auto-discovery is complete for non-Node.js runtimes
|
|
591
|
+
// This handles the case where users call getHandler() immediately after createApp()
|
|
592
|
+
this.ensureAutoDiscoveryComplete().catch(error => {
|
|
593
|
+
this.logger.error('Auto-discovery initialization failed for runtime handler', 'Framework', {
|
|
594
|
+
error: error instanceof Error ? error.message : String(error),
|
|
595
|
+
});
|
|
596
|
+
});
|
|
483
597
|
// Create a unified request handler that works with the runtime adapter
|
|
484
598
|
const handler = async (req, res) => {
|
|
485
599
|
// Add documentation middleware first (if enabled)
|
|
@@ -492,11 +606,11 @@ class Moro extends events_1.EventEmitter {
|
|
|
492
606
|
catch (error) {
|
|
493
607
|
// Documentation not enabled, that's fine
|
|
494
608
|
}
|
|
495
|
-
// Try
|
|
496
|
-
const handled = await this.
|
|
609
|
+
// Try unified router first (handles all routes)
|
|
610
|
+
const handled = await this.unifiedRouter.handleRequest(req, res);
|
|
497
611
|
if (handled)
|
|
498
612
|
return;
|
|
499
|
-
// Handle direct routes
|
|
613
|
+
// Handle legacy direct routes (backward compatibility)
|
|
500
614
|
if (this.routes.length > 0) {
|
|
501
615
|
await this.handleDirectRoutes(req, res);
|
|
502
616
|
}
|
|
@@ -644,6 +758,9 @@ class Moro extends events_1.EventEmitter {
|
|
|
644
758
|
}
|
|
645
759
|
// Private methods
|
|
646
760
|
addRoute(method, path, handler, options = {}) {
|
|
761
|
+
// Register with unified router (primary routing system)
|
|
762
|
+
this.unifiedRouter.addRoute(method, path, handler, options.middleware || []);
|
|
763
|
+
// Also store in legacy routes array for backward compatibility
|
|
647
764
|
const handlerName = `handler_${this.routes.length}`;
|
|
648
765
|
const route = {
|
|
649
766
|
method: method,
|
|
@@ -655,9 +772,9 @@ class Moro extends events_1.EventEmitter {
|
|
|
655
772
|
middleware: options.middleware,
|
|
656
773
|
};
|
|
657
774
|
this.routes.push(route);
|
|
658
|
-
// Organize routes for optimal lookup
|
|
775
|
+
// Organize routes for optimal lookup (legacy)
|
|
659
776
|
this.organizeRouteForLookup(route);
|
|
660
|
-
// Store handler for later module creation
|
|
777
|
+
// Store handler for later module creation (legacy)
|
|
661
778
|
this.routeHandlers[handlerName] = handler;
|
|
662
779
|
return this;
|
|
663
780
|
}
|
|
@@ -697,7 +814,6 @@ class Moro extends events_1.EventEmitter {
|
|
|
697
814
|
}
|
|
698
815
|
catch (error) {
|
|
699
816
|
// Handle universal validation errors
|
|
700
|
-
const { normalizeValidationError } = require('./core/validation/schema-interface');
|
|
701
817
|
const normalizedError = normalizeValidationError(error);
|
|
702
818
|
res.status(400).json({
|
|
703
819
|
success: false,
|
|
@@ -767,91 +883,266 @@ class Moro extends events_1.EventEmitter {
|
|
|
767
883
|
return true;
|
|
768
884
|
}
|
|
769
885
|
setupDefaultMiddleware(options) {
|
|
770
|
-
// CORS
|
|
771
|
-
if (options.cors
|
|
772
|
-
const corsOptions = typeof options.cors === 'object'
|
|
773
|
-
|
|
886
|
+
// CORS - check config enabled property OR options.security.cors.enabled === true
|
|
887
|
+
if (this.config.security.cors.enabled || options.security?.cors?.enabled === true) {
|
|
888
|
+
const corsOptions = typeof options.cors === 'object'
|
|
889
|
+
? options.cors
|
|
890
|
+
: this.config.security.cors
|
|
891
|
+
? this.config.security.cors
|
|
892
|
+
: {};
|
|
893
|
+
this.use(middleware.cors(corsOptions));
|
|
774
894
|
}
|
|
775
|
-
// Helmet
|
|
776
|
-
if (options.helmet
|
|
777
|
-
this.use(
|
|
895
|
+
// Helmet - check config enabled property OR options.security.helmet.enabled === true
|
|
896
|
+
if (this.config.security.helmet.enabled || options.security?.helmet?.enabled === true) {
|
|
897
|
+
this.use(middleware.helmet());
|
|
778
898
|
}
|
|
779
|
-
// Compression
|
|
780
|
-
if (
|
|
781
|
-
|
|
782
|
-
|
|
899
|
+
// Compression - check config enabled property OR options.performance.compression.enabled === true
|
|
900
|
+
if (this.config.performance.compression.enabled ||
|
|
901
|
+
options.performance?.compression?.enabled === true) {
|
|
902
|
+
const compressionOptions = typeof options.compression === 'object'
|
|
903
|
+
? options.compression
|
|
904
|
+
: this.config.performance.compression
|
|
905
|
+
? this.config.performance.compression
|
|
906
|
+
: {};
|
|
907
|
+
this.use(middleware.compression(compressionOptions));
|
|
783
908
|
}
|
|
784
909
|
// Body size limiting
|
|
785
|
-
this.use(
|
|
910
|
+
this.use(middleware.bodySize({ limit: '10mb' }));
|
|
786
911
|
}
|
|
787
|
-
|
|
912
|
+
// Enhanced auto-discovery initialization
|
|
913
|
+
async initializeAutoDiscovery(options) {
|
|
914
|
+
const { ModuleDiscovery } = await import('./core/modules/auto-discovery.js');
|
|
915
|
+
// Merge auto-discovery configuration
|
|
916
|
+
const autoDiscoveryConfig = this.mergeAutoDiscoveryConfig(options);
|
|
917
|
+
if (!autoDiscoveryConfig.enabled) {
|
|
918
|
+
return;
|
|
919
|
+
}
|
|
920
|
+
this.moduleDiscovery = new ModuleDiscovery(process.cwd());
|
|
788
921
|
try {
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
922
|
+
// Discover modules based on configuration
|
|
923
|
+
const modules = await this.moduleDiscovery.discoverModulesAdvanced(autoDiscoveryConfig);
|
|
924
|
+
// Load modules based on strategy
|
|
925
|
+
await this.loadDiscoveredModules(modules, autoDiscoveryConfig);
|
|
926
|
+
// Setup final module handler to run after user middleware (like auth)
|
|
927
|
+
this.coreFramework.setupFinalModuleHandler();
|
|
928
|
+
// Setup file watching if enabled
|
|
929
|
+
if (autoDiscoveryConfig.watchForChanges) {
|
|
930
|
+
this.moduleDiscovery.watchModulesAdvanced(autoDiscoveryConfig, async (updatedModules) => {
|
|
931
|
+
await this.handleModuleChanges(updatedModules);
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
this.logger.info(`Auto-discovery completed: ${modules.length} modules loaded`, 'ModuleDiscovery');
|
|
935
|
+
}
|
|
936
|
+
catch (error) {
|
|
937
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
938
|
+
if (autoDiscoveryConfig.failOnError) {
|
|
939
|
+
throw new Error(`Module auto-discovery failed: ${errorMsg}`);
|
|
940
|
+
}
|
|
941
|
+
else {
|
|
942
|
+
this.logger.warn(`Module auto-discovery failed: ${errorMsg}`, 'ModuleDiscovery');
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
// Merge auto-discovery configuration from multiple sources
|
|
947
|
+
mergeAutoDiscoveryConfig(options) {
|
|
948
|
+
const defaultConfig = this.config.modules.autoDiscovery;
|
|
949
|
+
// Handle legacy modulesPath option
|
|
950
|
+
if (options.modulesPath && !options.autoDiscover) {
|
|
951
|
+
return {
|
|
952
|
+
...defaultConfig,
|
|
953
|
+
paths: [options.modulesPath],
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
// Handle boolean autoDiscover option
|
|
957
|
+
if (typeof options.autoDiscover === 'boolean') {
|
|
958
|
+
return {
|
|
959
|
+
...defaultConfig,
|
|
960
|
+
enabled: options.autoDiscover,
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
// Handle object autoDiscover option
|
|
964
|
+
if (typeof options.autoDiscover === 'object') {
|
|
965
|
+
return {
|
|
966
|
+
...defaultConfig,
|
|
967
|
+
...options.autoDiscover,
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
return defaultConfig;
|
|
971
|
+
}
|
|
972
|
+
// Load discovered modules based on strategy
|
|
973
|
+
async loadDiscoveredModules(modules, config) {
|
|
974
|
+
switch (config.loadingStrategy) {
|
|
975
|
+
case 'eager':
|
|
976
|
+
// Load all modules immediately
|
|
977
|
+
for (const module of modules) {
|
|
978
|
+
await this.loadModule(module);
|
|
979
|
+
}
|
|
980
|
+
break;
|
|
981
|
+
case 'lazy':
|
|
982
|
+
// Register modules for lazy loading
|
|
983
|
+
this.registerLazyModules(modules);
|
|
984
|
+
break;
|
|
985
|
+
case 'conditional':
|
|
986
|
+
// Load modules based on conditions
|
|
987
|
+
await this.loadConditionalModules(modules);
|
|
988
|
+
break;
|
|
989
|
+
default:
|
|
990
|
+
// Default to eager loading
|
|
991
|
+
for (const module of modules) {
|
|
992
|
+
await this.loadModule(module);
|
|
804
993
|
}
|
|
805
|
-
});
|
|
806
994
|
}
|
|
807
|
-
|
|
808
|
-
|
|
995
|
+
}
|
|
996
|
+
// Register modules for lazy loading
|
|
997
|
+
registerLazyModules(modules) {
|
|
998
|
+
modules.forEach(module => {
|
|
999
|
+
// Store module for lazy loading when first route is accessed
|
|
1000
|
+
this.lazyModules.set(module.name, module);
|
|
1001
|
+
// Register placeholder routes that trigger lazy loading
|
|
1002
|
+
if (module.routes) {
|
|
1003
|
+
module.routes.forEach(route => {
|
|
1004
|
+
const basePath = `/api/v${module.version}/${module.name}`;
|
|
1005
|
+
const fullPath = `${basePath}${route.path}`;
|
|
1006
|
+
// Note: Lazy loading will be implemented when route is accessed
|
|
1007
|
+
// For now, we'll store the module for later loading
|
|
1008
|
+
this.logger.debug(`Registered lazy route: ${route.method} ${fullPath}`, 'ModuleDiscovery');
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
});
|
|
1012
|
+
this.logger.info(`Registered ${modules.length} modules for lazy loading`, 'ModuleDiscovery');
|
|
1013
|
+
}
|
|
1014
|
+
// Load modules conditionally based on environment or configuration
|
|
1015
|
+
async loadConditionalModules(modules) {
|
|
1016
|
+
for (const module of modules) {
|
|
1017
|
+
const shouldLoad = this.shouldLoadModule(module);
|
|
1018
|
+
if (shouldLoad) {
|
|
1019
|
+
await this.loadModule(module);
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
this.logger.debug(`Skipping module ${module.name} due to conditions`, 'ModuleDiscovery');
|
|
1023
|
+
}
|
|
809
1024
|
}
|
|
810
1025
|
}
|
|
1026
|
+
// Determine if a module should be loaded based on conditions
|
|
1027
|
+
shouldLoadModule(module) {
|
|
1028
|
+
const moduleConfig = module.config;
|
|
1029
|
+
// Check environment conditions
|
|
1030
|
+
if (moduleConfig?.conditions?.environment) {
|
|
1031
|
+
const requiredEnv = moduleConfig.conditions.environment;
|
|
1032
|
+
const currentEnv = process.env.NODE_ENV || 'development';
|
|
1033
|
+
if (Array.isArray(requiredEnv)) {
|
|
1034
|
+
if (!requiredEnv.includes(currentEnv)) {
|
|
1035
|
+
return false;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
else if (requiredEnv !== currentEnv) {
|
|
1039
|
+
return false;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
// Check feature flags
|
|
1043
|
+
if (moduleConfig?.conditions?.features) {
|
|
1044
|
+
const requiredFeatures = moduleConfig.conditions.features;
|
|
1045
|
+
for (const feature of requiredFeatures) {
|
|
1046
|
+
if (!process.env[`FEATURE_${feature.toUpperCase()}`]) {
|
|
1047
|
+
return false;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
// Check custom conditions
|
|
1052
|
+
if (moduleConfig?.conditions?.custom) {
|
|
1053
|
+
const customCondition = moduleConfig.conditions.custom;
|
|
1054
|
+
if (typeof customCondition === 'function') {
|
|
1055
|
+
return customCondition();
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
return true;
|
|
1059
|
+
}
|
|
1060
|
+
// Handle module changes during development
|
|
1061
|
+
async handleModuleChanges(modules) {
|
|
1062
|
+
this.logger.info('Module changes detected, reloading...', 'ModuleDiscovery');
|
|
1063
|
+
// Unload existing modules (if supported)
|
|
1064
|
+
// For now, just log the change
|
|
1065
|
+
this.eventBus.emit('modules:changed', {
|
|
1066
|
+
modules: modules.map(m => ({ name: m.name, version: m.version })),
|
|
1067
|
+
timestamp: new Date(),
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
// Legacy method for backward compatibility
|
|
1071
|
+
autoDiscoverModules(modulesPath) {
|
|
1072
|
+
// Redirect to new system
|
|
1073
|
+
this.initializeAutoDiscovery({
|
|
1074
|
+
autoDiscover: {
|
|
1075
|
+
enabled: true,
|
|
1076
|
+
paths: [modulesPath],
|
|
1077
|
+
},
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
811
1080
|
async importModule(modulePath) {
|
|
812
|
-
const module = await
|
|
1081
|
+
const module = await import(modulePath);
|
|
813
1082
|
return module.default || module;
|
|
814
1083
|
}
|
|
815
|
-
|
|
1084
|
+
/**
|
|
1085
|
+
* Node.js Clustering Implementation
|
|
1086
|
+
* This clustering algorithm is based on published research and Node.js best practices.
|
|
1087
|
+
*
|
|
1088
|
+
* IPC (Inter-Process Communication) Considerations:
|
|
1089
|
+
* - Excessive workers create IPC bottlenecks (Source: BetterStack Node.js Guide)
|
|
1090
|
+
* - Round-robin scheduling provides better load distribution (Node.js Documentation)
|
|
1091
|
+
* - Message passing overhead increases significantly with worker count
|
|
1092
|
+
*
|
|
1093
|
+
* Memory Management:
|
|
1094
|
+
* - ~2GB per worker prevents memory pressure and GC overhead
|
|
1095
|
+
* - Conservative heap limits reduce memory fragmentation
|
|
1096
|
+
*
|
|
1097
|
+
* References:
|
|
1098
|
+
* - Node.js Cluster Documentation: https://nodejs.org/api/cluster.html
|
|
1099
|
+
* - BetterStack Node.js Clustering: https://betterstack.com/community/guides/scaling-nodejs/node-clustering/
|
|
1100
|
+
*/
|
|
816
1101
|
clusterWorkers = new Map();
|
|
817
1102
|
startWithClustering(port, host, callback) {
|
|
818
|
-
|
|
819
|
-
const os = require('os');
|
|
820
|
-
// Smart worker count calculation based on actual bottlenecks
|
|
1103
|
+
// Worker count calculation - respect user choice
|
|
821
1104
|
let workerCount = this.config.performance?.clustering?.workers || os.cpus().length;
|
|
822
|
-
//
|
|
823
|
-
if (workerCount === 'auto'
|
|
824
|
-
// For high-core machines, limit workers to prevent IPC/memory bottlenecks
|
|
1105
|
+
// Only auto-optimize if user hasn't specified a number or set it to 'auto'
|
|
1106
|
+
if (workerCount === 'auto') {
|
|
825
1107
|
const cpuCount = os.cpus().length;
|
|
826
1108
|
const totalMemoryGB = os.totalmem() / (1024 * 1024 * 1024);
|
|
827
|
-
//
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
1109
|
+
// Get memory per worker from config - if not set by user, calculate dynamically
|
|
1110
|
+
let memoryPerWorkerGB = this.config.performance?.clustering?.memoryPerWorkerGB;
|
|
1111
|
+
if (!memoryPerWorkerGB) {
|
|
1112
|
+
// Dynamic calculation: (Total RAM - 4GB headroom) / CPU cores
|
|
1113
|
+
const headroomGB = 4;
|
|
1114
|
+
memoryPerWorkerGB = Math.max(0.5, Math.floor((totalMemoryGB - headroomGB) / cpuCount));
|
|
831
1115
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
}
|
|
840
|
-
|
|
1116
|
+
// Conservative formula based on general guidelines:
|
|
1117
|
+
// - Don't exceed CPU cores
|
|
1118
|
+
// - Respect user's memory allocation preference
|
|
1119
|
+
// - Let the system resources determine the limit
|
|
1120
|
+
workerCount = Math.min(cpuCount, // Don't exceed CPU cores
|
|
1121
|
+
Math.floor(totalMemoryGB / memoryPerWorkerGB) // User-configurable memory per worker
|
|
1122
|
+
);
|
|
1123
|
+
this.logger.info(`Auto-calculated worker count: ${workerCount} (CPU: ${cpuCount}, RAM: ${totalMemoryGB.toFixed(1)}GB, ${memoryPerWorkerGB}GB per worker)`, 'Cluster');
|
|
1124
|
+
}
|
|
1125
|
+
else if (typeof workerCount === 'number') {
|
|
1126
|
+
// User specified a number - respect their choice
|
|
1127
|
+
this.logger.info(`Using user-specified worker count: ${workerCount}`, 'Cluster');
|
|
841
1128
|
}
|
|
842
1129
|
if (cluster.isPrimary) {
|
|
843
|
-
this.logger.info(
|
|
1130
|
+
this.logger.info(`Starting ${workerCount} workers`, 'Cluster');
|
|
844
1131
|
// Optimize cluster scheduling for high concurrency
|
|
845
|
-
|
|
1132
|
+
// Round-robin is the default on all platforms except Windows (Node.js docs)
|
|
1133
|
+
// Provides better load distribution than shared socket approach
|
|
1134
|
+
cluster.schedulingPolicy = cluster.SCHED_RR;
|
|
846
1135
|
// Set cluster settings for better performance
|
|
847
1136
|
cluster.setupMaster({
|
|
848
|
-
exec: process.argv[1],
|
|
1137
|
+
exec: process.argv[1] || process.execPath,
|
|
849
1138
|
args: process.argv.slice(2),
|
|
850
1139
|
silent: false,
|
|
851
1140
|
});
|
|
852
|
-
//
|
|
1141
|
+
// IPC Optimization: Reduce communication overhead between master and workers
|
|
1142
|
+
// Research shows excessive IPC can create bottlenecks in clustered applications
|
|
1143
|
+
// (Source: BetterStack - Node.js Clustering Guide)
|
|
853
1144
|
process.env.NODE_CLUSTER_SCHED_POLICY = 'rr'; // Ensure round-robin
|
|
854
|
-
process.env.NODE_DISABLE_COLORS = '1'; // Reduce IPC message size
|
|
1145
|
+
process.env.NODE_DISABLE_COLORS = '1'; // Reduce IPC message size by disabling color codes
|
|
855
1146
|
// Graceful shutdown handler
|
|
856
1147
|
const gracefulShutdown = () => {
|
|
857
1148
|
this.logger.info('Gracefully shutting down cluster...', 'Cluster');
|
|
@@ -867,27 +1158,25 @@ class Moro extends events_1.EventEmitter {
|
|
|
867
1158
|
// Handle process signals for graceful shutdown
|
|
868
1159
|
process.on('SIGINT', gracefulShutdown);
|
|
869
1160
|
process.on('SIGTERM', gracefulShutdown);
|
|
870
|
-
// Fork workers with
|
|
1161
|
+
// Fork workers with basic tracking
|
|
871
1162
|
for (let i = 0; i < workerCount; i++) {
|
|
872
|
-
const worker = cluster.fork(
|
|
873
|
-
WORKER_ID: i,
|
|
874
|
-
WORKER_CPU_AFFINITY: i % os.cpus().length, // Distribute workers across CPUs
|
|
875
|
-
});
|
|
1163
|
+
const worker = cluster.fork();
|
|
876
1164
|
this.clusterWorkers.set(worker.process.pid, worker);
|
|
877
|
-
this.logger.info(`Worker ${worker.process.pid} started
|
|
878
|
-
// Handle individual worker messages
|
|
1165
|
+
this.logger.info(`Worker ${worker.process.pid} started`, 'Cluster');
|
|
1166
|
+
// Handle individual worker messages
|
|
879
1167
|
worker.on('message', this.handleWorkerMessage.bind(this));
|
|
880
1168
|
}
|
|
881
|
-
//
|
|
1169
|
+
// Simple worker exit handling
|
|
882
1170
|
cluster.on('exit', (worker, code, signal) => {
|
|
883
|
-
|
|
884
|
-
this.clusterWorkers.delete(
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
1171
|
+
const pid = worker.process.pid;
|
|
1172
|
+
this.clusterWorkers.delete(pid);
|
|
1173
|
+
if (code !== 0 && !worker.exitedAfterDisconnect) {
|
|
1174
|
+
this.logger.warn(`Worker ${pid} died unexpectedly (${signal || code}). Restarting...`, 'Cluster');
|
|
1175
|
+
// Simple restart
|
|
1176
|
+
const newWorker = cluster.fork();
|
|
1177
|
+
this.clusterWorkers.set(newWorker.process.pid, newWorker);
|
|
1178
|
+
this.logger.info(`Worker ${newWorker.process.pid} restarted`, 'Cluster');
|
|
1179
|
+
}
|
|
891
1180
|
});
|
|
892
1181
|
// Master process callback
|
|
893
1182
|
if (callback)
|
|
@@ -899,15 +1188,24 @@ class Moro extends events_1.EventEmitter {
|
|
|
899
1188
|
// Worker-specific optimizations for high concurrency
|
|
900
1189
|
process.env.UV_THREADPOOL_SIZE = '64';
|
|
901
1190
|
// Reduce logging contention in workers (major bottleneck)
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
1191
|
+
// Multiple workers writing to same log files creates I/O contention
|
|
1192
|
+
// ONLY reduce log level if user didn't explicitly set one
|
|
1193
|
+
if (!this.userSetLogger) {
|
|
1194
|
+
// Workers log less frequently to reduce I/O contention (only if not explicitly configured)
|
|
1195
|
+
applyLoggingConfiguration(undefined, { level: 'warn' }); // Only warnings and errors
|
|
905
1196
|
}
|
|
906
|
-
//
|
|
907
|
-
|
|
908
|
-
|
|
1197
|
+
// Research-based memory optimization for workers
|
|
1198
|
+
const totalMemoryGB = os.totalmem() / (1024 * 1024 * 1024);
|
|
1199
|
+
const workerCount = Object.keys(cluster.workers || {}).length || 1;
|
|
1200
|
+
// Conservative memory allocation
|
|
1201
|
+
const heapSizePerWorkerMB = Math.min(Math.floor(((totalMemoryGB * 1024) / workerCount) * 0.8), // 80% of available memory
|
|
1202
|
+
1536 // Cap at 1.5GB (GC efficiency threshold from research)
|
|
1203
|
+
);
|
|
1204
|
+
process.env.NODE_OPTIONS = `--max-old-space-size=${heapSizePerWorkerMB}`;
|
|
1205
|
+
this.logger.debug(`Worker memory allocated: ${heapSizePerWorkerMB}MB heap (${workerCount} workers, ${totalMemoryGB.toFixed(1)}GB total)`, 'Worker');
|
|
1206
|
+
// Optimize V8 flags for better performance
|
|
909
1207
|
if (process.env.NODE_ENV === 'production') {
|
|
910
|
-
//
|
|
1208
|
+
// Aggressive V8 optimizations for maximum performance
|
|
911
1209
|
const v8Flags = [
|
|
912
1210
|
'--optimize-for-size', // Trade memory for speed
|
|
913
1211
|
'--always-opt', // Always optimize functions
|
|
@@ -960,14 +1258,27 @@ class Moro extends events_1.EventEmitter {
|
|
|
960
1258
|
catch (error) {
|
|
961
1259
|
// Documentation not enabled, that's fine
|
|
962
1260
|
}
|
|
963
|
-
// Add
|
|
1261
|
+
// Add unified routing middleware (handles both chainable and direct routes)
|
|
1262
|
+
// Optimized: call router without extra async wrapper when possible
|
|
964
1263
|
this.coreFramework.addMiddleware(async (req, res, next) => {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1264
|
+
// Try unified router first (handles all route types)
|
|
1265
|
+
const handled = this.unifiedRouter.handleRequest(req, res);
|
|
1266
|
+
// Check if it's a promise (async route) or sync (fast-path)
|
|
1267
|
+
if (handled && typeof handled.then === 'function') {
|
|
1268
|
+
// Async - await the result
|
|
1269
|
+
const isHandled = await handled;
|
|
1270
|
+
if (!isHandled) {
|
|
1271
|
+
next();
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
else {
|
|
1275
|
+
// Sync - check immediately
|
|
1276
|
+
if (!handled) {
|
|
1277
|
+
next();
|
|
1278
|
+
}
|
|
968
1279
|
}
|
|
969
1280
|
});
|
|
970
|
-
// Register direct routes
|
|
1281
|
+
// Register legacy direct routes with the HTTP server (for backward compatibility)
|
|
971
1282
|
if (this.routes.length > 0) {
|
|
972
1283
|
this.registerDirectRoutes();
|
|
973
1284
|
}
|
|
@@ -980,15 +1291,36 @@ class Moro extends events_1.EventEmitter {
|
|
|
980
1291
|
worker: process.pid,
|
|
981
1292
|
});
|
|
982
1293
|
};
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1294
|
+
// Ensure WebSocket setup is complete before starting worker
|
|
1295
|
+
this.processQueuedWebSocketRegistrations()
|
|
1296
|
+
.then(() => {
|
|
1297
|
+
if (host) {
|
|
1298
|
+
this.coreFramework.listen(port, host, workerCallback);
|
|
1299
|
+
}
|
|
1300
|
+
else {
|
|
1301
|
+
this.coreFramework.listen(port, workerCallback);
|
|
1302
|
+
}
|
|
1303
|
+
})
|
|
1304
|
+
.catch(error => {
|
|
1305
|
+
this.logger.error('WebSocket initialization failed in worker', 'Worker', {
|
|
1306
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1307
|
+
});
|
|
1308
|
+
// For WebSocket failures with queued registrations, error will propagate
|
|
1309
|
+
if (error instanceof Error &&
|
|
1310
|
+
error.message.includes('WebSocket features require a WebSocket adapter')) {
|
|
1311
|
+
throw error;
|
|
1312
|
+
}
|
|
1313
|
+
// Start anyway for other errors
|
|
1314
|
+
if (host) {
|
|
1315
|
+
this.coreFramework.listen(port, host, workerCallback);
|
|
1316
|
+
}
|
|
1317
|
+
else {
|
|
1318
|
+
this.coreFramework.listen(port, workerCallback);
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
989
1321
|
}
|
|
990
1322
|
}
|
|
991
|
-
//
|
|
1323
|
+
// Simple worker message handler
|
|
992
1324
|
handleWorkerMessage(message) {
|
|
993
1325
|
// Handle inter-worker communication if needed
|
|
994
1326
|
if (message.type === 'health-check') {
|
|
@@ -998,32 +1330,81 @@ class Moro extends events_1.EventEmitter {
|
|
|
998
1330
|
// Log other worker messages
|
|
999
1331
|
this.logger.debug(`Worker message: ${JSON.stringify(message)}`, 'Cluster');
|
|
1000
1332
|
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Gracefully close the application and clean up resources
|
|
1335
|
+
* This should be called in tests and during shutdown
|
|
1336
|
+
*/
|
|
1337
|
+
async close() {
|
|
1338
|
+
this.logger.debug('Closing Moro application...');
|
|
1339
|
+
// Flush logger buffer before shutdown
|
|
1340
|
+
try {
|
|
1341
|
+
// Use flushBuffer for immediate synchronous flush
|
|
1342
|
+
this.logger.flushBuffer();
|
|
1343
|
+
}
|
|
1344
|
+
catch (error) {
|
|
1345
|
+
// Ignore flush errors during shutdown
|
|
1346
|
+
}
|
|
1347
|
+
// Close the core framework with timeout
|
|
1348
|
+
if (this.coreFramework && this.coreFramework.httpServer) {
|
|
1349
|
+
try {
|
|
1350
|
+
await Promise.race([
|
|
1351
|
+
new Promise(resolve => {
|
|
1352
|
+
this.coreFramework.httpServer.close(() => {
|
|
1353
|
+
resolve();
|
|
1354
|
+
});
|
|
1355
|
+
}),
|
|
1356
|
+
new Promise(resolve => setTimeout(resolve, 2000)), // 2 second timeout
|
|
1357
|
+
]);
|
|
1358
|
+
}
|
|
1359
|
+
catch (error) {
|
|
1360
|
+
// Force close if graceful close fails
|
|
1361
|
+
this.logger.warn('Force closing HTTP server due to timeout');
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
// Clean up module discovery watchers
|
|
1365
|
+
if (this.moduleDiscovery && typeof this.moduleDiscovery.cleanup === 'function') {
|
|
1366
|
+
try {
|
|
1367
|
+
this.moduleDiscovery.cleanup();
|
|
1368
|
+
}
|
|
1369
|
+
catch (error) {
|
|
1370
|
+
// Ignore cleanup errors
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
// Clean up event listeners
|
|
1374
|
+
try {
|
|
1375
|
+
this.eventBus.removeAllListeners();
|
|
1376
|
+
this.removeAllListeners();
|
|
1377
|
+
}
|
|
1378
|
+
catch (error) {
|
|
1379
|
+
// Ignore cleanup errors
|
|
1380
|
+
}
|
|
1381
|
+
this.logger.debug('Moro application closed successfully');
|
|
1382
|
+
}
|
|
1001
1383
|
}
|
|
1002
|
-
exports.Moro = Moro;
|
|
1003
1384
|
// Export convenience function
|
|
1004
|
-
function createApp(options) {
|
|
1385
|
+
export function createApp(options) {
|
|
1005
1386
|
return new Moro(options);
|
|
1006
1387
|
}
|
|
1007
1388
|
// Runtime-specific convenience functions
|
|
1008
|
-
function createAppNode(options) {
|
|
1389
|
+
export function createAppNode(options) {
|
|
1009
1390
|
return new Moro({
|
|
1010
1391
|
...options,
|
|
1011
1392
|
runtime: { type: 'node' },
|
|
1012
1393
|
});
|
|
1013
1394
|
}
|
|
1014
|
-
function createAppEdge(options) {
|
|
1395
|
+
export function createAppEdge(options) {
|
|
1015
1396
|
return new Moro({
|
|
1016
1397
|
...options,
|
|
1017
1398
|
runtime: { type: 'vercel-edge' },
|
|
1018
1399
|
});
|
|
1019
1400
|
}
|
|
1020
|
-
function createAppLambda(options) {
|
|
1401
|
+
export function createAppLambda(options) {
|
|
1021
1402
|
return new Moro({
|
|
1022
1403
|
...options,
|
|
1023
1404
|
runtime: { type: 'aws-lambda' },
|
|
1024
1405
|
});
|
|
1025
1406
|
}
|
|
1026
|
-
function createAppWorker(options) {
|
|
1407
|
+
export function createAppWorker(options) {
|
|
1027
1408
|
return new Moro({
|
|
1028
1409
|
...options,
|
|
1029
1410
|
runtime: { type: 'cloudflare-workers' },
|