@mks2508/better-logger 2.0.1 → 3.0.0

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 (172) hide show
  1. package/.claude/settings.local.json +6 -1
  2. package/CHANGELOG.json +93 -1
  3. package/CHANGELOG.md +127 -0
  4. package/CLAUDE.md +14 -1
  5. package/README.md +111 -20
  6. package/bun.lock +333 -0
  7. package/dist/Logger.d.ts +851 -0
  8. package/dist/Logger.d.ts.map +1 -0
  9. package/dist/ScopedLogger.d.ts +57 -0
  10. package/dist/ScopedLogger.d.ts.map +1 -0
  11. package/dist/chunks/Logger-BCfx_yCK.js +2 -0
  12. package/dist/chunks/Logger-BCfx_yCK.js.map +1 -0
  13. package/dist/chunks/Logger-C126NTrD.js +4269 -0
  14. package/dist/chunks/Logger-C126NTrD.js.map +1 -0
  15. package/dist/chunks/RemoteLogHandler-CjWpWZGl.js +33 -0
  16. package/dist/chunks/RemoteLogHandler-CjWpWZGl.js.map +1 -0
  17. package/dist/chunks/RemoteLogHandler-ymkQ97xl.js +2 -0
  18. package/dist/chunks/RemoteLogHandler-ymkQ97xl.js.map +1 -0
  19. package/dist/chunks/environment-Ba5kShbx.js +4 -0
  20. package/dist/chunks/environment-Ba5kShbx.js.map +1 -0
  21. package/dist/chunks/environment-TI2ByCPT.js +1209 -0
  22. package/dist/chunks/environment-TI2ByCPT.js.map +1 -0
  23. package/dist/chunks/formatting-Blwy-f0W.js +2 -0
  24. package/dist/chunks/formatting-Blwy-f0W.js.map +1 -0
  25. package/dist/chunks/formatting-CuNUqGks.js +380 -0
  26. package/dist/chunks/formatting-CuNUqGks.js.map +1 -0
  27. package/dist/cli/CommandProcessor.d.ts +100 -0
  28. package/dist/cli/CommandProcessor.d.ts.map +1 -0
  29. package/dist/cli/commands/ConfigCommand.d.ts +14 -0
  30. package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
  31. package/dist/cli/commands/ExportCommand.d.ts +48 -0
  32. package/dist/cli/commands/ExportCommand.d.ts.map +1 -0
  33. package/dist/cli/commands/HistoryCommand.d.ts +47 -0
  34. package/dist/cli/commands/HistoryCommand.d.ts.map +1 -0
  35. package/dist/cli/commands/StatusCommand.d.ts +30 -0
  36. package/dist/cli/commands/StatusCommand.d.ts.map +1 -0
  37. package/dist/cli/commands/ThemeCommand.d.ts +30 -0
  38. package/dist/cli/commands/ThemeCommand.d.ts.map +1 -0
  39. package/dist/cli/help.d.ts +12 -0
  40. package/dist/cli/help.d.ts.map +1 -0
  41. package/dist/cli/index.d.ts +15 -0
  42. package/dist/cli/index.d.ts.map +1 -0
  43. package/dist/constants.d.ts +227 -0
  44. package/dist/constants.d.ts.map +1 -0
  45. package/dist/core.cjs +2 -0
  46. package/dist/core.cjs.map +1 -0
  47. package/dist/core.d.ts +127 -0
  48. package/dist/core.d.ts.map +1 -0
  49. package/dist/core.js +291 -0
  50. package/dist/core.js.map +1 -0
  51. package/dist/example.d.ts +18 -0
  52. package/dist/example.d.ts.map +1 -0
  53. package/dist/exports-module.d.ts +196 -0
  54. package/dist/exports-module.d.ts.map +1 -0
  55. package/dist/exports.cjs +2 -0
  56. package/dist/exports.cjs.map +1 -0
  57. package/dist/exports.js +238 -0
  58. package/dist/exports.js.map +1 -0
  59. package/dist/handlers/AnalyticsLogHandler.d.ts +8 -0
  60. package/dist/handlers/AnalyticsLogHandler.d.ts.map +1 -0
  61. package/dist/handlers/ExportLogHandler.d.ts +100 -0
  62. package/dist/handlers/ExportLogHandler.d.ts.map +1 -0
  63. package/dist/handlers/FileLogHandler.d.ts +33 -0
  64. package/dist/handlers/FileLogHandler.d.ts.map +1 -0
  65. package/dist/handlers/RemoteLogHandler.d.ts +11 -0
  66. package/dist/handlers/RemoteLogHandler.d.ts.map +1 -0
  67. package/dist/handlers/index.d.ts +8 -0
  68. package/dist/handlers/index.d.ts.map +1 -0
  69. package/dist/hooks/HookManager.d.ts +21 -0
  70. package/dist/hooks/HookManager.d.ts.map +1 -0
  71. package/dist/hooks/index.d.ts +2 -0
  72. package/dist/hooks/index.d.ts.map +1 -0
  73. package/dist/index.cjs +2 -0
  74. package/dist/index.cjs.map +1 -0
  75. package/dist/index.d.ts +144 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +478 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/main.d.ts +2 -0
  80. package/dist/main.d.ts.map +1 -0
  81. package/dist/serializers/SerializerRegistry.d.ts +16 -0
  82. package/dist/serializers/SerializerRegistry.d.ts.map +1 -0
  83. package/dist/serializers/index.d.ts +2 -0
  84. package/dist/serializers/index.d.ts.map +1 -0
  85. package/dist/styling/LogStyleBuilder.d.ts +146 -0
  86. package/dist/styling/LogStyleBuilder.d.ts.map +1 -0
  87. package/dist/styling/SemanticStyles.d.ts +178 -0
  88. package/dist/styling/SemanticStyles.d.ts.map +1 -0
  89. package/dist/styling/SmartPresets.d.ts +22 -0
  90. package/dist/styling/SmartPresets.d.ts.map +1 -0
  91. package/dist/styling/StyleBuilder.d.ts +140 -0
  92. package/dist/styling/StyleBuilder.d.ts.map +1 -0
  93. package/dist/styling/StyleCache.d.ts +42 -0
  94. package/dist/styling/StyleCache.d.ts.map +1 -0
  95. package/dist/styling/banners.d.ts +42 -0
  96. package/dist/styling/banners.d.ts.map +1 -0
  97. package/dist/styling/index.d.ts +10 -0
  98. package/dist/styling/index.d.ts.map +1 -0
  99. package/dist/styling/themes.d.ts +7 -0
  100. package/dist/styling/themes.d.ts.map +1 -0
  101. package/dist/styling-module.d.ts +178 -0
  102. package/dist/styling-module.d.ts.map +1 -0
  103. package/dist/styling.cjs +2 -0
  104. package/dist/styling.cjs.map +1 -0
  105. package/dist/styling.js +146 -0
  106. package/dist/styling.js.map +1 -0
  107. package/dist/terminal/terminal-renderer.d.ts +63 -0
  108. package/dist/terminal/terminal-renderer.d.ts.map +1 -0
  109. package/dist/transports/ConsoleTransport.d.ts +9 -0
  110. package/dist/transports/ConsoleTransport.d.ts.map +1 -0
  111. package/dist/transports/FileTransport.d.ts +15 -0
  112. package/dist/transports/FileTransport.d.ts.map +1 -0
  113. package/dist/transports/HttpTransport.d.ts +16 -0
  114. package/dist/transports/HttpTransport.d.ts.map +1 -0
  115. package/dist/transports/TransportManager.d.ts +14 -0
  116. package/dist/transports/TransportManager.d.ts.map +1 -0
  117. package/dist/transports/index.d.ts +5 -0
  118. package/dist/transports/index.d.ts.map +1 -0
  119. package/dist/types/core.d.ts +272 -0
  120. package/dist/types/core.d.ts.map +1 -0
  121. package/dist/types/handlers.d.ts +85 -0
  122. package/dist/types/handlers.d.ts.map +1 -0
  123. package/dist/types/hooks.d.ts +36 -0
  124. package/dist/types/hooks.d.ts.map +1 -0
  125. package/dist/types/index.d.ts +11 -0
  126. package/dist/types/index.d.ts.map +1 -0
  127. package/dist/types/serializers.d.ts +25 -0
  128. package/dist/types/serializers.d.ts.map +1 -0
  129. package/dist/types/transports.d.ts +47 -0
  130. package/dist/types/transports.d.ts.map +1 -0
  131. package/dist/utils/adapter.d.ts +48 -0
  132. package/dist/utils/adapter.d.ts.map +1 -0
  133. package/dist/utils/ansi-colors.d.ts +156 -0
  134. package/dist/utils/ansi-colors.d.ts.map +1 -0
  135. package/dist/utils/environment-detector.d.ts +35 -0
  136. package/dist/utils/environment-detector.d.ts.map +1 -0
  137. package/dist/utils/environment.d.ts +47 -0
  138. package/dist/utils/environment.d.ts.map +1 -0
  139. package/dist/utils/formatting.d.ts +58 -0
  140. package/dist/utils/formatting.d.ts.map +1 -0
  141. package/dist/utils/index.d.ts +8 -0
  142. package/dist/utils/index.d.ts.map +1 -0
  143. package/dist/utils/opentui-detection.d.ts +34 -0
  144. package/dist/utils/opentui-detection.d.ts.map +1 -0
  145. package/dist/utils/output.d.ts +46 -0
  146. package/dist/utils/output.d.ts.map +1 -0
  147. package/dist/utils/stackTrace.d.ts +6 -0
  148. package/dist/utils/stackTrace.d.ts.map +1 -0
  149. package/dist/utils/timestamps.d.ts +20 -0
  150. package/dist/utils/timestamps.d.ts.map +1 -0
  151. package/dist/vite.svg +1 -0
  152. package/docs/API.md +227 -0
  153. package/package.json +1 -1
  154. package/packages/core/package.json +1 -1
  155. package/src/Logger.ts +391 -102
  156. package/src/ScopedLogger.ts +78 -318
  157. package/src/hooks/HookManager.ts +177 -0
  158. package/src/hooks/index.ts +1 -0
  159. package/src/index.ts +77 -2
  160. package/src/serializers/SerializerRegistry.ts +173 -0
  161. package/src/serializers/index.ts +1 -0
  162. package/src/styling/StyleCache.ts +131 -0
  163. package/src/transports/ConsoleTransport.ts +28 -0
  164. package/src/transports/FileTransport.ts +53 -0
  165. package/src/transports/HttpTransport.ts +56 -0
  166. package/src/transports/TransportManager.ts +130 -0
  167. package/src/transports/index.ts +4 -0
  168. package/src/types/core.ts +46 -0
  169. package/src/types/hooks.ts +45 -0
  170. package/src/types/index.ts +39 -1
  171. package/src/types/serializers.ts +30 -0
  172. package/src/types/transports.ts +52 -0
