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