@morojs/moro 1.5.5 → 1.5.6

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 (70) hide show
  1. package/dist/core/config/config-manager.d.ts +44 -0
  2. package/dist/core/config/config-manager.js +114 -0
  3. package/dist/core/config/config-manager.js.map +1 -0
  4. package/dist/core/config/config-sources.d.ts +21 -0
  5. package/dist/core/config/config-sources.js +314 -0
  6. package/dist/core/config/config-sources.js.map +1 -0
  7. package/dist/core/config/config-validator.d.ts +21 -0
  8. package/dist/core/config/config-validator.js +737 -0
  9. package/dist/core/config/config-validator.js.map +1 -0
  10. package/dist/core/config/file-loader.d.ts +0 -5
  11. package/dist/core/config/file-loader.js +0 -171
  12. package/dist/core/config/file-loader.js.map +1 -1
  13. package/dist/core/config/index.d.ts +39 -10
  14. package/dist/core/config/index.js +66 -29
  15. package/dist/core/config/index.js.map +1 -1
  16. package/dist/core/config/schema.js +22 -31
  17. package/dist/core/config/schema.js.map +1 -1
  18. package/dist/core/config/utils.d.ts +9 -2
  19. package/dist/core/config/utils.js +19 -32
  20. package/dist/core/config/utils.js.map +1 -1
  21. package/dist/core/framework.d.ts +2 -7
  22. package/dist/core/framework.js +12 -5
  23. package/dist/core/framework.js.map +1 -1
  24. package/dist/core/http/http-server.d.ts +12 -0
  25. package/dist/core/http/http-server.js +56 -0
  26. package/dist/core/http/http-server.js.map +1 -1
  27. package/dist/core/http/router.d.ts +12 -0
  28. package/dist/core/http/router.js +114 -36
  29. package/dist/core/http/router.js.map +1 -1
  30. package/dist/core/logger/index.d.ts +1 -1
  31. package/dist/core/logger/index.js +2 -1
  32. package/dist/core/logger/index.js.map +1 -1
  33. package/dist/core/logger/logger.d.ts +9 -1
  34. package/dist/core/logger/logger.js +36 -3
  35. package/dist/core/logger/logger.js.map +1 -1
  36. package/dist/core/routing/index.d.ts +20 -0
  37. package/dist/core/routing/index.js +109 -11
  38. package/dist/core/routing/index.js.map +1 -1
  39. package/dist/moro.d.ts +7 -20
  40. package/dist/moro.js +97 -192
  41. package/dist/moro.js.map +1 -1
  42. package/dist/types/config.d.ts +39 -2
  43. package/dist/types/core.d.ts +22 -39
  44. package/dist/types/logger.d.ts +4 -0
  45. package/package.json +1 -1
  46. package/src/core/config/config-manager.ts +133 -0
  47. package/src/core/config/config-sources.ts +384 -0
  48. package/src/core/config/config-validator.ts +1035 -0
  49. package/src/core/config/file-loader.ts +0 -233
  50. package/src/core/config/index.ts +77 -32
  51. package/src/core/config/schema.ts +22 -31
  52. package/src/core/config/utils.ts +22 -29
  53. package/src/core/framework.ts +18 -11
  54. package/src/core/http/http-server.ts +66 -0
  55. package/src/core/http/router.ts +127 -38
  56. package/src/core/logger/index.ts +1 -0
  57. package/src/core/logger/logger.ts +43 -4
  58. package/src/core/routing/index.ts +116 -12
  59. package/src/moro.ts +105 -225
  60. package/src/types/config.ts +40 -2
  61. package/src/types/core.ts +32 -43
  62. package/src/types/logger.ts +6 -0
  63. package/dist/core/config/loader.d.ts +0 -7
  64. package/dist/core/config/loader.js +0 -269
  65. package/dist/core/config/loader.js.map +0 -1
  66. package/dist/core/config/validation.d.ts +0 -17
  67. package/dist/core/config/validation.js +0 -131
  68. package/dist/core/config/validation.js.map +0 -1
  69. package/src/core/config/loader.ts +0 -633
  70. package/src/core/config/validation.ts +0 -140
