@morojs/moro 1.5.17 → 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.
Files changed (138) hide show
  1. package/README.md +48 -65
  2. package/dist/core/auth/morojs-adapter.js +12 -16
  3. package/dist/core/auth/morojs-adapter.js.map +1 -1
  4. package/dist/core/config/file-loader.d.ts +5 -0
  5. package/dist/core/config/file-loader.js +171 -0
  6. package/dist/core/config/file-loader.js.map +1 -1
  7. package/dist/core/config/index.d.ts +10 -39
  8. package/dist/core/config/index.js +29 -66
  9. package/dist/core/config/index.js.map +1 -1
  10. package/dist/core/config/loader.d.ts +7 -0
  11. package/dist/core/config/loader.js +269 -0
  12. package/dist/core/config/loader.js.map +1 -0
  13. package/dist/core/config/schema.js +31 -41
  14. package/dist/core/config/schema.js.map +1 -1
  15. package/dist/core/config/utils.d.ts +2 -9
  16. package/dist/core/config/utils.js +32 -19
  17. package/dist/core/config/utils.js.map +1 -1
  18. package/dist/core/config/validation.d.ts +17 -0
  19. package/dist/core/config/validation.js +131 -0
  20. package/dist/core/config/validation.js.map +1 -0
  21. package/dist/core/database/adapters/mongodb.d.ts +0 -10
  22. package/dist/core/database/adapters/mongodb.js +2 -23
  23. package/dist/core/database/adapters/mongodb.js.map +1 -1
  24. package/dist/core/database/adapters/mysql.d.ts +0 -11
  25. package/dist/core/database/adapters/mysql.js +0 -1
  26. package/dist/core/database/adapters/mysql.js.map +1 -1
  27. package/dist/core/database/adapters/postgresql.d.ts +1 -9
  28. package/dist/core/database/adapters/postgresql.js +1 -1
  29. package/dist/core/database/adapters/postgresql.js.map +1 -1
  30. package/dist/core/database/adapters/redis.d.ts +0 -9
  31. package/dist/core/database/adapters/redis.js +4 -14
  32. package/dist/core/database/adapters/redis.js.map +1 -1
  33. package/dist/core/framework.d.ts +7 -6
  34. package/dist/core/framework.js +16 -131
  35. package/dist/core/framework.js.map +1 -1
  36. package/dist/core/http/http-server.d.ts +0 -12
  37. package/dist/core/http/http-server.js +23 -151
  38. package/dist/core/http/http-server.js.map +1 -1
  39. package/dist/core/http/router.d.ts +0 -12
  40. package/dist/core/http/router.js +36 -114
  41. package/dist/core/http/router.js.map +1 -1
  42. package/dist/core/logger/filters.js +4 -12
  43. package/dist/core/logger/filters.js.map +1 -1
  44. package/dist/core/logger/index.d.ts +1 -1
  45. package/dist/core/logger/index.js +1 -2
  46. package/dist/core/logger/index.js.map +1 -1
  47. package/dist/core/logger/logger.d.ts +13 -29
  48. package/dist/core/logger/logger.js +203 -380
  49. package/dist/core/logger/logger.js.map +1 -1
  50. package/dist/core/logger/outputs.js +2 -0
  51. package/dist/core/logger/outputs.js.map +1 -1
  52. package/dist/core/middleware/built-in/auth.js +17 -88
  53. package/dist/core/middleware/built-in/auth.js.map +1 -1
  54. package/dist/core/middleware/built-in/cache.js +1 -3
  55. package/dist/core/middleware/built-in/cache.js.map +1 -1
  56. package/dist/core/middleware/built-in/index.d.ts +0 -1
  57. package/dist/core/middleware/built-in/index.js +1 -6
  58. package/dist/core/middleware/built-in/index.js.map +1 -1
  59. package/dist/core/middleware/built-in/request-logger.js +2 -3
  60. package/dist/core/middleware/built-in/request-logger.js.map +1 -1
  61. package/dist/core/middleware/built-in/sse.js +7 -9
  62. package/dist/core/middleware/built-in/sse.js.map +1 -1
  63. package/dist/core/modules/auto-discovery.d.ts +0 -17
  64. package/dist/core/modules/auto-discovery.js +12 -367
  65. package/dist/core/modules/auto-discovery.js.map +1 -1
  66. package/dist/core/modules/modules.js +2 -12
  67. package/dist/core/modules/modules.js.map +1 -1
  68. package/dist/core/networking/adapters/ws-adapter.d.ts +1 -1
  69. package/dist/core/networking/adapters/ws-adapter.js +2 -2
  70. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  71. package/dist/core/networking/service-discovery.js +7 -7
  72. package/dist/core/networking/service-discovery.js.map +1 -1
  73. package/dist/core/routing/index.d.ts +0 -20
  74. package/dist/core/routing/index.js +13 -178
  75. package/dist/core/routing/index.js.map +1 -1
  76. package/dist/core/runtime/node-adapter.js +6 -12
  77. package/dist/core/runtime/node-adapter.js.map +1 -1
  78. package/dist/moro.d.ts +0 -48
  79. package/dist/moro.js +148 -456
  80. package/dist/moro.js.map +1 -1
  81. package/dist/types/config.d.ts +2 -58
  82. package/dist/types/core.d.ts +40 -34
  83. package/dist/types/http.d.ts +1 -16
  84. package/dist/types/logger.d.ts +0 -7
  85. package/dist/types/module.d.ts +0 -11
  86. package/package.json +2 -2
  87. package/src/core/auth/morojs-adapter.ts +13 -18
  88. package/src/core/config/file-loader.ts +233 -0
  89. package/src/core/config/index.ts +32 -77
  90. package/src/core/config/loader.ts +633 -0
  91. package/src/core/config/schema.ts +31 -41
  92. package/src/core/config/utils.ts +29 -22
  93. package/src/core/config/validation.ts +140 -0
  94. package/src/core/database/README.md +16 -26
  95. package/src/core/database/adapters/mongodb.ts +2 -30
  96. package/src/core/database/adapters/mysql.ts +0 -14
  97. package/src/core/database/adapters/postgresql.ts +2 -12
  98. package/src/core/database/adapters/redis.ts +4 -27
  99. package/src/core/framework.ts +23 -163
  100. package/src/core/http/http-server.ts +36 -176
  101. package/src/core/http/router.ts +38 -127
  102. package/src/core/logger/filters.ts +4 -12
  103. package/src/core/logger/index.ts +0 -1
  104. package/src/core/logger/logger.ts +216 -427
  105. package/src/core/logger/outputs.ts +2 -0
  106. package/src/core/middleware/built-in/auth.ts +17 -98
  107. package/src/core/middleware/built-in/cache.ts +1 -3
  108. package/src/core/middleware/built-in/index.ts +0 -8
  109. package/src/core/middleware/built-in/request-logger.ts +1 -3
  110. package/src/core/middleware/built-in/sse.ts +7 -9
  111. package/src/core/modules/auto-discovery.ts +13 -476
  112. package/src/core/modules/modules.ts +9 -20
  113. package/src/core/networking/adapters/ws-adapter.ts +5 -2
  114. package/src/core/networking/service-discovery.ts +7 -6
  115. package/src/core/routing/index.ts +14 -198
  116. package/src/core/runtime/node-adapter.ts +6 -12
  117. package/src/moro.ts +166 -554
  118. package/src/types/config.ts +2 -59
  119. package/src/types/core.ts +45 -47
  120. package/src/types/http.ts +1 -23
  121. package/src/types/logger.ts +0 -9
  122. package/src/types/module.ts +0 -12
  123. package/dist/core/config/config-manager.d.ts +0 -44
  124. package/dist/core/config/config-manager.js +0 -114
  125. package/dist/core/config/config-manager.js.map +0 -1
  126. package/dist/core/config/config-sources.d.ts +0 -21
  127. package/dist/core/config/config-sources.js +0 -502
  128. package/dist/core/config/config-sources.js.map +0 -1
  129. package/dist/core/config/config-validator.d.ts +0 -21
  130. package/dist/core/config/config-validator.js +0 -765
  131. package/dist/core/config/config-validator.js.map +0 -1
  132. package/dist/core/middleware/built-in/jwt-helpers.d.ts +0 -118
  133. package/dist/core/middleware/built-in/jwt-helpers.js +0 -221
  134. package/dist/core/middleware/built-in/jwt-helpers.js.map +0 -1
  135. package/src/core/config/config-manager.ts +0 -133
  136. package/src/core/config/config-sources.ts +0 -596
  137. package/src/core/config/config-validator.ts +0 -1078
  138. package/src/core/middleware/built-in/jwt-helpers.ts +0 -240
