@morojs/moro 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/core/config/config-sources.js +4 -0
  2. package/dist/core/config/config-sources.js.map +1 -1
  3. package/dist/core/config/config-validator.js +3 -0
  4. package/dist/core/config/config-validator.js.map +1 -1
  5. package/dist/core/config/file-loader.js +3 -1
  6. package/dist/core/config/file-loader.js.map +1 -1
  7. package/dist/core/config/schema.js +4 -1
  8. package/dist/core/config/schema.js.map +1 -1
  9. package/dist/core/events/event-bus.js +1 -1
  10. package/dist/core/events/event-bus.js.map +1 -1
  11. package/dist/core/framework.d.ts +1 -1
  12. package/dist/core/framework.js +13 -7
  13. package/dist/core/framework.js.map +1 -1
  14. package/dist/core/http/http-server.d.ts +55 -15
  15. package/dist/core/http/http-server.js +70 -146
  16. package/dist/core/http/http-server.js.map +1 -1
  17. package/dist/core/http/index.d.ts +1 -1
  18. package/dist/core/http/index.js +1 -1
  19. package/dist/core/http/index.js.map +1 -1
  20. package/dist/core/http/uws-http-server.d.ts +4 -22
  21. package/dist/core/http/uws-http-server.js +43 -208
  22. package/dist/core/http/uws-http-server.js.map +1 -1
  23. package/dist/core/networking/adapters/uws-adapter.d.ts +1 -1
  24. package/dist/core/networking/adapters/uws-adapter.js +1 -1
  25. package/dist/core/pooling/object-pool-manager.d.ts +140 -0
  26. package/dist/core/pooling/object-pool-manager.js +502 -0
  27. package/dist/core/pooling/object-pool-manager.js.map +1 -0
  28. package/dist/core/routing/app-integration.d.ts +12 -10
  29. package/dist/core/routing/app-integration.js +43 -74
  30. package/dist/core/routing/app-integration.js.map +1 -1
  31. package/dist/core/routing/index.d.ts +15 -29
  32. package/dist/core/routing/index.js +43 -390
  33. package/dist/core/routing/index.js.map +1 -1
  34. package/dist/core/routing/path-matcher.d.ts +67 -0
  35. package/dist/core/routing/path-matcher.js +182 -0
  36. package/dist/core/routing/path-matcher.js.map +1 -0
  37. package/dist/core/{http → routing}/router.d.ts +21 -9
  38. package/dist/core/routing/router.js +68 -0
  39. package/dist/core/routing/router.js.map +1 -0
  40. package/dist/core/routing/unified-router.d.ts +148 -0
  41. package/dist/core/routing/unified-router.js +684 -0
  42. package/dist/core/routing/unified-router.js.map +1 -0
  43. package/dist/moro.d.ts +10 -7
  44. package/dist/moro.js +90 -41
  45. package/dist/moro.js.map +1 -1
  46. package/dist/types/config.d.ts +3 -0
  47. package/package.json +1 -1
  48. package/src/core/config/config-sources.ts +4 -0
  49. package/src/core/config/config-validator.ts +3 -0
  50. package/src/core/config/file-loader.ts +4 -1
  51. package/src/core/config/schema.ts +4 -1
  52. package/src/core/events/event-bus.ts +1 -1
  53. package/src/core/framework.ts +14 -9
  54. package/src/core/http/http-server.ts +76 -161
  55. package/src/core/http/index.ts +1 -1
  56. package/src/core/http/uws-http-server.ts +43 -246
  57. package/src/core/networking/adapters/uws-adapter.ts +1 -1
  58. package/src/core/pooling/object-pool-manager.ts +630 -0
  59. package/src/core/routing/app-integration.ts +57 -109
  60. package/src/core/routing/index.ts +62 -473
  61. package/src/core/routing/path-matcher.ts +222 -0
  62. package/src/core/routing/router.ts +97 -0
  63. package/src/core/routing/unified-router.ts +870 -0
  64. package/src/moro.ts +107 -57
  65. package/src/types/config.ts +3 -0
  66. package/dist/core/http/router.js +0 -183
  67. package/dist/core/http/router.js.map +0 -1
  68. package/src/core/http/router.ts +0 -230