@@ -26,6 +26,11 @@ export class MoroHttpServer {
26
26
  // Request handler pooling to avoid function creation overhead
27
27
  private middlewareExecutionCache = new Map<string, Function>();
28
28
 
29
+ // Response caching for ultra-fast common responses
30
+ private responseCache = new Map<string, Buffer>();
31
+ private responseCacheHits = 0;
32
+ private responseCacheMisses = 0;
33
+
29
34
  // String interning for common values (massive memory savings)
30
35
  private static readonly INTERNED_METHODS = new Map([
31
36
  ['GET', 'GET'],
@@ -492,6 +497,20 @@ export class MoroHttpServer {
492
497
  httpRes.json = async (data: any) => {
493
498
  if (httpRes.headersSent) return;
494
499
 
500
+ // PERFORMANCE OPTIMIZATION: Check response cache for common patterns
501
+ const cacheKey = this.getResponseCacheKey(data);
502
+ if (cacheKey) {
503
+ const cachedBuffer = this.responseCache.get(cacheKey);
504
+ if (cachedBuffer) {
505
+ this.responseCacheHits++;
506
+ httpRes.setHeader('Content-Type', 'application/json; charset=utf-8');
507
+ httpRes.setHeader('Content-Length', cachedBuffer.length);
508
+ httpRes.end(cachedBuffer);
509
+ return;
510
+ }
511
+ this.responseCacheMisses++;
512
+ }
513
+
495
514
  // Ultra-fast JSON serialization with zero-copy buffers
496
515
  let jsonString: string;
497
516
 
@@ -578,6 +597,12 @@ export class MoroHttpServer {
578
597
  });
579
598
 
580
599
  httpRes.end(finalBuffer);
600
+
601
+ // PERFORMANCE OPTIMIZATION: Cache small, common responses
602
+ if (cacheKey && finalBuffer.length < 1024 && this.responseCache.size < 100) {
603
+ this.responseCache.set(cacheKey, Buffer.from(finalBuffer));
604
+ }
605
+
581
606
  // Return buffer to pool after response (zero-copy achievement!)
582
607
  process.nextTick(() => MoroHttpServer.returnBuffer(buffer));
583
608
  };
@@ -953,6 +978,47 @@ export class MoroHttpServer {
953
978
  getServer(): Server {
954
979
  return this.server;
955
980
  }
981
+
982
+ // PERFORMANCE OPTIMIZATION: Generate cache key for common response patterns
983
+ private getResponseCacheKey(data: any): string | null {
984
+ // Only cache simple, common responses
985
+ if (!data || typeof data !== 'object') {
986
+ // Simple primitives or strings - generate key
987
+ const key = JSON.stringify(data);
988
+ return key.length < 100 ? key : null;
989
+ }
990
+
991
+ // Common API response patterns
992
+ if ('hello' in data && Object.keys(data).length <= 2) {
993
+ // Hello world type responses
994
+ return `hello:${JSON.stringify(data)}`;
995
+ }
996
+
997
+ if ('status' in data && Object.keys(data).length <= 3) {
998
+ // Status responses like {status: "ok", version: "1.0.0"}
999
+ return `status:${JSON.stringify(data)}`;
1000
+ }
1001
+
1002
+ if ('success' in data && 'message' in data && Object.keys(data).length <= 3) {
1003
+ // Simple success/error responses
1004
+ return `msg:${data.success}:${data.message}`;
1005
+ }
1006
+
1007
+ // Don't cache complex objects
1008
+ return null;
1009
+ }
1010
+
1011
+ // Performance statistics
1012
+ getPerformanceStats() {
1013
+ return {
1014
+ responseCacheHits: this.responseCacheHits,
1015
+ responseCacheMisses: this.responseCacheMisses,
1016
+ responseCacheSize: this.responseCache.size,
1017
+ paramObjectPoolSize: this.paramObjectPool.length,
1018
+ bufferPoolSize: this.bufferPool.length,
1019
+ middlewareExecutionCacheSize: this.middlewareExecutionCache.size,
1020
+ };
1021
+ }
956
1022
  }
957
1023
 
958
1024
  // Built-in middleware
@@ -12,6 +12,14 @@ export class Router {
12
12
  private routes: RouteDefinition[] = [];
13
13
  private logger = createFrameworkLogger('Router');
14
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
+
15
23
  get(path: string, ...handlers: (Middleware | HttpHandler)[]): void {
16
24
  this.addRoute('GET', path, handlers);
17
25
  }
@@ -37,14 +45,37 @@ export class Router {
37
45
  const handler = handlers.pop() as HttpHandler;
38
46
  const middleware = handlers as Middleware[];
39
47
 
40
- this.routes.push({
48
+ const route: RouteDefinition = {
41
49
  method,
42
50
  path,
43
51
  pattern,
44
52
  paramNames,
45
53
  handler,
46
54
  middleware,
47
- });
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
+ }
48
79
  }
49
80
 
50
81
  private pathToRegex(path: string): { pattern: RegExp; paramNames: string[] } {
@@ -77,10 +108,30 @@ export class Router {
77
108
  'Processing'
78
109
  );
79
110
 
80
- const route = this.routes.find(r => r.method === req.method && r.pattern.test(path));
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));
81
132
 
82
133
  this.logger.debug(
83
- `Found route: ${!!route}${route ? ` ${route.method} ${route.path}` : ' none'}`,
134
+ `Found dynamic route: ${!!route}${route ? ` ${route.method} ${route.path}` : ' none'}`,
84
135
  'RouteMatch'
85
136
  );
86
137
 
@@ -88,54 +139,92 @@ export class Router {
88
139
  return false; // Route not found
89
140
  }
90
141
 
91
- // Extract path parameters
142
+ // Extract path parameters using object pooling
92
143
  const matches = path.match(route.pattern);
93
144
  if (matches) {
94
- req.params = {};
145
+ req.params = this.acquireParamObject();
95
146
  route.paramNames.forEach((name, index) => {
96
147
  req.params[name] = matches[index + 1];
97
148
  });
98
149
  }
99
150
 
100
- // Execute middleware
101
- for (const mw of route.middleware) {
102
- await new Promise<void>((resolve, reject) => {
103
- let nextCalled = false;
104
-
105
- const next = () => {
106
- if (nextCalled) return;
107
- nextCalled = true;
108
- resolve();
109
- };
110
-
111
- try {
112
- const result = mw(req, res, next);
113
-
114
- if (result instanceof Promise) {
115
- result
116
- .then(() => {
117
- if (!nextCalled) next();
118
- })
119
- .catch(reject);
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);
120
175
  }
121
- } catch (error) {
122
- reject(error);
123
- }
124
- });
125
- }
176
+ });
126
177
 
