@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
@@ -1,230 +0,0 @@
1
- // src/core/router.ts
2
- import {
3
- HttpRequest,
4
- HttpResponse,
5
- HttpHandler,
6
- Middleware,
7
- RouteDefinition,
8
- } from '../../types/http.js';
9
- import { createFrameworkLogger } from '../logger/index.js';
10
-
11
- export class Router {
12
- private routes: RouteDefinition[] = [];
13
- private logger = createFrameworkLogger('Router');
14
-
15
- // Performance optimizations - O(1) static route lookup
16
- private staticRoutes = new Map<string, RouteDefinition>(); // "GET:/api/users" -> route
17
- private dynamicRoutes: RouteDefinition[] = []; // Routes with parameters
18
-
19
- // Object pooling for parameters to reduce GC pressure
20
- private paramObjectPool: Record<string, string>[] = [];
21
- private readonly maxPoolSize = 50;
22
-
23
- get(path: string, ...handlers: (Middleware | HttpHandler)[]): void {
24
- this.addRoute('GET', path, handlers);
25
- }
26
-
27
- post(path: string, ...handlers: (Middleware | HttpHandler)[]): void {
28
- this.addRoute('POST', path, handlers);
29
- }
30
-
31
- put(path: string, ...handlers: (Middleware | HttpHandler)[]): void {
32
- this.addRoute('PUT', path, handlers);
33
- }
34
-
35
- delete(path: string, ...handlers: (Middleware | HttpHandler)[]): void {
36
- this.addRoute('DELETE', path, handlers);
37
- }
38
-
39
- patch(path: string, ...handlers: (Middleware | HttpHandler)[]): void {
40
- this.addRoute('PATCH', path, handlers);
41
- }
42
-
43
- private addRoute(method: string, path: string, handlers: (Middleware | HttpHandler)[]): void {
44
- const { pattern, paramNames } = this.pathToRegex(path);
45
- const handler = handlers.pop() as HttpHandler;
46
- const middleware = handlers as Middleware[];
47
-
48
- const route: RouteDefinition = {
49
- method,
50
- path,
51
- pattern,
52
- paramNames,
53
- handler,
54
- middleware,
55
- };
56
-
57
- // Add to routes array (maintain compatibility)
58
- this.routes.push(route);
59
-
60
- // Performance optimization: separate static and dynamic routes
61
- const isStatic = !path.includes(':') && !path.includes('*');
62
- if (isStatic && middleware.length === 0) {
63
- // Static route with no middleware - use O(1) lookup
64
- const routeKey = `${method}:${path}`;
65
- this.staticRoutes.set(routeKey, route);
66
- this.logger.debug(`Added static route: ${routeKey}`, 'FastRoute');
67
- } else {
68
- // Dynamic route or has middleware - needs regex matching
69
- this.dynamicRoutes.push(route);
70
- this.logger.debug(`Added dynamic route: ${method} ${path}`, 'DynamicRoute');
71
- }
72
-
73
- // Initialize object pool on first route
74
- if (this.paramObjectPool.length === 0) {
75
- for (let i = 0; i < this.maxPoolSize; i++) {
76
- this.paramObjectPool.push({});
77
- }
78
- }
79
- }
80
-
81
- private pathToRegex(path: string): { pattern: RegExp; paramNames: string[] } {
82
- const paramNames: string[] = [];
83
-
84
- // Convert parameterized routes to regex
85
- const regexPattern = path
86
- .replace(/\/:([^/]+)/g, (match, paramName) => {
87
- paramNames.push(paramName);
88
- return '/([^/]+)';
89
- })
90
- .replace(/\//g, '\\/');
91
-
92
- return {
93
- pattern: new RegExp(`^${regexPattern}$`),
94
- paramNames,
95
- };
96
- }
97
-
98
- async handle(req: HttpRequest, res: HttpResponse, basePath: string = ''): Promise<boolean> {
99
- let path = req.path.startsWith(basePath) ? req.path.substring(basePath.length) : req.path;
100
-
101
- // If removing basePath results in empty string, default to '/'
102
- if (path === '' || path === undefined) {
103
- path = '/';
104
- }
105
-
106
- this.logger.debug(
107
- `Router processing: originalPath="${req.path}", basePath="${basePath}", processedPath="${path}"`,
108
- 'Processing'
109
- );
110
-
111
- // PERFORMANCE OPTIMIZATION: Fast path - O(1) static route lookup first
112
- const routeKey = `${req.method}:${path}`;
113
- const staticRoute = this.staticRoutes.get(routeKey);
114
-
115
- if (staticRoute) {
116
- this.logger.debug(`Fast route match: ${routeKey}`, 'FastRoute');
117
-
118
- // Static route with no middleware - execute handler directly
119
- req.params = {}; // No params for static routes
120
- const result = await staticRoute.handler(req, res);
121
-
122
- // If handler returns data and response hasn't been sent, send it
123
- if (result !== undefined && result !== null && !res.headersSent) {
124
- res.json(result);
125
- }
126
-
127
- return true;
128
- }
129
-
130
- // Fallback: Dynamic route matching (with middleware support)
131
- const route = this.dynamicRoutes.find(r => r.method === req.method && r.pattern.test(path));
132
-
133
- this.logger.debug(
134
- `Found dynamic route: ${!!route}${route ? ` ${route.method} ${route.path}` : ' none'}`,
135
- 'RouteMatch'
136
- );
137
-
138
- if (!route) {
139
- return false; // Route not found
140
- }
141
-
142
- // Extract path parameters using object pooling
143
- const matches = path.match(route.pattern);
144
- if (matches) {
145
- req.params = this.acquireParamObject();
146
- route.paramNames.forEach((name, index) => {
147
- req.params[name] = matches[index + 1];
148
- });
149
- }
150
-
151
- try {
152
- // Execute middleware
153
- for (const mw of route.middleware) {
154
- await new Promise<void>((resolve, reject) => {
155
- let nextCalled = false;
156
-
157
- const next = () => {
158
- if (nextCalled) return;
159
- nextCalled = true;
160
- resolve();
161
- };
162
-
163
- try {
164
- const result = mw(req, res, next);
165
-
166
- if (result instanceof Promise) {
167
- result
168
- .then(() => {
169
- if (!nextCalled) next();
170
- })
171
- .catch(reject);
172
- }
173
- } catch (error) {
174
- reject(error);
175
- }
176
- });
177
-
178
- if (res.headersSent) break; // Early exit if response sent
179
- }
180
-
181
- // Execute handler
182
- const result = await route.handler(req, res);
183
-
184
- // If handler returns data and response hasn't been sent, send it
185
- if (result !== undefined && result !== null && !res.headersSent) {
186
- res.json(result);
187
- }
188
-
189
- return true;
190
- } finally {
191
- // Release parameter object back to pool
192
- if (req.params && matches) {
193
- this.releaseParamObject(req.params);
194
- }
195
- }
196
- }
197
-
198
- getRoutes(): RouteDefinition[] {
199
- return [...this.routes];
200
- }
201
-
202
- // Object pooling methods for performance optimization
203
- private acquireParamObject(): Record<string, string> {
204
- const obj = this.paramObjectPool.pop();
205
- if (obj) {
206
- // Clear the object
207
- for (const key in obj) {
208
- delete obj[key];
209
- }
210
- return obj;
211
- }
212
- return {};
213
- }
214
-
215
- private releaseParamObject(obj: Record<string, string>): void {
216
- if (this.paramObjectPool.length < this.maxPoolSize) {
217
- this.paramObjectPool.push(obj);
218
- }
219
- }
220
-
221
- // Performance statistics for monitoring
222
- getPerformanceStats() {
223
- return {
224
- totalRoutes: this.routes.length,
225
- staticRoutes: this.staticRoutes.size,
226
- dynamicRoutes: this.dynamicRoutes.length,
227
- paramObjectPoolSize: this.paramObjectPool.length,
228
- };
229
- }
230
- }