@@ -0,0 +1,182 @@
1
+ // Shared Path Matching Utility with Caching
2
+ // Replaces 6 different pathToRegex implementations across the codebase
3
+ /**
4
+ * LRU Cache implementation for compiled paths
5
+ */
6
+ class LRUCache {
7
+ cache = new Map();
8
+ maxSize;
9
+ constructor(maxSize = 1000) {
10
+ this.maxSize = maxSize;
11
+ }
12
+ get(key) {
13
+ const value = this.cache.get(key);
14
+ if (value !== undefined) {
15
+ // Move to end (most recently used)
16
+ this.cache.delete(key);
17
+ this.cache.set(key, value);
18
+ }
19
+ return value;
20
+ }
21
+ set(key, value) {
22
+ // Remove if exists (to update position)
23
+ if (this.cache.has(key)) {
24
+ this.cache.delete(key);
25
+ }
26
+ // Add to end
27
+ this.cache.set(key, value);
28
+ // Evict oldest if over capacity
29
+ if (this.cache.size > this.maxSize) {
30
+ const firstKey = this.cache.keys().next().value;
31
+ if (firstKey !== undefined) {
32
+ this.cache.delete(firstKey);
33
+ }
34
+ }
35
+ }
36
+ has(key) {
37
+ return this.cache.has(key);
38
+ }
39
+ clear() {
40
+ this.cache.clear();
41
+ }
42
+ get size() {
43
+ return this.cache.size;
44
+ }
45
+ }
46
+ /**
47
+ * PathMatcher - Single source of truth for path pattern compilation and matching
48
+ */
49
+ export class PathMatcher {
50
+ static cache = new LRUCache(1000);
51
+ static compilationCount = 0;
52
+ static cacheHits = 0;
53
+ static cacheMisses = 0;
54
+ /**
55
+ * Compile a path pattern into an efficient matching structure
56
+ * Results are cached for performance
57
+ */
58
+ static compile(path) {
59
+ // Check cache first
60
+ const cached = this.cache.get(path);
61
+ if (cached) {
62
+ this.cacheHits++;
63
+ return cached;
64
+ }
65
+ this.cacheMisses++;
66
+ this.compilationCount++;
67
+ // Compile the pattern
68
+ const compiled = this.compileInternal(path);
69
+ this.cache.set(path, compiled);
70
+ return compiled;
71
+ }
72
+ /**
73
+ * Internal compilation logic
74
+ */
75
+ static compileInternal(path) {
76
+ const paramNames = [];
77
+ const isStatic = !path.includes(':') && !path.includes('*');
78
+ // Calculate segment count for optimization
79
+ const segments = path.split('/').filter(s => s.length > 0).length;
80
+ if (isStatic) {
81
+ // No regex needed for static routes
82
+ return {
83
+ pattern: null,
84
+ paramNames: [],
85
+ isStatic: true,
86
+ path,
87
+ segments,
88
+ };
89
+ }
90
+ // Convert parameterized routes to regex
91
+ // Match :paramName and capture the parameter name
92
+ const regexPath = path
93
+ .replace(/\/:([^/]+)/g, (match, paramName) => {
94
+ paramNames.push(paramName);
95
+ return '/([^/]+)';
96
+ })
97
+ .replace(/\//g, '\\/');
98
+ return {
99
+ pattern: new RegExp(`^${regexPath}$`),
100
+ paramNames,
101
+ isStatic: false,
102
+ path,
103
+ segments,
104
+ };
105
+ }
106
+ /**
107
+ * Match a request path against a compiled pattern
108
+ * Returns match result with extracted parameters, or null if no match
109
+ */
110
+ static match(compiledPath, requestPath) {
111
+ // Path for static routes - simple string comparison
112
+ if (compiledPath.isStatic) {
113
+ return compiledPath.path === requestPath ? { params: {} } : null;
114
+ }
115
+ // Dynamic route - use regex matching
116
+ if (!compiledPath.pattern) {
117
+ return null;
118
+ }
119
+ const matches = requestPath.match(compiledPath.pattern);
120
+ if (!matches) {
121
+ return null;
122
+ }
123
+ // Extract parameters
124
+ const params = {};
125
+ compiledPath.paramNames.forEach((name, index) => {
126
+ params[name] = matches[index + 1];
127
+ });
128
+ return { params };
129
+ }
130
+ /**
131
+ * Compile and match in one operation (convenience method)
132
+ */
133
+ static compileAndMatch(pathPattern, requestPath) {
134
+ const compiled = this.compile(pathPattern);
135
+ return this.match(compiled, requestPath);
136
+ }
137
+ /**
138
+ * Check if a path pattern is static (no parameters)
139
+ */
140
+ static isStatic(path) {
141
+ return !path.includes(':') && !path.includes('*');
142
+ }
143
+ /**
144
+ * Get performance statistics
145
+ */
146
+ static getStats() {
147
+ const totalRequests = this.cacheHits + this.cacheMisses;
148
+ return {
149
+ cacheSize: this.cache.size,
150
+ cacheHits: this.cacheHits,
151
+ cacheMisses: this.cacheMisses,
152
+ hitRate: totalRequests > 0 ? this.cacheHits / totalRequests : 0,
153
+ compilationCount: this.compilationCount,
154
+ };
155
+ }
156
+ /**
157
+ * Clear the cache (useful for testing)
158
+ */
159
+ static clearCache() {
160
+ this.cache.clear();
161
+ this.cacheHits = 0;
162
+ this.cacheMisses = 0;
163
+ }
164
+ /**
165
+ * Pre-compile multiple paths (cache warming)
166
+ */
167
+ static precompile(paths) {
168
+ paths.forEach(path => this.compile(path));
169
+ }
170
+ }
171
+ /**
172
+ * Legacy compatibility function - maps to PathMatcher.compile
173
+ * @deprecated Use PathMatcher.compile instead
174
+ */
175
+ export function pathToRegex(path) {
176
+ const compiled = PathMatcher.compile(path);
177
+ return {
178
+ pattern: compiled.pattern || new RegExp(`^${path.replace(/\//g, '\\/')}$`),
179
+ paramNames: compiled.paramNames,
180
+ };
181
+ }
182
+ //# sourceMappingURL=path-matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-matcher.js","sourceRoot":"","sources":["../../../src/core/routing/path-matcher.ts"],"names":[],"mappings":"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"}
@@ -1,26 +1,38 @@
1
1
  import { HttpRequest, HttpResponse, HttpHandler, Middleware, RouteDefinition } from '../../types/http.js';
2
2
  export declare class Router {
3
- private routes;
4
3
  private logger;
5
- private staticRoutes;
6
- private dynamicRoutes;
7
- private paramObjectPool;
8
- private readonly maxPoolSize;
4
+ private unifiedRouter;
5
+ private routes;
9
6
  get(path: string, ...handlers: (Middleware | HttpHandler)[]): void;
10
7
  post(path: string, ...handlers: (Middleware | HttpHandler)[]): void;
11
8
  put(path: string, ...handlers: (Middleware | HttpHandler)[]): void;
12
9
  delete(path: string, ...handlers: (Middleware | HttpHandler)[]): void;
13
10
  patch(path: string, ...handlers: (Middleware | HttpHandler)[]): void;
14
11
  private addRoute;
15
- private pathToRegex;
16
12
  handle(req: HttpRequest, res: HttpResponse, basePath?: string): Promise<boolean>;
17
13
  getRoutes(): RouteDefinition[];
18
- private acquireParamObject;
19
- private releaseParamObject;
20
14
  getPerformanceStats(): {
15
+ poolManager: {
16
+ routeCacheHitRate: number;
17
+ responseCacheHitRate: number;
18
+ paramPoolUtilization: number;
19
+ totalMemoryKB: number;
20
+ };
21
+ pathMatcher: {
22
+ cacheSize: number;
23
+ cacheHits: number;
24
+ cacheMisses: number;
25
+ hitRate: number;
26
+ compilationCount: number;
27
+ };
21
28
  totalRoutes: number;
22
29
  staticRoutes: number;
23
30
  dynamicRoutes: number;
24
- paramObjectPoolSize: number;
31
+ fastPathRoutes: number;
32
+ requestCount: number;
33
+ fastPathHits: number;
34
+ staticHits: number;
35
+ dynamicHits: number;
36
+ cacheHits: number;
25
37
  };
26
38
  }
@@ -0,0 +1,68 @@
1
+ import { createFrameworkLogger } from '../logger/index.js';
2
+ import { UnifiedRouter } from './unified-router.js';
3
+ export class Router {
4
+ logger = createFrameworkLogger('Router');
5
+ // Delegate to shared UnifiedRouter singleton for actual routing
6
+ unifiedRouter = UnifiedRouter.getInstance();
7
+ // Maintain route definitions for backward compatibility (getRoutes())
8
+ routes = [];
9
+ get(path, ...handlers) {
10
+ this.addRoute('GET', path, handlers);
11
+ }
12
+ post(path, ...handlers) {
13
+ this.addRoute('POST', path, handlers);
14
+ }
15
+ put(path, ...handlers) {
16
+ this.addRoute('PUT', path, handlers);
17
+ }
18
+ delete(path, ...handlers) {
19
+ this.addRoute('DELETE', path, handlers);
20
+ }
21
+ patch(path, ...handlers) {
22
+ this.addRoute('PATCH', path, handlers);
23
+ }
24
+ addRoute(method, path, handlers) {
25
+ const handler = handlers.pop();
26
+ const middleware = handlers;
27
+ // Delegate to UnifiedRouter for actual routing
28
+ this.unifiedRouter.addRoute(method, path, handler, middleware);
29
+ // Keep route definition for backward compatibility (getRoutes())
30
+ const route = {
31
+ method,
32
+ path,
33
+ pattern: new RegExp(''), // Not used since we delegate
34
+ paramNames: [],
35
+ handler,
36
+ middleware,
37
+ };
38
+ this.routes.push(route);
39
+ this.logger.debug(`Delegated route to UnifiedRouter: ${method} ${path}`, 'Facade');
40
+ }
41
+ async handle(req, res, basePath = '') {
42
+ // Adjust path for basePath
43
+ let path = req.path.startsWith(basePath) ? req.path.substring(basePath.length) : req.path;
44
+ if (path === '' || path === undefined) {
45
+ path = '/';
46
+ }
47
+ this.logger.debug(`Router delegating to UnifiedRouter: originalPath="${req.path}", basePath="${basePath}", processedPath="${path}"`, 'Facade');
48
+ // Temporarily adjust request path for processing
49
+ const originalPath = req.path;
50
+ req.path = path;
51
+ try {
52
+ // Delegate to UnifiedRouter for actual routing
53
+ return await this.unifiedRouter.handleRequest(req, res);
54
+ }
55
+ finally {
56
+ // Restore original path
57
+ req.path = originalPath;
58
+ }
59
+ }
60
+ getRoutes() {
61
+ return [...this.routes];
62
+ }
63
+ // Performance statistics for monitoring (delegates to UnifiedRouter)
64
+ getPerformanceStats() {
65
+ return this.unifiedRouter.getStats();
66
+ }
67
+ }
68
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/core/routing/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ import { HttpRequest, HttpResponse } from '../../types/http.js';
2
+ import { ValidationSchema } from '../validation/schema-interface.js';
3
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
4
+ export type RouteHandler<T = any> = (req: HttpRequest, res: HttpResponse) => T | Promise<T>;
5
+ export type Middleware = (req: HttpRequest, res: HttpResponse, next: () => void) => void | Promise<void>;
6
+ export interface ValidationConfig {
7
+ body?: ValidationSchema;
8
+ query?: ValidationSchema;
9
+ params?: ValidationSchema;
10
+ headers?: ValidationSchema;
11
+ }
12
+ export interface AuthConfig {
13
+ roles?: string[];
14
+ permissions?: string[];
15
+ optional?: boolean;
16
+ }
17
+ export interface RateLimitConfig {
18
+ requests: number;
19
+ window: number;
20
+ skipSuccessfulRequests?: boolean;
21
+ }
22
+ export interface CacheConfig {
23
+ ttl: number;
24
+ key?: string;
25
+ tags?: string[];
26
+ }
27
+ export interface MiddlewarePhases {
28
+ before?: Middleware[];
29
+ after?: Middleware[];
30
+ transform?: Middleware[];
31
+ }
32
+ export interface RouteSchema {
33
+ method: HttpMethod;
34
+ path: string;
35
+ handler: RouteHandler;
36
+ validation?: ValidationConfig;
37
+ auth?: AuthConfig;
38
+ rateLimit?: RateLimitConfig;
39
+ cache?: CacheConfig;
40
+ middleware?: MiddlewarePhases | Middleware[];
41
+ description?: string;
42
+ tags?: string[];
43
+ }
44
+ export declare class RouteBuilder {
45
+ private schema;
46
+ private router;
47
+ constructor(method: HttpMethod, path: string, router: UnifiedRouter);
48
+ validate(config: ValidationConfig): this;
49
+ body<T>(schema: ValidationSchema<T>): this;
50
+ query<T>(schema: ValidationSchema<T>): this;
51
+ params<T>(schema: ValidationSchema<T>): this;
52
+ headers<T>(schema: ValidationSchema<T>): this;
53
+ auth(config: AuthConfig): this;
54
+ rateLimit(config: RateLimitConfig): this;
55
+ cache(config: CacheConfig): this;
56
+ before(...middleware: Middleware[]): this;
57
+ after(...middleware: Middleware[]): this;
58
+ transform(...middleware: Middleware[]): this;
59
+ use(...middleware: Middleware[]): this;
60
+ describe(description: string): this;
61
+ tag(...tags: string[]): this;
62
+ handler<T>(handler: RouteHandler<T>): void;
63
+ }
64
+ export declare class UnifiedRouter {
65
+ private static instance;
66
+ private readonly poolManager;
67
+ private staticRoutes;
68
+ private dynamicRoutesBySegments;
69
+ private fastPathRoutes;
70
+ private allRoutes;
71
+ private stats;
72
+ constructor();
73
+ /**
74
+ * Get singleton instance (optional - can still create new instances)
75
+ */
76
+ static getInstance(): UnifiedRouter;
77
+ /**
78
+ * Reset singleton (useful for testing)
79
+ */
80
+ static reset(): void;
81
+ /**
82
+ * Clear all routes (useful for testing)
83
+ */
84
+ clearAllRoutes(): void;
85
+ /**
86
+ * Register a route (internal method)
87
+ */
88
+ registerRoute(schema: RouteSchema): void;
89
+ /**
90
+ * Chainable API methods
91
+ */
92
+ get(path: string): RouteBuilder;
93
+ post(path: string): RouteBuilder;
94
+ put(path: string): RouteBuilder;
95
+ delete(path: string): RouteBuilder;
96
+ patch(path: string): RouteBuilder;
97
+ head(path: string): RouteBuilder;
98
+ options(path: string): RouteBuilder;
99
+ /**
100
+ * Schema-first route registration
101
+ */
102
+ route(schema: RouteSchema): void;
103
+ /**
104
+ * Direct API (for backward compatibility)
105
+ */
106
+ addRoute(method: HttpMethod, path: string, handler: RouteHandler, middleware?: Middleware[]): void;
107
+ /**
108
+ * Find a matching route for the request
109
+ * Returns boolean (sync) for fast-path routes, Promise<boolean> for others
110
+ */
111
+ handleRequest(req: HttpRequest, res: HttpResponse): Promise<boolean> | boolean;
112
+ private executeRoute;
113
+ private executePhase;
114
+ private executeMiddleware;
115
+ private executeRateLimit;
116
+ private executeAuth;
117
+ private executeValidation;
118
+ private executeCache;
119
+ private isFastPathRoute;
120
+ private buildExecutionOrder;
121
+ getAllRoutes(): RouteSchema[];
122
+ getRouteCount(): number;
123
+ getStats(): {
124
+ poolManager: {
125
+ routeCacheHitRate: number;
126
+ responseCacheHitRate: number;
127
+ paramPoolUtilization: number;
128
+ totalMemoryKB: number;
129
+ };
130
+ pathMatcher: {
131
+ cacheSize: number;
132
+ cacheHits: number;
133
+ cacheMisses: number;
134
+ hitRate: number;
135
+ compilationCount: number;
136
+ };
137
+ totalRoutes: number;
138
+ staticRoutes: number;
139
+ dynamicRoutes: number;
140
+ fastPathRoutes: number;
141
+ requestCount: number;
142
+ fastPathHits: number;
143
+ staticHits: number;
144
+ dynamicHits: number;
145
+ cacheHits: number;
146
+ };
147
+ logPerformanceStats(): void;
148
+ }