@@ -11,15 +11,6 @@ interface RedisConfig {
11
11
  maxRetriesPerRequest?: number;
12
12
  retryDelayOnFailover?: number;
13
13
  lazyConnect?: boolean;
14
- tls?: {
15
- rejectUnauthorized?: boolean;
16
- ca?: string;
17
- cert?: string;
18
- key?: string;
19
- passphrase?: string;
20
- servername?: string;
21
- checkServerIdentity?: boolean;
22
- };
23
14
  cluster?: {
24
15
  enableReadyCheck?: boolean;
25
16
  redisOptions?: any;
@@ -39,20 +30,13 @@ export class RedisAdapter implements DatabaseAdapter {
39
30
 
40
31
  if (config.cluster) {
41
32
  // Redis Cluster
42
- const clusterOptions: any = {
33
+ this.client = new Redis.Cluster(config.cluster.nodes, {
43
34
  enableReadyCheck: config.cluster.enableReadyCheck || false,
44
35
  redisOptions: config.cluster.redisOptions || {},
45
- };
46
-
47
- // Add TLS options to cluster configuration
48
- if (config.tls) {
49
- clusterOptions.redisOptions.tls = { ...config.tls };
50
- }
51
-
52
- this.client = new Redis.Cluster(config.cluster.nodes, clusterOptions);
36
+ });
53
37
  } else {
54
38
  // Single Redis instance
55
- const redisOptions: any = {
39
+ this.client = new Redis({
56
40
  host: config.host || 'localhost',
57
41
  port: config.port || 6379,
58
42
  password: config.password,
@@ -60,14 +44,7 @@ export class RedisAdapter implements DatabaseAdapter {
60
44
  maxRetriesPerRequest: config.maxRetriesPerRequest || 3,
61
45
  retryDelayOnFailover: config.retryDelayOnFailover || 100,
62
46
  lazyConnect: config.lazyConnect || true,
63
- };
64
-
65
- // Add TLS options if provided
66
- if (config.tls) {
67
- redisOptions.tls = { ...config.tls };
68
- }
69
-
70
- this.client = new Redis(redisOptions);
47
+ });
71
48
  }
72
49
 
73
50
  this.client.on('error', (err: Error) => {
@@ -15,17 +15,19 @@ import { MoroEventBus } from './events';
15
15
  import { createFrameworkLogger, logger as globalLogger } from './logger';
16
16
  import { ModuleConfig, InternalRouteDefinition } from '../types/module';
17
17
  import { LogLevel, LoggerOptions } from '../types/logger';
18
- import { MoroOptions as CoreMoroOptions } from '../types/core';
19
18
  import { WebSocketAdapter, WebSocketAdapterOptions } from './networking/websocket-adapter';
20
19
 
21
- // Extended MoroOptions that includes both core options and framework-specific options
22
- export interface MoroOptions extends CoreMoroOptions {
20
+ export interface MoroOptions {
23
21
  http2?: boolean;
24
22
  https?: {
25
23
  key: string | Buffer;
26
24
  cert: string | Buffer;
27
25
  ca?: string | Buffer;
28
26
  };
27
+ compression?: {
28
+ enabled?: boolean;
29
+ threshold?: number;
30
+ };
29
31
  websocket?:
30
32
  | {
31
33
  enabled?: boolean;
@@ -35,7 +37,7 @@ export interface MoroOptions extends CoreMoroOptions {
35
37
  options?: WebSocketAdapterOptions;
36
38
  }
37
39
  | false;
38
- config?: any; // Full configuration object
40
+ logger?: LoggerOptions | boolean;
39
41
  }
40
42
 
41
43
  export class Moro extends EventEmitter {
@@ -52,12 +54,10 @@ export class Moro extends EventEmitter {
52
54
  // Framework logger
53
55
  private logger: any;
54
56
  private options: MoroOptions;
55
- private config: any;
56
57
 
57
58
  constructor(options: MoroOptions = {}) {
58
59
  super();
59
60
  this.options = options;
60
- this.config = options.config || {};
61
61
 
62
62
  // Configure global logger based on options
63
63
  if (options.logger !== undefined) {
@@ -106,11 +106,8 @@ export class Moro extends EventEmitter {
106
106
  this.container = new Container();
107
107
  this.moduleLoader = new ModuleLoader(this.container);
108
108
 
109
- // Setup WebSocket adapter if enabled in config OR options
110
- if (
111
- this.config.websocket.enabled ||
112
- (options.websocket && typeof options.websocket === 'object')
113
- ) {
109
+ // Setup WebSocket adapter if enabled
110
+ if (options.websocket !== false) {
114
111
  this.setupWebSockets(options.websocket || {});
115
112
  }
116
113
 
@@ -134,49 +131,19 @@ export class Moro extends EventEmitter {
134
131
  }
135
132
 
136
133
  private setupCore() {
137
- // PERFORMANCE FIX: Only apply middleware if enabled in config OR options
138
-
139
- // Security middleware - check config enabled property OR options.security.*.enabled === true
140
- if (this.config.security.helmet.enabled || this.options.security?.helmet?.enabled === true) {
141
- this.httpServer.use(middleware.helmet());
142
- }
134
+ // Security middleware
135
+ this.httpServer.use(middleware.helmet());
136
+ this.httpServer.use(middleware.cors());
143
137
 
144
- if (this.config.security.cors.enabled || this.options.security?.cors?.enabled === true) {
145
- const corsOptions =
146
- typeof this.options.cors === 'object'
147
- ? this.options.cors
148
- : this.config.security.cors
149
- ? this.config.security.cors
150
- : {};
151
- this.httpServer.use(middleware.cors(corsOptions));
152
- }
153
-
154
- // Performance middleware - check config enabled property OR options.performance.*.enabled === true
155
- if (
156
- this.config.performance.compression.enabled ||
157
- this.options.performance?.compression?.enabled === true
158
- ) {
159
- const compressionOptions =
160
- typeof this.options.compression === 'object'
161
- ? this.options.compression
162
- : this.config.performance.compression
163
- ? this.config.performance.compression
164
- : {};
165
- this.httpServer.use(middleware.compression(compressionOptions));
166
- }
138
+ // Performance middleware
139
+ this.httpServer.use(middleware.compression());
140
+ this.httpServer.use(middleware.bodySize({ limit: '10mb' }));
167
141
 
168
- // Body size middleware - always enabled with configurable limit
169
- this.httpServer.use(middleware.bodySize({ limit: this.config.server.bodySizeLimit }));
142
+ // Request tracking middleware
143
+ this.httpServer.use(this.requestTrackingMiddleware());
170
144
 
171
- // Request tracking middleware - configurable
172
- if (this.config.server.requestTracking.enabled) {
173
- this.httpServer.use(this.requestTrackingMiddleware());
174
- }
175
-
176
- // Error boundary middleware - configurable but recommended to keep enabled
177
- if (this.config.server.errorBoundary.enabled) {
178
- this.httpServer.use(this.errorBoundaryMiddleware());
179
- }
145
+ // Error boundary middleware
146
+ this.httpServer.use(this.errorBoundaryMiddleware());
180
147
  }
181
148
 
182
149
  /**
@@ -444,76 +411,6 @@ export class Moro extends EventEmitter {
444
411
  throw new Error(`Handler ${route.handler} is not a function`);
445
412
  }
446
413
 
447
- // Check authentication if auth configuration is provided
448
- if ((route as any).auth) {
449
- const auth = (req as any).auth;
450
- const authConfig = (route as any).auth;
451
-
452
- if (!auth) {
453
- res.status(401);
454
- res.json({
455
- success: false,
456
- error: 'Authentication required',
457
- message: 'You must be logged in to access this resource',
458
- });
459
- return;
460
- }
461
-
462
- // Check authentication requirement (default is required unless optional: true)
463
- if (!authConfig.optional && !auth.isAuthenticated) {
464
- res.status(401);
465
- res.json({
466
- success: false,
467
- error: 'Authentication required',
468
- message: 'You must be logged in to access this resource',
469
- });
470
- return;
471
- }
472
-
473
- // Skip further checks if not authenticated but optional
474
- if (!auth.isAuthenticated && authConfig.optional) {
475
- // Continue to handler
476
- } else if (auth.isAuthenticated) {
477
- const user = auth.user;
478
-
479
- // Check roles if specified
480
- if (authConfig.roles && authConfig.roles.length > 0) {
481
- const userRoles = user?.roles || [];
482
- const hasRole = authConfig.roles.some((role: string) => userRoles.includes(role));
483
-
484
- if (!hasRole) {
485
- res.status(403);
486
- res.json({
487
- success: false,
488
- error: 'Insufficient permissions',
489
- message: `Required roles: ${authConfig.roles.join(', ')}`,
490
- userRoles,
491
- });
492
- return;
493
- }
494
- }
495
-
496
- // Check permissions if specified
497
- if (authConfig.permissions && authConfig.permissions.length > 0) {
498
- const userPermissions = user?.permissions || [];
499
- const hasPermission = authConfig.permissions.every((permission: string) =>
500
- userPermissions.includes(permission)
501
- );
502
-
503
- if (!hasPermission) {
504
- res.status(403);
505
- res.json({
506
- success: false,
507
- error: 'Insufficient permissions',
508
- message: `Required permissions: ${authConfig.permissions.join(', ')}`,
509
- userPermissions,
510
- });
511
- return;
512
- }
513
- }
514
- }
515
- }
516
-
517
414
  // Validate request if validation schema is provided
518
415
  if (route.validation) {
519
416
  try {
@@ -619,61 +516,22 @@ export class Moro extends EventEmitter {
619
516
  this.logger.debug(`Mounting router for basePath: ${basePath}`, 'Router');
620
517
 
621
518
  // Enterprise-grade middleware integration with performance optimization
622
- // IMPORTANT: Module middleware runs AFTER user middleware (like auth) to ensure proper order
623
519
  this.httpServer.use(async (req: HttpRequest, res: HttpResponse, next: () => void) => {
624
520
  if (req.path.startsWith(basePath)) {
625
521
  this.logger.debug(`Module middleware handling: ${req.method} ${req.path}`, 'Middleware', {
626
522
  basePath,
627
523
  });
628
524
 
629
- // Mark this request as being handled by a module
630
- (req as any).__moduleBasePath = basePath;
631
- (req as any).__moduleRouter = router;
632
-
633
- // Continue to next middleware (including auth) first
634
- next();
635
- } else {
636
- next();
637
- }
638
- });
639
-
640
- this.logger.info(`Router mounted for ${basePath}`, 'Router');
641
- }
642
-
643
- private finalModuleHandlerSetup = false;
644
-
645
- // Setup final module handler that runs after all user middleware
646
- setupFinalModuleHandler(): void {
647
- // Prevent duplicate setup
648
- if (this.finalModuleHandlerSetup) {
649
- this.logger.debug('Final module handler already set up, skipping', 'ModuleSystem');
650
- return;
651
- }
652
- this.finalModuleHandlerSetup = true;
653
-
654
- this.logger.info(
655
- 'Setting up final module handler to run after user middleware',
656
- 'ModuleSystem'
657
- );
658
-
659
- this.httpServer.use(async (req: HttpRequest, res: HttpResponse, next: () => void) => {
660
- // Check if this request was marked for module handling
661
- const moduleBasePath = (req as any).__moduleBasePath;
662
- const moduleRouter = (req as any).__moduleRouter;
663
-
664
- if (moduleBasePath && moduleRouter && !res.headersSent) {
665
- this.logger.debug(`Final module handler processing: ${req.method} ${req.path}`, 'Router');
666
-
667
525
  try {
668
- const handled = await moduleRouter.handle(req, res, moduleBasePath);
669
- this.logger.debug(`Route handled by module: ${handled}`, 'Router');
526
+ const handled = await router.handle(req, res, basePath);
527
+ this.logger.debug(`Route handled: ${handled}`, 'Router');
670
528
 
671
529
  if (!handled) {
672
530
  next(); // Let other middleware handle it
673
531
  }
674
532
  // If handled, the router already sent the response, so don't call next()
675
533
  } catch (error) {
676
- this.logger.error('Module router error', 'Router', {
534
+ this.logger.error('Router error', 'Router', {
677
535
  error: error instanceof Error ? error.message : String(error),
678
536
  });
679
537
  if (!res.headersSent) {
@@ -684,6 +542,8 @@ export class Moro extends EventEmitter {
684
542
  next();
685
543
  }
686
544
  });
545
+
546
+ this.logger.info(`Router mounted for ${basePath}`, 'Router');
687
547
  }
688
548
 
689
549
  private async setupWebSocketHandlers(config: ModuleConfig): Promise<void> {
@@ -26,11 +26,6 @@ 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
-
34
29
  // String interning for common values (massive memory savings)
35
30
  private static readonly INTERNED_METHODS = new Map([
36
31
  ['GET', 'GET'],
@@ -286,13 +281,18 @@ export class MoroHttpServer {
286
281
  await route.handler(httpReq, httpRes);
287
282
  } catch (error) {
288
283
  // Debug: Log the actual error and where it came from
289
- this.logger.debug('Request error details', 'RequestHandler', {
290
- errorType: typeof error,
291
- errorMessage: error instanceof Error ? error.message : String(error),
292
- errorStack: error instanceof Error ? error.stack : 'No stack trace',
293
- requestPath: req.url,
294
- requestMethod: req.method,
295
- });
284
+ this.logger.debug('🚨 MoroJS Request Error Details:', 'RequestHandler');
285
+ this.logger.debug(`📍 Error type: ${typeof error}`, 'RequestHandler');
286
+ this.logger.debug(
287
+ `📍 Error message: ${error instanceof Error ? error.message : String(error)}`,
288
+ 'RequestHandler'
289
+ );
290
+ this.logger.debug(
291
+ `📍 Error stack: ${error instanceof Error ? error.stack : 'No stack trace'}`,
292
+ 'RequestHandler'
293
+ );
294
+ this.logger.debug(`📍 Request path: ${req.url}`, 'RequestHandler');
295
+ this.logger.debug(`📍 Request method: ${req.method}`, 'RequestHandler');
296
296
 
297
297
  this.logger.error('Request error', 'RequestHandler', {
298
298
  error: error instanceof Error ? error.message : String(error),
@@ -316,10 +316,14 @@ export class MoroHttpServer {
316
316
  httpRes.setHeader('Content-Type', 'application/json');
317
317
  } else {
318
318
  // Even setHeader doesn't exist - object is completely wrong
319
- this.logger.error('Response object is not a proper ServerResponse', 'RequestHandler', {
320
- responseType: typeof httpRes,
321
- responseKeys: Object.keys(httpRes),
322
- });
319
+ this.logger.error(
320
+ '❌ Response object is not a proper ServerResponse:',
321
+ 'RequestHandler',
322
+ {
323
+ responseType: typeof httpRes,
324
+ responseKeys: Object.keys(httpRes),
325
+ }
326
+ );
323
327
  }
324
328
 
325
329
  if (typeof httpRes.end === 'function') {
@@ -332,7 +336,7 @@ export class MoroHttpServer {
332
336
  );
333
337
  } else {
334
338
  this.logger.error(
335
- 'Cannot send error response - end() method missing',
339
+ 'Cannot send error response - end() method missing',
336
340
  'RequestHandler'
337
341
  );
338
342
  }
@@ -497,20 +501,6 @@ export class MoroHttpServer {
497
501
  httpRes.json = async (data: any) => {
498
502
  if (httpRes.headersSent) return;
499
503
 
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
-
514
504
  // Ultra-fast JSON serialization with zero-copy buffers
515
505
  let jsonString: string;
516
506
 
@@ -597,12 +587,6 @@ export class MoroHttpServer {
597
587
  });
598
588
 
599
589
  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
-
606
590
  // Return buffer to pool after response (zero-copy achievement!)
607
591
  process.nextTick(() => MoroHttpServer.returnBuffer(buffer));
608
592
  };
@@ -631,26 +615,6 @@ export class MoroHttpServer {
631
615
  };
632
616
 
633
617
  httpRes.cookie = (name: string, value: string, options: any = {}) => {
634
- if (httpRes.headersSent) {
635
- const isCritical =
636
- options.critical ||
637
- name.includes('session') ||
638
- name.includes('auth') ||
639
- name.includes('csrf');
640
- const message = `Cookie '${name}' could not be set - headers already sent`;
641
-
642
- if (isCritical || options.throwOnLateSet) {
643
- throw new Error(`${message}. This may cause authentication or security issues.`);
644
- } else {
645
- this.logger.warn(message, 'CookieWarning', {
646
- cookieName: name,
647
- critical: isCritical,
648
- stackTrace: new Error().stack,
649
- });
650
- }
651
- return httpRes;
652
- }
653
-
654
618
  const cookieValue = encodeURIComponent(value);
655
619
  let cookieString = `${name}=${cookieValue}`;
656
620
 
@@ -714,62 +678,6 @@ export class MoroHttpServer {
714
678
  }
715
679
  };
716
680
 
717
- // Header management utilities
718
- httpRes.hasHeader = (name: string): boolean => {
719
- return httpRes.getHeader(name) !== undefined;
720
- };
721
-
722
- // Note: removeHeader is inherited from ServerResponse, we don't override it
723
-
724
- httpRes.setBulkHeaders = (headers: Record<string, string | number>) => {
725
- if (httpRes.headersSent) {
726
- this.logger.warn('Cannot set headers - headers already sent', 'HeaderWarning', {
727
- attemptedHeaders: Object.keys(headers),
728
- });
729
- return httpRes;
730
- }
731
-
732
- Object.entries(headers).forEach(([key, value]) => {
733
- httpRes.setHeader(key, value);
734
- });
735
- return httpRes;
736
- };
737
-
738
- httpRes.appendHeader = (name: string, value: string | string[]) => {
739
- if (httpRes.headersSent) {
740
- this.logger.warn(
741
- `Cannot append to header '${name}' - headers already sent`,
742
- 'HeaderWarning'
743
- );
744
- return httpRes;
745
- }
746
-
747
- const existing = httpRes.getHeader(name);
748
- if (existing) {
749
- const values = Array.isArray(existing) ? existing : [existing.toString()];
750
- const newValues = Array.isArray(value) ? value : [value];
751
- httpRes.setHeader(name, [...values, ...newValues]);
752
- } else {
753
- httpRes.setHeader(name, value);
754
- }
755
- return httpRes;
756
- };
757
-
758
- // Response state utilities
759
- httpRes.canSetHeaders = (): boolean => {
760
- return !httpRes.headersSent;
761
- };
762
-
763
- httpRes.getResponseState = () => {
764
- return {
765
- headersSent: httpRes.headersSent,
766
- statusCode: httpRes.statusCode,
767
- headers: httpRes.getHeaders ? httpRes.getHeaders() : {},
768
- finished: httpRes.finished || false,
769
- writable: httpRes.writable,
770
- };
771
- };
772
-
773
681
  return httpRes;
774
682
  }
775
683
 
@@ -1015,9 +923,7 @@ export class MoroHttpServer {
1015
923
  .then(() => {
1016
924
  if (!nextCalled) next();
1017
925
  })
1018
- .catch(error => {
1019
- reject(error);
1020
- });
926
+ .catch(reject);
1021
927
  }
1022
928
  } catch (error) {
1023
929
  reject(error);
@@ -1056,47 +962,6 @@ export class MoroHttpServer {
1056
962
  getServer(): Server {
1057
963
  return this.server;
1058
964
  }
1059
-
1060
- // PERFORMANCE OPTIMIZATION: Generate cache key for common response patterns
1061
- private getResponseCacheKey(data: any): string | null {
1062
- // Only cache simple, common responses
1063
- if (!data || typeof data !== 'object') {
1064
- // Simple primitives or strings - generate key
1065
- const key = JSON.stringify(data);
1066
- return key.length < 100 ? key : null;
1067
- }
1068
-
1069
- // Common API response patterns
1070
- if ('hello' in data && Object.keys(data).length <= 2) {
1071
- // Hello world type responses
1072
- return `hello:${JSON.stringify(data)}`;
1073
- }
1074
-
1075
- if ('status' in data && Object.keys(data).length <= 3) {
1076
- // Status responses like {status: "ok", version: "1.0.0"}
1077
- return `status:${JSON.stringify(data)}`;
1078
- }
1079
-
1080
- if ('success' in data && 'message' in data && Object.keys(data).length <= 3) {
1081
- // Simple success/error responses
1082
- return `msg:${data.success}:${data.message}`;
1083
- }
1084
-
1085
- // Don't cache complex objects
1086
- return null;
1087
- }
1088
-
1089
- // Performance statistics
1090
- getPerformanceStats() {
1091
- return {
1092
- responseCacheHits: this.responseCacheHits,
1093
- responseCacheMisses: this.responseCacheMisses,
1094
- responseCacheSize: this.responseCache.size,
1095
- paramObjectPoolSize: this.paramObjectPool.length,
1096
- bufferPoolSize: this.bufferPool.length,
1097
- middlewareExecutionCacheSize: this.middlewareExecutionCache.size,
1098
- };
1099
- }
1100
965
  }
1101
966
 
1102
967
  // Built-in middleware
@@ -1153,25 +1018,23 @@ export const middleware = {
1153
1018
  }
1154
1019
 
1155
1020
  if (acceptEncoding.includes('gzip')) {
1021
+ res.setHeader('Content-Encoding', 'gzip');
1156
1022
  zlib.gzip(buffer, { level }, (err: any, compressed: Buffer) => {
1157
1023
  if (err) {
1158
1024
  return isJson ? originalJson.call(res, data) : originalSend.call(res, data);
1159
1025
  }
1160
- if (!res.headersSent) {
1161
- res.setHeader('Content-Encoding', 'gzip');
1162
- res.setHeader('Content-Length', compressed.length);
1163
- }
1026
+ res.setHeader('Content-Length', compressed.length);
1027
+ res.writeHead(res.statusCode || 200, res.getHeaders());
1164
1028
  res.end(compressed);
1165
1029
  });
1166
1030
  } else if (acceptEncoding.includes('deflate')) {
1031
+ res.setHeader('Content-Encoding', 'deflate');
1167
1032
  zlib.deflate(buffer, { level }, (err: any, compressed: Buffer) => {
1168
1033
  if (err) {
1169
1034
  return isJson ? originalJson.call(res, data) : originalSend.call(res, data);
1170
1035
  }
1171
- if (!res.headersSent) {
1172
- res.setHeader('Content-Encoding', 'deflate');
1173
- res.setHeader('Content-Length', compressed.length);
1174
- }
1036
+ res.setHeader('Content-Length', compressed.length);
1037
+ res.writeHead(res.statusCode || 200, res.getHeaders());
1175
1038
  res.end(compressed);
1176
1039
  });
1177
1040
  } else {
@@ -1599,15 +1462,13 @@ export const middleware = {
1599
1462
  // Only handle SSE requests
1600
1463
  if (req.headers.accept?.includes('text/event-stream')) {
1601
1464
  // Set SSE headers
1602
- if (!res.headersSent) {
1603
- res.writeHead(200, {
1604
- 'Content-Type': 'text/event-stream',
1605
- 'Cache-Control': 'no-cache',
1606
- Connection: 'keep-alive',
1607
- 'Access-Control-Allow-Origin': options.cors ? '*' : undefined,
1608
- 'Access-Control-Allow-Headers': options.cors ? 'Cache-Control' : undefined,
1609
- });
1610
- }
1465
+ res.writeHead(200, {
1466
+ 'Content-Type': 'text/event-stream',
1467
+ 'Cache-Control': 'no-cache',
1468
+ Connection: 'keep-alive',
1469
+ 'Access-Control-Allow-Origin': options.cors ? '*' : undefined,
1470
+ 'Access-Control-Allow-Headers': options.cors ? 'Cache-Control' : undefined,
1471
+ });
1611
1472
 
1612
1473
  // Add SSE methods to response
1613
1474
  (res as any).sendEvent = (data: any, event?: string, id?: string) => {
@@ -1708,8 +1569,7 @@ export const middleware = {
1708
1569
  const chunkSize = end - start + 1;
1709
1570
 
1710
1571
  if (start >= fileSize || end >= fileSize) {
1711
- res.status(416);
1712
- res.setHeader('Content-Range', `bytes */${fileSize}`);
1572
+ res.status(416).setHeader('Content-Range', `bytes */${fileSize}`);
1713
1573
  res.json({ success: false, error: 'Range not satisfiable' });
1714
1574
  return;
1715
1575
  }