127
- // Execute handler
128
- const result = await route.handler(req, res);
178
+ if (res.headersSent) break; // Early exit if response sent
179
+ }
129
180
 
130
- // If handler returns data and response hasn't been sent, send it
131
- if (result !== undefined && result !== null && !res.headersSent) {
132
- res.json(result);
133
- }
181
+ // Execute handler
182
+ const result = await route.handler(req, res);
134
183
 
135
- return true;
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
+ }
136
196
  }
137
197
 
138
198
  getRoutes(): RouteDefinition[] {
139
199
  return [...this.routes];
140
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
+ }
141
230
  }
@@ -5,6 +5,7 @@ export {
5
5
  createFrameworkLogger,
6
6
  configureGlobalLogger,
7
7
  applyLoggingConfiguration,
8
+ destroyGlobalLogger,
8
9
  } from './logger';
9
10
  export * from './filters';
10
11
 
@@ -60,6 +60,7 @@ export class MoroLogger implements Logger {
60
60
  // Buffer overflow protection
61
61
  private bufferOverflowThreshold: number;
62
62
  private emergencyFlushInProgress = false;
63
+ private isDestroyed = false;
63
64
 
64
65
  // High-performance output methods
65
66
 
@@ -226,7 +227,9 @@ export class MoroLogger implements Logger {
226
227
  }
227
228
 
228
229
  child(context: string, metadata?: Record<string, any>): Logger {
229
- const childLogger = new MoroLogger(this.options);
230
+ // Create child logger with current parent level (not original options level)
231
+ const childOptions = { ...this.options, level: this.level };
232
+ const childLogger = new MoroLogger(childOptions);
230
233
  childLogger.contextPrefix = this.contextPrefix ? `${this.contextPrefix}:${context}` : context;
231
234
  childLogger.contextMetadata = { ...this.contextMetadata, ...metadata };
232
235
  childLogger.outputs = this.outputs;
@@ -242,6 +245,10 @@ export class MoroLogger implements Logger {
242
245
  this.level = level;
243
246
  }
244
247
 
248
+ getLevel(): LogLevel {
249
+ return this.level;
250
+ }
251
+
245
252
  addOutput(output: LogOutput): void {
246
253
  this.outputs.set(output.name, output);
247
254
  }
@@ -725,8 +732,8 @@ export class MoroLogger implements Logger {
725
732
  }
726
733
 
727
734
  private scheduleFlush(): void {
728
- if (this.flushTimeout) {
729
- return; // Already scheduled
735
+ if (this.flushTimeout || this.isDestroyed) {
736
+ return; // Already scheduled or destroyed
730
737
  }
731
738
 
732
739
  this.flushTimeout = setTimeout(() => {
@@ -734,7 +741,7 @@ export class MoroLogger implements Logger {
734
741
  }, this.flushInterval);
735
742
  }
736
743
 
737
- private flushBuffer(): void {
744
+ public flushBuffer(): void {
738
745
  if (this.outputBuffer.length === 0) {
739
746
  return;
740
747
  }
@@ -916,6 +923,30 @@ export class MoroLogger implements Logger {
916
923
  // Ignore flush errors
917
924
  }
918
925
  }
926
+
927
+ // Destroy logger and clean up all resources (for testing)
928
+ public destroy(): void {
929
+ // Mark as destroyed to prevent new timeouts
930
+ this.isDestroyed = true;
931
+
932
+ // Clear any remaining timeouts
933
+ if (this.flushTimeout) {
934
+ clearTimeout(this.flushTimeout);
935
+ this.flushTimeout = null;
936
+ }
937
+
938
+ // Flush any remaining buffer
939
+ this.flushBuffer();
940
+
941
+ // Clear outputs and filters
942
+ this.outputs.clear();
943
+ this.filters.clear();
944
+
945
+ // Clear history
946
+ this.history.length = 0;
947
+ this.historyIndex = 0;
948
+ this.historySize = 0;
949
+ }
919
950
  }
920
951
 
921
952
  // Global logger instance
@@ -942,6 +973,14 @@ export function configureGlobalLogger(options: Partial<LoggerOptions>): void {
942
973
  // For now, focusing on level which is the most critical
943
974
  }
944
975
 
976
+ /**
977
+ * Destroy the global logger and clean up resources (for testing)
978
+ * @internal
979
+ */
980
+ export function destroyGlobalLogger(): void {
981
+ logger.destroy();
982
+ }
983
+
945
984
  /**
946
985
  * Apply logging configuration from the config system and/or createApp options
947
986
  */
@@ -256,20 +256,91 @@ export class IntelligentRouteBuilder implements RouteBuilder {
256
256
 
257
257
  // Executable route with intelligent middleware ordering
258
258
  export class ExecutableRoute implements CompiledRoute {
259
- constructor(public readonly schema: RouteSchema) {}
259
+ // PERFORMANCE OPTIMIZATION: Pre-analyze route requirements
260
+ private readonly requiresAuth: boolean;
261
+ private readonly requiresValidation: boolean;
262
+ private readonly requiresRateLimit: boolean;
263
+ private readonly requiresCache: boolean;
264
+ private readonly hasBeforeMiddleware: boolean;
265
+ private readonly hasAfterMiddleware: boolean;
266
+ private readonly hasTransformMiddleware: boolean;
267
+ private readonly isFastPath: boolean;
268
+
269
+ constructor(public readonly schema: RouteSchema) {
270
+ // Pre-calculate what this route actually needs
271
+ this.requiresAuth = !!this.schema.auth;
272
+ this.requiresValidation = !!this.schema.validation;
273
+ this.requiresRateLimit = !!this.schema.rateLimit;
274
+ this.requiresCache = !!this.schema.cache;
275
+ this.hasBeforeMiddleware = !!this.schema.middleware?.before?.length;
276
+ this.hasAfterMiddleware = !!this.schema.middleware?.after?.length;
277
+ this.hasTransformMiddleware = !!this.schema.middleware?.transform?.length;
278
+
279
+ // Fast path: no middleware, no auth, no validation, no rate limiting
280
+ this.isFastPath =
281
+ !this.requiresAuth &&
282
+ !this.requiresValidation &&
283
+ !this.requiresRateLimit &&
284
+ !this.requiresCache &&
285
+ !this.hasBeforeMiddleware &&
286
+ !this.hasAfterMiddleware &&
287
+ !this.hasTransformMiddleware;
288
+
289
+ // Log fast path routes for monitoring
290
+ if (this.isFastPath) {
291
+ logger.debug(`Fast path route: ${this.schema.method} ${this.schema.path}`, 'FastPath');
292
+ }
293
+ }
260
294
 
261
295
  async execute(req: HttpRequest, res: HttpResponse): Promise<void> {
262
296
  const validatedReq = req as ValidatedRequest;
263
297
 
264
298
  try {
265
- // Execute middleware in intelligent order
266
- await this.executePhase('before', validatedReq, res);
267
- await this.executePhase('rateLimit', validatedReq, res);
268
- await this.executePhase('auth', validatedReq, res);
269
- await this.executePhase('validation', validatedReq, res);
270
- await this.executePhase('transform', validatedReq, res);
271
- await this.executePhase('cache', validatedReq, res);
272
- await this.executePhase('after', validatedReq, res);
299
+ // PERFORMANCE OPTIMIZATION: Fast path for simple routes
300
+ if (this.isFastPath) {
301
+ // Skip all middleware - execute handler directly
302
+ const result = await this.schema.handler(validatedReq, res);
303
+ if (result !== undefined && !res.headersSent) {
304
+ res.json(result);
305
+ }
306
+ return;
307
+ }
308
+
309
+ // Optimized middleware execution - only run what's needed
310
+ if (this.hasBeforeMiddleware) {
311
+ await this.executePhase('before', validatedReq, res);
312
+ if (res.headersSent) return;
313
+ }
314
+
315
+ if (this.requiresRateLimit) {
316
+ await this.executePhase('rateLimit', validatedReq, res);
317
+ if (res.headersSent) return;
318
+ }
319
+
320
+ if (this.requiresAuth) {
321
+ await this.executePhase('auth', validatedReq, res);
322
+ if (res.headersSent) return;
323
+ }
324
+
325
+ if (this.requiresValidation) {
326
+ await this.executePhase('validation', validatedReq, res);
327
+ if (res.headersSent) return;
328
+ }
329
+
330
+ if (this.hasTransformMiddleware) {
331
+ await this.executePhase('transform', validatedReq, res);
332
+ if (res.headersSent) return;
333
+ }
334
+
335
+ if (this.requiresCache) {
336
+ await this.executePhase('cache', validatedReq, res);
337
+ if (res.headersSent) return;
338
+ }
339
+
340
+ if (this.hasAfterMiddleware) {
341
+ await this.executePhase('after', validatedReq, res);
342
+ if (res.headersSent) return;
343
+ }
273
344
 
274
345
  // Execute handler last
275
346
  if (!res.headersSent) {
@@ -361,15 +432,32 @@ export class ExecutableRoute implements CompiledRoute {
361
432
  req: HttpRequest,
362
433
  res: HttpResponse
363
434
  ): Promise<void> {
435
+ // PERFORMANCE OPTIMIZATION: Reduce Promise overhead
364
436
  return new Promise((resolve, reject) => {
437
+ let resolved = false;
438
+
439
+ const next = () => {
440
+ if (!resolved) {
441
+ resolved = true;
442
+ resolve();
443
+ }
444
+ };
445
+
365
446
  try {
366
- const next = () => resolve();
367
447
  const result = middleware(req, res, next);
368
448
  if (result instanceof Promise) {
369
- result.then(() => resolve()).catch(reject);
449
+ result.then(() => !resolved && next()).catch(reject);
450
+ } else {
451
+ // Synchronous middleware - call next immediately if not called
452
+ if (!resolved) {
453
+ next();
454
+ }
370
455
  }
371
456
  } catch (error) {
372
- reject(error);
457
+ if (!resolved) {
458
+ resolved = true;
459
+ reject(error);
460
+ }
373
461
  }
374
462
  });
375
463
  }
@@ -475,6 +563,22 @@ export class ExecutableRoute implements CompiledRoute {
475
563
  config: this.schema.cache,
476
564
  });
477
565
  }
566
+
567
+ // Performance monitoring
568
+ getPerformanceInfo() {
569
+ return {
570
+ path: this.schema.path,
571
+ method: this.schema.method,
572
+ isFastPath: this.isFastPath,
573
+ requiresAuth: this.requiresAuth,
574
+ requiresValidation: this.requiresValidation,
575
+ requiresRateLimit: this.requiresRateLimit,
576
+ requiresCache: this.requiresCache,
577
+ hasBeforeMiddleware: this.hasBeforeMiddleware,
578
+ hasAfterMiddleware: this.hasAfterMiddleware,
579
+ hasTransformMiddleware: this.hasTransformMiddleware,
580
+ };
581
+ }
478
582
  }
479
583
 
480
584
  // Factory functions for creating routes