package/src/Logger.ts CHANGED
@@ -17,9 +17,21 @@ import type {
17
17
  TimerEntry,
18
18
  ILogHandler,
19
19
  LogMetadata,
20
- StyleOptions
20
+ StyleOptions,
21
+ Bindings,
22
+ SerializerFn,
23
+ HookEvent,
24
+ HookCallback,
25
+ MiddlewareFn,
26
+ TransportTarget,
27
+ TransportRecord
21
28
  } from './types/index.js';
22
29
 
30
+ // Enterprise features
31
+ import { SerializerRegistry } from './serializers/index.js';
32
+ import { HookManager } from './hooks/index.js';
33
+ import { TransportManager } from './transports/index.js';
34
+
23
35
  // Utility imports
24
36
  import { parseStackTrace } from './utils/stackTrace.js';
25
37
  import { formatTimestamp } from './utils/timestamps.js';
@@ -39,6 +51,9 @@ import {
39
51
  import { getSmartPreset, getAvailablePresets, hasPreset } from './styling/SmartPresets.js';
40
52
  import { createLogStyleBuilder } from './styling/LogStyleBuilder.js';
41
53
 
54
+ // Scoped loggers (static import for performance)
55
+ import { ScopedLogger, APILogger, ComponentLogger } from './ScopedLogger.js';
56
+
42
57
  // Handler imports
43
58
  import { ExportLogHandler } from './handlers/index.js';
44
59
 
@@ -89,12 +104,17 @@ export class Logger {
89
104
  private exportHandler?: ExportLogHandler;
90
105
  private cliProcessor?: CommandProcessor;
91
106
  private themeChangeListener?: (() => void) | null;
107
+ private badgeList: string[] = [];
92
108
  private displaySettings = {
93
109
  showTimestamp: true,
94
110
  showLocation: true,
95
111
  showBadges: true
96
112
  };
97
113
 
114
+ private serializerRegistry: SerializerRegistry;
115
+ private hookManager: HookManager;
116
+ private transportManager?: TransportManager;
117
+
98
118
  /**
99
119
  * Crea una nueva instancia del Logger
100
120
  *
@@ -115,6 +135,10 @@ export class Logger {
115
135
  ...config,
116
136
  };
117
137
 
138
+ // Initialize enterprise features
139
+ this.serializerRegistry = new SerializerRegistry();
140
+ this.hookManager = new HookManager();
141
+
118
142
  // Initialize export handler if buffer size is specified
119
143
  if (this.config.bufferSize) {
120
144
  this.exportHandler = new ExportLogHandler(this.config.bufferSize);
@@ -123,7 +147,7 @@ export class Logger {
123
147
 
124
148
  // Initialize CLI processor
125
149
  this.cliProcessor = createDefaultCLI();
126
-
150
+
127
151
  // Set up theme change listener if auto-detection is enabled
128
152
  if (this.config.autoDetectTheme) {
129
153
  this.setupAutoThemeDetection();
@@ -324,36 +348,10 @@ export class Logger {
324
348
  this.themeChangeListener();
325
349
  this.themeChangeListener = null;
326
350
  }
351
+ // Close transports
352
+ this.transportManager?.close().catch(() => {});
327
353
  }
328
354
 
329
- /**
330
- * Factory method para crear loggers con scope evitando dependencias circulares
331
- * @private
332
- * @param {string} type - Tipo de logger ('scope' | 'api' | 'component')
333
- * @param {string} name - Nombre del scope
334
- * @returns {Promise<any>} Logger con scope
335
- */
336
- private async createScopedLogger(type: string, name: string): Promise<any> {
337
- try {
338
- const { ScopedLogger, APILogger, ComponentLogger } = await import('./ScopedLogger.js');
339
-
340
- switch (type) {
341
- case 'component':
342
- return new ComponentLogger(this, name);
343
- case 'api':
344
- return new APILogger(this, name);
345
- case 'scope':
346
- default:
347
- return new ScopedLogger(this, name);
348
- }
349
- } catch (error) {
350
- // Fallback: crear logger básico con prefijo
351
- this.error('Failed to load ScopedLogger, using basic logger with prefix:', error);
352
- const basicLogger = new Logger(this.getConfig());
353
- basicLogger.setGlobalPrefix(`${this.config.globalPrefix || ''}:${name}`);
354
- return basicLogger;
355
- }
356
- }
357
355
 
358
356
  // ===== SIMPLIFIED API =====
359
357
 
@@ -486,12 +484,12 @@ export class Logger {
486
484
 
487
485
  /**
488
486
  * Muestra los badges en los logs
489
- *
487
+ *
490
488
  * @example
491
489
  * logger.showBadges();
492
490
  * const api = logger.api('GraphQL');
493
491
  * api.info('Con badges'); // [API] [GraphQL] Con badges
494
- *
492
+ *
495
493
  * @since 0.3.0
496
494
  */
497
495
  showBadges(): void {
@@ -499,71 +497,68 @@ export class Logger {
499
497
  this.success('Badges shown');
500
498
  }
501
499
 
502
- // ===== SCOPED LOGGERS =====
503
-
504
500
  /**
505
- * Crea un logger para componentes con estilo automático
506
- *
507
- * @param {string} name - Nombre del componente
508
- * @returns {ComponentLogger} Logger con scope de componente
509
- *
501
+ * Establece múltiples badges para los logs
502
+ *
503
+ * @param {string[]} badges - Array de badges a mostrar
504
+ * @returns {this} Logger instance para encadenamiento
505
+ *
510
506
  * @example
511
- * const authLogger = logger.component('Autenticación');
512
- * authLogger.info('Validando credenciales');
513
- * // [COMPONENT] [Autenticación] Validando credenciales
514
- *
515
- * authLogger.success('Usuario autenticado');
516
- * // [COMPONENT] [Autenticación] ✓ Usuario autenticado
517
- *
518
- * @since 0.3.0
507
+ * logger.badges(['v3', 'stable']).info('Release publicado');
508
+ * logger.badges(['API', 'v2']).warn('Endpoint deprecado');
509
+ *
510
+ * @since 3.0.0
519
511
  */
520
- component(name: string): any {
521
- // Lazy dynamic import to avoid circular dependency
522
- return this.createScopedLogger('component', name);
512
+ badges(badges: string[]): this {
513
+ this.badgeList = [...badges];
514
+ return this;
523
515
  }
524
516
 
525
517
  /**
526
- * Crea un logger para APIs con badges automáticos
527
- *
528
- * @param {string} name - Nombre de la API o endpoint
529
- * @returns {APILogger} Logger con scope de API
530
- *
518
+ * Añade un badge individual a la lista
519
+ *
520
+ * @param {string} badge - Badge a añadir
521
+ * @returns {this} Logger instance para encadenamiento
522
+ *
531
523
  * @example
532
- * const api = logger.api('REST');
533
- * api.info('GET /users');
534
- * // [API] [REST] GET /users
535
- *
536
- * // Con badges adicionales
537
- * api.badges(['v2', 'cached']).info('Respuesta desde caché');
538
- * // [API] [v2] [cached] [REST] Respuesta desde caché
539
- *
540
- * @since 0.3.0
524
+ * logger.badge('DEBUG').badge('AUTH').info('Token validado');
525
+ *
526
+ * @since 3.0.0
541
527
  */
542
- api(name: string): any {
543
- // Lazy dynamic import to avoid circular dependency
544
- return this.createScopedLogger('api', name);
528
+ badge(badge: string): this {
529
+ if (!this.badgeList.includes(badge)) {
530
+ this.badgeList.push(badge);
531
+ }
532
+ return this;
545
533
  }
546
534
 
547
535
  /**
548
- * Crea un logger con scope general y soporte de badges
549
- *
550
- * @param {string} name - Nombre del scope
551
- * @returns {ScopedLogger} Logger con scope personalizado
552
- *
536
+ * Limpia todos los badges activos
537
+ *
538
+ * @returns {this} Logger instance para encadenamiento
539
+ *
553
540
  * @example
554
- * const dbLogger = logger.scope('Database');
555
- * dbLogger.info('Conectando a MongoDB');
556
- * // [Database] Conectando a MongoDB
557
- *
558
- * // Con badges personalizados
559
- * dbLogger.badge('SLOW').warn('Query tardó 5s');
560
- * // [SLOW] [Database] Query tardó 5s
561
- *
562
- * @since 0.3.0
541
+ * logger.clearBadges().info('Sin badges');
542
+ *
543
+ * @since 3.0.0
563
544
  */
564
- scope(name: string): any {
565
- // Lazy dynamic import to avoid circular dependency
566
- return this.createScopedLogger('scope', name);
545
+ clearBadges(): this {
546
+ this.badgeList = [];
547
+ return this;
548
+ }
549
+
550
+ // ===== SCOPED LOGGERS =====
551
+
552
+ component(name: string): ComponentLogger {
553
+ return new ComponentLogger(this, name);
554
+ }
555
+
556
+ api(name: string): APILogger {
557
+ return new APILogger(this, name);
558
+ }
559
+
560
+ scope(name: string): ScopedLogger {
561
+ return new ScopedLogger(this, name);
567
562
  }
568
563
 
569
564
  // ===== SIMPLE CUSTOMIZATION =====
@@ -654,7 +649,7 @@ export class Logger {
654
649
 
655
650
  /**
656
651
  * Obtiene el handler de exportación si está disponible
657
- *
652
+ *
658
653
  * @returns {ExportLogHandler | undefined} Handler de exportación o undefined
659
654
  * @since 0.3.0
660
655
  */
@@ -662,6 +657,212 @@ export class Logger {
662
657
  return this.exportHandler;
663
658
  }
664
659
 
660
+ // ===== SERIALIZERS =====
661
+
662
+ /**
663
+ * Añade un serializador personalizado para un tipo específico
664
+ *
665
+ * @param type - Constructor del tipo a serializar
666
+ * @param serializer - Función de serialización
667
+ * @param priority - Prioridad (mayor = primero)
668
+ *
669
+ * @example
670
+ * logger.addSerializer(Error, (err) => ({
671
+ * name: err.name,
672
+ * message: err.message,
673
+ * stack: err.stack?.split('\n').slice(0, 5)
674
+ * }));
675
+ *
676
+ * @since 3.0.0
677
+ */
678
+ addSerializer<T>(
679
+ type: new (...args: any[]) => T,
680
+ serializer: SerializerFn<T>,
681
+ priority?: number
682
+ ): void {
683
+ this.serializerRegistry.add(type, serializer, priority);
684
+ }
685
+
686
+ /**
687
+ * Elimina un serializador registrado
688
+ *
689
+ * @param type - Constructor del tipo a remover
690
+ * @returns true si se eliminó
691
+ *
692
+ * @since 3.0.0
693
+ */
694
+ removeSerializer<T>(type: new (...args: any[]) => T): boolean {
695
+ return this.serializerRegistry.remove(type);
696
+ }
697
+
698
+ /**
699
+ * Obtiene el registry de serializadores
700
+ *
701
+ * @returns SerializerRegistry
702
+ * @since 3.0.0
703
+ */
704
+ getSerializerRegistry(): SerializerRegistry {
705
+ return this.serializerRegistry;
706
+ }
707
+
708
+ // ===== HOOKS & MIDDLEWARE =====
709
+
710
+ /**
711
+ * Registra un hook para un evento
712
+ *
713
+ * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
714
+ * @param callback - Función a ejecutar
715
+ * @param priority - Prioridad (mayor = primero)
716
+ * @returns Función para desregistrar
717
+ *
718
+ * @example
719
+ * const unsubscribe = logger.on('beforeLog', (entry) => {
720
+ * entry.correlationId = getCorrelationId();
721
+ * return entry;
722
+ * });
723
+ *
724
+ * @since 3.0.0
725
+ */
726
+ on(event: HookEvent, callback: HookCallback, priority?: number): () => void {
727
+ return this.hookManager.on(event, callback, priority);
728
+ }
729
+
730
+ /**
731
+ * Registra un hook que se ejecuta solo una vez
732
+ *
733
+ * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
734
+ * @param callback - Función a ejecutar
735
+ * @param priority - Prioridad (mayor = primero)
736
+ * @returns Función para desregistrar
737
+ *
738
+ * @since 3.0.0
739
+ */
740
+ once(event: HookEvent, callback: HookCallback, priority?: number): () => void {
741
+ return this.hookManager.once(event, callback, priority);
742
+ }
743
+
744
+ /**
745
+ * Elimina un hook registrado
746
+ *
747
+ * @param event - Evento del hook
748
+ * @param callback - Callback a remover
749
+ * @returns true si se eliminó
750
+ *
751
+ * @since 3.0.0
752
+ */
753
+ off(event: HookEvent, callback: HookCallback): boolean {
754
+ return this.hookManager.off(event, callback);
755
+ }
756
+
757
+ /**
758
+ * Añade un middleware al pipeline
759
+ *
760
+ * @param middleware - Función middleware
761
+ * @param priority - Prioridad (mayor = primero)
762
+ * @returns Función para desregistrar
763
+ *
764
+ * @example
765
+ * logger.use((entry, next) => {
766
+ * entry.requestId = asyncLocalStorage.getStore()?.requestId;
767
+ * next();
768
+ * });
769
+ *
770
+ * @since 3.0.0
771
+ */
772
+ use(middleware: MiddlewareFn, priority?: number): () => void {
773
+ return this.hookManager.use(middleware, priority);
774
+ }
775
+
776
+ /**
777
+ * Obtiene el HookManager
778
+ *
779
+ * @returns HookManager
780
+ * @since 3.0.0
781
+ */
782
+ getHookManager(): HookManager {
783
+ return this.hookManager;
784
+ }
785
+
786
+ // ===== TRANSPORTS =====
787
+
788
+ /**
789
+ * Añade un transport para envío de logs
790
+ *
791
+ * @param target - Configuración del transport
792
+ * @returns ID único del transport
793
+ *
794
+ * @example
795
+ * // File transport
796
+ * logger.addTransport({
797
+ * target: 'file',
798
+ * options: { destination: '/var/log/app.log' }
799
+ * });
800
+ *
801
+ * @example
802
+ * // HTTP transport con batching
803
+ * logger.addTransport({
804
+ * target: 'http',
805
+ * options: {
806
+ * url: 'https://logs.example.com',
807
+ * batchSize: 100,
808
+ * flushInterval: 5000
809
+ * },
810
+ * level: 'warn'
811
+ * });
812
+ *
813
+ * @since 3.0.0
814
+ */
815
+ addTransport(target: TransportTarget): string {
816
+ if (!this.transportManager) {
817
+ this.transportManager = new TransportManager();
818
+ }
819
+ return this.transportManager.add(target);
820
+ }
821
+
822
+ /**
823
+ * Elimina un transport
824
+ *
825
+ * @param id - ID del transport a remover
826
+ * @returns true si se eliminó
827
+ *
828
+ * @since 3.0.0
829
+ */
830
+ removeTransport(id: string): boolean {
831
+ return this.transportManager?.remove(id) ?? false;
832
+ }
833
+
834
+ /**
835
+ * Fuerza el flush de todos los transports
836
+ *
837
+ * @returns Promise que resuelve cuando todos los buffers están vaciados
838
+ *
839
+ * @since 3.0.0
840
+ */
841
+ async flushTransports(): Promise<void> {
842
+ await this.transportManager?.flush();
843
+ }
844
+
845
+ /**
846
+ * Cierra todos los transports
847
+ *
848
+ * @returns Promise que resuelve cuando todos están cerrados
849
+ *
850
+ * @since 3.0.0
851
+ */
852
+ async closeTransports(): Promise<void> {
853
+ await this.transportManager?.close();
854
+ }
855
+
856
+ /**
857
+ * Obtiene el TransportManager
858
+ *
859
+ * @returns TransportManager o undefined si no hay transports
860
+ * @since 3.0.0
861
+ */
862
+ getTransportManager(): TransportManager | undefined {
863
+ return this.transportManager;
864
+ }
865
+
665
866
  // ===== CORE LOGGING METHODS =====
666
867
 
667
868
  /**
@@ -697,8 +898,33 @@ export class Logger {
697
898
 
698
899
  const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
699
900
  const prefix = this.getEffectivePrefix();
700
- const message = args.length > 0 ? String(args[0]) : '';
701
- const additionalArgs = args.slice(1);
901
+ const timestamp = formatTimestamp();
902
+
903
+ // Serialize args using registry
904
+ const serializedArgs = args.map(arg => this.serializerRegistry.serialize(arg));
905
+
906
+ // Prepend badges to message if any
907
+ let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : '';
908
+ if (this.badgeList.length > 0 && this.displaySettings.showBadges) {
909
+ const badgePrefix = this.badgeList.map(b => `[${b}]`).join('');
910
+ message = badgePrefix + ' ' + message;
911
+ }
912
+ const additionalArgs = serializedArgs.slice(1);
913
+
914
+ // Process beforeLog hooks (sync for performance)
915
+ let hookEntry = {
916
+ level,
917
+ message,
918
+ args: serializedArgs,
919
+ timestamp,
920
+ prefix,
921
+ stackInfo: stackInfo || undefined
922
+ };
923
+
924
+ // Emit beforeLog event (fire-and-forget for sync logging)
925
+ this.hookManager.emit('beforeLog', hookEntry).then(processed => {
926
+ message = processed.message;
927
+ }).catch(() => {});
702
928
 
703
929
  // Create styled output with theme detection and display settings
704
930
  const [format, ...styles] = createStyledOutput(
@@ -730,7 +956,7 @@ export class Logger {
730
956
 
731
957
  // Call custom handlers
732
958
  const metadata: LogMetadata = {
733
- timestamp: formatTimestamp(),
959
+ timestamp,
734
960
  level,
735
961
  prefix,
736
962
  stackInfo: stackInfo ? stackInfo : undefined,
@@ -738,24 +964,55 @@ export class Logger {
738
964
 
739
965
  this.handlers.forEach(handler => {
740
966
  try {
741
- handler.handle(level, message, args, metadata);
967
+ handler.handle(level, message, serializedArgs, metadata);
742
968
  } catch (error) {
743
969
  console.error('Log handler failed:', error);
744
970
  }
745
971
  });
972
+
973
+ // Write to transports (async, fire-and-forget)
974
+ if (this.transportManager) {
975
+ const levelValues: Record<LogLevel, number> = {
976
+ debug: 0, info: 1, warn: 2, error: 3, critical: 4
977
+ };
978
+ const record: TransportRecord = {
979
+ level,
980
+ levelValue: levelValues[level],
981
+ time: Date.now(),
982
+ msg: message,
983
+ prefix,
984
+ location: stackInfo ? {
985
+ file: stackInfo.file,
986
+ line: stackInfo.line,
987
+ column: stackInfo.column,
988
+ function: stackInfo.function
989
+ } : undefined
990
+ };
991
+ this.transportManager.write(record).catch(() => {});
992
+ }
993
+
994
+ // Emit afterLog event (fire-and-forget)
995
+ this.hookManager.emit('afterLog', hookEntry).catch(() => {});
996
+ }
997
+
998
+ logWithBindings(bindings: Bindings, level: LogLevel, ...args: any[]): void {
999
+ if (!this.shouldLog(level)) return;
1000
+
1001
+ let prefix = '';
1002
+ if (bindings.badges?.length) {
1003
+ prefix += bindings.badges.map(b => `[${b}]`).join('');
1004
+ }
1005
+ if (bindings.scope) {
1006
+ prefix += `[${bindings.scope}] `;
1007
+ }
1008
+
1009
+ if (prefix && args.length > 0) {
1010
+ args[0] = prefix + String(args[0]);
1011
+ }
1012
+
1013
+ this.log(level, ...args);
746
1014
  }
747
1015
 
748
- /**
749
- * Registra información de debug (prioridad más baja)
750
- *
751
- * @param {...any} args - Mensajes y datos a loggear
752
- *
753
- * @example
754
- * logger.debug('Variable estado:', { usuario: 'Juan', activo: true });
755
- * logger.debug('Iniciando proceso de validación');
756
- *
757
- * @since 0.3.0
758
- */
759
1016
  debug(...args: any[]): void {
760
1017
  this.log('debug', ...args);
761
1018
  }
@@ -1309,14 +1566,46 @@ export const hideLocation = () => getDefaultLogger().hideLocation();
1309
1566
  export const showLocation = () => getDefaultLogger().showLocation();
1310
1567
  export const hideBadges = () => getDefaultLogger().hideBadges();
1311
1568
  export const showBadges = () => getDefaultLogger().showBadges();
1569
+ export const badges = (badgeList: string[]) => getDefaultLogger().badges(badgeList);
1570
+ export const badge = (badgeName: string) => getDefaultLogger().badge(badgeName);
1571
+ export const clearBadges = () => getDefaultLogger().clearBadges();
1312
1572
  export const component = (name: string) => getDefaultLogger().component(name);
1313
1573
  export const api = (name: string) => getDefaultLogger().api(name);
1314
1574
  export const scope = (name: string) => getDefaultLogger().scope(name);
1315
1575
  export const customize = (overrides: any) => getDefaultLogger().customize(overrides);
1316
1576
  export const styles = () => getDefaultLogger().styles();
1317
1577
 
1578
+ // Enterprise features exports
1579
+ export const addSerializer = <T>(
1580
+ type: new (...args: any[]) => T,
1581
+ serializer: SerializerFn<T>,
1582
+ priority?: number
1583
+ ) => getDefaultLogger().addSerializer(type, serializer, priority);
1584
+ export const removeSerializer = <T>(type: new (...args: any[]) => T) =>
1585
+ getDefaultLogger().removeSerializer(type);
1586
+ export const on = (event: HookEvent, callback: HookCallback, priority?: number) =>
1587
+ getDefaultLogger().on(event, callback, priority);
1588
+ export const once = (event: HookEvent, callback: HookCallback, priority?: number) =>
1589
+ getDefaultLogger().once(event, callback, priority);
1590
+ export const off = (event: HookEvent, callback: HookCallback) =>
1591
+ getDefaultLogger().off(event, callback);
1592
+ export const use = (middleware: MiddlewareFn, priority?: number) =>
1593
+ getDefaultLogger().use(middleware, priority);
1594
+ export const addTransport = (target: TransportTarget) =>
1595
+ getDefaultLogger().addTransport(target);
1596
+ export const removeTransport = (id: string) =>
1597
+ getDefaultLogger().removeTransport(id);
1598
+ export const flushTransports = () =>
1599
+ getDefaultLogger().flushTransports();
1600
+ export const closeTransports = () =>
1601
+ getDefaultLogger().closeTransports();
1602
+
1318
1603
  // Re-export handlers and utilities for backward compatibility
1319
1604
  export { FileLogHandler, RemoteLogHandler, AnalyticsLogHandler, ExportLogHandler } from './handlers/index.js';
1320
1605
  export { StyleBuilder, StylePresets as Styles } from './styling/index.js';
1321
- // Commented out to avoid circular dependency - import these directly from ScopedLogger.js if needed
1322
- // export { ScopedLogger, APILogger, ComponentLogger } from './ScopedLogger.js';
1606
+
1607
+ // Re-export enterprise features
1608
+ export { SerializerRegistry } from './serializers/index.js';
1609
+ export { HookManager } from './hooks/index.js';
1610
+ export { TransportManager, ConsoleTransport, FileTransport, HttpTransport } from './transports/index.js';
1611
+ export { StyleCache, getStyleCache } from './styling/StyleCache.js';