@mks2508/better-logger 0.18.3 → 0.18.4
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.
- package/dist/Logger.d.ts +0 -18
- package/dist/Logger.d.ts.map +1 -1
- package/dist/chunks/{LogContext-Dyzs61XG.js → LogContext-BO-f0KXu.js} +20 -14
- package/dist/chunks/{LogContext-Dyzs61XG.js.map → LogContext-BO-f0KXu.js.map} +1 -1
- package/dist/chunks/{LogContext-DZasm_P5.cjs → LogContext-CIKxWPrK.cjs} +20 -14
- package/dist/chunks/{LogContext-DZasm_P5.cjs.map → LogContext-CIKxWPrK.cjs.map} +1 -1
- package/dist/context/LogContext.d.ts.map +1 -1
- package/dist/context.cjs +1 -1
- package/dist/context.js +1 -1
- package/dist/index.cjs +25 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +25 -35
- package/dist/index.js.map +1 -1
- package/dist/transports/SpanRuntime.d.ts +3 -0
- package/dist/transports/SpanRuntime.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/LogContext-BaMXleWj.cjs +0 -105
- package/dist/chunks/LogContext-BaMXleWj.cjs.map +0 -1
- package/dist/chunks/LogContext-DjlITOzZ.js +0 -100
- package/dist/chunks/LogContext-DjlITOzZ.js.map +0 -1
- package/dist/chunks/transports-BGfwwakw.js +0 -1237
- package/dist/chunks/transports-BGfwwakw.js.map +0 -1
- package/dist/chunks/transports-yK6CL0Ml.cjs +0 -1278
- package/dist/chunks/transports-yK6CL0Ml.cjs.map +0 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["THEME_PRESETS","StyleBuilder","BANNER_VARIANTS","StyleBuilder","TransportManager","resolveAsyncLocalStorage","isRunningInTerminal","renderStep","getColorCapability","renderHeader","renderDivider","renderBox","renderTable","NoopSpinner","SpinnerManager","ServerFallback","THEME_PRESETS","DEFAULT_CONFIG","createSerializerBridge","createHookBridge","createLogContext","createStyleManager","setupThemeChangeListener","hasPreset","THEME_BANNERS","getAvailablePresets","getSmartPreset","getEnvironment","LOG_LEVELS","LOG_LEVEL_TO_SEVERITY_NUMBER","LOG_LEVEL_TO_SEVERITY_TEXT","parseStackTrace","formatTimestamp","createStyledOutput","getColorCapability","formatBadge","StylePresets","StyleBuilder","CLI_LEVEL_MAP"],"sources":["../src/ScopedLogger.ts","../src/cli/CommandProcessor.ts","../src/cli/commands/ConfigCommand.ts","../src/cli/commands/ThemeCommand.ts","../src/cli/commands/ExportCommand.ts","../src/cli/help.ts","../src/cli/index.ts","../src/transports/TransportBridge.ts","../src/transports/SpanRuntime.ts","../src/playground/TerminalBridge.ts","../src/Logger.ts","../src/index.ts"],"sourcesContent":["import { Logger, resolveSpanArgs } from './Logger.js';\nimport type {\n TimerEntry,\n Bindings,\n ISpinnerHandle,\n IBoxOptions,\n ITableOptions,\n CLILogLevel,\n Span,\n SpanAttributes\n} from './types/index.js';\n\n/**\n * Logger prefijado por un scope nominal. Mantiene su propio stack de badges\n * y contextos y delega el envío de mensajes al {@link Logger} padre a través\n * de bindings (`{ scope, badges }`).\n *\n * Es la base de la jerarquía temática: {@link APILogger} y\n * {@link ComponentLogger} extienden de ella, y {@link ContextLogger} la\n * consume para apilar/subdesapilar sub-prefijos en el scope.\n *\n * No se construye directamente: se obtiene con `logger.scope('name')`.\n *\n * @example\n * // El factory method del Logger raíz devuelve un ScopedLogger\n * import logger from '@mks2508/better-logger';\n *\n * const http = logger.scope('HTTP');\n * http.badge('OUTBOUND').info('Request enviada');\n * // salida: [HTTP] [OUTBOUND] Request enviada\n *\n * @example\n * // Anidar contextos dentro de un scope (el prefijo se compone con ':')\n * const retry = http.context('retry');\n * retry.run(() => http.warn('Reintentando petición'));\n * // salida: [HTTP:retry] Reintentando petición\n *\n * @see {@link Logger.scope}\n * @see {@link APILogger}\n * @see {@link ComponentLogger}\n * @see {@link ContextLogger}\n */\nexport class ScopedLogger {\n private readonly parent: Logger;\n private readonly scopeName: string;\n private badgeList: string[] = [];\n private contextStack: string[] = [];\n private _timers?: Map<string, TimerEntry>;\n\n /**\n * Construye un ScopedLogger vinculado a un {@link Logger} padre.\n *\n * Los clientes no deben llamar a este constructor directamente: usen\n * `logger.scope(name)`, que configura correctamente la instancia.\n *\n * @param {Logger} parent - Logger raíz al que se delegan los mensajes.\n * @param {string} scopeName - Etiqueta del scope; se renderiza como\n * prefijo `[scopeName]` en cada línea.\n */\n constructor(parent: Logger, scopeName: string) {\n this.parent = parent;\n this.scopeName = scopeName;\n }\n\n private get timers(): Map<string, TimerEntry> {\n if (!this._timers) this._timers = new Map();\n return this._timers;\n }\n\n private getBindings(): Bindings {\n return {\n scope: this.getScopePrefix(),\n badges: this.badgeList.length > 0 ? [...this.badgeList] : undefined,\n };\n }\n\n private getScopePrefix(): string {\n if (this.contextStack.length === 0) return this.scopeName;\n return [this.scopeName, ...this.contextStack].join(':');\n }\n\n /**\n * Reemplaza la lista actual de badges por la pasada y la aplica a todos\n * los mensajes posteriores de este scope.\n *\n * @param {string[]} badges - Etiquetas a mostrar como badges adyacentes\n * al prefijo (p. ej. `['OUTBOUND', 'CACHED']`).\n * @returns {this} La misma instancia, para encadenar llamadas.\n *\n * @example\n * logger.scope('HTTP').badges(['OUTBOUND', 'CACHED']).info('Cache hit');\n * // salida: [HTTP] [OUTBOUND] [CACHED] Cache hit\n *\n * @see {@link badge} para añadir sin reemplazar los existentes.\n * @see {@link clearBadges} para vaciar la lista.\n */\n badges(badges: string[]): this {\n this.badgeList = [...badges];\n return this;\n }\n\n /**\n * Añade un badge al scope de forma idempotente (no lo duplica si ya existe).\n *\n * @param {string} badge - Etiqueta a añadir a la lista de badges.\n * @returns {this} La misma instancia, para encadenar llamadas.\n *\n * @example\n * logger.scope('API')\n * .badge('OUTBOUND')\n * .badge('RETRY')\n * .warn('Reintentando');\n * // salida: [API] [OUTBOUND] [RETRY] Reintentando\n */\n badge(badge: string): this {\n if (!this.badgeList.includes(badge)) {\n this.badgeList.push(badge);\n }\n return this;\n }\n\n /**\n * Vacía la lista de badges del scope.\n *\n * @returns {this} La misma instancia, para encadenar llamadas.\n *\n * @example\n * const http = logger.scope('HTTP');\n * http.badge('OUTBOUND').info('uno');\n * http.clearBadges().info('dos');\n * // [HTTP] [OUTBOUND] uno / [HTTP] dos\n */\n clearBadges(): this {\n this.badgeList = [];\n return this;\n }\n\n /**\n * Aplica un theme preset al logger padre. El preset afecta a toda la\n * instancia raíz (no solo a este scope) porque el style es compartido.\n *\n * @param {string} presetName - Nombre del preset registrado en el StyleManager.\n * @returns {this} La misma instancia, para encadenar llamadas.\n *\n * @example\n * logger.scope('UI').style('cyberpunk').info('neon');\n * @see {@link Logger.setTheme}\n */\n style(presetName: string): this {\n this.parent.setTheme(presetName as any);\n return this;\n }\n\n /**\n * Crea un {@link ContextLogger} vinculado a este scope. Los contextos se\n * apilan en el prefijo separados por `:`, permitiendo agrupar bloques de\n * logs relacionados (reintentos, sub-etapas, etc.) sin `console.group`.\n *\n * @param {string} contextName - Nombre del contexto a apilar.\n * @returns {ContextLogger} Handler con `run`, `runAsync`, `start`/`end`.\n *\n * @example\n * const retry = logger.scope('HTTP').context('retry');\n * retry.run(() => logger.warn('Reintentando'));\n * // salida: [HTTP:retry] Reintentando\n * @see {@link ContextLogger}\n */\n context(contextName: string): ContextLogger {\n return new ContextLogger(this, contextName);\n }\n\n /**\n * Inicia un timer etiquetado bajo el namespace `<scopeName>:<label>`.\n * El label es local a este scope, así que dos scopes pueden reutilizar el\n * mismo nombre sin colisión.\n *\n * @param {string} label - Identificador del timer.\n *\n * @example\n * const http = logger.scope('HTTP');\n * http.time('request');\n * // ... trabajo ...\n * http.timeEnd('request'); // imprime \"Timer: request - 12.34ms\"\n * @see {@link timeEnd}\n */\n time(label: string): void {\n this.timers.set(label, {\n label: `${this.scopeName}:${label}`,\n startTime: performance.now(),\n });\n }\n\n /**\n * Detiene un timer previamente iniciado con {@link time} y registra la\n * duración con nivel `success`. Si el label no existe, emite un `warn`\n * y devuelve `undefined`.\n *\n * @param {string} label - Mismo label pasado a {@link time}.\n * @returns {number | undefined} Milisegundos transcurridos, o `undefined`\n * si el timer no estaba registrado.\n *\n * @example\n * const http = logger.scope('HTTP');\n * http.time('fetch');\n * await fetch(url);\n * const ms = http.timeEnd('fetch');\n * if (ms && ms > 1000) http.warn('Latencia alta');\n */\n timeEnd(label: string): number | undefined {\n const timer = this.timers.get(label);\n if (!timer) {\n this.warn(`Timer '${label}' not found`);\n return undefined;\n }\n const elapsed = performance.now() - timer.startTime;\n this.timers.delete(label);\n this.success(`Timer: ${label} - ${elapsed.toFixed(2)}ms`);\n return elapsed;\n }\n\n /**\n * Emite un mensaje a nivel `debug` con los bindings actuales del scope.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales (objetos,\n * errores, etc.) serializados igual que en el logger raíz.\n *\n * @example\n * logger.scope('DB').debug('query', { sql, params });\n */\n debug(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'debug', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `info` con los bindings actuales del scope.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('AUTH').info('Login exitoso', { userId });\n */\n info(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'info', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `warn` con los bindings actuales del scope.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('CACHE').warn('Cache miss', { key });\n */\n warn(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'warn', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `error` con los bindings actuales del scope.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales (típicamente\n * un `Error` o contexto del fallo).\n *\n * @example\n * logger.scope('DB').error('Conexión rechazada', err);\n */\n error(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'error', ...args);\n }\n\n /**\n * Emite un mensaje con badge visual `SUCCESS` a nivel `info`. Úselo para\n * hitos positivos dentro del scope (conexión establecida, sync completo,\n * commit aplicado).\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('SYNC').success('Sincronización completa', { count: 42 });\n */\n success(...args: unknown[]): void {\n const bindings = this.getBindings();\n this.parent.logWithBindingsAndTag(bindings, 'info', 'success', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `critical` con los bindings actuales del scope.\n * Reservado para fallos que detienen el flujo de la aplicación.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('PAY').critical('Pasarela inaccesible', err);\n */\n critical(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'critical', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `trace` (verbosidad máxima) con los bindings\n * actuales del scope. Solo aparece si la verbosity global lo permite.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('NET').trace('packet', { bytes });\n */\n trace(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'trace', ...args);\n }\n\n // ===== SPANS / TRACES (delegation to Logger) =====\n\n /**\n * Emite un point-span con el scope de este logger como\n * `SpanRecord.scope`. Ver {@link Logger.event}.\n *\n * @param {string} name - Nombre del evento.\n * @param {SpanAttributes} [attributes] - Attributes del span.\n *\n * @example\n * logger.scope('BUILD').event('step.done', { step: 'compile' });\n */\n event(name: string, attributes?: SpanAttributes): void {\n this.parent._emitSpanEvent(name, attributes, this.getScopePrefix());\n }\n\n /**\n * Ejecuta `fn` dentro de un span activo etiquetado con el scope de este\n * logger. Los logs dentro de `fn` correlacionan con el span vía\n * `traceId`/`spanId`. Ver {@link Logger.span}.\n *\n * @typeParam T - Tipo resuelto por `fn`.\n * @param {string} name - Nombre de la operación.\n * @param {(s: Span) => T | Promise<T>} fn - Work-block a medir.\n * @returns {Promise<T>} Lo que resuelve `fn`.\n *\n * @example\n * await logger.scope('DB').span('migrate', async (s) => {\n * await runMigrations();\n * });\n */\n span<T>(name: string, fn: (s: Span) => T | Promise<T>): Promise<T>;\n span<T>(name: string, attributes: SpanAttributes, fn: (s: Span) => T | Promise<T>): Promise<T>;\n span<T>(\n name: string,\n fnOrAttributes: ((s: Span) => T | Promise<T>) | SpanAttributes,\n maybeFn?: (s: Span) => T | Promise<T>\n ): Promise<T> {\n const { attributes, fn } = resolveSpanArgs(fnOrAttributes, maybeFn);\n return this.parent._runSpan(name, attributes, this.getScopePrefix(), fn);\n }\n\n /**\n * Inicia un span externally-ended etiquetado con el scope de este\n * logger. Ver {@link Logger.startSpan}.\n *\n * @param {string} name - Nombre de la operación.\n * @param {SpanAttributes} [attributes] - Attributes iniciales.\n * @returns {Span} Handle con `set`/`end`/`fail`.\n */\n startSpan(name: string, attributes?: SpanAttributes): Span {\n return this.parent._startSpan(name, attributes, this.getScopePrefix());\n }\n\n // ===== CLI PRIMITIVES (delegation to Logger) =====\n\n /**\n * Delegación a {@link Logger.step}: dibuja una barra de progreso discreta\n * `current/total` para este scope.\n *\n * @param {number} current - Paso actual (1-indexed).\n * @param {number} total - Total de pasos.\n * @param {string} message - Texto mostrado junto al contador.\n * @see {@link Logger.step}\n */\n step(current: number, total: number, message: string): void {\n this.parent.step(current, total, message);\n }\n\n /**\n * Delegación a {@link Logger.header}: imprime un título con separadores visuales.\n *\n * @param {string} title - Texto del título.\n * @param {string} [subtitle] - Subtítulo opcional bajo el título.\n * @see {@link Logger.header}\n */\n header(title: string, subtitle?: string): void {\n this.parent.header(title, subtitle);\n }\n\n /**\n * Delegación a {@link Logger.divider}: imprime una línea separadora horizontal.\n * @see {@link Logger.divider}\n */\n divider(): void {\n this.parent.divider();\n }\n\n /**\n * Delegación a {@link Logger.blank}: inserta una línea en blanco.\n * @see {@link Logger.blank}\n */\n blank(): void {\n this.parent.blank();\n }\n\n /**\n * Delegación a {@link Logger.box}: dibuja un recuadro ANSI alrededor de `content`.\n *\n * @param {string} content - Texto a enmarcar.\n * @param {IBoxOptions} [options] - Opciones de estilo del box.\n * @see {@link Logger.box}\n */\n box(content: string, options?: IBoxOptions): void {\n this.parent.box(content, options);\n }\n\n /**\n * Delegación a {@link Logger.cliTable}: renderiza `rows` como tabla ASCII.\n *\n * @param {Record<string, unknown>[]} rows - Filas a mostrar.\n * @param {ITableOptions} [options] - Opciones de columnas y estilo.\n * @see {@link Logger.cliTable}\n */\n cliTable(rows: Record<string, unknown>[], options?: ITableOptions): void {\n this.parent.cliTable(rows, options);\n }\n\n /**\n * Delegación a {@link Logger.spinner}: arranca un spinner con `message`.\n *\n * @param {string} message - Texto a mostrar al lado del spinner.\n * @returns {ISpinnerHandle} Handle para detener/actualizar el spinner.\n * @see {@link Logger.spinner}\n */\n spinner(message: string): ISpinnerHandle {\n return this.parent.spinner(message);\n }\n\n /**\n * Delegación a {@link Logger.setCLILevel}: ajusta el nivel mínimo de las\n * primitivas CLI visibles.\n *\n * @param {CLILogLevel} level - Nivel CLI (`silent` … `verbose`).\n * @see {@link Logger.setCLILevel}\n */\n setCLILevel(level: CLILogLevel): void {\n this.parent.setCLILevel(level);\n }\n\n /**\n * Apila un contexto en el prefijo del scope. Invocado por\n * {@link ContextLogger}; los clientes no deben llamarlo directamente.\n *\n * @param {string} context - Nombre del contexto a apilar.\n * @internal\n */\n _pushContext(context: string): void {\n this.contextStack.push(context);\n }\n\n /**\n * Desapila el último contexto del prefijo del scope. Invocado por\n * {@link ContextLogger}; los clientes no deben llamarlo directamente.\n *\n * @internal\n */\n _popContext(): void {\n this.contextStack.pop();\n }\n}\n\n/**\n * Logger especializado para llamadas a APIs y servicios externos.\n *\n * Extiende {@link ScopedLogger} pre-seteando el badge `API` y exponiendo\n * atajos para eventos típicos de integración: llamadas lentas ({@link slow}),\n * rate limiting ({@link rateLimit}), fallos de autenticación ({@link auth}) y\n * APIs deprecadas ({@link deprecated}).\n *\n * Se obtiene con `logger.api(name)` y no se construye directamente.\n *\n * @example\n * import logger from '@mks2508/better-logger';\n *\n * const stripe = logger.api('Stripe');\n * stripe.info('Consultando customer', { id });\n * // salida: [API:Stripe] [API] Consultando customer\n *\n * stripe.slow('customer.retrieve', 1250);\n * // salida: [API:Stripe] [API] [SLOW] customer.retrieve (1250ms)\n *\n * @see {@link Logger.api}\n * @see {@link ScopedLogger}\n */\nexport class APILogger extends ScopedLogger {\n /**\n * Construye un APILogger con scope `API:<apiName>` y badge `API` ya aplicado.\n *\n * Los clientes deben usar `logger.api(name)`.\n *\n * @param {Logger} parent - Logger raíz al que se delegan los mensajes.\n * @param {string} apiName - Nombre del servicio/API (se prefija con `API:`).\n */\n constructor(parent: Logger, apiName: string) {\n super(parent, `API:${apiName}`);\n this.badge('API');\n }\n\n /**\n * Registra una llamada lenta con badge `SLOW` a nivel `warn`.\n *\n * @param {string} message - Descripción de la operación lenta.\n * @param {number} [duration] - Duración medida en ms; si se pasa, se\n * anexa al mensaje como `(Nms)`.\n *\n * @example\n * const t0 = performance.now();\n * await stripe.customers.retrieve(id);\n * logger.api('Stripe').slow('retrieve', performance.now() - t0);\n */\n slow(message: string, duration?: number): void {\n this.badge('SLOW');\n const msg = duration ? `${message} (${duration}ms)` : message;\n this.warn(msg);\n }\n\n /**\n * Registra un evento de rate limiting (HTTP 429) con badge `RATE_LIMIT`.\n *\n * @param {string} message - Detalle del límite golpeado.\n *\n * @example\n * logger.api('GitHub').rateLimit('Secondary rate limit on /search');\n */\n rateLimit(message: string): void {\n this.badge('RATE_LIMIT');\n this.warn(message);\n }\n\n /**\n * Registra un fallo de autenticación (401/403) con badge `AUTH` a nivel\n * `error`.\n *\n * @param {string} message - Detalle del fallo de credenciales/token.\n *\n * @example\n * logger.api('OAuth').auth('Token expirado');\n */\n auth(message: string): void {\n this.badge('AUTH');\n this.error(message);\n }\n\n /**\n * Marca una API como deprecada con badge `DEPRECATED` a nivel `warn`.\n *\n * @param {string} message - Mensaje guiando a la migración (endpoint\n * alternativo, versión retirada, etc.).\n *\n * @example\n * logger.api('Legacy').deprecated('Usar v3; v2 se retira en Q4');\n */\n deprecated(message: string): void {\n this.badge('DEPRECATED');\n this.warn(message);\n }\n}\n\n/**\n * Logger para componentes UI, módulos o cualquier unidad con ciclo de vida.\n *\n * Extiende {@link ScopedLogger} pre-seteando el badge `COMPONENT` y exponiendo\n * atajos para eventos típicos: {@link lifecycle}, {@link stateChange} y\n * {@link propsChange}.\n *\n * Se obtiene con `logger.component(name)` y no se construye directamente.\n *\n * @example\n * import logger from '@mks2508/better-logger';\n *\n * const cart = logger.component('Cart');\n * cart.lifecycle('mount');\n * // salida: [Cart] [COMPONENT] [LIFECYCLE] mount\n *\n * cart.stateChange('empty', 'has-items', { count: 3 });\n * // salida: [Cart] [COMPONENT] [STATE] empty → has-items { count: 3 }\n *\n * @see {@link Logger.component}\n * @see {@link ScopedLogger}\n */\nexport class ComponentLogger extends ScopedLogger {\n /**\n * Construye un ComponentLogger con badge `COMPONENT` ya aplicado.\n *\n * Los clientes deben usar `logger.component(name)`.\n *\n * @param {Logger} parent - Logger raíz al que se delegan los mensajes.\n * @param {string} componentName - Nombre del componente (scope label).\n */\n constructor(parent: Logger, componentName: string) {\n super(parent, componentName);\n this.badge('COMPONENT');\n }\n\n /**\n * Registra un evento de ciclo de vida con badge `LIFECYCLE` a nivel `info`.\n *\n * @param {string} event - Nombre del evento (`mount`, `unmount`,\n * `update`, ...).\n * @param {string} [message] - Detalle opcional; si se omite, solo se\n * registra el nombre del evento.\n *\n * @example\n * logger.component('Cart').lifecycle('mount', 'Modal abierto');\n */\n lifecycle(event: string, message?: string): void {\n this.badge('LIFECYCLE');\n const msg = message ? `${event}: ${message}` : event;\n this.info(msg);\n }\n\n /**\n * Registra una transición de estado con badge `STATE` a nivel `info`.\n *\n * @param {string} from - Estado previo.\n * @param {string} to - Estado nuevo.\n * @param {unknown} [data] - Payload opcional asociado a la transición.\n *\n * @example\n * const fsm = logger.component('FSM');\n * fsm.stateChange('idle', 'loading');\n * fsm.stateChange('loading', 'success', { items: 3 });\n */\n stateChange(from: string, to: string, data?: unknown): void {\n this.badge('STATE');\n const msg = `${from} → ${to}`;\n if (data) {\n this.info(msg, data);\n } else {\n this.info(msg);\n }\n }\n\n /**\n * Registra cambios de props/debug del componente con badge `PROPS` a nivel\n * `debug`.\n *\n * @param {Record<string, unknown>} changes - Mapa prop → valor (típicamente\n * el diff de props entre renders).\n *\n * @example\n * logger.component('Cart').propsChange({ itemCount: 5, currency: 'EUR' });\n */\n propsChange(changes: Record<string, unknown>): void {\n this.badge('PROPS');\n this.debug('Props changed:', changes);\n }\n}\n\n/**\n * Handler de contexto apilable sobre un {@link ScopedLogger}.\n *\n * Permite agrupar bloques de logs bajo un sub-prefijo separado por `:`,\n * manteniendo la correlación visual sin necesidad de `console.group`. El\n * prefijo compuesto se forma como `<scopeName>:<contextName>`.\n *\n * Se crea con `scopedLogger.context(name)`. El patrón idiomático es\n * {@link run}/{@link runAsync} (auto push/pop con try/finally); {@link start}\n * y {@link end} permiten control manual cuando el bloque no cierra\n * léxicamente (event handlers distribuidos, promesas de larga duración).\n *\n * @example\n * import logger from '@mks2508/better-logger';\n *\n * const http = logger.scope('HTTP');\n *\n * // Bloque síncrono auto-cerrado\n * http.context('retry').run(() => {\n * http.warn('Reintentando petición');\n * });\n * // salida: [HTTP:retry] Reintentando petición\n *\n * // Bloque async auto-cerrado\n * await http.context('refresh').runAsync(async () => {\n * await refreshToken();\n * http.info('Token refrescado');\n * });\n *\n * @see {@link ScopedLogger.context}\n */\nexport class ContextLogger {\n private parentLogger: ScopedLogger;\n private contextName: string;\n\n /**\n * @param {ScopedLogger} parentLogger - Scope sobre el que se apila el contexto.\n * @param {string} contextName - Sub-prefijo a apilar en el scope padre.\n */\n constructor(parentLogger: ScopedLogger, contextName: string) {\n this.parentLogger = parentLogger;\n this.contextName = contextName;\n }\n\n /**\n * Ejecuta `fn` síncrona dentro del contexto, garantizando el pop del\n * prefijo incluso si `fn` lanza. El contexto solo está activo durante la\n * ejecución de `fn`.\n *\n * @typeParam T - Tipo de retorno de `fn`.\n * @param {() => T} fn - Función a ejecutar bajo el contexto.\n * @returns {T} Lo que devuelva `fn`.\n * @throws {unknown} Relanza cualquier excepción de `fn` tras desapilar.\n *\n * @example\n * logger.scope('HTTP').context('warmup').run(() => {\n * logger.info('Pre-cargando caché');\n * });\n */\n run<T>(fn: () => T): T {\n this.parentLogger._pushContext(this.contextName);\n try {\n return fn();\n } finally {\n this.parentLogger._popContext();\n }\n }\n\n /**\n * Variante async de {@link run}: mantiene el contexto activo mientras se\n * awaiting la promesa de `fn`, incluyendo awaits internos.\n *\n * @typeParam T - Tipo resuelto por la promesa de `fn`.\n * @param {() => Promise<T>} fn - Función async a ejecutar bajo el contexto.\n * @returns {Promise<T>} Promesa que resuelve al valor de `fn`.\n * @throws {unknown} Relanza cualquier rechazo de `fn` tras desapilar.\n *\n * @example\n * await logger.scope('HTTP').context('fetch').runAsync(async () => {\n * const r = await fetch(url);\n * logger.info('Recibido', { status: r.status });\n * });\n */\n async runAsync<T>(fn: () => Promise<T>): Promise<T> {\n this.parentLogger._pushContext(this.contextName);\n try {\n return await fn();\n } finally {\n this.parentLogger._popContext();\n }\n }\n\n /**\n * Apila el contexto manualmente. Útil cuando el bloque que lo consume no\n * cierra léxicamente (event handlers, timeouts, streams). Debe emparejarse\n * con un {@link end} posterior; olvidarlo deja el prefijo contaminado para\n * los logs siguientes del scope.\n *\n * @example\n * const ctx = logger.scope('WS').context('subscribe');\n * socket.onopen = () => { ctx.start(); ctx.info('connected'); };\n * socket.onclose = () => { ctx.info('disconnected'); ctx.end(); };\n * @see {@link end}\n */\n start(): void {\n this.parentLogger._pushContext(this.contextName);\n }\n\n /**\n * Desapila el último contexto abierto con {@link start}.\n *\n * @see {@link start}\n */\n end(): void {\n this.parentLogger._popContext();\n }\n\n /**\n * Atajo a `scopedLogger.debug(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n debug(...args: unknown[]): void { this.parentLogger.debug(...args); }\n\n /**\n * Atajo a `scopedLogger.info(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n info(...args: unknown[]): void { this.parentLogger.info(...args); }\n\n /**\n * Atajo a `scopedLogger.warn(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n warn(...args: unknown[]): void { this.parentLogger.warn(...args); }\n\n /**\n * Atajo a `scopedLogger.error(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n error(...args: unknown[]): void { this.parentLogger.error(...args); }\n\n /**\n * Atajo a `scopedLogger.success(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n success(...args: unknown[]): void { this.parentLogger.success(...args); }\n\n /**\n * Atajo a `scopedLogger.critical(...)`. El contexto se aplica al prefijo\n * del scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n critical(...args: unknown[]): void { this.parentLogger.critical(...args); }\n}\n","/**\n * @fileoverview Procesador central del CLI del logger. Resuelve comandos,\n * despacha ejecución, mantiene historial y soporta plugins. No es un binario\n * standalone: se invoca vía `logger.cli()` o `window.cli()` en browser.\n */\n\nimport type { Logger } from '../Logger.js';\n\n/**\n * Comando del CLI del logger. Cada implementación se registra en un\n * {@link CommandProcessor} para ser invocable vía `/name` desde la consola\n * del navegador o cualquier host interactivo.\n *\n * @see {@link CommandProcessor.registerCommand}\n * @see {@link HelpCommand}\n */\nexport interface ICommand {\n /** Nombre canónico del comando, sin la barra inicial `/`. Debe ser único. */\n name: string;\n /** Descripción corta humana; la usa el sistema de help. */\n description: string;\n /** Sintaxis de uso mostrada en `/help`, p.ej. `/export <format>`. */\n usage: string;\n /** Agrupación opcional para el help (`Configuration`, `Export`, ...). */\n category?: string;\n /** Nombres alternativos sin la `/`; se resuelven al comando real. */\n aliases?: string[];\n /**\n * Ejecuta el comando. Recibe los argumentos como string plano (todo lo\n * posterior al primer token, re-joined con espacios) y el {@link Logger}\n * activo para emitir output.\n *\n * @param args - Argumentos del comando (string), puede ser `''`.\n * @param logger - Logger activo.\n */\n execute(args: string, logger: Logger): void | Promise<void>;\n}\n\n/**\n * Plugin de CLI: agrupa uno o más {@link ICommand} con lifecycle\n * `initialize`/`cleanup`. Permite a terceros empaquetar funcionalidad\n * extendida (ej: integración con un dashboard, transport custom) y\n * registrarla de golpe vía {@link CommandProcessor.registerPlugin}.\n *\n * @example\n * ```ts\n * const telemetryPlugin: ICLIPlugin = {\n * name: 'telemetry',\n * version: '1.0.0',\n * description: 'Comandos de telemetría',\n * commands: [new TelemetryDumpCommand()],\n * initialize(processor, logger) {\n * logger.info('telemetry plugin cargado');\n * },\n * cleanup() {\n * // liberar suscripciones/recursos\n * }\n * };\n * processor.registerPlugin(telemetryPlugin, logger);\n * ```\n *\n * @see {@link CommandProcessor.registerPlugin}\n */\nexport interface ICLIPlugin {\n /** Identificador único del plugin. */\n name: string;\n /** Versión semántica del plugin. */\n version: string;\n /** Descripción humana corta. */\n description: string;\n /** Comandos que el plugin aporta al registry al registrarse. */\n commands: ICommand[];\n /** Hook opcional llamado tras el registro — útil para suscribirse a eventos del processor. */\n initialize?(processor: CommandProcessor, logger: Logger): void;\n /** Hook opcional llamado al desregistrar el plugin — liberar recursos. */\n cleanup?(): void;\n}\n\n/**\n * Entrada del historial de comandos ejecutados. No se exporta; solo circula\n * internamente entre {@link CommandProcessor.getHistory} y el storage privado.\n *\n * @internal\n */\ninterface HistoryEntry {\n command: string;\n timestamp: Date;\n success: boolean;\n}\n\n/**\n * Procesador central del CLI del logger. Resuelve nombres de comando (con\n * aliases), despacha ejecución, mantiene historial acotado (max 100 entradas)\n * y soporta un sistema de plugins para extensión de terceros.\n *\n * No es un binario standalone: se invoca desde la consola del navegador vía\n * `window.cli(\"<command>\")` (modo interactivo habilitado por\n * {@link enterInteractiveMode}) o desde código vía `logger.cli()`. El\n * constructor no registra ningún comando por defecto — usar\n * {@link createDefaultCLI} para obtener una instancia con los 8 comandos\n * estándar ya cargados.\n *\n * @example\n * ```ts\n * const cli = createDefaultCLI();\n * await cli.processCommand('/themes', logger);\n * await cli.processCommand('/config theme=neon', logger);\n * ```\n *\n * @example\n * ```ts\n * // Modo interactivo: expone `window.cli` en el navegador\n * cli.enterInteractiveMode(logger);\n * // Desde la devtools: cli('help') → procesa '/help'\n * ```\n *\n * @see {@link createDefaultCLI}\n * @see {@link ICommand}\n * @see {@link ICLIPlugin}\n */\nexport class CommandProcessor {\n private commands: Map<string, ICommand> = new Map();\n private aliases: Map<string, string> = new Map();\n private plugins: Map<string, ICLIPlugin> = new Map();\n private history: HistoryEntry[] = [];\n private maxHistorySize: number = 100;\n private isInteractiveMode: boolean = false;\n\n /**\n * Registra un comando. Si el comando declara `aliases`, también se indexan\n * para resolución. Un comando con el mismo `name` sobreescribe al previo.\n *\n * @param {ICommand} command - Comando a registrar.\n * @see {@link ICommand}\n */\n registerCommand(command: ICommand): void {\n this.commands.set(command.name, command);\n \n // Register aliases\n if (command.aliases) {\n for (const alias of command.aliases) {\n this.aliases.set(alias, command.name);\n }\n }\n }\n \n /**\n * Registra un plugin: indexa todos sus commands y, si el plugin define\n * `initialize`, lo invoca con el processor y el logger. Los comandos del\n * plugin se registran vía {@link registerCommand} y sus aliases quedan\n * resolvibles igual que los directos.\n *\n * @param {ICLIPlugin} plugin - Plugin a registrar.\n * @param {Logger} [logger] - Logger activo; requerido solo si el plugin define `initialize`.\n * @throws {Error} Si ya existe un plugin registrado con el mismo `name`.\n * @see {@link unregisterPlugin}\n */\n registerPlugin(plugin: ICLIPlugin, logger?: Logger): void {\n if (this.plugins.has(plugin.name)) {\n throw new Error(`Plugin ${plugin.name} is already registered`);\n }\n \n this.plugins.set(plugin.name, plugin);\n \n // Register plugin commands\n for (const command of plugin.commands) {\n this.registerCommand(command);\n }\n \n // Initialize plugin\n if (plugin.initialize && logger) {\n plugin.initialize(this, logger);\n }\n }\n \n /**\n * Desregistra un plugin por nombre: elimina todos sus commands (y los\n * aliases que aportasen), invoca su hook `cleanup` si existe y lo quita\n * del registry. No-op si el nombre no existe.\n *\n * @param {string} pluginName - Nombre del plugin a desregistrar.\n * @see {@link registerPlugin}\n */\n unregisterPlugin(pluginName: string): void {\n const plugin = this.plugins.get(pluginName);\n if (!plugin) return;\n \n // Remove plugin commands\n for (const command of plugin.commands) {\n this.commands.delete(command.name);\n if (command.aliases) {\n for (const alias of command.aliases) {\n this.aliases.delete(alias);\n }\n }\n }\n \n // Cleanup plugin\n if (plugin.cleanup) {\n plugin.cleanup();\n }\n \n this.plugins.delete(pluginName);\n }\n\n /**\n * Lista todos los commands registrados (directamente o vía plugins).\n * No incluye aliases.\n *\n * @returns {ICommand[]} Snapshot array de los commands registrados.\n */\n getCommands(): ICommand[] {\n return Array.from(this.commands.values());\n }\n\n /**\n * Resuelve un comando por nombre canónico o alias. Devuelve `undefined`\n * si no existe ninguno que matchee.\n *\n * @param {string} name - Nombre canónico o alias del comando.\n * @returns {ICommand | undefined} El comando resuelto, o `undefined`.\n */\n getCommand(name: string): ICommand | undefined {\n // Check direct command name\n let command = this.commands.get(name);\n if (command) return command;\n \n // Check aliases\n const aliasTarget = this.aliases.get(name);\n if (aliasTarget) {\n return this.commands.get(aliasTarget);\n }\n \n return undefined;\n }\n \n /**\n * Devuelve una copia del historial de comandos ejecutados (más recientes\n * primero). Acotado a 100 entradas por {@link maxHistorySize}; las más\n * viejas se descartan al insertar nuevas.\n *\n * @returns {HistoryEntry[]} Snapshot del historial; mutar el array devuelto\n * no afecta al estado interno del processor.\n */\n getHistory(): HistoryEntry[] {\n return [...this.history];\n }\n\n /**\n * Vacía el historial de comandos en memoria.\n */\n clearHistory(): void {\n this.history = [];\n }\n\n /**\n * Lista los plugins actualmente registrados.\n *\n * @returns {ICLIPlugin[]} Snapshot array de plugins activos.\n */\n getPlugins(): ICLIPlugin[] {\n return Array.from(this.plugins.values());\n }\n\n /**\n * Activa el modo interactivo. Marca el flag interno y, si se ejecuta en\n * navegador, expone `window.cli(command)` para invocar comandos desde la\n * devtools sin prefijo `/` (se añade automáticamente al input).\n *\n * @param {Logger} logger - Logger activo (emite el mensaje de bienvenida\n * con hint sobre `cli(...)` en browser).\n * @see {@link exitInteractiveMode}\n */\n enterInteractiveMode(logger: Logger): void {\n this.isInteractiveMode = true;\n logger.info('🔧 Interactive CLI mode activated. Type /exit to quit, /help for commands.');\n \n // Set up browser console listener for interactive commands\n if (typeof window !== 'undefined') {\n this.setupBrowserInteractiveMode(logger);\n }\n }\n \n /**\n * Desactiva el flag de modo interactivo. Nota: no elimina el `window.cli`\n * que {@link enterInteractiveMode} haya expuesto en el navegador — el\n * handler global sigue vivo hasta reload.\n *\n * @see {@link enterInteractiveMode}\n */\n exitInteractiveMode(): void {\n this.isInteractiveMode = false;\n }\n \n /**\n * Instala `window.cli(command)` como wrapper delgado alrededor de\n * {@link processCommand}, prefijando `/` automáticamente. Solo se invoca\n * desde {@link enterInteractiveMode} cuando `window` está disponible.\n *\n * @internal\n * @param logger - Logger activo, reenviado a cada invocación.\n */\n private setupBrowserInteractiveMode(logger: Logger): void {\n // Add global CLI function for browser usage\n (window as any).cli = (commandString: string) => {\n return this.processCommand(`/${commandString}`, logger);\n };\n \n logger.info('💡 Use cli(\"command\") to execute CLI commands in browser console.');\n }\n\n /**\n * Parsea y ejecuta un comando. El formato esperado es `/name args...`:\n * split por espacios, primer token = nombre del comando, resto = args\n * (re-joined con espacios). Si el comando no existe, loguea el error y\n * sugiere similares vía {@link getSuggestions} (\"Did you mean: ...?\").\n *\n * Toda invocación (válida o no) se registra en el historial con flag de\n * éxito/fallo según si `execute` resolvió o throweó.\n *\n * @param {string} commandString - Comando completo, debe empezar con `/`.\n * @param {Logger} logger - Logger activo para output y errores.\n * @returns {Promise<void>} Resuelve cuando el comando termina (sync o async).\n * Nunca rechaza: los errores de `execute` se capturan y se loguean.\n * @see {@link ICommand.execute}\n * @see {@link getSuggestions}\n */\n async processCommand(commandString: string, logger: Logger): Promise<void> {\n if (!commandString.startsWith('/')) {\n logger.error('Invalid command. Commands must start with /');\n this.addToHistory(commandString, false);\n return;\n }\n\n const parts = commandString.slice(1).split(' ');\n const commandName = parts[0] || '';\n const args = parts.slice(1).join(' ');\n\n const command = this.getCommand(commandName);\n if (!command) {\n logger.error(`Unknown command: ${commandName}. Type /help for available commands.`);\n \n // Suggest similar commands\n const suggestions = this.getSuggestions(commandName);\n if (suggestions.length > 0) {\n logger.info(`📋 Did you mean: ${suggestions.slice(0, 3).join(', ')}?`);\n }\n \n this.addToHistory(commandString, false);\n return;\n }\n\n try {\n await command.execute(args || '', logger);\n this.addToHistory(commandString, true);\n } catch (error) {\n logger.error(`Command '${commandName}' failed:`, error);\n this.addToHistory(commandString, false);\n }\n }\n \n /**\n * Inserta una entrada al frente del historial y trunca a\n * {@link maxHistorySize} (100) si hace falta.\n *\n * @internal\n * @param command - String crudo del comando ejecutado.\n * @param success - Si la ejecución tuvo éxito.\n */\n private addToHistory(command: string, success: boolean): void {\n this.history.unshift({\n command,\n timestamp: new Date(),\n success\n });\n \n // Limit history size\n if (this.history.length > this.maxHistorySize) {\n this.history = this.history.slice(0, this.maxHistorySize);\n }\n }\n\n /**\n * Devuelve nombres de comando que empiezan con el prefijo dado. Alimente\n * el hint \"Did you mean\" de {@link processCommand} cuando un comando no\n * se encuentra. Match por `startsWith` (no fuzzy).\n *\n * @param {string} partial - Prefijo parcial tipeado por el usuario.\n * @returns {string[]} Nombres canónicos que matchean; aliases excluidos.\n */\n getSuggestions(partial: string): string[] {\n const commandNames = Array.from(this.commands.keys());\n return commandNames.filter(name => name.startsWith(partial));\n }\n}","/**\n * @fileoverview Configuration commands for Advanced Logger CLI\n */\n\nimport type { ICommand } from '../CommandProcessor.js';\nimport type { Logger } from '../../Logger.js';\nimport type { ThemeVariant, BannerType, Verbosity } from '../../types/index.js';\n\n/**\n * Comando `/config` del CLI runtime del {@link Logger}. Inspecciona o muta\n * la configuración del logger en vivo desde la DevTools console.\n *\n * Acepta tres modos de invocación:\n * - Sin argumentos: vuelca el estado actual como tabla agrupada.\n * - JSON completo (empieza con `{`): aplica un objeto de configuración parcial.\n * - Pares `key=value` separados por coma: atajo para mutaciones puntuales.\n *\n * Solo se aplican las keys de la whitelist interna (`theme`, `verbosity`,\n * `enableColors`, `enableTimestamps`, `enableStackTrace`, `globalPrefix`,\n * `bannerType`); cualquier otra key se rechaza con un `warn` y se ignora.\n *\n * @example\n * // Sin argumentos: ver estado actual\n * // > /config\n *\n * @example\n * // Objeto JSON completo\n * // > /config {\"theme\":\"neon\",\"verbosity\":\"debug\"}\n *\n * @example\n * // Atajo key=value (múltiples pares separados por coma)\n * // > /config theme=neon,verbosity=debug,globalPrefix=MiApp\n *\n * @see {@link ICommand} para el contrato que implementa este comando.\n * @see {@link Logger.setTheme}, {@link Logger.setVerbosity},\n * {@link Logger.setBannerType}, {@link Logger.setGlobalPrefix}\n * para los setters subyacentes.\n */\nexport class ConfigCommand implements ICommand {\n name = 'config';\n description = 'Show or update logger configuration';\n usage = '/config [json|key=value,...]';\n\n /**\n * Ejecuta el comando `/config` contra el logger dado.\n *\n * @param args - Argumentos crudos del usuario. Vacío = status; con `{`\n * inicial = parse JSON; resto = pares `key=value` separados\n * por coma.\n * @param logger - Instancia destino cuyos setters se invocan.\n */\n execute(args: string, logger: Logger): void {\n if (!args) {\n this.showStatus(logger);\n return;\n }\n\n try {\n // Try to parse as JSON first\n if (args.startsWith('{')) {\n const config = JSON.parse(args);\n this.applyConfig(config, logger);\n } else {\n // Parse key=value pairs\n const pairs = args.split(',').map(pair => pair.trim().split('='));\n const config: any = {};\n pairs.forEach(([key, value]) => {\n if (key && value) {\n config[key.trim()] = value.trim().replace(/[\"']/g, '');\n }\n });\n this.applyConfig(config, logger);\n }\n } catch (error) {\n logger.error('Invalid config format. Use JSON or key=value pairs:', error);\n logger.info('Examples: /config {\"theme\":\"dark\"} or /config theme=neon,verbosity=debug');\n }\n }\n\n private showStatus(logger: Logger): void {\n const statusData = {\n theme: logger.getConfig().theme || 'default',\n verbosity: logger.getConfig().verbosity,\n colors: logger.getConfig().enableColors,\n timestamps: logger.getConfig().enableTimestamps,\n stackTrace: logger.getConfig().enableStackTrace,\n globalPrefix: logger.getConfig().globalPrefix || 'none',\n bannerType: logger.getConfig().bannerType || 'simple',\n handlers: logger.getHandlers().length\n };\n\n logger.group('⚙️ Logger Configuration');\n logger.table(statusData);\n logger.groupEnd();\n }\n\n private applyConfig(config: any, logger: Logger): void {\n const validKeys = ['theme', 'verbosity', 'enableColors', 'enableTimestamps', 'enableStackTrace', 'globalPrefix', 'bannerType'];\n const applied: string[] = [];\n\n Object.entries(config).forEach(([key, value]) => {\n if (validKeys.includes(key)) {\n if (key === 'theme' && typeof value === 'string') {\n logger.setTheme(value as ThemeVariant);\n applied.push(`${key}=${value}`);\n } else if (key === 'bannerType' && typeof value === 'string') {\n logger.setBannerType(value as BannerType);\n applied.push(`${key}=${value}`);\n } else if (key === 'verbosity') {\n logger.setVerbosity(value as Verbosity);\n applied.push(`${key}=${value}`);\n } else if (key === 'globalPrefix') {\n logger.setGlobalPrefix(value as string);\n applied.push(`${key}=${value}`);\n } else {\n logger.updateConfig({ [key]: value });\n applied.push(`${key}=${value}`);\n }\n } else {\n logger.warn(`Invalid config key: ${key}`);\n }\n });\n\n if (applied.length > 0) {\n logger.success(`Configuration updated: ${applied.join(', ')}`);\n }\n }\n}","/**\n * @fileoverview Theme and banner commands for Advanced Logger CLI\n */\n\nimport type { ICommand } from '../CommandProcessor.js';\nimport type { Logger } from '../../Logger.js';\nimport type { BannerType } from '../../types/index.js';\nimport { THEME_PRESETS, BANNER_VARIANTS } from '../../styling/index.js';\nimport { StyleBuilder } from '../../styling/index.js';\n\n/**\n * Comando `/themes` del CLI runtime del {@link Logger}. Lista los presets\n * temáticos disponibles en {@link THEME_PRESETS}, renderizando una preview\n * con los colores reales de cada tema (background, foreground, border).\n *\n * Es de solo lectura: no muta el logger. Útil para descubrir qué tema\n * aplicar antes de correr `/config theme=<name>`.\n *\n * @example\n * // Listar todos los temas con preview coloreada\n * // > /themes\n *\n * @see {@link THEME_PRESETS} para el catálogo completo de temas.\n * @see {@link ConfigCommand} para aplicar un tema vía `/config theme=...`.\n */\nexport class ThemesCommand implements ICommand {\n name = 'themes';\n description = 'Show available theme presets';\n usage = '/themes';\n\n /**\n * Ejecuta el comando `/themes` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia usada para abrir/cerrar el `group` de salida.\n */\n execute(_args: string, logger: Logger): void {\n logger.group('🎨 Available Themes');\n Object.keys(THEME_PRESETS).forEach(themeName => {\n const preview = (THEME_PRESETS as any)[themeName];\n const previewStyle = new StyleBuilder()\n .bg(preview.info.background)\n .color(preview.info.color)\n .padding('4px 8px')\n .rounded('4px')\n .border(preview.info.border)\n .build();\n \n console.log(`%c${themeName}`, previewStyle, `- ${themeName} theme preview`);\n });\n logger.groupEnd();\n }\n}\n\n/**\n * Comando `/banners` del CLI runtime del {@link Logger}. Enumera los tipos\n * de banner disponibles en {@link BANNER_VARIANTS} (`simple`, `ascii`,\n * `unicode`, ...) con una mini-preview de cada uno para inspección visual.\n *\n * Es de solo lectura: no muta el logger. Para cambiar el banner activo\n * usar {@link BannerCommand}.\n *\n * @example\n * // Listar todas las variantes de banner con preview\n * // > /banners\n *\n * @see {@link BANNER_VARIANTS} para el catálogo completo de variantes.\n * @see {@link BannerCommand} para aplicar un tipo concreto.\n */\nexport class BannersCommand implements ICommand {\n name = 'banners';\n description = 'Show available banner types';\n usage = '/banners';\n\n /**\n * Ejecuta el comando `/banners` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia usada para abrir/cerrar el `group` de salida.\n */\n execute(_args: string, logger: Logger): void {\n logger.group('🖼️ Available Banner Types');\n Object.keys(BANNER_VARIANTS).forEach(bannerName => {\n const banner = (BANNER_VARIANTS as any)[bannerName];\n console.log(`%c${bannerName}`, 'font-weight: bold; color: #667eea;');\n console.log(`%cPreview:`, 'color: #666; font-size: 12px;');\n \n // Show a mini preview\n if (bannerName === 'simple') {\n console.log(`%c${banner.text}`, banner.style);\n } else if (bannerName === 'ascii') {\n console.log(`%c${banner.text.split('\\n').slice(1, 4).join('\\n')}...`, 'font-family: monospace; color: #667eea; font-size: 10px;');\n } else if (bannerName === 'unicode') {\n console.log(`%c${banner.text}`, banner.style);\n } else {\n console.log(`%c${bannerName} banner`, 'color: #666; font-style: italic;');\n }\n });\n logger.groupEnd();\n }\n}\n\n/**\n * Comando `/banner [type]` del CLI runtime del {@link Logger}.\n *\n * - Sin argumentos: re-renderiza el banner actualmente activo.\n * - Con un tipo válido: lo aplica vía {@link Logger.setBannerType} y lo\n * muestra inmediatamente.\n * - Con un tipo inválido: loguea un `error` listando las opciones válidas.\n *\n * @example\n * // Mostrar el banner actual\n * // > /banner\n *\n * @example\n * // Cambiar a un tipo concreto\n * // > /banner ascii\n *\n * @see {@link BANNER_VARIANTS} para los tipos aceptados.\n * @see {@link Logger.setBannerType} y {@link Logger.showBanner} para los\n * métodos subyacentes.\n */\nexport class BannerCommand implements ICommand {\n name = 'banner';\n description = 'Change or show current banner type';\n usage = '/banner [type]';\n\n /**\n * Ejecuta el comando `/banner` contra el logger dado.\n *\n * @param args - Tipo de banner solicitado. Vacío = mostrar banner actual.\n * @param logger - Instancia destino cuyo banner se actualiza/muestra.\n */\n execute(args: string, logger: Logger): void {\n if (!args) {\n logger.showBanner();\n return;\n }\n\n if (args in BANNER_VARIANTS) {\n logger.setBannerType(args as BannerType);\n logger.showBanner();\n } else {\n logger.error(`Invalid banner type: ${args}. Available: ${Object.keys(BANNER_VARIANTS).join(', ')}`);\n }\n }\n}","/**\n * @fileoverview Status and demo commands for Advanced Logger CLI\n */\n\nimport type { ICommand } from '../CommandProcessor.js';\nimport type { Logger } from '../../Logger.js';\n\n/**\n * Comando `/status` del CLI runtime del {@link Logger}. Vuelca la\n * configuración vigente y algunas estadísticas (theme, verbosity, flags\n * de features, handler count, bufferSize) en una tabla agrupada dentro\n * de la consola. Es de solo lectura: no muta el logger.\n *\n * @example\n * // Inspeccionar el estado actual del logger\n * // > /status\n *\n * @see {@link Logger.getConfig} fuente de los datos mostrados.\n */\nexport class StatusCommand implements ICommand {\n name = 'status';\n description = 'Show current logger status and configuration';\n usage = '/status';\n\n /**\n * Ejecuta el comando `/status` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia de la que se lee la configuración.\n */\n execute(_args: string, logger: Logger): void {\n const config = logger.getConfig();\n const statusData = {\n theme: config.theme ? config.theme : 'default',\n verbosity: config.verbosity,\n colors: config.enableColors,\n timestamps: config.enableTimestamps,\n stackTrace: config.enableStackTrace,\n globalPrefix: config.globalPrefix ? config.globalPrefix : 'none',\n bannerType: config.bannerType ? config.bannerType : 'simple',\n handlers: logger.getHandlers().length,\n bufferSize: config.bufferSize ? config.bufferSize : 1000\n };\n\n logger.group('⚙️ Logger Configuration');\n logger.table(statusData);\n logger.groupEnd();\n }\n}\n\n/**\n * Comando `/reset` del CLI runtime del {@link Logger}. Restaura la\n * configuración a sus defaults de fábrica vía {@link Logger.resetConfig}.\n * No resetea handlers ni transports registrados — solo config.\n *\n * @example\n * // Volver a la configuración por defecto\n * // > /reset\n *\n * @see {@link Logger.resetConfig} para el método subyacente.\n */\nexport class ResetCommand implements ICommand {\n name = 'reset';\n description = 'Reset logger configuration to defaults';\n usage = '/reset';\n\n /**\n * Ejecuta el comando `/reset` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia cuya configuración se resetea.\n */\n execute(_args: string, logger: Logger): void {\n logger.resetConfig();\n }\n}\n\n/**\n * Comando `/demo` del CLI runtime del {@link Logger}. Ejecuta una\n * demostración integral de las capacidades del logger: todos los niveles\n * de log (debug → critical), tablas, timers (`time`/`timeEnd`), SVG inline\n * y mensajes animados. Útil para validar que el styling funciona en un\n * entorno nuevo o tras un cambio de tema.\n *\n * @example\n * // Lanzar la demo completa\n * // > /demo\n *\n * @see {@link Logger} para cada feature individual (`table`, `time`,\n * `logWithSVG`, `logAnimated`, ...).\n */\nexport class DemoCommand implements ICommand {\n name = 'demo';\n description = 'Show comprehensive feature demonstration';\n usage = '/demo';\n\n /**\n * Ejecuta el comando `/demo` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia sobre la que se ejecutan los ejemplos.\n */\n execute(_args: string, logger: Logger): void {\n logger.group('🎪 Advanced Logger Demo');\n\n // Basic logging demo\n logger.debug('Debug message with detailed information');\n logger.info('Informational message about system state');\n logger.warn('Warning about deprecated feature');\n logger.error('Error processing user request');\n logger.success('Operation completed successfully');\n logger.critical('Critical system failure detected');\n\n // Advanced features demo\n logger.group('📊 Advanced Features Demo');\n\n // Table demo\n logger.table([\n { feature: 'Styled Console', status: '✅ Active', performance: 'Excellent' },\n { feature: 'Theme System', status: '✅ Active', performance: 'Great' },\n { feature: 'CLI Interface', status: '✅ Active', performance: 'Good' },\n { feature: 'Export System', status: '✅ Active', performance: 'Excellent' }\n ]);\n\n // Timer demo\n logger.time('demo-operation');\n setTimeout(() => {\n logger.timeEnd('demo-operation');\n }, 100);\n\n // SVG demo\n logger.logWithSVG('SVG Demo');\n\n // Animated demo\n logger.logAnimated('🌟 Animated Logger Demo 🌟', 2);\n\n logger.groupEnd();\n logger.groupEnd();\n\n logger.info('Demo completed! Check the console for styled output.');\n }\n}\n","/**\n * @fileoverview Help system del CLI del logger. Expone {@link HelpCommand},\n * que renderiza un panel ASCII con la lista completa de comandos, opciones de\n * configuración, filtros de export y ejemplos de uso.\n */\n\nimport type { ICommand } from './CommandProcessor.js';\nimport type { Logger } from '../Logger.js';\nimport { StyleBuilder } from '../styling/index.js';\n\n/**\n * Comando `/help`: renderiza en consola el panel de ayuda del CLI con todos\n * los comandos disponibles, opciones de configuración, filtros de export y\n * ejemplos. El panel usa un gradient claro con {@link StyleBuilder} y los\n * quick tips se agrupan vía `logger.group`.\n *\n * Registrado por defecto por {@link createDefaultCLI}.\n *\n * @example\n * ```ts\n * const cli = createDefaultCLI();\n * await cli.processCommand('/help', logger);\n * // Imprime el panel ASCII con gradient + grupo \"Quick Tips\".\n * ```\n *\n * @see {@link ICommand}\n * @see {@link createDefaultCLI}\n */\nexport class HelpCommand implements ICommand {\n name = 'help';\n description = 'Show CLI help and available commands';\n usage = '/help [command]';\n\n /**\n * Renderiza el panel de ayuda completo. Actualmente ignora `_args`: el\n * `usage` declara `/help [command]` (sub-comando opcional) pero la\n * implementación siempre muestra el panel global.\n *\n * @param {string} _args - Argumentos opcionales (reservado para ayuda por\n * sub-comando; sin uso actual).\n * @param {Logger} logger - Logger activo; se usa solo para `group`/`info`\n * de los quick tips.\n * @returns {void}\n */\n execute(_args: string, logger: Logger): void {\n const helpStyle = new StyleBuilder()\n .bg('linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)')\n .color('#495057')\n .padding('15px 20px')\n .rounded('8px')\n .border('1px solid #dee2e6')\n .font('Monaco, Consolas, monospace')\n .size('13px')\n .build();\n\n const helpText = `\n╭─────────────── ADVANCED LOGGER CLI COMMANDS ─────────────────╮\n│ │\n│ CONFIGURATION │\n│ /config Show current configuration │\n│ /config {json} Apply JSON configuration │\n│ /config key=val Apply key-value configuration │\n│ /themes Show available themes │\n│ /banners Show available banner types │\n│ /banner [type] Change/show banner type │\n│ /status Show logger status & buffer stats │\n│ /demo Show feature demonstration │\n│ /reset Reset to default configuration │\n│ │\n│ EXPORT & CLIPBOARD │\n│ /export <format> Export logs (json|csv|md|plain|html) │\n│ /copy <format> Copy logs to clipboard │\n│ /buffer-size N Set log buffer size │\n│ /buffer-info Show buffer statistics │\n│ /clear-buffer Clear stored logs │\n│ │\n│ EXPORT FILTERS (for export/copy commands) │\n│ --level error,warn Filter by log levels │\n│ --since 2h Logs from last 2 hours │\n│ --until 1h Logs until 1 hour ago │\n│ --prefix API,DB Filter by prefixes │\n│ --exclude-prefix INT Exclude prefixes │\n│ --last 50 Last 50 logs only │\n│ --first 25 First 25 logs only │\n│ --search \"error\" Search in log messages │\n│ --with-stack Only logs with stack traces │\n│ --errors-only Only error + critical logs │\n│ --group-by level Group by level/prefix/hour │\n│ │\n│ EXPORT OPTIONS │\n│ --minimal Minimal output format │\n│ --compact Remove extra whitespace │\n│ --styled Include styling (HTML format) │\n│ │\n├──────────────────── CONFIGURATION OPTIONS ─────────────────┤\n│ │\n│ theme: default | dark | light | neon | minimal | cyberpunk│\n│ bannerType: simple | ascii | unicode | svg | animated │\n│ verbosity: debug | info | warn | error | critical | silent│\n│ enableColors: true | false │\n│ enableTimestamps: true | false │\n│ enableStackTrace: true | false │\n│ globalPrefix: \"string\" │\n│ bufferSize: number (50-10000) │\n│ │\n├──────────────────────── EXAMPLES ──────────────────────────┤\n│ │\n│ Basic Configuration: │\n│ /config {\"theme\":\"dark\",\"verbosity\":\"debug\"} │\n│ /config theme=neon,bufferSize=2000 │\n│ /banner animated Change to animated banner │\n│ │\n│ Export Examples: │\n│ /export json --level=error,warn --last=25 │\n│ /export csv --since=2h --prefix=API │\n│ /export markdown --group-by=level --errors-only │\n│ /export html --styled --since=1h │\n│ │\n│ Clipboard Examples: │\n│ /copy plain --minimal --last=10 │\n│ /copy json --search=\"authentication\" --compact │\n│ /copy csv --since=30m --exclude-prefix=DEBUG │\n│ │\n│ Buffer Management: │\n│ /buffer-size 5000 Increase buffer to 5000 logs │\n│ /buffer-info Show detailed buffer statistics │\n│ /clear-buffer Clear all stored logs │\n│ │\n│ Time Formats: │\n│ --since=2h 2 hours ago │\n│ --since=30m 30 minutes ago │\n│ --since=1d 1 day ago │\n│ --since=\"2024-01-01T10:00:00Z\" Specific ISO date │\n│ │\n╰─────────────────────────────────────────────────────────────╯`;\n\n console.log(`%c${helpText}`, helpStyle);\n\n // Show quick tips\n logger.group('💡 Quick Tips');\n const tips = [\n 'Use /demo to see all logger features in action',\n 'Logs are automatically stored in a circular buffer for export',\n 'Export formats: JSON (structured), CSV (Excel), Markdown (readable), Plain (simple), HTML (styled)',\n 'Time filters support relative (2h, 30m) and absolute (ISO) formats',\n 'Combine multiple filters: /export json --level=error --since=1h --search=\"auth\"',\n 'Use /copy for quick clipboard access instead of /export'\n ];\n \n tips.forEach(tip => {\n logger.info(`• ${tip}`);\n });\n logger.groupEnd();\n }\n}","/**\n * @fileoverview Punto de entrada del subsistema CLI del logger. Re-exporta el\n * processor, los comandos estándar y expone {@link createDefaultCLI} como\n * factory principal. El CLI no es un binario standalone — se invoca desde\n * código vía `logger.cli()` o desde la devtools vía `window.cli()` (cuando el\n * modo interactivo está activo).\n */\n\n// Core CLI system\nexport { CommandProcessor, type ICommand } from './CommandProcessor.js';\nimport { CommandProcessor } from './CommandProcessor.js';\n\n// Commands\nexport { ConfigCommand } from './commands/ConfigCommand.js';\nexport { ThemesCommand, BannersCommand, BannerCommand } from './commands/ThemeCommand.js';\nexport { StatusCommand, ResetCommand, DemoCommand } from './commands/ExportCommand.js';\n\n// Help system\nexport { HelpCommand } from './help.js';\n\n// Import all commands\nimport { HelpCommand } from './help.js';\nimport { ConfigCommand } from './commands/ConfigCommand.js';\nimport { ThemesCommand, BannersCommand, BannerCommand } from './commands/ThemeCommand.js';\nimport { StatusCommand, ResetCommand, DemoCommand } from './commands/ExportCommand.js';\n\n/**\n * Crea un {@link CommandProcessor} con los 8 comandos estándar ya registrados:\n * `help`, `config`, `themes`, `banners`, `banner`, `status`, `reset` y\n * `demo`. Es el factory canónico — los consumidores normalmente no construyen\n * un `CommandProcessor` vacío a mano, ya que este no trae comandos cargados.\n *\n * @returns {CommandProcessor} Processor listo para usar, sin modo interactivo activo.\n *\n * @example\n * ```ts\n * const cli = createDefaultCLI();\n * await cli.processCommand('/help', logger);\n * await cli.processCommand('/config theme=neon', logger);\n * ```\n *\n * @example\n * ```ts\n * // Modo interactivo en el navegador: expone `window.cli`\n * const cli = createDefaultCLI();\n * cli.enterInteractiveMode(logger);\n * // desde devtools: cli('themes') → procesa '/themes'\n * ```\n *\n * @see {@link CommandProcessor}\n * @see {@link HelpCommand}\n */\nexport function createDefaultCLI(): CommandProcessor {\n const processor = new CommandProcessor();\n\n // Register all default commands\n processor.registerCommand(new HelpCommand());\n processor.registerCommand(new ConfigCommand());\n processor.registerCommand(new ThemesCommand());\n processor.registerCommand(new BannersCommand());\n processor.registerCommand(new BannerCommand());\n processor.registerCommand(new StatusCommand());\n processor.registerCommand(new ResetCommand());\n processor.registerCommand(new DemoCommand());\n\n return processor;\n}","/**\n * @fileoverview TransportBridge — facade de TransportManager.\n * Encapsula el lifecycle de transports: add, remove, flush, close.\n *\n * @internal\n */\n\nimport type { TransportTarget } from '../types/index.js';\nimport { TransportManager } from '../transports/index.js';\n\n/**\n * Resultado de añadir un transport.\n */\nexport interface AddTransportResult {\n /** ID único del transport. */\n id: string;\n /** La instancia de TransportManager (creada al primer add). */\n manager: TransportManager;\n}\n\n/**\n * Bridge para la gestión del lifecycle de transports.\n *\n * @internal\n */\nexport interface TransportBridge {\n /** Añade un transport y devuelve su ID. */\n addTransport(target: TransportTarget): string;\n /** Elimina un transport por ID. Devuelve `true` si se eliminó. */\n removeTransport(id: string): boolean;\n /** Fuerza el flush de todos los buffers de transports. */\n flushTransports(): Promise<void>;\n /** Cierra todos los transports de forma graceful. */\n closeTransports(): Promise<void>;\n /** Devuelve el manager subyacente (o `undefined` si nunca se usó). */\n getTransportManager(): TransportManager | undefined;\n /** Escribe un transport record (fire-and-forget). No-op si el manager no está inicializado. */\n writeRecord(record: Parameters<TransportManager['write']>[0]): void;\n}\n\n/**\n * Crea una instancia de {@link TransportBridge}.\n *\n * @internal\n */\nexport function createTransportBridge(): TransportBridge {\n let transportManager: TransportManager | undefined;\n\n return {\n addTransport(target: TransportTarget): string {\n if (!transportManager) {\n transportManager = new TransportManager();\n }\n return transportManager.add(target);\n },\n\n removeTransport(id: string): boolean {\n return transportManager?.remove(id) ?? false;\n },\n\n async flushTransports(): Promise<void> {\n await transportManager?.flush();\n },\n\n async closeTransports(): Promise<void> {\n await transportManager?.close();\n },\n\n getTransportManager(): TransportManager | undefined {\n return transportManager;\n },\n\n writeRecord(record): void {\n if (!transportManager) return;\n // Fire-and-forget — nunca rompe el sync log path.\n transportManager.write(record).catch(() => {});\n }\n };\n}\n","/**\n * @fileoverview SpanRuntime — runtime de spans del trio API\n * `event` / `span` / `startSpan`.\n *\n * Vive en transports/ porque es la extensión del pipeline de dispatch: los\n * {@link SpanRecord} que produce viajan por el {@link TransportManager} junto\n * a los log records, enrutados por kind (`accepts`).\n *\n * Tres responsabilidades:\n * - **ALS singleton del módulo**: un único `AsyncLocalStorage<SpanRecord>`\n * compartido por TODAS las instancias de Logger — \"qué instancia lleva el\n * span\" es ambiguo con MDC por-instancia, el span activo es una propiedad\n * del call stack, no del logger.\n * - **Generación de ids** conforme a W3C Trace Context (traceId 16 bytes →\n * 32 hex, spanId 8 bytes → 16 hex) vía `crypto.getRandomValues`.\n * - **Leak-safety**: registry de spans abiertos; en flush/shutdown se\n * fuerzan a `end()` con `incomplete: true` y se exportan — nunca se tiran.\n */\n\nimport type { Span, SpanAttributes, SpanRecord } from '../types/index.js';\nimport { resolveAsyncLocalStorage, type AsyncLocalStorageLike } from '../utils/asyncLocalStorage.js';\n\n/**\n * Forma mínima del `AsyncLocalStorage` de `node:async_hooks` que usa el\n * runtime. Undefined en browser sin polyfill.\n */\ntype SpanALS = AsyncLocalStorageLike<SpanRecord>;\n\n/** ALS singleton del módulo — compartido por todas las instancias de Logger.\n *\n * Resolución por capas (global → `process.getBuiltinModule` → `require`,\n * undefined en browser) delegada al helper compartido\n * {@link resolveAsyncLocalStorage} — ver su doc para el detalle de capas.\n * `context/LogContext.ts` usa el mismo helper para su ALS de MDC. */\nconst activeSpanStore: SpanALS | undefined = resolveAsyncLocalStorage<SpanRecord>();\n\n/**\n * Span activo en el call stack corriente (dentro de `span(fn)`), si lo hay.\n * Lo consumen la correlación log→span (`TransportRecord.traceId/spanId`) y la\n * resolución de `parentSpanId` en spans hijos.\n */\nexport function getActiveSpan(): SpanRecord | undefined {\n return activeSpanStore?.getStore();\n}\n\n/**\n * Ejecuta `fn` con `record` como span activo. Sin ALS disponible (browser),\n * ejecuta `fn` directamente — sin correlación pero funcional.\n */\nexport function runWithActiveSpan<R>(record: SpanRecord, fn: () => R): R {\n return activeSpanStore ? activeSpanStore.run(record, fn) : fn();\n}\n\n/** Nanosegundos Unix actuales como string decimal (formato OTLP). */\nexport function nowUnixNano(): string {\n return String(BigInt(Date.now()) * 1_000_000n);\n}\n\n/**\n * Hex aleatorio de `bytes` bytes. Usa `crypto.getRandomValues`; sin\n * `crypto` (runtimes exóticos) degrada a `Math.random` — suficiente para ids\n * de correlación, no para secrets.\n */\nfunction randomHex(bytes: number): string {\n const cryptoObj = (globalThis as { crypto?: { getRandomValues?: (buf: Uint8Array) => Uint8Array } }).crypto;\n if (cryptoObj?.getRandomValues) {\n const buf = new Uint8Array(bytes);\n cryptoObj.getRandomValues(buf);\n let out = '';\n for (const b of buf) {\n out += b.toString(16).padStart(2, '0');\n }\n return out;\n }\n let out = '';\n for (let i = 0; i < bytes * 2; i++) {\n out += Math.floor(Math.random() * 16).toString(16);\n }\n return out;\n}\n\n/** Trace id W3C: 16 bytes → 32 chars hex. */\nexport function generateTraceId(): string {\n return randomHex(16);\n}\n\n/** Span id W3C: 8 bytes → 16 chars hex. */\nexport function generateSpanId(): string {\n return randomHex(8);\n}\n\ninterface OpenSpanEntry {\n record: SpanRecord;\n /** End normal: cierra el span con su duración real. */\n end: () => void;\n /** End forzado por flush: marca `incomplete: true` antes de cerrar. */\n forceEnd: () => void;\n}\n\n/**\n * Registry de spans abiertos (leak-safety). Cubre tanto los de `startSpan()`\n * (externally-ended, el caso del handoff) como los de `span(fn)` en curso:\n * si un flush llega mid-flight, es mejor exportar el span incompleto que\n * tirarlo. El doble-`end()` es no-op, así que el cierre natural posterior no\n * duplica el export.\n */\nconst openSpans = new Map<SpanRecord, OpenSpanEntry>();\n\n/**\n * Crea el record de span y su {@link Span} handle. El handle registra el\n * span en el registry de abiertos; `onEnd` se invoca una única vez, con el\n * record final (duración real o `incomplete: true`), para su export al\n * pipeline de transports.\n *\n * `end()` solo fija `endTimeUnixNano` si no se fijó antes — así los\n * point-spans (`event()`) pueden fijar `end = start` exacto.\n *\n * @param name - Nombre de la operación.\n * @param attributes - Attributes iniciales (copia propia del record).\n * @param scope - Scope del logger emisor.\n * @param onEnd - Callback de export; recibe el record cerrado.\n * @returns El record (para el ALS store) y el handle del span.\n */\nexport function createSpan(\n name: string,\n attributes: SpanAttributes | undefined,\n scope: string,\n onEnd: (record: SpanRecord) => void\n): { record: SpanRecord; span: Span } {\n const parent = getActiveSpan();\n\n const record: SpanRecord = {\n kind: 'span',\n traceId: parent?.traceId ?? generateTraceId(),\n spanId: generateSpanId(),\n parentSpanId: parent?.spanId,\n name,\n spanKind: 1,\n startTimeUnixNano: nowUnixNano(),\n endTimeUnixNano: '0',\n attributes: { ...(attributes ?? {}) },\n scope\n };\n\n let ended = false;\n\n const finish = (): void => {\n if (ended) return;\n ended = true;\n openSpans.delete(record);\n onEnd(record);\n };\n\n openSpans.set(record, {\n record,\n end: finish,\n forceEnd: (): void => {\n if (ended) return;\n record.incomplete = true;\n if (record.endTimeUnixNano === '0') {\n record.endTimeUnixNano = nowUnixNano();\n }\n finish();\n }\n });\n\n const handle: Span = {\n traceId: record.traceId,\n spanId: record.spanId,\n set(key: string, value: string | number | boolean): Span {\n record.attributes[key] = value;\n return handle;\n },\n end(attributes?: SpanAttributes): void {\n if (attributes) {\n Object.assign(record.attributes, attributes);\n }\n if (ended) return;\n if (record.endTimeUnixNano === '0') {\n record.endTimeUnixNano = nowUnixNano();\n }\n finish();\n },\n fail(err: unknown): void {\n if (ended) return;\n record.status = {\n code: 2,\n message: err instanceof Error ? err.message : String(err)\n };\n this.end();\n }\n };\n\n return { record, span: handle };\n}\n\n/**\n * Emite un point-span (`event()`): start = end exactamente, sin registro en\n * abiertos tras el cierre — no hay leak posible. El `parentSpanId` se resuelve\n * contra el span activo si existe, pero NO fija contexto ALS.\n */\nexport function emitEventSpan(\n name: string,\n attributes: SpanAttributes | undefined,\n scope: string,\n onEnd: (record: SpanRecord) => void\n): void {\n const { record, span } = createSpan(name, attributes, scope, onEnd);\n record.endTimeUnixNano = record.startTimeUnixNano;\n span.end();\n}\n\n/**\n * Fuerza el cierre de todos los spans abiertos (`incomplete: true`) y los\n * exporta vía el `onEnd` de cada uno. Lo invocan `flushTransports()` /\n * `closeTransports()` / `cleanup()` ANTES del flush real — un span abierto\n * nunca se tira en shutdown.\n *\n * @returns Los records forzados a cerrar (para diagnóstico/tests).\n */\nexport function forceCloseOpenSpans(): SpanRecord[] {\n // Snapshot: forceEnd muta el Map durante la iteración.\n const snapshot = [...openSpans.values()];\n for (const entry of snapshot) {\n entry.forceEnd();\n }\n return snapshot.map(entry => entry.record);\n}\n\n/** Número de spans actualmente abiertos (expuesto para tests/diagnóstico). */\nexport function openSpanCount(): number {\n return openSpans.size;\n}\n","/**\n * @fileoverview TerminalBridge — integración de terminal CLI.\n * Encapsula detección de TTY, renderizado de primitivas CLI y fallback a\n * server-mode para entornos non-TTY.\n *\n * @internal\n */\n\nimport type { CLILogLevel, ISpinnerHandle, IBoxOptions, ITableOptions } from '../types/index.js';\nimport { renderStep } from '../playground/step.js';\nimport { renderHeader } from '../playground/header.js';\nimport { renderDivider } from '../playground/divider.js';\nimport { renderBox } from '../playground/box.js';\nimport { renderTable } from '../playground/cli-table.js';\nimport { SpinnerManager, NoopSpinner } from '../playground/spinner.js';\nimport { ServerFallback } from '../playground/server-fallback.js';\nimport { getColorCapability, isRunningInTerminal } from '../utils/environment-detector.js';\nimport type { LoggerConfig } from '../types/index.js';\nimport type { Logger } from '../Logger.js';\n\n/**\n * Bridge para operaciones de terminal CLI.\n *\n * @internal\n */\nexport interface TerminalBridge {\n /** Muestra un indicador de progreso tipo step. */\n step(current: number, total: number, message: string): void;\n /** Muestra un header con estilo. */\n header(title: string, subtitle?: string): void;\n /** Muestra un divider horizontal. */\n divider(): void;\n /** Emite una línea en blanco. */\n blank(): void;\n /** Renderiza contenido dentro de un box con border. */\n box(content: string, options?: IBoxOptions): void;\n /** Renderiza un array de objetos como tabla ASCII. */\n cliTable(rows: Record<string, unknown>[], options?: ITableOptions): void;\n /** Crea un handle de spinner. */\n spinner(message: string): ISpinnerHandle;\n /** Indica si las primitivas CLI deben mostrarse. */\n getShowPrimitives(): boolean;\n /** Define si las primitivas CLI deben mostrarse. */\n setShowPrimitives(show: boolean): void;\n /** Devuelve la instancia del server fallback (lazy). */\n getServerFallback(): ServerFallback;\n /** Devuelve `true` si se ejecuta en un TTY. */\n isInTerminal(): boolean;\n}\n\ninterface ITerminalBridgeCtorOptions {\n config: LoggerConfig;\n getLogger: () => Logger;\n}\n\n/**\n * Crea un {@link TerminalBridge} usando un getter para evitar referencias\n * circulares en la construcción.\n *\n * @internal\n */\nexport function createTerminalBridge(options: ITerminalBridgeCtorOptions): TerminalBridge {\n let _showPrimitives = true;\n let _serverFallback: ServerFallback | undefined;\n\n return {\n step(current: number, total: number, message: string): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().step(current, total, message);\n return;\n }\n const colorCap = getColorCapability();\n const output = renderStep(current, total, message, colorCap);\n process.stderr.write(output + '\\n');\n },\n\n header(title: string, subtitle?: string): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().header(title, subtitle);\n return;\n }\n const output = renderHeader(title, subtitle);\n process.stderr.write(output + '\\n');\n },\n\n divider(): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().divider();\n return;\n }\n const output = renderDivider();\n process.stderr.write(output + '\\n');\n },\n\n blank(): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().blank();\n return;\n }\n process.stderr.write('\\n');\n },\n\n box(content: string, opts?: IBoxOptions): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().box(content, opts);\n return;\n }\n const colorCap = getColorCapability();\n const output = renderBox(content, opts, colorCap);\n process.stderr.write(output + '\\n');\n },\n\n cliTable(rows: Record<string, unknown>[], opts?: ITableOptions): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().cliTable(rows, opts);\n return;\n }\n const colorCap = getColorCapability();\n const output = renderTable(rows, opts, colorCap);\n process.stderr.write(output + '\\n');\n },\n\n spinner(message: string): ISpinnerHandle {\n const logger = options.getLogger();\n if (!isRunningInTerminal() || options.config.outputMode === 'silent') {\n return new NoopSpinner(message, logger);\n }\n return new SpinnerManager(message, options.config, logger);\n },\n\n getShowPrimitives(): boolean {\n return _showPrimitives;\n },\n\n setShowPrimitives(show: boolean): void {\n _showPrimitives = show;\n },\n\n getServerFallback(): ServerFallback {\n if (!_serverFallback) {\n _serverFallback = new ServerFallback(options.getLogger());\n }\n return _serverFallback;\n },\n\n isInTerminal(): boolean {\n return isRunningInTerminal();\n }\n };\n}\n","/**\n * @fileoverview Logger avanzado con arquitectura modular y API simplificada\n * \n * Sistema de logging profesional con estilos CSS avanzados, temas adaptativos,\n * badges automáticos, contextos temporales y exportación de datos.\n */\n\n// Type imports\nimport type {\n LogLevel,\n LogTag,\n Verbosity,\n ThemeVariant,\n BannerType,\n LoggerConfig,\n TimerEntry,\n ILogHandler,\n LogMetadata,\n StyleOptions,\n Bindings,\n SerializerFn,\n HookEvent,\n HookCallback,\n MiddlewareFn,\n TransportTarget,\n TransportRecord,\n ILogResourceRef,\n StackInfo,\n LogStyles,\n ILogAttributes,\n LogAttributeValue,\n Span,\n SpanAttributes\n} from './types/index.js';\n\nimport { LOG_LEVELS } from './types/index.js';\nimport {\n LOG_LEVEL_TO_SEVERITY_NUMBER,\n LOG_LEVEL_TO_SEVERITY_TEXT,\n type ILogResource as ITransportLogResource\n} from './types/index.js';\n\n// Enterprise features\nimport { SerializerRegistry } from './serializers/index.js';\nimport { HookManager } from './hooks/index.js';\nimport { TransportManager } from './transports/index.js';\n\n// Utility imports\nimport { parseStackTrace } from './utils/stackTrace.js';\nimport { formatTimestamp } from './utils/timestamps.js';\nimport { createStyledOutput, setupThemeChangeListener } from './utils/output.js';\nimport { getEnvironment, getColorCapability, isRunningInTerminal } from './utils/environment-detector.js';\nimport { formatBadge } from './terminal/formatter.js';\n\n// Styling imports\nimport {\n THEME_PRESETS,\n THEME_BANNERS,\n displayInitBanner,\n StylePresets,\n StyleBuilder\n} from './styling/index.js';\n\n// Smart presets and dynamic scoped loggers\nimport { getSmartPreset, getAvailablePresets, hasPreset } from './styling/SmartPresets.js';\n\n// Scoped loggers (static import for performance)\nimport { ScopedLogger, APILogger, ComponentLogger } from './ScopedLogger.js';\n\n// CLI imports\nimport { createDefaultCLI, type CommandProcessor } from './cli/index.js';\n\n// Constants\nimport { DEFAULT_CONFIG, CLI_LEVEL_MAP } from './constants.js';\n\n// CLI Primitives\nimport type { CLILogLevel, ISpinnerHandle, IBoxOptions, ITableOptions } from './types/index.js';\n\n// Bridge imports\nimport { createLogContext, type LogContext } from './context/LogContext.js';\nimport { createTransportBridge, type TransportBridge } from './transports/TransportBridge.js';\nimport {\n getActiveSpan,\n runWithActiveSpan,\n createSpan,\n emitEventSpan,\n forceCloseOpenSpans\n} from './transports/SpanRuntime.js';\nimport { createHookBridge, type HookBridge } from './hooks/HookBridge.js';\nimport { createSerializerBridge, type SerializerBridge } from './serializers/SerializerBridge.js';\nimport { createTerminalBridge, type TerminalBridge } from './playground/TerminalBridge.js';\nimport { createStyleManager, type StyleManager } from './styles/StyleManager.js';\n\n/**\n * Estilos del tema activo actual\n * @private\n */\nlet LEVEL_STYLES = THEME_PRESETS.default;\n\n/**\n * Clase principal Logger con capacidades avanzadas de logging\n * \n * @class Logger\n * @description Sistema completo de logging con temas, badges, contextos y exportación.\n * Detecta automáticamente el tema claro/oscuro del navegador.\n * \n * @example\n * // Uso básico sin configuración\n * import logger from '@mks2508/better-logger';\n * logger.info('Aplicación iniciada');\n * logger.success('Conexión establecida');\n * \n * @example\n * // Aplicar un preset temático\n * logger.preset('cyberpunk');\n * logger.warn('Advertencia con estilo neón');\n * \n * @example\n * // Logger con scope para componentes\n * const auth = logger.component('Autenticación');\n * auth.info('Usuario intentando login');\n * auth.success('Login exitoso');\n * \n */\nexport class Logger {\n private config: LoggerConfig;\n private scopedPrefix?: string;\n private handlers: ILogHandler[] = [];\n private timers: Map<string, TimerEntry> = new Map();\n private groupDepth: number = 0;\n private cliProcessor?: CommandProcessor;\n private themeChangeListener?: (() => void) | null;\n private badgeList: string[] = [];\n private displaySettings = {\n showTimestamp: true,\n showLocation: true,\n showBadges: true\n };\n\n private serializerBridge: SerializerBridge;\n private hookBridge: HookBridge;\n private logContext: LogContext;\n private transportBridge: TransportBridge;\n /** Fijado por `success()` para que `log()` salte su propio dispatch. */\n private _successTagDispatched = false;\n private styleManager: StyleManager;\n\n /** Controla si las CLI primitives (step, box, header, ...) deben renderizarse. */\n private _showPrimitives = true;\n private terminalBridge: TerminalBridge;\n\n /**\n * Referencia activa al smart-preset (fijada por `preset()`). Tipada como\n * `unknown` para mantener limpia la surface pública; la consume\n * `createStyledOutput`.\n */\n private _activePreset?: unknown;\n /**\n * Nombre del smart-preset activo. Se guarda aparte para que la detección\n * de cambio de tema pueda re-renderizar sin re-ejecutar el body del preset.\n */\n private _activePresetName?: string;\n /**\n * Overrides aplicados por el último `customize()`. Se conservan para que\n * `createStyledOutput` los lea después.\n */\n private _customization?: unknown;\n\n /**\n * Bindings propios de este logger (provenientes de llamadas a `child()`).\n * Source of truth única de la contribución de este logger a la cadena de contexto.\n * @private\n */\n private _bindings: Record<string, unknown> = {};\n\n /**\n * Referencia al record de contexto mergueado del parent en el momento en\n * que se creó este logger. Junto con `_bindings`, forma la cadena de\n * contexto. `undefined` para el logger raíz.\n * @private\n */\n private _parentContextRecord: Record<string, unknown> | undefined;\n\n /**\n * Crea una nueva instancia del Logger\n * \n * @param {Partial<LoggerConfig>} config - Configuración opcional del logger\n * \n * @example\n * // Logger con configuración personalizada\n * const logger = new Logger({\n * theme: 'neon',\n * globalPrefix: 'MiApp',\n * verbosity: 'debug',\n * bufferSize: 1000\n * });\n */\n constructor(config: Partial<LoggerConfig> = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n };\n\n // Enterprise features\n this.serializerBridge = createSerializerBridge();\n this.hookBridge = createHookBridge();\n\n // LogContext bridge\n this.logContext = createLogContext({\n initialResource: this.config.resource,\n childLoggerFactory: (childConfig: Partial<LoggerConfig>): Logger => {\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n return new Logger({ ...this.config, ...childConfig });\n },\n // Captura el contexto mergueado completo del parent en el momento\n // de creación del child, para que los child loggers puedan construir\n // la cadena correctamente.\n getParentContextRecord: () => this._captureMergedContext()\n });\n\n // TransportBridge\n this.transportBridge = createTransportBridge();\n\n // StyleManager bridge\n this.styleManager = createStyleManager();\n\n // TerminalBridge lazy — usa getter para evitar circular ref\n this.terminalBridge = createTerminalBridge({\n config: this.config,\n getLogger: () => this\n });\n\n // CLI processor lazy.\n // Los consumers que usan `logger.cli(...)` pagan el setup en el momento de la llamada.\n this.cliProcessor = createDefaultCLI();\n\n // Set up theme change listener si auto-detection está habilitado\n if (this.config.autoDetectTheme) {\n this.setupAutoThemeDetection();\n }\n }\n\n // ===== PRIVATE HELPER METHODS =====\n \n /**\n * Configura la detección automática de tema con listener de cambios\n * @private\n * @description Detecta automáticamente si el navegador está en modo claro u oscuro\n */\n private setupAutoThemeDetection(): void {\n // Limpia el listener existente si lo hay\n if (this.themeChangeListener) {\n this.themeChangeListener();\n this.themeChangeListener = null;\n }\n\n // Set up nuevo listener\n this.themeChangeListener = setupThemeChangeListener((theme) => {\n // Theme cambió — los logs usarán automáticamente los nuevos colores en la próxima llamada.\n // No hace falta actualizar nada: los colores se resuelven dinámicamente.\n this.debug(`DevTools theme changed to: ${theme}`);\n });\n }\n\n // ===== CONFIGURATION METHODS =====\n\n /**\n * Obtiene la configuración actual del logger\n * \n * @returns {LoggerConfig} Configuración completa actual\n * \n * @example\n * const config = logger.getConfig();\n * console.log('Verbosidad actual:', config.verbosity);\n * console.log('Tema actual:', config.theme);\n * \n */\n getConfig(): LoggerConfig {\n return { ...this.config };\n }\n\n /**\n * Actualiza la configuración del logger\n * \n * @param {Partial<LoggerConfig>} updates - Propiedades a actualizar\n * \n * @example\n * logger.updateConfig({\n * verbosity: 'debug',\n * enableTimestamps: false,\n * theme: 'cyberpunk'\n * });\n * \n */\n updateConfig(updates: Partial<LoggerConfig>): void {\n const previousAutoDetect = this.config.autoDetectTheme;\n this.config = { ...this.config, ...updates };\n \n // Handle de cambios de auto-detection\n if (updates.autoDetectTheme !== undefined && updates.autoDetectTheme !== previousAutoDetect) {\n if (updates.autoDetectTheme) {\n this.setupAutoThemeDetection();\n } else if (this.themeChangeListener) {\n this.themeChangeListener();\n this.themeChangeListener = null;\n }\n }\n }\n\n /**\n * Establece el prefijo global para todos los mensajes de log\n * \n * @param {string} prefix - Prefijo a usar\n * \n * @example\n * logger.setGlobalPrefix('MiApp');\n * logger.info('Iniciado'); // [MiApp] Iniciado\n * \n */\n setGlobalPrefix(prefix: string): void {\n this.config.globalPrefix = prefix;\n }\n\n /**\n * Establece el nivel de verbosidad para filtrar la salida de logs\n * \n * @param {Verbosity} level - Nivel mínimo a mostrar ('debug' | 'info' | 'warn' | 'error' | 'critical' | 'silent')\n * \n * @example\n * logger.setVerbosity('warn'); // Solo muestra warn, error y critical\n * logger.setVerbosity('debug'); // Muestra todos los niveles\n * logger.setVerbosity('silent'); // No muestra nada\n * \n */\n setVerbosity(level: Verbosity): void {\n this.config.verbosity = level;\n }\n\n /**\n * Establece el tema del logger\n * \n * @param {ThemeVariant} theme - Tema a aplicar ('default' | 'dark' | 'light' | 'neon' | 'minimal' | 'cyberpunk')\n * \n * @example\n * logger.setTheme('neon'); // Tema con colores neón\n * logger.setTheme('minimal'); // Tema minimalista\n * logger.setTheme('cyberpunk'); // Tema cyberpunk con efectos\n * \n */\n setTheme(theme: ThemeVariant): void {\n // Primero comprueba si es un smart preset\n if (hasPreset(theme)) {\n this.preset(theme);\n return;\n }\n\n // Fallback al sistema de temas legacy — delega al StyleManager para\n // mantener el LEVEL_STYLES module-level sincronizado con el bridge.\n const applied = this.styleManager.setTheme(theme);\n if (applied) {\n this.config.theme = theme;\n\n // Muestra el banner específico del theme a través del writer\n // centralizado para respetar los outputMode silent/custom.\n const bannersRecord = THEME_BANNERS as Record<string, { simple: string; style: string }>;\n if (theme in bannersRecord) {\n const themeBanner = bannersRecord[theme];\n if (themeBanner) {\n this.writeOutput(`%c${themeBanner.simple}`, 'info', [themeBanner.style], []);\n }\n }\n\n this.success(`Theme changed to: ${theme}`);\n } else {\n this.error(`Invalid theme: ${theme}. Available:`, [...getAvailablePresets(), ...Object.keys(THEME_PRESETS)]);\n }\n }\n\n /**\n * Establece el tipo de banner para mostrar en la inicialización\n * \n * @param {BannerType} bannerType - Tipo de banner ('simple' | 'ascii' | 'unicode' | 'svg' | 'animated')\n * \n * @example\n * logger.setBannerType('ascii'); // Banner con arte ASCII\n * logger.setBannerType('unicode'); // Banner con caracteres Unicode\n * logger.setBannerType('animated'); // Banner con animación\n * \n */\n setBannerType(bannerType: BannerType): void {\n this.config.bannerType = bannerType;\n this.success(`Banner type changed to: ${bannerType}`);\n }\n\n /**\n * Ejecuta `fn` dentro de un scope AsyncLocalStorage donde `bindings` se\n * merguean al contexto para todas las llamadas de log dentro de `fn`.\n *\n * Sin `fn` (el shape legacy de setter): no-op por backwards compatibility.\n * Preferir `child()` para bindings persistentes o `withContextAsync()`\n * para callbacks async.\n *\n * @param bindings - Pares key-value a adjuntar durante la ejecución de `fn`\n * @param fn - Función sincrónica opcional a ejecutar con los bindings en scope\n * @returns El valor de retorno de `fn`, o `undefined` si no se pasa `fn`\n *\n * @example\n * // Callback sincrónico scoped\n * logger.withContext({ requestId: 'r-42' }, () => {\n * doWork(); // los logs de aquí ven requestId en attributes\n * });\n *\n * @example\n * // Binding persistente: usar child()\n * const reqLog = logger.child({ requestId: 'r-42' });\n * reqLog.info('handling request'); // attributes incluye requestId\n *\n * @see {@link child} para una copia inmutable con el contexto mergueado\n * @see {@link withContextAsync} para la variante con callback async\n */\n withContext<R>(bindings: Record<string, unknown>, fn?: () => R): R | undefined {\n return this.logContext.withContext(bindings, fn);\n }\n\n /**\n * Variante async de `withContext`. Ejecuta `fn` dentro de un scope\n * AsyncLocalStorage para que los bindings estén disponibles a todas las\n * llamadas de log async dentro de `fn`.\n *\n * @param bindings - Pares key-value a adjuntar durante la ejecución de `fn`\n * @param fn - Función async a ejecutar con los bindings en scope\n * @returns El valor de retorno de `fn`\n *\n * @example\n * await logger.withContextAsync({ requestId: 'r-42' }, async () => {\n * await fetchData(); // los logs de aquí ven requestId en attributes\n * });\n *\n * @see {@link child} para un child logger persistente\n * @see {@link withContext} para la variante con callback sincrónico\n */\n withContextAsync<R>(bindings: Record<string, unknown>, fn: () => Promise<R>): Promise<R> {\n return this.logContext.withContextAsync(bindings, fn);\n }\n\n /**\n * Devuelve una copia inmutable de este logger con el contexto extra bound.\n * Las llamadas futuras sobre el child emiten con el contexto mergueado,\n * sin mutar al parent — el patrón canónico de MDC.\n *\n * @param extra - Pares key-value a adjuntar (requestId, userId, ...)\n * @returns Un nuevo Logger con el contexto mergueado\n *\n * @example\n * const reqLog = logger.child({ requestId: req.id });\n * reqLog.info('start'); // emite attributes: { requestId }\n * logger.info('unrelated'); // NO afectado — el contexto del parent queda intacto\n *\n */\n child(extra: Record<string, unknown>): Logger {\n // LogContext.child() crea el child Logger vía factory y captura el\n // snapshot de _getContextRecord() del parent (contexto parent + ALS)\n // en __parentSnapshot sobre el child. Aquí lo recogemos y lo\n // asignamos a _parentContextRecord, y luego fijamos los _bindings del child.\n const childLogger = this.logContext.child(extra) as unknown as Logger;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const snapshot = (childLogger as any)['__parentSnapshot'] as Record<string, unknown> | undefined;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (childLogger as any)._parentContextRecord = snapshot ?? {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (childLogger as any)._bindings = extra;\n return childLogger;\n }\n\n /**\n * Descarta todas las keys del contexto bound. Tras esta llamada, los\n * records emitidos dejan de llevar `attributes` hasta que\n * {@link withContext} o {@link child} restablezcan uno.\n *\n * @returns La misma instancia del logger, ahora sin contexto\n */\n clearContext(): this {\n this.logContext.clearContext();\n return this;\n }\n\n /**\n * Snapshot del contexto bound. El objeto devuelto es una shallow copy:\n * mutarlo NO afecta lo que emiten las llamadas de log posteriores.\n *\n * @returns Un snapshot read-only del contexto actual\n */\n getContext(): Readonly<Record<string, unknown>> {\n // Devuelve la cadena de contexto (snapshot del parent + bindings propios),\n // SIN incluir el scope ALS (que es transitorio). Esto replica lo que usa\n // dispatchToTransports para attributes, pero sin el overlay de ALS.\n let merged: Record<string, unknown> = this._parentContextRecord ?? {};\n if (this._bindings && Object.keys(this._bindings).length > 0) {\n merged = { ...merged, ...this._bindings };\n }\n return merged;\n }\n\n /**\n * Actualiza el resource OTel por defecto (service.name, version, env).\n * Se persiste en el campo `resource` de cada record emitido, salvo que\n * el propio record lo override.\n *\n * @param resource - Resource OTel parcial a merguear con el actual\n * @returns La misma instancia del logger, para chaining\n *\n * @example\n * logger.setResource({ 'service.name': 'api', 'service.version': '1.2.3' });\n *\n */\n setResource(resource: Partial<ILogResourceRef>): this {\n this.logContext.setResource(resource);\n return this;\n return this;\n }\n\n /**\n * Reinicia el logger a la configuración por defecto\n * \n * @example\n * logger.resetConfig();\n * // Todo vuelve a la configuración inicial\n * \n */\n resetConfig(): void {\n // Clean up del theme listener\n if (this.themeChangeListener) {\n this.themeChangeListener();\n this.themeChangeListener = null;\n }\n\n this.config = { ...DEFAULT_CONFIG };\n this.styleManager.resetStyles();\n\n // Re-setup auto theme detection si está habilitado en la config por defecto\n if (this.config.autoDetectTheme) {\n this.setupAutoThemeDetection();\n }\n \n this.success('Logger configuration reset to defaults');\n }\n\n /**\n * Método de limpieza para eliminar listeners y liberar recursos.\n *\n * Vacía los transports (drain), limpia timers, suelta la lista de\n * handlers legacy, resetea el group depth y limpia el context.\n * Seguro de invocar múltiples veces.\n *\n * @example\n * // Antes de cerrar la aplicación\n * await logger.cleanup();\n *\n */\n async cleanup(): Promise<void> {\n if (this.themeChangeListener) {\n try {\n this.themeChangeListener();\n } catch {\n // Listener cleanup es best-effort\n }\n this.themeChangeListener = null;\n }\n\n // Drain del queue de transports en cleanup. Los spans aún abiertos se\n // fuerzan a cerrar (incomplete) para no perderlos en el drain.\n forceCloseOpenSpans();\n await this.transportBridge.closeTransports();\n\n // Suelta las refs de handlers para que el GC los pueda recolectar.\n this.handlers.length = 0;\n // Reset del mutable runtime state\n this.timers.clear();\n this.badgeList = [];\n this.logContext.clearContext();\n this.groupDepth = 0;\n }\n\n\n // ===== SIMPLIFIED API =====\n\n /**\n * Aplica un preset inteligente - funciona perfectamente sin configuración\n * \n * @param {string} name - Nombre del preset a aplicar\n * \n * @example\n * // Presets disponibles\n * logger.preset('default'); // Limpio y adaptativo\n * logger.preset('cyberpunk'); // Colores neón, efectos brillantes\n * logger.preset('glassmorphism'); // Efectos de blur modernos\n * logger.preset('minimal'); // Minimalista y elegante\n * logger.preset('debug'); // Modo desarrollo detallado\n * logger.preset('production'); // Enfocado en producción\n * \n */\n preset(name: string): void {\n if (!hasPreset(name)) {\n this.error(`Unknown preset: ${name}. Available presets:`, getAvailablePresets());\n return;\n }\n\n const presetConfig = getSmartPreset(name);\n if (presetConfig) {\n // Aplica la configuración del smart preset\n this.displaySettings.showTimestamp = presetConfig.timestamp?.show ?? true;\n this.displaySettings.showLocation = presetConfig.location?.show ?? true;\n\n // Guarda la config del preset para que la use createStyledOutput\n this._activePreset = presetConfig;\n this._activePresetName = name;\n\n // Solo muestra el mensaje de success en navegador para evitar verbose terminal logs\n if (getEnvironment() === 'browser') {\n this.success(`Applied preset: ${name}`);\n }\n }\n }\n\n /**\n * Lista todos los presets disponibles\n * \n * @returns {string[]} Array con nombres de presets disponibles\n * \n * @example\n * const disponibles = logger.presets();\n * console.log(disponibles); // ['default', 'cyberpunk', 'glassmorphism', ...]\n * \n */\n presets(): string[] {\n return getAvailablePresets();\n }\n\n // ===== TOGGLE METHODS =====\n\n /**\n * Oculta el timestamp en los logs\n * \n * @example\n * logger.hideTimestamp();\n * logger.info('Sin marca de tiempo'); // Sin timestamp visible\n * \n */\n hideTimestamp(): this {\n this.displaySettings.showTimestamp = false;\n return this;\n }\n\n /**\n * Muestra el timestamp en los logs\n * \n * @example\n * logger.showTimestamp();\n * logger.info('Con marca de tiempo'); // [2024-01-15 10:30:45] Con marca de tiempo\n * \n */\n showTimestamp(): this {\n this.displaySettings.showTimestamp = true;\n return this;\n }\n\n /**\n * Oculta la información de ubicación (archivo:línea) en los logs\n * \n * @example\n * logger.hideLocation();\n * logger.debug('Sin ubicación'); // Sin mostrar archivo:línea\n * \n */\n hideLocation(): this {\n this.displaySettings.showLocation = false;\n return this;\n }\n\n /**\n * Muestra la información de ubicación (archivo:línea) en los logs\n * \n * @example\n * logger.showLocation();\n * logger.debug('Con ubicación'); // app.js:42 Con ubicación\n * \n */\n showLocation(): this {\n this.displaySettings.showLocation = true;\n return this;\n }\n\n /**\n * Oculta los badges en los logs\n * \n * @example\n * logger.hideBadges();\n * const api = logger.api('REST');\n * api.info('Sin badges'); // Sin mostrar [API] [REST]\n * \n */\n hideBadges(): this {\n this.displaySettings.showBadges = false;\n return this;\n }\n\n /**\n * Muestra los badges en los logs\n *\n * @example\n * logger.showBadges();\n * const api = logger.api('GraphQL');\n * api.info('Con badges'); // [API] [GraphQL] Con badges\n *\n */\n showBadges(): this {\n this.displaySettings.showBadges = true;\n return this;\n }\n\n /**\n * Establece múltiples badges para los logs\n *\n * @param {string[]} badges - Array de badges a mostrar\n * @returns {this} Logger instance para encadenamiento\n *\n * @example\n * logger.badges(['v3', 'stable']).info('Release publicado');\n * logger.badges(['API', 'v2']).warn('Endpoint deprecado');\n *\n */\n badges(badges: string[]): this {\n this.badgeList = [...badges];\n return this;\n }\n\n /**\n * Añade un badge individual a la lista\n *\n * @param {string} badge - Badge a añadir\n * @returns {this} Logger instance para encadenamiento\n *\n * @example\n * logger.badge('DEBUG').badge('AUTH').info('Token validado');\n *\n */\n badge(badge: string): this {\n if (!this.badgeList.includes(badge)) {\n this.badgeList.push(badge);\n }\n return this;\n }\n\n /**\n * Limpia todos los badges activos\n *\n * @returns {this} Logger instance para encadenamiento\n *\n * @example\n * logger.clearBadges().info('Sin badges');\n *\n */\n clearBadges(): this {\n this.badgeList = [];\n return this;\n }\n\n // ===== SCOPED LOGGERS =====\n\n /**\n * Crea un logger scoped para un componente o módulo del dominio.\n *\n * El `ComponentLogger` resultante prepends un badge `[name]` a cada\n * mensaje y comparte configuración, transports y hooks con el logger\n * padre. Útil para trazar el origen de los logs en apps con muchos\n * módulos (Auth, DB, Cache, ...).\n *\n * @param {string} name - Nombre del componente que aparecerá como badge\n * @returns {ComponentLogger} Logger scoped para el componente\n *\n * @example\n * const auth = logger.component('Auth');\n * auth.info('Validando token'); // [Auth] Validando token\n * auth.success('Token válido');\n *\n * @see {@link api} para loggers de endpoints REST/GraphQL\n * @see {@link scope} para un scope genérico sin badge de componente\n */\n component(name: string): ComponentLogger {\n return new ComponentLogger(this, name);\n }\n\n /**\n * Crea un logger scoped para un endpoint o surface de API.\n *\n * Como `component()` pero con styling orientado a APIs (badge `[API]`\n * por defecto más el nombre del sub-scope). Útil para distinguir\n * tráfico REST vs GraphQL vs WebSocket en los logs.\n *\n * @param {string} name - Nombre de la API o surface (p.ej. `'REST'`, `'GraphQL'`)\n * @returns {APILogger} Logger scoped para la API\n *\n * @example\n * const rest = logger.api('REST');\n * rest.info('GET /users/42'); // [API] [REST] GET /users/42\n *\n * @see {@link component} para loggers de componentes de dominio\n */\n api(name: string): APILogger {\n return new APILogger(this, name);\n }\n\n /**\n * Crea un logger scoped genérico con un prefijo.\n *\n * Variante minimal de `component()` / `api()`: solo aplica un prefijo\n * de scope sin badges ni styling especial. Útil para sub-módulos que\n * no encajan en las categorías de `component`/`api`.\n *\n * @param {string} name - Texto del prefijo de scope\n * @returns {ScopedLogger} Logger con el scope aplicado\n *\n * @example\n * const db = logger.scope('db');\n * db.info('Pool conectado'); // [db] Pool conectado\n *\n * @see {@link component} y {@link api} para variantes con badges\n */\n scope(name: string): ScopedLogger {\n return new ScopedLogger(this, name);\n }\n\n // ===== SIMPLE CUSTOMIZATION =====\n\n /**\n * Personalización simple con configuración mínima\n * \n * @param {Object} overrides - Opciones de personalización\n * @param {Object} overrides.message - Configuración del mensaje\n * @param {Object} overrides.timestamp - Configuración del timestamp\n * @param {Object} overrides.location - Configuración de ubicación\n * @param {Object} overrides.level - Configuración del nivel\n * @param {Object} overrides.prefix - Configuración del prefijo\n * @param {string} overrides.spacing - Espaciado: 'compact' | 'normal' | 'spacious'\n * \n * @example\n * logger.customize({\n * message: { color: '#00ff00', size: '16px' },\n * timestamp: { show: false },\n * spacing: 'compact'\n * });\n * \n */\n customize(overrides: {\n message?: { color?: string; font?: string; size?: string };\n timestamp?: { show?: boolean; color?: string };\n location?: { show?: boolean; color?: string };\n level?: { uppercase?: boolean; style?: string };\n prefix?: { show?: boolean; style?: string };\n spacing?: 'compact' | 'normal' | 'spacious';\n }): void {\n // Aplica los overrides simples\n if (overrides.timestamp?.show !== undefined) {\n this.displaySettings.showTimestamp = overrides.timestamp.show;\n }\n if (overrides.location?.show !== undefined) {\n this.displaySettings.showLocation = overrides.location.show;\n }\n if (overrides.prefix?.show !== undefined) {\n // Se manejará al integrar con el preset system\n }\n\n // Guarda la customization para que la use createStyledOutput\n this._customization = overrides;\n this.success('Customization applied');\n }\n\n // ===== HANDLER MANAGEMENT =====\n\n /**\n * Añade un handler personalizado para extender funcionalidad\n * \n * @param {ILogHandler} handler - Handler que implementa ILogHandler\n *\n * @example\n * // Handler personalizado para enviar logs a servidor\n * logger.addHandler({\n * handle(level, message, args, metadata) {\n * fetch('/logs', { method: 'POST', body: JSON.stringify({ level, message }) });\n * }\n * });\n *\n * @example\n * // Para escribir a archivo, usa `addTransport` con un `FileTransport`\n * logger.addTransport({ target: new FileTransport({ destination: 'app.log' }) });\n *\n */\n addHandler(handler: ILogHandler): void {\n this.handlers.push(handler);\n }\n\n /**\n * Obtiene todos los handlers registrados\n * \n * @returns {ILogHandler[]} Array de handlers activos\n */\n getHandlers(): ILogHandler[] {\n return [...this.handlers];\n }\n\n // ===== SERIALIZERS =====\n\n /**\n * Añade un serializador personalizado para un tipo específico\n *\n * @param type - Constructor del tipo a serializar\n * @param serializer - Función de serialización\n * @param priority - Prioridad (mayor = primero)\n *\n * @example\n * logger.addSerializer(Error, (err) => ({\n * name: err.name,\n * message: err.message,\n * stack: err.stack?.split('\\n').slice(0, 5)\n * }));\n *\n */\n addSerializer<T>(\n type: new (...args: unknown[]) => T,\n serializer: SerializerFn<T>,\n priority?: number\n ): void {\n this.serializerBridge.addSerializer(type, serializer, priority);\n }\n\n /**\n * Elimina un serializador registrado\n *\n * @param type - Constructor del tipo a remover\n * @returns true si se eliminó\n *\n */\n removeSerializer<T>(type: new (...args: unknown[]) => T): boolean {\n return this.serializerBridge.removeSerializer(type);\n }\n\n /**\n * Obtiene el registry de serializadores\n *\n * @returns SerializerRegistry\n */\n getSerializerRegistry(): SerializerRegistry {\n return this.serializerBridge.getSerializerRegistry();\n }\n\n // ===== HOOKS & MIDDLEWARE =====\n\n /**\n * Registra un hook para un evento\n *\n * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'\n * @param callback - Función a ejecutar\n * @param priority - Prioridad (mayor = primero)\n * @returns Función para desregistrar\n *\n * @example\n * const unsubscribe = logger.on('beforeLog', (entry) => {\n * entry.correlationId = getCorrelationId();\n * return entry;\n * });\n *\n */\n on(event: HookEvent, callback: HookCallback, priority?: number): () => void {\n return this.hookBridge.on(event, callback, priority);\n }\n\n /**\n * Registra un hook que se ejecuta solo una vez\n *\n * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'\n * @param callback - Función a ejecutar\n * @param priority - Prioridad (mayor = primero)\n * @returns Función para desregistrar\n *\n */\n once(event: HookEvent, callback: HookCallback, priority?: number): () => void {\n return this.hookBridge.once(event, callback, priority);\n }\n\n /**\n * Elimina un hook registrado\n *\n * @param event - Evento del hook\n * @param callback - Callback a remover\n * @returns true si se eliminó\n *\n */\n off(event: HookEvent, callback: HookCallback): boolean {\n return this.hookBridge.off(event, callback);\n }\n\n /**\n * Añade un middleware al pipeline\n *\n * @param middleware - Función middleware\n * @param priority - Prioridad (mayor = primero)\n * @returns Función para desregistrar\n *\n * @example\n * logger.use((entry, next) => {\n * entry.requestId = asyncLocalStorage.getStore()?.requestId;\n * next();\n * });\n *\n */\n use(middleware: MiddlewareFn, priority?: number): () => void {\n return this.hookBridge.use(middleware, priority);\n }\n\n /**\n * Obtiene el HookManager\n *\n * @returns HookManager\n */\n getHookManager(): HookManager {\n return this.hookBridge.getHookManager();\n }\n\n // ===== TRANSPORTS =====\n\n /**\n * Añade un transport para envío de logs\n *\n * @param target - Configuración del transport\n * @returns ID único del transport\n *\n * @example\n * // File transport\n * logger.addTransport({\n * target: 'file',\n * options: { destination: '/var/log/app.log' }\n * });\n *\n * @example\n * // HTTP transport con batching\n * logger.addTransport({\n * target: 'http',\n * options: {\n * url: 'https://logs.example.com',\n * batchSize: 100,\n * flushInterval: 5000\n * },\n * level: 'warn'\n * });\n *\n */\n addTransport(target: TransportTarget): string {\n return this.transportBridge.addTransport(target);\n }\n\n /**\n * Elimina un transport\n *\n * @param id - ID del transport a remover\n * @returns true si se eliminó\n *\n */\n removeTransport(id: string): boolean {\n return this.transportBridge.removeTransport(id);\n }\n\n /**\n * Fuerza el flush de todos los transports. Antes de flushear, cierra los\n * spans aún abiertos (`incomplete: true`) y los encola para export — un\n * span abierto nunca se tira en un flush.\n *\n * @returns Promise que resuelve cuando todos los buffers están vaciados\n *\n */\n async flushTransports(): Promise<void> {\n forceCloseOpenSpans();\n await this.transportBridge.flushTransports();\n }\n\n /**\n * Cierra todos los transports. Como en {@link flushTransports}, primero\n * fuerza el cierre de los spans abiertos para que viajen en el flush\n * final del close.\n *\n * @returns Promise que resuelve cuando todos están cerrados\n *\n */\n async closeTransports(): Promise<void> {\n forceCloseOpenSpans();\n await this.transportBridge.closeTransports();\n }\n\n /**\n * Obtiene el TransportManager\n *\n * @returns TransportManager o undefined si no hay transports\n */\n getTransportManager(): TransportManager | undefined {\n return this.transportBridge.getTransportManager();\n }\n\n // ===== CORE LOGGING METHODS =====\n\n /**\n * Verifica si un nivel de log debe mostrarse según la verbosidad actual.\n * @private\n * @param {LogLevel} level - Nivel de log a verificar\n * @returns {boolean} True si debe mostrarse, false si no\n */\n private shouldLog(level: LogLevel): boolean {\n if (this.config.verbosity === 'silent') return false;\n return LOG_LEVELS[level] >= LOG_LEVELS[this.config.verbosity as LogLevel];\n }\n\n /**\n * Tag pendiente de inyectar en el siguiente `TransportRecord` emitido\n * por `log()`. Lo fijan `success()` y `logWithBindingsAndTag()` antes\n * de delegar; `log()` lo consume y lo resetea a `undefined`.\n *\n * @internal\n */\n protected _dispatchTag: string | undefined;\n\n /**\n * Computa el contexto completamente mergueado para este logger.\n *\n * La cadena de contexto se construye en el momento de crear el child:\n * cada child almacena el contexto fully-merged de su parent (en ese\n * instante) como `_parentContextRecord`. Esto implica que\n * `_parentContextRecord` ya contiene los bindings de todos los ancestros\n * en el orden de precedencia correcto (root primero, child más cercano al final).\n *\n * Orden de merge (gana el último):\n * 1. _parentContextRecord — snapshot del contexto mergueado del parent en la creación\n * 2. _bindings — bindings propios de este logger (llamadas a `child()`)\n * 3. ALS store — scope de `withContext`/`withContextAsync` (prioridad máxima)\n *\n * @internal\n * @returns El record de contexto mergueado\n */\n private _getMergedContext(): Record<string, unknown> {\n // Empieza con el snapshot del parent (ya contiene todos los ancestros)\n let merged: Record<string, unknown> = this._parentContextRecord ?? {};\n\n // Layer de los bindings propios de este logger (gana el más cercano)\n if (this._bindings && Object.keys(this._bindings).length > 0) {\n merged = { ...merged, ...this._bindings };\n }\n\n // Layer del scope ALS (prioridad máxima)\n const alsContext = this.logContext._getAlsStore?.() ?? {};\n if (alsContext && Object.keys(alsContext).length > 0) {\n merged = { ...merged, ...alsContext };\n }\n\n return merged;\n }\n\n /** @internal Expone el contexto base mergueado (sin ALS) a la closure de la child factory de LogContext. */\n _captureMergedContext(): Record<string, unknown> {\n // Devuelve el contexto base sin ALS — ALS es transitorio y no debe\n // quedar baked en _parentContextRecord en el momento de crear el child.\n let merged: Record<string, unknown> = this._parentContextRecord ?? {};\n if (this._bindings && Object.keys(this._bindings).length > 0) {\n merged = { ...merged, ...this._bindings };\n }\n return merged;\n }\n\n /**\n * Construye y despacha un `TransportRecord` al {@link TransportManager}\n * (no-op si no hay transports registrados). Lo comparten todos los\n * caminos de log — `log()`, `success()` y los métodos visuales como\n * `table()` / `group()` / `time()` — para que toda emisión atraviese\n * el mismo pipeline de transports.\n *\n * @protected\n * @param {LogLevel} level - Nivel canónico (trace/debug/info/warn/error/critical)\n * @param {string} message - Mensaje final, post-hook\n * @param {string | undefined} prefix - Prefijo efectivo (global + scope)\n * @param {StackInfo | null} stackInfo - Ubicación del caller, opcional\n * @param {Partial<TransportRecord>} [extra] - Campos extra a mergear en el record\n * (p.ej. `{ tag: 'success' }` o `attributes` adicionales)\n */\n protected dispatchToTransports(\n level: LogLevel,\n message: string,\n prefix: string | undefined,\n stackInfo: StackInfo | null,\n extra?: Partial<TransportRecord>\n ): void {\n const record: TransportRecord = {\n level,\n levelValue: LOG_LEVELS[level],\n severityNumber: LOG_LEVEL_TO_SEVERITY_NUMBER[level],\n severityText: LOG_LEVEL_TO_SEVERITY_TEXT[level],\n time: Date.now(),\n msg: message,\n prefix,\n location: stackInfo\n ? {\n file: stackInfo.file,\n line: stackInfo.line,\n column: stackInfo.column,\n function: stackInfo.function\n }\n : undefined,\n attributes: Object.keys(this.logContext._getContextRecord()).length > 0\n ? toLogAttributes(this.logContext._getContextRecord())\n : undefined,\n resource: this.logContext._getResource()\n ? { ...this.logContext._getResource() } as Partial<ITransportLogResource>\n : undefined,\n ...extra\n };\n\n // Correlación log→span: si hay un span activo en el ALS del módulo,\n // el record hereda su traceId/spanId (los campos ya existían en\n // TransportRecord; ahora se pueblan → correlación gratis en backends).\n const activeSpan = getActiveSpan();\n if (activeSpan && !record.traceId) {\n record.traceId = activeSpan.traceId;\n record.spanId = activeSpan.spanId;\n }\n\n // Fire-and-forget vía bridge — nunca rompe el path de log sincrónico.\n this.transportBridge.writeRecord(record);\n }\n\n /**\n * Obtiene el prefijo efectivo (global + scope)\n * @private\n * @returns {string | undefined} Prefijo combinado o undefined\n */\n private getEffectivePrefix(): string | undefined {\n const parts = [this.config.globalPrefix, this.scopedPrefix].filter(Boolean);\n return parts.length > 0 ? parts.join(':') : undefined;\n }\n\n /**\n * Método central de logging. Espera el hook pipeline `beforeLog`\n * antes de despachar a consola y transports, para que redacciones\n * o enriquecimientos (PII, correlation IDs) se reflejen en el\n * mensaje emitido.\n *\n * Los callers fire-and-forget (p.ej. `logger.info(...)` sin `await`)\n * siguen funcionando: el `Promise<void>` resultante se descarta.\n * Se recomienda `await` cuando los hooks `beforeLog` mutan `message`.\n *\n * El tag opcional (`TransportRecord.tag`) NO se pasa como argumento:\n * se establece vía `_dispatchTag` (ver `success()` y\n * {@link logWithBindingsAndTag}) antes de invocar este método.\n *\n * @protected\n * @param {LogLevel} level - Nivel del log\n * @param {unknown[]} args - Argumentos a loggear (mensaje + datos)\n * @returns {Promise<void>} Promesa que resuelve al completar el dispatch\n *\n */\n protected async log(level: LogLevel, ...args: unknown[]): Promise<void> {\n if (!this.shouldLog(level)) return;\n\n // Comprueba _dispatchTag ANTES de procesar los args para que el tag\n // NO termine en additionalArgs. success() lo fija en vez de pasar\n // 'success' como arg.\n const dispatchTag = this._dispatchTag;\n this._dispatchTag = undefined;\n\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n const prefix = this.getEffectivePrefix();\n const timestamp = formatTimestamp();\n\n const serializedArgs = args.map(arg => this.serializerBridge.getSerializerRegistry().serialize(arg));\n\n let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : '';\n if (this.badgeList.length > 0 && this.displaySettings.showBadges) {\n const badgePrefix = this.badgeList.map(b => `[${b}]`).join('');\n message = badgePrefix + ' ' + message;\n }\n const additionalArgs = serializedArgs.slice(1);\n\n const hookEntry = {\n level,\n message,\n args: serializedArgs,\n timestamp,\n prefix,\n stackInfo: stackInfo ?? undefined\n };\n\n // Await de los hooks beforeLog para que las redacciones / enriquecimientos\n // se reflejen en el mensaje emitido.\n let processed;\n try {\n processed = await this.hookBridge.getHookManager().emit('beforeLog', hookEntry);\n } catch (error) {\n // El Hook manager ya dispara onError por su cuenta; cae a los\n // valores pre-hook para que la llamada de log no se rompa.\n // eslint-disable-next-line no-console\n console.error('HookManager beforeLog failed:', error);\n processed = hookEntry;\n }\n message = processed.message;\n\n const [format, ...styles] = createStyledOutput(\n level,\n this.styleManager.getStyles(),\n prefix,\n message,\n this.displaySettings.showLocation ? stackInfo : null,\n this.config.autoDetectTheme,\n this._activePreset as LogStyles | undefined,\n this._activePresetName\n );\n\n const groupIndent = ' '.repeat(this.groupDepth);\n const finalFormat = groupIndent + format;\n\n this.writeOutput(finalFormat, level, styles, additionalArgs);\n\n const metadata: LogMetadata = {\n timestamp,\n level,\n prefix,\n stackInfo: stackInfo ?? undefined\n };\n\n this.handlers.forEach(handler => {\n try {\n handler.handle(level, message, serializedArgs, metadata);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Log handler failed:', error);\n }\n });\n\n // Si se fijó dispatchTag (por success()), despacha con él.\n if (dispatchTag !== undefined) {\n this.dispatchToTransports(level, message, prefix, stackInfo, { tag: dispatchTag as LogTag });\n } else {\n this.dispatchToTransports(level, message, prefix, stackInfo);\n }\n\n // Fire-and-forget de afterLog — las mutaciones after-side no cambian\n // el mensaje que ya está en pantalla, así que no bloqueamos con él.\n this.hookBridge.getHookManager().emit('afterLog', processed).catch(() => {});\n }\n\n /**\n * Emite un log aplicando bindings (badges, scope) al prefijo del\n * mensaje antes de delegar en {@link Logger.log}.\n *\n * No es API pública de consumo: existe para que `ScopedLogger`\n * (`component()` / `api()` / `scope()`) pueda reutilizar el pipeline\n * central de `log()` sin duplicar la lógica de styling/badges.\n *\n * @internal\n * @param {Bindings} bindings - Bindings de scope (badges, scope name, ...)\n * @param {LogLevel} level - Nivel de log\n * @param {unknown[]} args - Argumentos a loggear\n * @returns {Promise<void>} Promesa del dispatch\n *\n * @see {@link logWithBindingsAndTag} para la variante con `tag`\n */\n logWithBindings(bindings: Bindings, level: LogLevel, ...args: unknown[]): Promise<void> {\n if (!this.shouldLog(level)) return Promise.resolve();\n\n let prefix = '';\n const colorCapability = getColorCapability();\n\n if (bindings.badges?.length) {\n prefix += bindings.badges.map(b => formatBadge(b, 'pill', colorCapability, '#00ff88')).join(' ') + ' ';\n }\n if (bindings.scope) {\n prefix += formatBadge(bindings.scope, 'pill', colorCapability, '#00ffff') + ' ';\n }\n\n if (prefix && args.length > 0) {\n args[0] = prefix + String(args[0]);\n }\n\n return this.log(level, ...args);\n }\n\n /**\n * Como {@link logWithBindings} pero fija `_dispatchTag` antes de\n * delegar, para que `log()` despache el `TransportRecord` con el\n * tag indicado. Lo usa `ScopedLogger.success()` para propagar\n * `tag: 'success'` a través del pipeline normal de `log()`.\n *\n * @internal\n * @param {Bindings} bindings - Bindings de scope (badges, scope name, ...)\n * @param {LogLevel} level - Nivel de log\n * @param {LogTag} tag - Tag a inyectar en el `TransportRecord`\n * @param {unknown[]} args - Argumentos a loggear\n * @returns {Promise<void>} Promesa del dispatch\n */\n logWithBindingsAndTag(bindings: Bindings, level: LogLevel, tag: LogTag, ...args: unknown[]): Promise<void> {\n this._dispatchTag = tag;\n return this.logWithBindings(bindings, level, ...args);\n }\n\n /**\n * Registra mensajes de debug (nivel más verboso junto a `trace`).\n * Pensado para diagnóstico de desarrollo: valores intermedios, flags\n * de control flow, estado interno. Devuelve `Promise<void>`.\n *\n * Filtrado por defecto cuando `verbosity > 'debug'` (ver `setVerbosity`).\n *\n * @param {unknown[]} args - Mensaje + datos a inspeccionar\n * @returns {Promise<void>} Promesa del dispatch\n *\n * @example\n * logger.debug('Estado interno:', { conn, queueSize });\n * logger.debug('Entrando en branch X');\n *\n * @see {@link trace} para diagnósticos aún más granulares\n * @see {@link setVerbosity} para controlar el nivel mínimo visible\n */\n debug(...args: unknown[]): Promise<void> {\n return this.log('debug', ...args);\n }\n\n /**\n * Registra mensajes informativos. El `await` retorna cuando el hook\n * `beforeLog` y el dispatch a transports han terminado.\n *\n * @param args - Mensajes y datos informativos\n *\n * @example\n * logger.info('Servidor iniciado en puerto 3000');\n * await logger.info('Procesando', totalItems, 'elementos'); // espera hooks\n *\n */\n info(...args: unknown[]): Promise<void> {\n return this.log('info', ...args);\n }\n\n /**\n * Registra mensajes de advertencia.\n *\n * @param args - Mensajes de advertencia\n *\n */\n warn(...args: unknown[]): Promise<void> {\n return this.log('warn', ...args);\n }\n\n /**\n * Registra mensajes de error.\n *\n * @param args - Mensaje de error y stack traces\n *\n */\n error(...args: unknown[]): Promise<void> {\n return this.log('error', ...args);\n }\n\n /**\n * Registra mensajes de éxito. Mapeado internamente a nivel `info` con\n * styling de success y `record.tag = 'success'` para que los transports\n * puedan distinguirlo (sin perder info semantics para filtering).\n *\n * @param args - Mensaje + datos adicionales\n *\n * @example\n * logger.success('Base de datos conectada');\n * logger.success('Usuario creado con ID:', userId);\n * logger.success('✓ Tests pasados: 42/42');\n *\n */\n async success(...args: unknown[]): Promise<void> {\n if (!this.shouldLog('info')) return;\n\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n const prefix = this.getEffectivePrefix();\n const timestamp = formatTimestamp();\n const serializedArgs = args.map(arg => this.serializerBridge.getSerializerRegistry().serialize(arg));\n let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : '';\n if (this.badgeList.length > 0 && this.displaySettings.showBadges) {\n const badgePrefix = this.badgeList.map(b => `[${b}]`).join('');\n message = badgePrefix + ' ' + message;\n }\n const additionalArgs = serializedArgs.slice(1);\n\n const hookEntry = {\n level: 'info' as LogLevel,\n message,\n args: serializedArgs,\n timestamp,\n prefix,\n stackInfo: stackInfo ?? undefined\n };\n\n // Await de beforeLog para que las redacciones se propaguen (match con log())\n try {\n const processed = await this.hookBridge.getHookManager().emit('beforeLog', hookEntry);\n message = processed.message;\n } catch {\n // El Hook manager ya disparó onError\n }\n\n const [format, ...styles] = createStyledOutput(\n 'info',\n this.styleManager.getStyles(),\n prefix,\n message,\n this.displaySettings.showLocation ? stackInfo : null,\n this.config.autoDetectTheme,\n this._activePreset as LogStyles | undefined,\n this._activePresetName\n );\n\n const successStyle = this.styleManager.getStyles().success;\n const emoji = successStyle?.emoji ?? '✅';\n const label = successStyle?.label ?? 'SUCCESS';\n const successFormat = format.replace(/ℹ️ INFO/, `${emoji} ${label}`);\n\n const groupIndent = ' '.repeat(this.groupDepth);\n const finalFormat = groupIndent + successFormat;\n\n this.writeOutput(finalFormat, 'info', styles, additionalArgs);\n\n const metadata: LogMetadata = {\n timestamp,\n level: 'info',\n prefix,\n stackInfo: stackInfo ?? undefined\n };\n this.handlers.forEach(handler => {\n try {\n handler.handle('info', message, args, metadata);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Log handler failed:', error);\n }\n });\n\n // Fija _dispatchTag para que log() despache con el tag.\n // 'success' NO se pasa como arg (evita que aparezca en additionalArgs).\n this._dispatchTag = 'success';\n await this.log('info', ...args);\n\n this.hookBridge.getHookManager().emit('afterLog', hookEntry).catch(() => {});\n }\n\n /**\n * Registra información de trace (nivel más bajo, debajo de debug).\n * Alineado con OpenTelemetry `TRACE` severity (1-4).\n *\n * @param args - Datos muy verbosos (entrada/salida de funciones, valores intermedios)\n *\n * @example\n * logger.trace('Entrando en función processData');\n * logger.trace('Variables intermedias:', { a, b, c });\n *\n */\n trace(...args: unknown[]): void {\n this.log('trace', ...args);\n }\n\n /**\n * Registra errores críticos (prioridad más alta).\n *\n * @param args - Errores críticos del sistema\n *\n * @example\n * await logger.critical('Sistema caído - reinicio inmediato requerido');\n *\n */\n critical(...args: unknown[]): Promise<void> {\n return this.log('critical', ...args);\n }\n\n // ===== SPANS / TRACES (trio API) =====\n\n /**\n * Emite un **point-span**: un span con `start = end` para completion\n * signals y eventos puntuales (una operación instantánea, un hito).\n * No registra contexto activo ni puede leakear — se exporta de inmediato.\n *\n * El nombre `event` (y no `trace`) es deliberado: `trace` es un log level\n * (el -1) y está reservado.\n *\n * @param {string} name - Nombre del evento (`job.completed`, `cache.flushed`, ...).\n * @param {SpanAttributes} [attributes] - Attributes del span.\n *\n * @example\n * logger.event('build.finished', { status: 'ok', durationMs: 4200 });\n *\n * @see {@link span} para intervalos con work-block\n * @see {@link startSpan} para intervalos externally-ended\n */\n event(name: string, attributes?: SpanAttributes): void {\n emitEventSpan(name, attributes, this._spanScopeName(), record => {\n this.transportBridge.writeRecord(record);\n });\n }\n\n /**\n * Ejecuta `fn` dentro de un span de intervalo. El span queda **activo en\n * el AsyncLocalStorage del módulo** mientras `fn` corre: los logs emitidos\n * dentro heredan su `traceId`/`spanId`, y los spans hijos lo toman como\n * `parentSpanId`.\n *\n * Al retornar `fn` el span se cierra automáticamente; si `fn` lanza, se\n * marca `status {code: 2}` con el mensaje del error (`fail`) y la\n * excepción se relanza intacta.\n *\n * @typeParam T - Tipo resuelto por `fn`.\n * @param {string} name - Nombre de la operación.\n * @param {(s: Span) => T | Promise<T>} fn - Work-block a medir.\n * @returns {Promise<T>} Lo que resuelve `fn`.\n * @throws {unknown} Relanza cualquier error de `fn` tras marcar el span fallido.\n *\n * @example\n * await logger.span('db.migrate', { target: 'v2' }, async (s) => {\n * await runMigrations();\n * s.set('tables', 14);\n * });\n *\n * @see {@link event} para point-spans\n * @see {@link startSpan} para spans externally-ended (poll/callback)\n */\n span<T>(name: string, fn: (s: Span) => T | Promise<T>): Promise<T>;\n span<T>(name: string, attributes: SpanAttributes, fn: (s: Span) => T | Promise<T>): Promise<T>;\n span<T>(\n name: string,\n fnOrAttributes: ((s: Span) => T | Promise<T>) | SpanAttributes,\n maybeFn?: (s: Span) => T | Promise<T>\n ): Promise<T> {\n const { attributes, fn } = resolveSpanArgs(fnOrAttributes, maybeFn);\n return this._runSpan(name, attributes, this._spanScopeName(), fn);\n }\n\n /**\n * Inicia un span de intervalo **externally-ended**: devuelve el handle y\n * NO fija contexto ALS (el cierre ocurre fuera del bloque léxico — p.ej.\n * un `cli.spawn` que se cierra desde un poll o callback externo).\n *\n * Si el span no se cierra antes de `flushTransports()` / shutdown, el\n * flush lo fuerza a cerrar con `incomplete: true` y lo exporta — nunca\n * se tira.\n *\n * @param {string} name - Nombre de la operación.\n * @param {SpanAttributes} [attributes] - Attributes iniciales.\n * @returns {Span} Handle con `set`/`end`/`fail` y los ids del span.\n *\n * @example\n * const s = logger.startSpan('spawn.build', { cmd: 'make' });\n * proc.on('exit', code => {\n * if (code === 0) s.end({ exitCode: code });\n * else s.fail(new Error(`exit ${code}`));\n * });\n *\n * @see {@link span} para el caso con work-block\n */\n startSpan(name: string, attributes?: SpanAttributes): Span {\n return this._startSpan(name, attributes, this._spanScopeName());\n }\n\n /**\n * Scope por defecto de los spans emitidos por este logger (el\n * `globalPrefix`, o `'root'`).\n * @internal\n */\n _spanScopeName(): string {\n return this.config.globalPrefix || 'root';\n }\n\n /**\n * Emite un point-span con scope explícito. Lo consume\n * {@link ScopedLogger.event}, que pasa su scope compuesto.\n * @internal\n */\n _emitSpanEvent(name: string, attributes: SpanAttributes | undefined, scope: string): void {\n emitEventSpan(name, attributes, scope, record => {\n this.transportBridge.writeRecord(record);\n });\n }\n\n /**\n * Crea un span externally-ended con scope explícito. Lo consume\n * {@link ScopedLogger.startSpan}.\n * @internal\n */\n _startSpan(name: string, attributes: SpanAttributes | undefined, scope: string): Span {\n const { span } = createSpan(name, attributes, scope, record => {\n this.transportBridge.writeRecord(record);\n });\n return span;\n }\n\n /**\n * Corre `fn` dentro de un span activo en el ALS con scope explícito.\n * Lo consume {@link ScopedLogger.span}.\n * @internal\n */\n async _runSpan<T>(\n name: string,\n attributes: SpanAttributes | undefined,\n scope: string,\n fn: (s: Span) => T | Promise<T>\n ): Promise<T> {\n const { record, span } = createSpan(name, attributes, scope, r => {\n this.transportBridge.writeRecord(r);\n });\n try {\n const result = await runWithActiveSpan(record, () => fn(span));\n span.end();\n return result;\n } catch (error) {\n span.fail(error);\n throw error;\n }\n }\n\n // ===== ADVANCED LOGGING FEATURES =====\n\n /**\n * Muestra datos en formato de tabla. Pasa por la pipeline completa\n * (outputMode-respecting writeOutput + transports + hooks).\n *\n * @param data - Array de objetos o matriz\n * @param columns - Columnas específicas a mostrar (opcional)\n *\n * @example\n * logger.table([{ id: 1, nombre: 'Juan' }, { id: 2, nombre: 'María' }]);\n *\n */\n table(data: unknown, columns?: string[]): void {\n if (!this.shouldLog('info')) return;\n const prefix = this.getEffectivePrefix();\n const tableStyle = StylePresets.accent().build();\n\n const headerLabel = `📊 TABLE${prefix ? ` [${prefix}]` : ''}`;\n const format = `%c${headerLabel}`;\n const styles = [tableStyle];\n\n // Emite el header vía el writer centralizado\n this.writeOutput(format, 'info', styles, []);\n\n // console.table no respeta outputMode — pero aún así queremos que\n // los datos fluyan a los transports. Solución: serializa los datos\n // como segundo argumento para que los transports observen un payload estructurado.\n const additionalArgs = [data, ...(columns ? [columns] : [])];\n if (this.config.outputMode !== 'silent') {\n if (columns) {\n console.table(data, columns);\n } else {\n console.table(data);\n }\n }\n\n const message = `table:${Array.isArray(data) ? `${data.length} rows` : 'data'}`;\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', message, prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'table',\n 'logger.data': JSON.stringify(data).slice(0, 4096),\n ...(columns ? { 'logger.columns': columns.join(',') } : {})\n }\n });\n }\n\n /**\n * Inicia un grupo colapsable en la consola. Emite un marker a\n * transports con `attributes.logger.visual = 'groupStart'` para que\n * backends puedan reconstruir la jerarquía.\n *\n * @param label - Etiqueta del grupo\n * @param collapsed - Si el grupo inicia colapsado (default: false)\n *\n * @example\n * logger.group('Procesando usuarios');\n * logger.info('Usuario 1 procesado');\n * logger.groupEnd();\n *\n */\n group(label: string, collapsed: boolean = false): void {\n const groupStyle = new StyleBuilder()\n .bg('linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%)')\n .color('#1565c0')\n .border('1px solid #90caf9')\n .padding('4px 12px')\n .rounded('6px')\n .bold()\n .build();\n\n const format = `%c📁 ${label}`;\n\n if (this.config.outputMode !== 'silent') {\n if (collapsed) {\n console.groupCollapsed(format, groupStyle);\n } else {\n console.group(format, groupStyle);\n }\n }\n\n this.groupDepth++;\n\n // Emite un record sintético de info que marca el boundary del group\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', `group:start:${label}`, prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'groupStart',\n 'logger.group.label': label,\n 'logger.group.collapsed': collapsed,\n 'logger.group.depth': this.groupDepth\n }\n });\n }\n\n /**\n * Finaliza el grupo actual de la consola. Emite un marker a transports\n * simétrico al `group()` start, para que backends puedan cerrar la\n * jerarquía correctamente.\n *\n * @example\n * logger.group('Operaciones');\n * logger.info('Operación 1');\n * logger.groupEnd();\n *\n */\n groupEnd(): void {\n if (this.groupDepth > 0) {\n this.groupDepth--;\n if (this.config.outputMode !== 'silent') {\n console.groupEnd();\n }\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', 'group:end', prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'groupEnd',\n 'logger.group.depth': this.groupDepth\n }\n });\n }\n }\n\n // ===== PERFORMANCE TIMING =====\n\n /**\n * Inicia un temporizador con la etiqueta dada\n * \n * @param {string} label - Etiqueta identificadora del temporizador\n * \n * @example\n * logger.time('proceso-datos');\n * // ... operación costosa ...\n * logger.timeEnd('proceso-datos'); // ⏱️ Timer ended: proceso-datos - 1523.45ms\n * \n */\n time(label: string): void {\n const timer: TimerEntry = {\n label,\n startTime: (typeof performance !== 'undefined' ? performance : Date).now()\n };\n this.timers.set(label, timer);\n\n const timerStyle = StylePresets.warning().build();\n const format = `%c⏱️ Timer started: ${label}`;\n this.writeOutput(format, 'debug', [timerStyle], []);\n }\n\n /**\n * Finaliza un temporizador y muestra el tiempo transcurrido\n *\n * @param {string} label - Etiqueta del temporizador a finalizar\n * @returns {number} Milisegundos transcurridos, o `-1` si no se encuentra el timer\n *\n * @example\n * logger.time('consulta-db');\n * await consultarBaseDatos();\n * const elapsed = logger.timeEnd('consulta-db'); // ⏱️ Timer ended: consulta-db - 234.56ms\n *\n */\n timeEnd(label: string): number {\n const timer = this.timers.get(label);\n if (!timer) {\n this.warn(`Timer '${label}' does not exist`);\n return -1;\n }\n\n const now = (typeof performance !== 'undefined' ? performance : Date).now();\n const elapsed = now - timer.startTime;\n this.timers.delete(label);\n\n const timerStyle = StylePresets.success().build();\n const format = `%c⏱️ Timer ended: ${label} - ${elapsed.toFixed(2)}ms`;\n this.writeOutput(format, 'info', [timerStyle], []);\n\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', `timer:${label}`, prefix, stackInfo, {\n tag: 'success',\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'timer',\n 'logger.timer.label': label,\n 'logger.timer.elapsedMs': elapsed\n }\n });\n\n return elapsed;\n }\n\n // ===== ADVANCED VISUAL FEATURES =====\n\n /**\n * Muestra un banner con el tipo especificado o configurado\n * \n * @param {BannerType} bannerType - Tipo de banner (opcional)\n * \n * @example\n * logger.showBanner('ascii'); // Banner ASCII art\n * logger.showBanner('unicode'); // Banner con caracteres Unicode\n * logger.showBanner('svg'); // Banner con gráfico SVG\n * logger.showBanner(); // Usa el tipo configurado\n * \n */\n showBanner(bannerType?: BannerType): void {\n const effectiveBannerType = bannerType ? bannerType : this.config.bannerType;\n displayInitBanner(effectiveBannerType);\n }\n\n /**\n * Registra mensaje con imagen SVG de fondo\n * \n * @param {string} message - Mensaje a mostrar\n * @param {string} svgContent - Contenido SVG personalizado (opcional)\n * @param {StyleOptions} options - Opciones de estilo (ancho, alto, padding)\n * \n * @example\n * // SVG automático con gradiente\n * logger.logWithSVG('🎆 Bienvenido a Better Logger');\n * \n * @example\n * // SVG personalizado\n * const customSVG = '<svg>...</svg>';\n * logger.logWithSVG('Logo', customSVG, { width: 400, height: 100 });\n * \n */\n logWithSVG(message: string, svgContent?: string, options: StyleOptions = {}): void {\n if (!this.shouldLog('info')) return;\n const { width = 300, height = 60, padding = '30px 150px' } = options;\n\n let svgDataUri = '';\n if (svgContent) {\n const encodedSVG = encodeURIComponent(svgContent);\n svgDataUri = `data:image/svg+xml,${encodedSVG}`;\n } else {\n const defaultSVG = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${width} ${height}'><defs><linearGradient id='grad' x1='0%' y1='0%' x2='100%' y2='0%'><stop offset='0%' style='stop-color:%23667eea'/><stop offset='100%' style='stop-color:%23764ba2'/></linearGradient></defs><rect width='100%' height='100%' fill='url(%23grad)' rx='4'/><text x='${width/2}' y='${height/2 + 5}' text-anchor='middle' fill='white' font-family='monospace' font-size='14' font-weight='bold'>${message}</text></svg>`;\n svgDataUri = `data:image/svg+xml,${encodeURIComponent(defaultSVG)}`;\n }\n\n const svgStyle = new StyleBuilder()\n .bg(`url(\"${svgDataUri}\") no-repeat center center`)\n .padding(padding)\n .color('transparent')\n .rounded('4px')\n .build();\n\n this.writeOutput(`%c${message}`, 'info', [svgStyle], []);\n\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', `svg:${message}`, prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'svg',\n 'logger.svg.width': width,\n 'logger.svg.height': height\n }\n });\n }\n\n /**\n * Registra mensaje con gradiente animado de fondo\n * \n * @param {string} message - Mensaje a animar\n * @param {number} duration - Duración de la animación en segundos (default: 3)\n * \n * @example\n * logger.logAnimated('🌈 Animación en progreso');\n * logger.logAnimated('Cargando...', 5); // Animación de 5 segundos\n * \n */\n logAnimated(message: string, duration: number = 3): void {\n if (!this.shouldLog('info')) return;\n\n // DOM-guard: las animaciones solo tienen sentido en un entorno de navegador real.\n if (typeof document !== 'undefined') {\n if (!document.getElementById('logger-animations')) {\n const style = document.createElement('style');\n style.id = 'logger-animations';\n style.textContent = `\n @keyframes loggerGradient {\n 0% { background-position: 0% 50%; }\n 50% { background-position: 100% 50%; }\n 100% { background-position: 0% 50%; }\n }\n `;\n document.head.appendChild(style);\n }\n }\n\n const animatedStyle = new StyleBuilder()\n .bg('linear-gradient(-45deg, #667eea, #764ba2, #667eea, #764ba2)')\n .css('background-size', '400% 400%')\n .color('#ffffff')\n .padding('12px 20px')\n .rounded('8px')\n .bold()\n .font('Monaco, Consolas, monospace')\n .animation(`loggerGradient ${duration}s ease infinite`)\n .display('inline-block')\n .build();\n\n this.writeOutput(`%c${message}`, 'info', [animatedStyle], []);\n\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', `animated:${message}`, prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'animated',\n 'logger.animation.durationSec': duration\n }\n });\n }\n\n // ===== CLI PRIMITIVES (v5.0) =====\n\n /**\n * Muestra un indicador de progreso de pasos en la terminal\n *\n * @param {number} current - Número de paso actual\n * @param {number} total - Número total de pasos\n * @param {string} message - Descripción del paso\n *\n * @example\n * logger.step(1, 5, 'Analyzing repository...');\n * logger.step(2, 5, 'Generating commit message...');\n *\n */\n step(current: number, total: number, message: string): void {\n this.terminalBridge.step(current, total, message);\n }\n\n /**\n * Muestra un header con estilo y subtítulo opcional\n *\n * @param {string} title - Texto del título principal\n * @param {string} subtitle - Subtítulo opcional (se renderiza atenuado)\n *\n * @example\n * logger.header('Commit Wizard', 'v2.0.0');\n *\n */\n header(title: string, subtitle?: string): void {\n this.terminalBridge.header(title, subtitle);\n }\n\n /**\n * Muestra una línea divisoria horizontal\n *\n * @example\n * logger.divider();\n *\n */\n divider(): void {\n this.terminalBridge.divider();\n }\n\n /**\n * Emite una línea en blanco\n *\n * @example\n * logger.blank();\n *\n */\n blank(): void {\n this.terminalBridge.blank();\n }\n\n /**\n * Renderiza contenido dentro de un box con borde\n *\n * @param {string} content - String de contenido (puede contener newlines)\n * @param {IBoxOptions} options - Opciones de renderizado del box\n *\n * @example\n * logger.box('3 commits generated\\nProvider: Groq', { title: 'Done', borderColor: '#00ff00' });\n *\n */\n box(content: string, options?: IBoxOptions): void {\n this.terminalBridge.box(content, options);\n }\n\n /**\n * Renderiza un array de objetos como una tabla ASCII formateada.\n * Distinto del método `table()` existente, que usa `console.table`.\n *\n * @param {Record<string, unknown>[]} rows - Array de objetos fila\n * @param {ITableOptions} options - Opciones de renderizado de la tabla\n *\n * @example\n * logger.cliTable([\n * { provider: 'Groq', status: 'Available', model: 'llama-3.3-70b' },\n * { provider: 'Gemini', status: 'Configured', model: 'gemini-2.5-flash' },\n * ]);\n *\n */\n cliTable(rows: Record<string, unknown>[], options?: ITableOptions): void {\n this.terminalBridge.cliTable(rows, options);\n }\n\n /**\n * Crea un handle de spinner para mostrar progreso durante operaciones async.\n * Devuelve un `NoopSpinner` en entornos non-TTY.\n *\n * @param {string} message - Texto inicial del spinner\n * @returns {ISpinnerHandle} Controller del spinner\n *\n * @example\n * const s = logger.spinner('Analyzing repository...');\n * s.start();\n * await analyzeRepo();\n * s.succeed('Analysis complete (1.2s)');\n *\n */\n spinner(message: string): ISpinnerHandle {\n return this.terminalBridge.spinner(message);\n }\n\n /**\n * Fija el nivel de verbosidad del CLI, controlando a la vez la verbosidad\n * de logs y la visibilidad de las primitives\n *\n * @param {CLILogLevel} level - Nivel de log del CLI\n *\n * @example\n * logger.setCLILevel('quiet'); // Solo errors, sin CLI primitives\n * logger.setCLILevel('verbose'); // Debug logs + todas las CLI primitives\n *\n */\n setCLILevel(level: CLILogLevel): void {\n const mapping = CLI_LEVEL_MAP[level];\n this.setVerbosity(mapping.verbosity);\n this.terminalBridge.setShowPrimitives(mapping.showPrimitives);\n this.config.cliLevel = level;\n }\n\n /**\n * Devuelve el nivel de log del CLI actual\n * @returns {CLILogLevel} Nivel de log del CLI actual\n */\n get cliLevel(): CLILogLevel {\n return this.config.cliLevel ?? 'normal';\n }\n\n // ===== OUTPUT WRITER SYSTEM =====\n\n /**\n * Escribe output formateado al destino configurado.\n * Respeta la configuración `outputMode` para output a consola, silencioso o custom.\n *\n * @private\n * @param {string} message - Mensaje de log formateado\n * @param {LogLevel} level - Nivel de log\n * @param {string[]} styles - Estilos CSS para la consola del navegador\n * @param {unknown[]} additionalArgs - Argumentos adicionales a loggear\n */\n private writeOutput(\n message: string,\n level: LogLevel,\n styles: string[],\n additionalArgs: unknown[]\n ): void {\n const mode = this.config.outputMode ?? 'console';\n\n // Silent mode: sin output\n if (mode === 'silent') {\n return;\n }\n\n // Custom mode: usa el writer configurado\n if (mode === 'custom' && this.config.outputWriter) {\n const fullMessage = additionalArgs.length > 0\n ? `${message} ${additionalArgs.map(a => String(a)).join(' ')}`\n : message;\n this.config.outputWriter.write(fullMessage, level, styles);\n return;\n }\n\n // Default: output a consola\n if (additionalArgs.length > 0) {\n console.log(message, ...styles, ...additionalArgs);\n } else {\n console.log(message, ...styles);\n }\n }\n\n // ===== CLI SYSTEM =====\n\n /**\n * Procesador de comandos CLI para configuración y exportación del logger\n * \n * @param {string} command - Comando CLI a ejecutar\n * @returns {Promise<void>}\n * \n * @example\n * // Comandos disponibles\n * await logger.cli('export json'); // Exporta logs en JSON\n * await logger.cli('export csv'); // Exporta logs en CSV\n * await logger.cli('theme list'); // Lista temas disponibles\n * await logger.cli('theme set neon'); // Cambia al tema neon\n * await logger.cli('config show'); // Muestra configuración actual\n * await logger.cli('history clear'); // Limpia historial de logs\n * await logger.cli('status'); // Muestra estado del logger\n * await logger.cli('help'); // Muestra ayuda de comandos\n * \n */\n async cli(command: string): Promise<void> {\n if (!this.cliProcessor) {\n this.error('CLI processor not initialized');\n return;\n }\n\n await this.cliProcessor.processCommand(command, this);\n }\n}\n\n/**\n * Instancia singleton lazy — se inicializa en la primera llamada a\n * {@link getDefaultLogger}, no al importar el módulo.\n *\n * @private\n */\nlet _defaultLogger: Logger | null = null;\n\n/**\n * Crea el singleton del Logger por defecto de forma lazy.\n *\n * El singleton se construye solo en la primera llamada, de modo que\n * importar el módulo nunca ejecuta `new Logger(...)` ni\n * `displayInitBanner()`. Así los imports del módulo quedan side-effect free.\n *\n * @returns La instancia compartida de Logger\n */\nfunction getDefaultLogger(): Logger {\n if (!_defaultLogger) {\n _defaultLogger = new Logger({\n verbosity: 'info',\n enableColors: true,\n enableTimestamps: true,\n enableStackTrace: true,\n cliLevel: 'normal'\n });\n\n // Muestra el init banner solo en el primer uso real, no en el import.\n try {\n if (typeof window !== 'undefined' || typeof document !== 'undefined') {\n displayInitBanner();\n }\n } catch {\n // Fail silencioso si no se puede mostrar el banner (SSR, workers, etc.)\n }\n }\n return _defaultLogger;\n}\n\n/**\n * Resetea el singleton por defecto. Limpia la instancia cacheada para que la\n * próxima llamada a `getDefaultLogger()` la reconstruya desde defaults. Útil\n * para tests y escenarios de hot reload.\n *\n */\nexport function resetDefaultLogger(): void {\n if (_defaultLogger) {\n // Cleanup best-effort; el user puede tener ya una referencia y\n // querer drenar logs pendientes a propósito.\n void _defaultLogger.cleanup().catch(() => {});\n }\n _defaultLogger = null;\n}\n\n/**\n * Lazy default export — every property access defers to `getDefaultLogger()`.\n * Sin side-effects al importar el módulo (la primera llamada al singleton\n * se produce en el primer acceso a una propiedad, no en el `import`).\n *\n * @example\n * import logger from 'better-logger';\n * logger.info('hello'); // first call here triggers singleton init\n */\nconst loggerProxy: Logger = new Proxy({} as Logger, {\n get(_target, prop, receiver) {\n const instance = getDefaultLogger();\n const value = Reflect.get(instance, prop, receiver);\n return typeof value === 'function' ? value.bind(instance) : value;\n }\n});\n\nexport default loggerProxy;\n\n// ===== Internal converters =====\n\n/**\n * Estrecha un contexto free-form `Record<string, unknown>` a un bag tipado\n * `ILogAttributes`. Los shapes desconocidos caen a strings JSON-encoded,\n * lo que mantiene conforme al transport OTLP (cada valor cae en un slot tipado).\n *\n * @param input - Contexto suministrado por el usuario (típicamente `Logger.context`).\n * @returns Un nuevo bag de attributes que satisface `ILogAttributes`.\n */\nfunction toLogAttributes(input: Record<string, unknown>): ILogAttributes {\n const out: Record<string, LogAttributeValue> = {};\n for (const [key, value] of Object.entries(input)) {\n const mapped = toAttributeValue(value);\n if (mapped !== undefined) {\n out[key] = mapped;\n }\n }\n return out;\n}\n\nfunction toAttributeValue(value: unknown): LogAttributeValue | undefined {\n if (value === null || value === undefined) return undefined;\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return value;\n }\n if (Array.isArray(value)) {\n const values: LogAttributeValue[] = [];\n for (const item of value) {\n const mapped = toAttributeValue(item);\n if (mapped !== undefined) values.push(mapped);\n }\n return values;\n }\n // Plain objects → fallback a string JSON (el transport OTLP lo maneja)\n try {\n return JSON.stringify(value);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resuelve los argumentos del overload `span(name, fn?)` /\n * `span(name, attributes, fn)` a `{ attributes, fn }`.\n *\n * @internal Compartido con `ScopedLogger.span`; no es API pública.\n */\nexport function resolveSpanArgs<T>(\n fnOrAttributes: ((s: Span) => T | Promise<T>) | SpanAttributes,\n maybeFn?: (s: Span) => T | Promise<T>\n): { attributes: SpanAttributes | undefined; fn: (s: Span) => T | Promise<T> } {\n if (typeof fnOrAttributes === 'function') {\n return { attributes: undefined, fn: fnOrAttributes };\n }\n if (typeof maybeFn === 'function') {\n return { attributes: fnOrAttributes, fn: maybeFn };\n }\n throw new TypeError('span(name, …): se requiere una función fn');\n}\n\n/**\n * Métodos individuales exportados para conveniencia\n * @description Todos los métodos están correctamente enlazados al singleton lazy\n */\nexport const debug = (...args: unknown[]) => getDefaultLogger().debug(...args);\nexport const info = (...args: unknown[]) => getDefaultLogger().info(...args);\nexport const warn = (...args: unknown[]) => getDefaultLogger().warn(...args);\nexport const error = (...args: unknown[]) => getDefaultLogger().error(...args);\nexport const success = (...args: unknown[]) => getDefaultLogger().success(...args);\nexport const trace = (...args: unknown[]) => getDefaultLogger().trace(...args);\nexport const critical = (...args: unknown[]) => getDefaultLogger().critical(...args);\nexport const table = (data: unknown, columns?: string[]) => getDefaultLogger().table(data, columns);\nexport const group = (label: string, collapsed?: boolean) => getDefaultLogger().group(label, collapsed);\nexport const groupEnd = () => getDefaultLogger().groupEnd();\nexport const time = (label: string) => getDefaultLogger().time(label);\nexport const timeEnd = (label: string) => getDefaultLogger().timeEnd(label);\nexport const event = (name: string, attributes?: SpanAttributes): void =>\n getDefaultLogger().event(name, attributes);\nexport const startSpan = (name: string, attributes?: SpanAttributes): Span =>\n getDefaultLogger().startSpan(name, attributes);\nexport function span<T>(name: string, fn: (s: Span) => T | Promise<T>): Promise<T>;\nexport function span<T>(name: string, attributes: SpanAttributes, fn: (s: Span) => T | Promise<T>): Promise<T>;\nexport function span<T>(\n name: string,\n fnOrAttributes: SpanAttributes | ((s: Span) => T | Promise<T>),\n maybeFn?: (s: Span) => T | Promise<T>\n): Promise<T> {\n return getDefaultLogger().span(\n name,\n fnOrAttributes as SpanAttributes,\n maybeFn as (s: Span) => T | Promise<T>\n );\n}\nexport const setGlobalPrefix = (prefix: string) => getDefaultLogger().setGlobalPrefix(prefix);\nexport const setVerbosity = (level: Verbosity) => getDefaultLogger().setVerbosity(level);\nexport const addHandler = (handler: ILogHandler) => getDefaultLogger().addHandler(handler);\nexport const setTheme = (theme: ThemeVariant) => getDefaultLogger().setTheme(theme);\nexport const setBannerType = (bannerType: BannerType) => getDefaultLogger().setBannerType(bannerType);\nexport const showBanner = (bannerType?: BannerType) => getDefaultLogger().showBanner(bannerType);\nexport const logWithSVG = (message: string, svgContent?: string, options?: StyleOptions) =>\n getDefaultLogger().logWithSVG(message, svgContent, options);\nexport const logAnimated = (message: string, duration?: number) =>\n getDefaultLogger().logAnimated(message, duration);\nexport const cli = (command: string) => getDefaultLogger().cli(command);\nexport const cleanup = () => getDefaultLogger().cleanup();\n\n// Simplified API exports\nexport const preset = (name: string) => getDefaultLogger().preset(name);\nexport const presets = () => getDefaultLogger().presets();\nexport const hideTimestamp = () => getDefaultLogger().hideTimestamp();\nexport const showTimestamp = () => getDefaultLogger().showTimestamp();\nexport const hideLocation = () => getDefaultLogger().hideLocation();\nexport const showLocation = () => getDefaultLogger().showLocation();\nexport const hideBadges = () => getDefaultLogger().hideBadges();\nexport const showBadges = () => getDefaultLogger().showBadges();\nexport const badges = (badgeList: string[]) => getDefaultLogger().badges(badgeList);\nexport const badge = (badgeName: string) => getDefaultLogger().badge(badgeName);\nexport const clearBadges = () => getDefaultLogger().clearBadges();\nexport const component = (name: string) => getDefaultLogger().component(name);\nexport const api = (name: string) => getDefaultLogger().api(name);\nexport const scope = (name: string) => getDefaultLogger().scope(name);\nexport const customize = (overrides: Parameters<Logger['customize']>[0]) => getDefaultLogger().customize(overrides);\n\n// Enterprise features exports\nexport const addSerializer = <T>(\n type: new (...args: unknown[]) => T,\n serializer: SerializerFn<T>,\n priority?: number\n) => getDefaultLogger().addSerializer(type, serializer, priority);\nexport const removeSerializer = <T>(type: new (...args: unknown[]) => T) =>\n getDefaultLogger().removeSerializer(type);\nexport const on = (event: HookEvent, callback: HookCallback, priority?: number) =>\n getDefaultLogger().on(event, callback, priority);\nexport const once = (event: HookEvent, callback: HookCallback, priority?: number) =>\n getDefaultLogger().once(event, callback, priority);\nexport const off = (event: HookEvent, callback: HookCallback) =>\n getDefaultLogger().off(event, callback);\nexport const use = (middleware: MiddlewareFn, priority?: number) =>\n getDefaultLogger().use(middleware, priority);\nexport const addTransport = (target: TransportTarget) =>\n getDefaultLogger().addTransport(target);\nexport const removeTransport = (id: string) =>\n getDefaultLogger().removeTransport(id);\nexport const flushTransports = () =>\n getDefaultLogger().flushTransports();\nexport const closeTransports = () =>\n getDefaultLogger().closeTransports();\n\n// Re-export utilities\nexport { StyleBuilder, StylePresets as Styles } from './styling/index.js';\n\n// Re-export enterprise features\nexport { SerializerRegistry } from './serializers/index.js';\nexport { HookManager } from './hooks/index.js';\nexport { TransportManager, ConsoleTransport, FileTransport, HttpTransport } from './transports/index.js';\n","/**\n * @fileoverview Better Logger — default entry point.\n *\n * Re-exports `Logger`, the scoped loggers, subpath-style bridges, and\n * cross-runtime styling/utility helpers. Side-effect free at import.\n */\n\n// Main Logger class with all features\nimport { Logger } from './Logger.js';\nimport type {\n LogLevel,\n Verbosity,\n ThemeVariant,\n BannerType,\n StyleOptions,\n ILogHandler,\n CLILogLevel,\n IBoxOptions,\n ITableOptions,\n Span,\n SpanAttributes,\n} from './types/index.js';\n\n// Lazy singleton - se inicializa solo cuando se necesita\nlet _logger: Logger | null = null;\n\nfunction getLogger(): Logger {\n if (!_logger) {\n _logger = new Logger();\n }\n return _logger;\n}\n\n/**\n * Main `Logger` class — orchestrator for styling, transports, hooks,\n * serializers, MDC, and CLI primitives. Construct directly or use the\n * default singleton below.\n */\nexport { Logger };\n\n/**\n * Default Logger singleton (lazy). Use this for the common case.\n */\nexport default getLogger();\n\n/**\n * Top-level log methods bound to the default singleton.\n */\nexport const debug = (...args: unknown[]) => getLogger().debug(...args);\nexport const info = (...args: unknown[]) => getLogger().info(...args);\nexport const warn = (...args: unknown[]) => getLogger().warn(...args);\nexport const error = (...args: unknown[]) => getLogger().error(...args);\nexport const success = (...args: unknown[]) => getLogger().success(...args);\nexport const critical = (...args: unknown[]) => getLogger().critical(...args);\nexport const trace = (...args: unknown[]) => getLogger().trace(...args);\nexport const table = (data: unknown, columns?: string[]) => getLogger().table(data, columns);\nexport const group = (label: string, collapsed?: boolean) => getLogger().group(label, collapsed);\nexport const groupEnd = () => getLogger().groupEnd();\nexport const time = (label: string) => getLogger().time(label);\nexport const timeEnd = (label: string) => getLogger().timeEnd(label);\nexport const event = (name: string, attributes?: SpanAttributes): void =>\n getLogger().event(name, attributes);\nexport const startSpan = (name: string, attributes?: SpanAttributes): Span =>\n getLogger().startSpan(name, attributes);\nexport function span<T>(name: string, fn: (s: Span) => T | Promise<T>): Promise<T>;\nexport function span<T>(name: string, attributes: SpanAttributes, fn: (s: Span) => T | Promise<T>): Promise<T>;\nexport function span<T>(\n name: string,\n fnOrAttributes: SpanAttributes | ((s: Span) => T | Promise<T>),\n maybeFn?: (s: Span) => T | Promise<T>\n): Promise<T> {\n return getLogger().span(\n name,\n fnOrAttributes as SpanAttributes,\n maybeFn as (s: Span) => T | Promise<T>\n );\n}\nexport const setGlobalPrefix = (prefix: string) => getLogger().setGlobalPrefix(prefix);\nexport const scope = (name: string) => getLogger().scope(name);\nexport const component = (name: string) => getLogger().component(name);\nexport const api = (name: string) => getLogger().api(name);\nexport const badges = (badgeList: string[]) => getLogger().badges(badgeList);\nexport const badge = (badgeName: string) => getLogger().badge(badgeName);\nexport const clearBadges = () => getLogger().clearBadges();\nexport const setVerbosity = (level: Verbosity) => getLogger().setVerbosity(level);\nexport const addHandler = (handler: ILogHandler) => getLogger().addHandler(handler);\nexport const setTheme = (theme: ThemeVariant) => getLogger().setTheme(theme);\nexport const setBannerType = (bannerType: BannerType) => getLogger().setBannerType(bannerType);\nexport const showBanner = (bannerType?: BannerType) => getLogger().showBanner(bannerType);\nexport const logWithSVG = (message: string, svgContent?: string, options?: StyleOptions) =>\n getLogger().logWithSVG(message, svgContent, options);\nexport const logAnimated = (message: string, duration?: number) =>\n getLogger().logAnimated(message, duration);\nexport const cli = (command: string) => getLogger().cli(command);\n\n// Type exports\nexport type {\n LogLevel,\n Verbosity,\n ThemeVariant,\n BannerType,\n StyleOptions,\n ILogHandler,\n LoggerConfig,\n LogMetadata,\n StackInfo,\n TimerEntry,\n TimerResult,\n OutputFormat,\n IScopedLogger,\n IAPILogger,\n IComponentLogger,\n Bindings,\n SerializerFn,\n SerializerContext,\n SerializerConfig,\n ISerializerRegistry,\n HookLogEntry,\n HookEvent,\n HookCallback,\n MiddlewareFn,\n IHookManager,\n TransportRecord,\n TransportOptions,\n TransportTarget,\n ITransport,\n TimestampFormat,\n ColumnAlign,\n ColumnConfig,\n LogOptions,\n CLILogLevel,\n ISpinnerHandle,\n IBoxOptions,\n ITableOptions,\n} from './types/index.js';\n\n// Styling utilities\nexport {\n StyleBuilder,\n StylePresets,\n THEME_PRESETS,\n THEME_BANNERS,\n BANNER_VARIANTS\n} from './styling/index.js';\n\n// Enterprise features — convenience wrappers bound to the singleton.\nimport type { SerializerFn, HookEvent, HookCallback, MiddlewareFn, TransportTarget } from './types/index.js';\nexport const addSerializer = <T>(\n type: new (...args: unknown[]) => T,\n serializer: SerializerFn<T>,\n priority?: number\n) => getLogger().addSerializer(type, serializer, priority);\nexport const removeSerializer = <T>(type: new (...args: unknown[]) => T) =>\n getLogger().removeSerializer(type);\nexport const on = (event: HookEvent, callback: HookCallback, priority?: number) =>\n getLogger().on(event, callback, priority);\nexport const once = (event: HookEvent, callback: HookCallback, priority?: number) =>\n getLogger().once(event, callback, priority);\nexport const off = (event: HookEvent, callback: HookCallback) =>\n getLogger().off(event, callback);\nexport const use = (middleware: MiddlewareFn, priority?: number) =>\n getLogger().use(middleware, priority);\nexport const addTransport = (target: TransportTarget) =>\n getLogger().addTransport(target);\nexport const removeTransport = (id: string) =>\n getLogger().removeTransport(id);\nexport const flushTransports = () =>\n getLogger().flushTransports();\nexport const closeTransports = () =>\n getLogger().closeTransports();\n\n// Scoped loggers\nexport {\n ScopedLogger,\n APILogger,\n ComponentLogger,\n ContextLogger\n} from './ScopedLogger.js';\n\n// Constants\nexport { DEFAULT_CONFIG } from './constants.js';\n\n// Utility exports\nexport {\n parseStackTrace,\n formatTimestamp,\n getConsoleMethod,\n createLogEntry,\n formatTablePlain,\n safeSerialize\n} from './utils/index.js';\n\n// ANSI color utilities\nexport {\n ansiStyle,\n ansiColor,\n ansiBackground,\n ansiBold,\n ansiDim,\n ansiUnderline,\n formatLogLevelANSI,\n formatSuccessANSI\n} from './utils/ansi-colors.js';\n\n// Environment detection\nexport {\n getEnvironment,\n isRunningInTerminal,\n supportsANSI,\n getColorCapability,\n getTerminalWidth,\n getTerminalHeight,\n getEnvironmentInfo,\n} from './utils/environment-detector.js';\n\nexport type { Environment } from './utils/environment-detector.js';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["THEME_PRESETS","StyleBuilder","BANNER_VARIANTS","StyleBuilder","TransportManager","resolveAsyncLocalStorage","isRunningInTerminal","renderStep","getColorCapability","renderHeader","renderDivider","renderBox","renderTable","NoopSpinner","SpinnerManager","ServerFallback","THEME_PRESETS","DEFAULT_CONFIG","createSerializerBridge","createHookBridge","createLogContext","createStyleManager","setupThemeChangeListener","hasPreset","THEME_BANNERS","getAvailablePresets","getSmartPreset","getEnvironment","LOG_LEVELS","LOG_LEVEL_TO_SEVERITY_NUMBER","LOG_LEVEL_TO_SEVERITY_TEXT","parseStackTrace","formatTimestamp","createStyledOutput","getColorCapability","formatBadge","StylePresets","StyleBuilder","CLI_LEVEL_MAP"],"sources":["../src/ScopedLogger.ts","../src/cli/CommandProcessor.ts","../src/cli/commands/ConfigCommand.ts","../src/cli/commands/ThemeCommand.ts","../src/cli/commands/ExportCommand.ts","../src/cli/help.ts","../src/cli/index.ts","../src/transports/TransportBridge.ts","../src/transports/SpanRuntime.ts","../src/playground/TerminalBridge.ts","../src/Logger.ts","../src/index.ts"],"sourcesContent":["import { Logger, resolveSpanArgs } from './Logger.js';\nimport type {\n TimerEntry,\n Bindings,\n ISpinnerHandle,\n IBoxOptions,\n ITableOptions,\n CLILogLevel,\n Span,\n SpanAttributes\n} from './types/index.js';\n\n/**\n * Logger prefijado por un scope nominal. Mantiene su propio stack de badges\n * y contextos y delega el envío de mensajes al {@link Logger} padre a través\n * de bindings (`{ scope, badges }`).\n *\n * Es la base de la jerarquía temática: {@link APILogger} y\n * {@link ComponentLogger} extienden de ella, y {@link ContextLogger} la\n * consume para apilar/subdesapilar sub-prefijos en el scope.\n *\n * No se construye directamente: se obtiene con `logger.scope('name')`.\n *\n * @example\n * // El factory method del Logger raíz devuelve un ScopedLogger\n * import logger from '@mks2508/better-logger';\n *\n * const http = logger.scope('HTTP');\n * http.badge('OUTBOUND').info('Request enviada');\n * // salida: [HTTP] [OUTBOUND] Request enviada\n *\n * @example\n * // Anidar contextos dentro de un scope (el prefijo se compone con ':')\n * const retry = http.context('retry');\n * retry.run(() => http.warn('Reintentando petición'));\n * // salida: [HTTP:retry] Reintentando petición\n *\n * @see {@link Logger.scope}\n * @see {@link APILogger}\n * @see {@link ComponentLogger}\n * @see {@link ContextLogger}\n */\nexport class ScopedLogger {\n private readonly parent: Logger;\n private readonly scopeName: string;\n private badgeList: string[] = [];\n private contextStack: string[] = [];\n private _timers?: Map<string, TimerEntry>;\n\n /**\n * Construye un ScopedLogger vinculado a un {@link Logger} padre.\n *\n * Los clientes no deben llamar a este constructor directamente: usen\n * `logger.scope(name)`, que configura correctamente la instancia.\n *\n * @param {Logger} parent - Logger raíz al que se delegan los mensajes.\n * @param {string} scopeName - Etiqueta del scope; se renderiza como\n * prefijo `[scopeName]` en cada línea.\n */\n constructor(parent: Logger, scopeName: string) {\n this.parent = parent;\n this.scopeName = scopeName;\n }\n\n private get timers(): Map<string, TimerEntry> {\n if (!this._timers) this._timers = new Map();\n return this._timers;\n }\n\n private getBindings(): Bindings {\n return {\n scope: this.getScopePrefix(),\n badges: this.badgeList.length > 0 ? [...this.badgeList] : undefined,\n };\n }\n\n private getScopePrefix(): string {\n if (this.contextStack.length === 0) return this.scopeName;\n return [this.scopeName, ...this.contextStack].join(':');\n }\n\n /**\n * Reemplaza la lista actual de badges por la pasada y la aplica a todos\n * los mensajes posteriores de este scope.\n *\n * @param {string[]} badges - Etiquetas a mostrar como badges adyacentes\n * al prefijo (p. ej. `['OUTBOUND', 'CACHED']`).\n * @returns {this} La misma instancia, para encadenar llamadas.\n *\n * @example\n * logger.scope('HTTP').badges(['OUTBOUND', 'CACHED']).info('Cache hit');\n * // salida: [HTTP] [OUTBOUND] [CACHED] Cache hit\n *\n * @see {@link badge} para añadir sin reemplazar los existentes.\n * @see {@link clearBadges} para vaciar la lista.\n */\n badges(badges: string[]): this {\n this.badgeList = [...badges];\n return this;\n }\n\n /**\n * Añade un badge al scope de forma idempotente (no lo duplica si ya existe).\n *\n * @param {string} badge - Etiqueta a añadir a la lista de badges.\n * @returns {this} La misma instancia, para encadenar llamadas.\n *\n * @example\n * logger.scope('API')\n * .badge('OUTBOUND')\n * .badge('RETRY')\n * .warn('Reintentando');\n * // salida: [API] [OUTBOUND] [RETRY] Reintentando\n */\n badge(badge: string): this {\n if (!this.badgeList.includes(badge)) {\n this.badgeList.push(badge);\n }\n return this;\n }\n\n /**\n * Vacía la lista de badges del scope.\n *\n * @returns {this} La misma instancia, para encadenar llamadas.\n *\n * @example\n * const http = logger.scope('HTTP');\n * http.badge('OUTBOUND').info('uno');\n * http.clearBadges().info('dos');\n * // [HTTP] [OUTBOUND] uno / [HTTP] dos\n */\n clearBadges(): this {\n this.badgeList = [];\n return this;\n }\n\n /**\n * Aplica un theme preset al logger padre. El preset afecta a toda la\n * instancia raíz (no solo a este scope) porque el style es compartido.\n *\n * @param {string} presetName - Nombre del preset registrado en el StyleManager.\n * @returns {this} La misma instancia, para encadenar llamadas.\n *\n * @example\n * logger.scope('UI').style('cyberpunk').info('neon');\n * @see {@link Logger.setTheme}\n */\n style(presetName: string): this {\n this.parent.setTheme(presetName as any);\n return this;\n }\n\n /**\n * Crea un {@link ContextLogger} vinculado a este scope. Los contextos se\n * apilan en el prefijo separados por `:`, permitiendo agrupar bloques de\n * logs relacionados (reintentos, sub-etapas, etc.) sin `console.group`.\n *\n * @param {string} contextName - Nombre del contexto a apilar.\n * @returns {ContextLogger} Handler con `run`, `runAsync`, `start`/`end`.\n *\n * @example\n * const retry = logger.scope('HTTP').context('retry');\n * retry.run(() => logger.warn('Reintentando'));\n * // salida: [HTTP:retry] Reintentando\n * @see {@link ContextLogger}\n */\n context(contextName: string): ContextLogger {\n return new ContextLogger(this, contextName);\n }\n\n /**\n * Inicia un timer etiquetado bajo el namespace `<scopeName>:<label>`.\n * El label es local a este scope, así que dos scopes pueden reutilizar el\n * mismo nombre sin colisión.\n *\n * @param {string} label - Identificador del timer.\n *\n * @example\n * const http = logger.scope('HTTP');\n * http.time('request');\n * // ... trabajo ...\n * http.timeEnd('request'); // imprime \"Timer: request - 12.34ms\"\n * @see {@link timeEnd}\n */\n time(label: string): void {\n this.timers.set(label, {\n label: `${this.scopeName}:${label}`,\n startTime: performance.now(),\n });\n }\n\n /**\n * Detiene un timer previamente iniciado con {@link time} y registra la\n * duración con nivel `success`. Si el label no existe, emite un `warn`\n * y devuelve `undefined`.\n *\n * @param {string} label - Mismo label pasado a {@link time}.\n * @returns {number | undefined} Milisegundos transcurridos, o `undefined`\n * si el timer no estaba registrado.\n *\n * @example\n * const http = logger.scope('HTTP');\n * http.time('fetch');\n * await fetch(url);\n * const ms = http.timeEnd('fetch');\n * if (ms && ms > 1000) http.warn('Latencia alta');\n */\n timeEnd(label: string): number | undefined {\n const timer = this.timers.get(label);\n if (!timer) {\n this.warn(`Timer '${label}' not found`);\n return undefined;\n }\n const elapsed = performance.now() - timer.startTime;\n this.timers.delete(label);\n this.success(`Timer: ${label} - ${elapsed.toFixed(2)}ms`);\n return elapsed;\n }\n\n /**\n * Emite un mensaje a nivel `debug` con los bindings actuales del scope.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales (objetos,\n * errores, etc.) serializados igual que en el logger raíz.\n *\n * @example\n * logger.scope('DB').debug('query', { sql, params });\n */\n debug(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'debug', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `info` con los bindings actuales del scope.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('AUTH').info('Login exitoso', { userId });\n */\n info(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'info', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `warn` con los bindings actuales del scope.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('CACHE').warn('Cache miss', { key });\n */\n warn(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'warn', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `error` con los bindings actuales del scope.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales (típicamente\n * un `Error` o contexto del fallo).\n *\n * @example\n * logger.scope('DB').error('Conexión rechazada', err);\n */\n error(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'error', ...args);\n }\n\n /**\n * Emite un mensaje con badge visual `SUCCESS` a nivel `info`. Úselo para\n * hitos positivos dentro del scope (conexión establecida, sync completo,\n * commit aplicado).\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('SYNC').success('Sincronización completa', { count: 42 });\n */\n success(...args: unknown[]): void {\n const bindings = this.getBindings();\n this.parent.logWithBindingsAndTag(bindings, 'info', 'success', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `critical` con los bindings actuales del scope.\n * Reservado para fallos que detienen el flujo de la aplicación.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('PAY').critical('Pasarela inaccesible', err);\n */\n critical(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'critical', ...args);\n }\n\n /**\n * Emite un mensaje a nivel `trace` (verbosidad máxima) con los bindings\n * actuales del scope. Solo aparece si la verbosity global lo permite.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n *\n * @example\n * logger.scope('NET').trace('packet', { bytes });\n */\n trace(...args: unknown[]): void {\n this.parent.logWithBindings(this.getBindings(), 'trace', ...args);\n }\n\n // ===== SPANS / TRACES (delegation to Logger) =====\n\n /**\n * Emite un point-span con el scope de este logger como\n * `SpanRecord.scope`. Ver {@link Logger.event}.\n *\n * @param {string} name - Nombre del evento.\n * @param {SpanAttributes} [attributes] - Attributes del span.\n *\n * @example\n * logger.scope('BUILD').event('step.done', { step: 'compile' });\n */\n event(name: string, attributes?: SpanAttributes): void {\n this.parent._emitSpanEvent(name, attributes, this.getScopePrefix());\n }\n\n /**\n * Ejecuta `fn` dentro de un span activo etiquetado con el scope de este\n * logger. Los logs dentro de `fn` correlacionan con el span vía\n * `traceId`/`spanId`. Ver {@link Logger.span}.\n *\n * @typeParam T - Tipo resuelto por `fn`.\n * @param {string} name - Nombre de la operación.\n * @param {(s: Span) => T | Promise<T>} fn - Work-block a medir.\n * @returns {Promise<T>} Lo que resuelve `fn`.\n *\n * @example\n * await logger.scope('DB').span('migrate', async (s) => {\n * await runMigrations();\n * });\n */\n span<T>(name: string, fn: (s: Span) => T | Promise<T>): Promise<T>;\n span<T>(name: string, attributes: SpanAttributes, fn: (s: Span) => T | Promise<T>): Promise<T>;\n span<T>(\n name: string,\n fnOrAttributes: ((s: Span) => T | Promise<T>) | SpanAttributes,\n maybeFn?: (s: Span) => T | Promise<T>\n ): Promise<T> {\n const { attributes, fn } = resolveSpanArgs(fnOrAttributes, maybeFn);\n return this.parent._runSpan(name, attributes, this.getScopePrefix(), fn);\n }\n\n /**\n * Inicia un span externally-ended etiquetado con el scope de este\n * logger. Ver {@link Logger.startSpan}.\n *\n * @param {string} name - Nombre de la operación.\n * @param {SpanAttributes} [attributes] - Attributes iniciales.\n * @returns {Span} Handle con `set`/`end`/`fail`.\n */\n startSpan(name: string, attributes?: SpanAttributes): Span {\n return this.parent._startSpan(name, attributes, this.getScopePrefix());\n }\n\n // ===== CLI PRIMITIVES (delegation to Logger) =====\n\n /**\n * Delegación a {@link Logger.step}: dibuja una barra de progreso discreta\n * `current/total` para este scope.\n *\n * @param {number} current - Paso actual (1-indexed).\n * @param {number} total - Total de pasos.\n * @param {string} message - Texto mostrado junto al contador.\n * @see {@link Logger.step}\n */\n step(current: number, total: number, message: string): void {\n this.parent.step(current, total, message);\n }\n\n /**\n * Delegación a {@link Logger.header}: imprime un título con separadores visuales.\n *\n * @param {string} title - Texto del título.\n * @param {string} [subtitle] - Subtítulo opcional bajo el título.\n * @see {@link Logger.header}\n */\n header(title: string, subtitle?: string): void {\n this.parent.header(title, subtitle);\n }\n\n /**\n * Delegación a {@link Logger.divider}: imprime una línea separadora horizontal.\n * @see {@link Logger.divider}\n */\n divider(): void {\n this.parent.divider();\n }\n\n /**\n * Delegación a {@link Logger.blank}: inserta una línea en blanco.\n * @see {@link Logger.blank}\n */\n blank(): void {\n this.parent.blank();\n }\n\n /**\n * Delegación a {@link Logger.box}: dibuja un recuadro ANSI alrededor de `content`.\n *\n * @param {string} content - Texto a enmarcar.\n * @param {IBoxOptions} [options] - Opciones de estilo del box.\n * @see {@link Logger.box}\n */\n box(content: string, options?: IBoxOptions): void {\n this.parent.box(content, options);\n }\n\n /**\n * Delegación a {@link Logger.cliTable}: renderiza `rows` como tabla ASCII.\n *\n * @param {Record<string, unknown>[]} rows - Filas a mostrar.\n * @param {ITableOptions} [options] - Opciones de columnas y estilo.\n * @see {@link Logger.cliTable}\n */\n cliTable(rows: Record<string, unknown>[], options?: ITableOptions): void {\n this.parent.cliTable(rows, options);\n }\n\n /**\n * Delegación a {@link Logger.spinner}: arranca un spinner con `message`.\n *\n * @param {string} message - Texto a mostrar al lado del spinner.\n * @returns {ISpinnerHandle} Handle para detener/actualizar el spinner.\n * @see {@link Logger.spinner}\n */\n spinner(message: string): ISpinnerHandle {\n return this.parent.spinner(message);\n }\n\n /**\n * Delegación a {@link Logger.setCLILevel}: ajusta el nivel mínimo de las\n * primitivas CLI visibles.\n *\n * @param {CLILogLevel} level - Nivel CLI (`silent` … `verbose`).\n * @see {@link Logger.setCLILevel}\n */\n setCLILevel(level: CLILogLevel): void {\n this.parent.setCLILevel(level);\n }\n\n /**\n * Apila un contexto en el prefijo del scope. Invocado por\n * {@link ContextLogger}; los clientes no deben llamarlo directamente.\n *\n * @param {string} context - Nombre del contexto a apilar.\n * @internal\n */\n _pushContext(context: string): void {\n this.contextStack.push(context);\n }\n\n /**\n * Desapila el último contexto del prefijo del scope. Invocado por\n * {@link ContextLogger}; los clientes no deben llamarlo directamente.\n *\n * @internal\n */\n _popContext(): void {\n this.contextStack.pop();\n }\n}\n\n/**\n * Logger especializado para llamadas a APIs y servicios externos.\n *\n * Extiende {@link ScopedLogger} pre-seteando el badge `API` y exponiendo\n * atajos para eventos típicos de integración: llamadas lentas ({@link slow}),\n * rate limiting ({@link rateLimit}), fallos de autenticación ({@link auth}) y\n * APIs deprecadas ({@link deprecated}).\n *\n * Se obtiene con `logger.api(name)` y no se construye directamente.\n *\n * @example\n * import logger from '@mks2508/better-logger';\n *\n * const stripe = logger.api('Stripe');\n * stripe.info('Consultando customer', { id });\n * // salida: [API:Stripe] [API] Consultando customer\n *\n * stripe.slow('customer.retrieve', 1250);\n * // salida: [API:Stripe] [API] [SLOW] customer.retrieve (1250ms)\n *\n * @see {@link Logger.api}\n * @see {@link ScopedLogger}\n */\nexport class APILogger extends ScopedLogger {\n /**\n * Construye un APILogger con scope `API:<apiName>` y badge `API` ya aplicado.\n *\n * Los clientes deben usar `logger.api(name)`.\n *\n * @param {Logger} parent - Logger raíz al que se delegan los mensajes.\n * @param {string} apiName - Nombre del servicio/API (se prefija con `API:`).\n */\n constructor(parent: Logger, apiName: string) {\n super(parent, `API:${apiName}`);\n this.badge('API');\n }\n\n /**\n * Registra una llamada lenta con badge `SLOW` a nivel `warn`.\n *\n * @param {string} message - Descripción de la operación lenta.\n * @param {number} [duration] - Duración medida en ms; si se pasa, se\n * anexa al mensaje como `(Nms)`.\n *\n * @example\n * const t0 = performance.now();\n * await stripe.customers.retrieve(id);\n * logger.api('Stripe').slow('retrieve', performance.now() - t0);\n */\n slow(message: string, duration?: number): void {\n this.badge('SLOW');\n const msg = duration ? `${message} (${duration}ms)` : message;\n this.warn(msg);\n }\n\n /**\n * Registra un evento de rate limiting (HTTP 429) con badge `RATE_LIMIT`.\n *\n * @param {string} message - Detalle del límite golpeado.\n *\n * @example\n * logger.api('GitHub').rateLimit('Secondary rate limit on /search');\n */\n rateLimit(message: string): void {\n this.badge('RATE_LIMIT');\n this.warn(message);\n }\n\n /**\n * Registra un fallo de autenticación (401/403) con badge `AUTH` a nivel\n * `error`.\n *\n * @param {string} message - Detalle del fallo de credenciales/token.\n *\n * @example\n * logger.api('OAuth').auth('Token expirado');\n */\n auth(message: string): void {\n this.badge('AUTH');\n this.error(message);\n }\n\n /**\n * Marca una API como deprecada con badge `DEPRECATED` a nivel `warn`.\n *\n * @param {string} message - Mensaje guiando a la migración (endpoint\n * alternativo, versión retirada, etc.).\n *\n * @example\n * logger.api('Legacy').deprecated('Usar v3; v2 se retira en Q4');\n */\n deprecated(message: string): void {\n this.badge('DEPRECATED');\n this.warn(message);\n }\n}\n\n/**\n * Logger para componentes UI, módulos o cualquier unidad con ciclo de vida.\n *\n * Extiende {@link ScopedLogger} pre-seteando el badge `COMPONENT` y exponiendo\n * atajos para eventos típicos: {@link lifecycle}, {@link stateChange} y\n * {@link propsChange}.\n *\n * Se obtiene con `logger.component(name)` y no se construye directamente.\n *\n * @example\n * import logger from '@mks2508/better-logger';\n *\n * const cart = logger.component('Cart');\n * cart.lifecycle('mount');\n * // salida: [Cart] [COMPONENT] [LIFECYCLE] mount\n *\n * cart.stateChange('empty', 'has-items', { count: 3 });\n * // salida: [Cart] [COMPONENT] [STATE] empty → has-items { count: 3 }\n *\n * @see {@link Logger.component}\n * @see {@link ScopedLogger}\n */\nexport class ComponentLogger extends ScopedLogger {\n /**\n * Construye un ComponentLogger con badge `COMPONENT` ya aplicado.\n *\n * Los clientes deben usar `logger.component(name)`.\n *\n * @param {Logger} parent - Logger raíz al que se delegan los mensajes.\n * @param {string} componentName - Nombre del componente (scope label).\n */\n constructor(parent: Logger, componentName: string) {\n super(parent, componentName);\n this.badge('COMPONENT');\n }\n\n /**\n * Registra un evento de ciclo de vida con badge `LIFECYCLE` a nivel `info`.\n *\n * @param {string} event - Nombre del evento (`mount`, `unmount`,\n * `update`, ...).\n * @param {string} [message] - Detalle opcional; si se omite, solo se\n * registra el nombre del evento.\n *\n * @example\n * logger.component('Cart').lifecycle('mount', 'Modal abierto');\n */\n lifecycle(event: string, message?: string): void {\n this.badge('LIFECYCLE');\n const msg = message ? `${event}: ${message}` : event;\n this.info(msg);\n }\n\n /**\n * Registra una transición de estado con badge `STATE` a nivel `info`.\n *\n * @param {string} from - Estado previo.\n * @param {string} to - Estado nuevo.\n * @param {unknown} [data] - Payload opcional asociado a la transición.\n *\n * @example\n * const fsm = logger.component('FSM');\n * fsm.stateChange('idle', 'loading');\n * fsm.stateChange('loading', 'success', { items: 3 });\n */\n stateChange(from: string, to: string, data?: unknown): void {\n this.badge('STATE');\n const msg = `${from} → ${to}`;\n if (data) {\n this.info(msg, data);\n } else {\n this.info(msg);\n }\n }\n\n /**\n * Registra cambios de props/debug del componente con badge `PROPS` a nivel\n * `debug`.\n *\n * @param {Record<string, unknown>} changes - Mapa prop → valor (típicamente\n * el diff de props entre renders).\n *\n * @example\n * logger.component('Cart').propsChange({ itemCount: 5, currency: 'EUR' });\n */\n propsChange(changes: Record<string, unknown>): void {\n this.badge('PROPS');\n this.debug('Props changed:', changes);\n }\n}\n\n/**\n * Handler de contexto apilable sobre un {@link ScopedLogger}.\n *\n * Permite agrupar bloques de logs bajo un sub-prefijo separado por `:`,\n * manteniendo la correlación visual sin necesidad de `console.group`. El\n * prefijo compuesto se forma como `<scopeName>:<contextName>`.\n *\n * Se crea con `scopedLogger.context(name)`. El patrón idiomático es\n * {@link run}/{@link runAsync} (auto push/pop con try/finally); {@link start}\n * y {@link end} permiten control manual cuando el bloque no cierra\n * léxicamente (event handlers distribuidos, promesas de larga duración).\n *\n * @example\n * import logger from '@mks2508/better-logger';\n *\n * const http = logger.scope('HTTP');\n *\n * // Bloque síncrono auto-cerrado\n * http.context('retry').run(() => {\n * http.warn('Reintentando petición');\n * });\n * // salida: [HTTP:retry] Reintentando petición\n *\n * // Bloque async auto-cerrado\n * await http.context('refresh').runAsync(async () => {\n * await refreshToken();\n * http.info('Token refrescado');\n * });\n *\n * @see {@link ScopedLogger.context}\n */\nexport class ContextLogger {\n private parentLogger: ScopedLogger;\n private contextName: string;\n\n /**\n * @param {ScopedLogger} parentLogger - Scope sobre el que se apila el contexto.\n * @param {string} contextName - Sub-prefijo a apilar en el scope padre.\n */\n constructor(parentLogger: ScopedLogger, contextName: string) {\n this.parentLogger = parentLogger;\n this.contextName = contextName;\n }\n\n /**\n * Ejecuta `fn` síncrona dentro del contexto, garantizando el pop del\n * prefijo incluso si `fn` lanza. El contexto solo está activo durante la\n * ejecución de `fn`.\n *\n * @typeParam T - Tipo de retorno de `fn`.\n * @param {() => T} fn - Función a ejecutar bajo el contexto.\n * @returns {T} Lo que devuelva `fn`.\n * @throws {unknown} Relanza cualquier excepción de `fn` tras desapilar.\n *\n * @example\n * logger.scope('HTTP').context('warmup').run(() => {\n * logger.info('Pre-cargando caché');\n * });\n */\n run<T>(fn: () => T): T {\n this.parentLogger._pushContext(this.contextName);\n try {\n return fn();\n } finally {\n this.parentLogger._popContext();\n }\n }\n\n /**\n * Variante async de {@link run}: mantiene el contexto activo mientras se\n * awaiting la promesa de `fn`, incluyendo awaits internos.\n *\n * @typeParam T - Tipo resuelto por la promesa de `fn`.\n * @param {() => Promise<T>} fn - Función async a ejecutar bajo el contexto.\n * @returns {Promise<T>} Promesa que resuelve al valor de `fn`.\n * @throws {unknown} Relanza cualquier rechazo de `fn` tras desapilar.\n *\n * @example\n * await logger.scope('HTTP').context('fetch').runAsync(async () => {\n * const r = await fetch(url);\n * logger.info('Recibido', { status: r.status });\n * });\n */\n async runAsync<T>(fn: () => Promise<T>): Promise<T> {\n this.parentLogger._pushContext(this.contextName);\n try {\n return await fn();\n } finally {\n this.parentLogger._popContext();\n }\n }\n\n /**\n * Apila el contexto manualmente. Útil cuando el bloque que lo consume no\n * cierra léxicamente (event handlers, timeouts, streams). Debe emparejarse\n * con un {@link end} posterior; olvidarlo deja el prefijo contaminado para\n * los logs siguientes del scope.\n *\n * @example\n * const ctx = logger.scope('WS').context('subscribe');\n * socket.onopen = () => { ctx.start(); ctx.info('connected'); };\n * socket.onclose = () => { ctx.info('disconnected'); ctx.end(); };\n * @see {@link end}\n */\n start(): void {\n this.parentLogger._pushContext(this.contextName);\n }\n\n /**\n * Desapila el último contexto abierto con {@link start}.\n *\n * @see {@link start}\n */\n end(): void {\n this.parentLogger._popContext();\n }\n\n /**\n * Atajo a `scopedLogger.debug(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n debug(...args: unknown[]): void { this.parentLogger.debug(...args); }\n\n /**\n * Atajo a `scopedLogger.info(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n info(...args: unknown[]): void { this.parentLogger.info(...args); }\n\n /**\n * Atajo a `scopedLogger.warn(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n warn(...args: unknown[]): void { this.parentLogger.warn(...args); }\n\n /**\n * Atajo a `scopedLogger.error(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n error(...args: unknown[]): void { this.parentLogger.error(...args); }\n\n /**\n * Atajo a `scopedLogger.success(...)`. El contexto se aplica al prefijo del\n * scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n success(...args: unknown[]): void { this.parentLogger.success(...args); }\n\n /**\n * Atajo a `scopedLogger.critical(...)`. El contexto se aplica al prefijo\n * del scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.\n *\n * @param {...unknown[]} args - Mensaje y argumentos adicionales.\n */\n critical(...args: unknown[]): void { this.parentLogger.critical(...args); }\n}\n","/**\n * @fileoverview Procesador central del CLI del logger. Resuelve comandos,\n * despacha ejecución, mantiene historial y soporta plugins. No es un binario\n * standalone: se invoca vía `logger.cli()` o `window.cli()` en browser.\n */\n\nimport type { Logger } from '../Logger.js';\n\n/**\n * Comando del CLI del logger. Cada implementación se registra en un\n * {@link CommandProcessor} para ser invocable vía `/name` desde la consola\n * del navegador o cualquier host interactivo.\n *\n * @see {@link CommandProcessor.registerCommand}\n * @see {@link HelpCommand}\n */\nexport interface ICommand {\n /** Nombre canónico del comando, sin la barra inicial `/`. Debe ser único. */\n name: string;\n /** Descripción corta humana; la usa el sistema de help. */\n description: string;\n /** Sintaxis de uso mostrada en `/help`, p.ej. `/export <format>`. */\n usage: string;\n /** Agrupación opcional para el help (`Configuration`, `Export`, ...). */\n category?: string;\n /** Nombres alternativos sin la `/`; se resuelven al comando real. */\n aliases?: string[];\n /**\n * Ejecuta el comando. Recibe los argumentos como string plano (todo lo\n * posterior al primer token, re-joined con espacios) y el {@link Logger}\n * activo para emitir output.\n *\n * @param args - Argumentos del comando (string), puede ser `''`.\n * @param logger - Logger activo.\n */\n execute(args: string, logger: Logger): void | Promise<void>;\n}\n\n/**\n * Plugin de CLI: agrupa uno o más {@link ICommand} con lifecycle\n * `initialize`/`cleanup`. Permite a terceros empaquetar funcionalidad\n * extendida (ej: integración con un dashboard, transport custom) y\n * registrarla de golpe vía {@link CommandProcessor.registerPlugin}.\n *\n * @example\n * ```ts\n * const telemetryPlugin: ICLIPlugin = {\n * name: 'telemetry',\n * version: '1.0.0',\n * description: 'Comandos de telemetría',\n * commands: [new TelemetryDumpCommand()],\n * initialize(processor, logger) {\n * logger.info('telemetry plugin cargado');\n * },\n * cleanup() {\n * // liberar suscripciones/recursos\n * }\n * };\n * processor.registerPlugin(telemetryPlugin, logger);\n * ```\n *\n * @see {@link CommandProcessor.registerPlugin}\n */\nexport interface ICLIPlugin {\n /** Identificador único del plugin. */\n name: string;\n /** Versión semántica del plugin. */\n version: string;\n /** Descripción humana corta. */\n description: string;\n /** Comandos que el plugin aporta al registry al registrarse. */\n commands: ICommand[];\n /** Hook opcional llamado tras el registro — útil para suscribirse a eventos del processor. */\n initialize?(processor: CommandProcessor, logger: Logger): void;\n /** Hook opcional llamado al desregistrar el plugin — liberar recursos. */\n cleanup?(): void;\n}\n\n/**\n * Entrada del historial de comandos ejecutados. No se exporta; solo circula\n * internamente entre {@link CommandProcessor.getHistory} y el storage privado.\n *\n * @internal\n */\ninterface HistoryEntry {\n command: string;\n timestamp: Date;\n success: boolean;\n}\n\n/**\n * Procesador central del CLI del logger. Resuelve nombres de comando (con\n * aliases), despacha ejecución, mantiene historial acotado (max 100 entradas)\n * y soporta un sistema de plugins para extensión de terceros.\n *\n * No es un binario standalone: se invoca desde la consola del navegador vía\n * `window.cli(\"<command>\")` (modo interactivo habilitado por\n * {@link enterInteractiveMode}) o desde código vía `logger.cli()`. El\n * constructor no registra ningún comando por defecto — usar\n * {@link createDefaultCLI} para obtener una instancia con los 8 comandos\n * estándar ya cargados.\n *\n * @example\n * ```ts\n * const cli = createDefaultCLI();\n * await cli.processCommand('/themes', logger);\n * await cli.processCommand('/config theme=neon', logger);\n * ```\n *\n * @example\n * ```ts\n * // Modo interactivo: expone `window.cli` en el navegador\n * cli.enterInteractiveMode(logger);\n * // Desde la devtools: cli('help') → procesa '/help'\n * ```\n *\n * @see {@link createDefaultCLI}\n * @see {@link ICommand}\n * @see {@link ICLIPlugin}\n */\nexport class CommandProcessor {\n private commands: Map<string, ICommand> = new Map();\n private aliases: Map<string, string> = new Map();\n private plugins: Map<string, ICLIPlugin> = new Map();\n private history: HistoryEntry[] = [];\n private maxHistorySize: number = 100;\n private isInteractiveMode: boolean = false;\n\n /**\n * Registra un comando. Si el comando declara `aliases`, también se indexan\n * para resolución. Un comando con el mismo `name` sobreescribe al previo.\n *\n * @param {ICommand} command - Comando a registrar.\n * @see {@link ICommand}\n */\n registerCommand(command: ICommand): void {\n this.commands.set(command.name, command);\n \n // Register aliases\n if (command.aliases) {\n for (const alias of command.aliases) {\n this.aliases.set(alias, command.name);\n }\n }\n }\n \n /**\n * Registra un plugin: indexa todos sus commands y, si el plugin define\n * `initialize`, lo invoca con el processor y el logger. Los comandos del\n * plugin se registran vía {@link registerCommand} y sus aliases quedan\n * resolvibles igual que los directos.\n *\n * @param {ICLIPlugin} plugin - Plugin a registrar.\n * @param {Logger} [logger] - Logger activo; requerido solo si el plugin define `initialize`.\n * @throws {Error} Si ya existe un plugin registrado con el mismo `name`.\n * @see {@link unregisterPlugin}\n */\n registerPlugin(plugin: ICLIPlugin, logger?: Logger): void {\n if (this.plugins.has(plugin.name)) {\n throw new Error(`Plugin ${plugin.name} is already registered`);\n }\n \n this.plugins.set(plugin.name, plugin);\n \n // Register plugin commands\n for (const command of plugin.commands) {\n this.registerCommand(command);\n }\n \n // Initialize plugin\n if (plugin.initialize && logger) {\n plugin.initialize(this, logger);\n }\n }\n \n /**\n * Desregistra un plugin por nombre: elimina todos sus commands (y los\n * aliases que aportasen), invoca su hook `cleanup` si existe y lo quita\n * del registry. No-op si el nombre no existe.\n *\n * @param {string} pluginName - Nombre del plugin a desregistrar.\n * @see {@link registerPlugin}\n */\n unregisterPlugin(pluginName: string): void {\n const plugin = this.plugins.get(pluginName);\n if (!plugin) return;\n \n // Remove plugin commands\n for (const command of plugin.commands) {\n this.commands.delete(command.name);\n if (command.aliases) {\n for (const alias of command.aliases) {\n this.aliases.delete(alias);\n }\n }\n }\n \n // Cleanup plugin\n if (plugin.cleanup) {\n plugin.cleanup();\n }\n \n this.plugins.delete(pluginName);\n }\n\n /**\n * Lista todos los commands registrados (directamente o vía plugins).\n * No incluye aliases.\n *\n * @returns {ICommand[]} Snapshot array de los commands registrados.\n */\n getCommands(): ICommand[] {\n return Array.from(this.commands.values());\n }\n\n /**\n * Resuelve un comando por nombre canónico o alias. Devuelve `undefined`\n * si no existe ninguno que matchee.\n *\n * @param {string} name - Nombre canónico o alias del comando.\n * @returns {ICommand | undefined} El comando resuelto, o `undefined`.\n */\n getCommand(name: string): ICommand | undefined {\n // Check direct command name\n let command = this.commands.get(name);\n if (command) return command;\n \n // Check aliases\n const aliasTarget = this.aliases.get(name);\n if (aliasTarget) {\n return this.commands.get(aliasTarget);\n }\n \n return undefined;\n }\n \n /**\n * Devuelve una copia del historial de comandos ejecutados (más recientes\n * primero). Acotado a 100 entradas por {@link maxHistorySize}; las más\n * viejas se descartan al insertar nuevas.\n *\n * @returns {HistoryEntry[]} Snapshot del historial; mutar el array devuelto\n * no afecta al estado interno del processor.\n */\n getHistory(): HistoryEntry[] {\n return [...this.history];\n }\n\n /**\n * Vacía el historial de comandos en memoria.\n */\n clearHistory(): void {\n this.history = [];\n }\n\n /**\n * Lista los plugins actualmente registrados.\n *\n * @returns {ICLIPlugin[]} Snapshot array de plugins activos.\n */\n getPlugins(): ICLIPlugin[] {\n return Array.from(this.plugins.values());\n }\n\n /**\n * Activa el modo interactivo. Marca el flag interno y, si se ejecuta en\n * navegador, expone `window.cli(command)` para invocar comandos desde la\n * devtools sin prefijo `/` (se añade automáticamente al input).\n *\n * @param {Logger} logger - Logger activo (emite el mensaje de bienvenida\n * con hint sobre `cli(...)` en browser).\n * @see {@link exitInteractiveMode}\n */\n enterInteractiveMode(logger: Logger): void {\n this.isInteractiveMode = true;\n logger.info('🔧 Interactive CLI mode activated. Type /exit to quit, /help for commands.');\n \n // Set up browser console listener for interactive commands\n if (typeof window !== 'undefined') {\n this.setupBrowserInteractiveMode(logger);\n }\n }\n \n /**\n * Desactiva el flag de modo interactivo. Nota: no elimina el `window.cli`\n * que {@link enterInteractiveMode} haya expuesto en el navegador — el\n * handler global sigue vivo hasta reload.\n *\n * @see {@link enterInteractiveMode}\n */\n exitInteractiveMode(): void {\n this.isInteractiveMode = false;\n }\n \n /**\n * Instala `window.cli(command)` como wrapper delgado alrededor de\n * {@link processCommand}, prefijando `/` automáticamente. Solo se invoca\n * desde {@link enterInteractiveMode} cuando `window` está disponible.\n *\n * @internal\n * @param logger - Logger activo, reenviado a cada invocación.\n */\n private setupBrowserInteractiveMode(logger: Logger): void {\n // Add global CLI function for browser usage\n (window as any).cli = (commandString: string) => {\n return this.processCommand(`/${commandString}`, logger);\n };\n \n logger.info('💡 Use cli(\"command\") to execute CLI commands in browser console.');\n }\n\n /**\n * Parsea y ejecuta un comando. El formato esperado es `/name args...`:\n * split por espacios, primer token = nombre del comando, resto = args\n * (re-joined con espacios). Si el comando no existe, loguea el error y\n * sugiere similares vía {@link getSuggestions} (\"Did you mean: ...?\").\n *\n * Toda invocación (válida o no) se registra en el historial con flag de\n * éxito/fallo según si `execute` resolvió o throweó.\n *\n * @param {string} commandString - Comando completo, debe empezar con `/`.\n * @param {Logger} logger - Logger activo para output y errores.\n * @returns {Promise<void>} Resuelve cuando el comando termina (sync o async).\n * Nunca rechaza: los errores de `execute` se capturan y se loguean.\n * @see {@link ICommand.execute}\n * @see {@link getSuggestions}\n */\n async processCommand(commandString: string, logger: Logger): Promise<void> {\n if (!commandString.startsWith('/')) {\n logger.error('Invalid command. Commands must start with /');\n this.addToHistory(commandString, false);\n return;\n }\n\n const parts = commandString.slice(1).split(' ');\n const commandName = parts[0] || '';\n const args = parts.slice(1).join(' ');\n\n const command = this.getCommand(commandName);\n if (!command) {\n logger.error(`Unknown command: ${commandName}. Type /help for available commands.`);\n \n // Suggest similar commands\n const suggestions = this.getSuggestions(commandName);\n if (suggestions.length > 0) {\n logger.info(`📋 Did you mean: ${suggestions.slice(0, 3).join(', ')}?`);\n }\n \n this.addToHistory(commandString, false);\n return;\n }\n\n try {\n await command.execute(args || '', logger);\n this.addToHistory(commandString, true);\n } catch (error) {\n logger.error(`Command '${commandName}' failed:`, error);\n this.addToHistory(commandString, false);\n }\n }\n \n /**\n * Inserta una entrada al frente del historial y trunca a\n * {@link maxHistorySize} (100) si hace falta.\n *\n * @internal\n * @param command - String crudo del comando ejecutado.\n * @param success - Si la ejecución tuvo éxito.\n */\n private addToHistory(command: string, success: boolean): void {\n this.history.unshift({\n command,\n timestamp: new Date(),\n success\n });\n \n // Limit history size\n if (this.history.length > this.maxHistorySize) {\n this.history = this.history.slice(0, this.maxHistorySize);\n }\n }\n\n /**\n * Devuelve nombres de comando que empiezan con el prefijo dado. Alimente\n * el hint \"Did you mean\" de {@link processCommand} cuando un comando no\n * se encuentra. Match por `startsWith` (no fuzzy).\n *\n * @param {string} partial - Prefijo parcial tipeado por el usuario.\n * @returns {string[]} Nombres canónicos que matchean; aliases excluidos.\n */\n getSuggestions(partial: string): string[] {\n const commandNames = Array.from(this.commands.keys());\n return commandNames.filter(name => name.startsWith(partial));\n }\n}","/**\n * @fileoverview Configuration commands for Advanced Logger CLI\n */\n\nimport type { ICommand } from '../CommandProcessor.js';\nimport type { Logger } from '../../Logger.js';\nimport type { ThemeVariant, BannerType, Verbosity } from '../../types/index.js';\n\n/**\n * Comando `/config` del CLI runtime del {@link Logger}. Inspecciona o muta\n * la configuración del logger en vivo desde la DevTools console.\n *\n * Acepta tres modos de invocación:\n * - Sin argumentos: vuelca el estado actual como tabla agrupada.\n * - JSON completo (empieza con `{`): aplica un objeto de configuración parcial.\n * - Pares `key=value` separados por coma: atajo para mutaciones puntuales.\n *\n * Solo se aplican las keys de la whitelist interna (`theme`, `verbosity`,\n * `enableColors`, `enableTimestamps`, `enableStackTrace`, `globalPrefix`,\n * `bannerType`); cualquier otra key se rechaza con un `warn` y se ignora.\n *\n * @example\n * // Sin argumentos: ver estado actual\n * // > /config\n *\n * @example\n * // Objeto JSON completo\n * // > /config {\"theme\":\"neon\",\"verbosity\":\"debug\"}\n *\n * @example\n * // Atajo key=value (múltiples pares separados por coma)\n * // > /config theme=neon,verbosity=debug,globalPrefix=MiApp\n *\n * @see {@link ICommand} para el contrato que implementa este comando.\n * @see {@link Logger.setTheme}, {@link Logger.setVerbosity},\n * {@link Logger.setBannerType}, {@link Logger.setGlobalPrefix}\n * para los setters subyacentes.\n */\nexport class ConfigCommand implements ICommand {\n name = 'config';\n description = 'Show or update logger configuration';\n usage = '/config [json|key=value,...]';\n\n /**\n * Ejecuta el comando `/config` contra el logger dado.\n *\n * @param args - Argumentos crudos del usuario. Vacío = status; con `{`\n * inicial = parse JSON; resto = pares `key=value` separados\n * por coma.\n * @param logger - Instancia destino cuyos setters se invocan.\n */\n execute(args: string, logger: Logger): void {\n if (!args) {\n this.showStatus(logger);\n return;\n }\n\n try {\n // Try to parse as JSON first\n if (args.startsWith('{')) {\n const config = JSON.parse(args);\n this.applyConfig(config, logger);\n } else {\n // Parse key=value pairs\n const pairs = args.split(',').map(pair => pair.trim().split('='));\n const config: any = {};\n pairs.forEach(([key, value]) => {\n if (key && value) {\n config[key.trim()] = value.trim().replace(/[\"']/g, '');\n }\n });\n this.applyConfig(config, logger);\n }\n } catch (error) {\n logger.error('Invalid config format. Use JSON or key=value pairs:', error);\n logger.info('Examples: /config {\"theme\":\"dark\"} or /config theme=neon,verbosity=debug');\n }\n }\n\n private showStatus(logger: Logger): void {\n const statusData = {\n theme: logger.getConfig().theme || 'default',\n verbosity: logger.getConfig().verbosity,\n colors: logger.getConfig().enableColors,\n timestamps: logger.getConfig().enableTimestamps,\n stackTrace: logger.getConfig().enableStackTrace,\n globalPrefix: logger.getConfig().globalPrefix || 'none',\n bannerType: logger.getConfig().bannerType || 'simple',\n handlers: logger.getHandlers().length\n };\n\n logger.group('⚙️ Logger Configuration');\n logger.table(statusData);\n logger.groupEnd();\n }\n\n private applyConfig(config: any, logger: Logger): void {\n const validKeys = ['theme', 'verbosity', 'enableColors', 'enableTimestamps', 'enableStackTrace', 'globalPrefix', 'bannerType'];\n const applied: string[] = [];\n\n Object.entries(config).forEach(([key, value]) => {\n if (validKeys.includes(key)) {\n if (key === 'theme' && typeof value === 'string') {\n logger.setTheme(value as ThemeVariant);\n applied.push(`${key}=${value}`);\n } else if (key === 'bannerType' && typeof value === 'string') {\n logger.setBannerType(value as BannerType);\n applied.push(`${key}=${value}`);\n } else if (key === 'verbosity') {\n logger.setVerbosity(value as Verbosity);\n applied.push(`${key}=${value}`);\n } else if (key === 'globalPrefix') {\n logger.setGlobalPrefix(value as string);\n applied.push(`${key}=${value}`);\n } else {\n logger.updateConfig({ [key]: value });\n applied.push(`${key}=${value}`);\n }\n } else {\n logger.warn(`Invalid config key: ${key}`);\n }\n });\n\n if (applied.length > 0) {\n logger.success(`Configuration updated: ${applied.join(', ')}`);\n }\n }\n}","/**\n * @fileoverview Theme and banner commands for Advanced Logger CLI\n */\n\nimport type { ICommand } from '../CommandProcessor.js';\nimport type { Logger } from '../../Logger.js';\nimport type { BannerType } from '../../types/index.js';\nimport { THEME_PRESETS, BANNER_VARIANTS } from '../../styling/index.js';\nimport { StyleBuilder } from '../../styling/index.js';\n\n/**\n * Comando `/themes` del CLI runtime del {@link Logger}. Lista los presets\n * temáticos disponibles en {@link THEME_PRESETS}, renderizando una preview\n * con los colores reales de cada tema (background, foreground, border).\n *\n * Es de solo lectura: no muta el logger. Útil para descubrir qué tema\n * aplicar antes de correr `/config theme=<name>`.\n *\n * @example\n * // Listar todos los temas con preview coloreada\n * // > /themes\n *\n * @see {@link THEME_PRESETS} para el catálogo completo de temas.\n * @see {@link ConfigCommand} para aplicar un tema vía `/config theme=...`.\n */\nexport class ThemesCommand implements ICommand {\n name = 'themes';\n description = 'Show available theme presets';\n usage = '/themes';\n\n /**\n * Ejecuta el comando `/themes` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia usada para abrir/cerrar el `group` de salida.\n */\n execute(_args: string, logger: Logger): void {\n logger.group('🎨 Available Themes');\n Object.keys(THEME_PRESETS).forEach(themeName => {\n const preview = (THEME_PRESETS as any)[themeName];\n const previewStyle = new StyleBuilder()\n .bg(preview.info.background)\n .color(preview.info.color)\n .padding('4px 8px')\n .rounded('4px')\n .border(preview.info.border)\n .build();\n \n console.log(`%c${themeName}`, previewStyle, `- ${themeName} theme preview`);\n });\n logger.groupEnd();\n }\n}\n\n/**\n * Comando `/banners` del CLI runtime del {@link Logger}. Enumera los tipos\n * de banner disponibles en {@link BANNER_VARIANTS} (`simple`, `ascii`,\n * `unicode`, ...) con una mini-preview de cada uno para inspección visual.\n *\n * Es de solo lectura: no muta el logger. Para cambiar el banner activo\n * usar {@link BannerCommand}.\n *\n * @example\n * // Listar todas las variantes de banner con preview\n * // > /banners\n *\n * @see {@link BANNER_VARIANTS} para el catálogo completo de variantes.\n * @see {@link BannerCommand} para aplicar un tipo concreto.\n */\nexport class BannersCommand implements ICommand {\n name = 'banners';\n description = 'Show available banner types';\n usage = '/banners';\n\n /**\n * Ejecuta el comando `/banners` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia usada para abrir/cerrar el `group` de salida.\n */\n execute(_args: string, logger: Logger): void {\n logger.group('🖼️ Available Banner Types');\n Object.keys(BANNER_VARIANTS).forEach(bannerName => {\n const banner = (BANNER_VARIANTS as any)[bannerName];\n console.log(`%c${bannerName}`, 'font-weight: bold; color: #667eea;');\n console.log(`%cPreview:`, 'color: #666; font-size: 12px;');\n \n // Show a mini preview\n if (bannerName === 'simple') {\n console.log(`%c${banner.text}`, banner.style);\n } else if (bannerName === 'ascii') {\n console.log(`%c${banner.text.split('\\n').slice(1, 4).join('\\n')}...`, 'font-family: monospace; color: #667eea; font-size: 10px;');\n } else if (bannerName === 'unicode') {\n console.log(`%c${banner.text}`, banner.style);\n } else {\n console.log(`%c${bannerName} banner`, 'color: #666; font-style: italic;');\n }\n });\n logger.groupEnd();\n }\n}\n\n/**\n * Comando `/banner [type]` del CLI runtime del {@link Logger}.\n *\n * - Sin argumentos: re-renderiza el banner actualmente activo.\n * - Con un tipo válido: lo aplica vía {@link Logger.setBannerType} y lo\n * muestra inmediatamente.\n * - Con un tipo inválido: loguea un `error` listando las opciones válidas.\n *\n * @example\n * // Mostrar el banner actual\n * // > /banner\n *\n * @example\n * // Cambiar a un tipo concreto\n * // > /banner ascii\n *\n * @see {@link BANNER_VARIANTS} para los tipos aceptados.\n * @see {@link Logger.setBannerType} y {@link Logger.showBanner} para los\n * métodos subyacentes.\n */\nexport class BannerCommand implements ICommand {\n name = 'banner';\n description = 'Change or show current banner type';\n usage = '/banner [type]';\n\n /**\n * Ejecuta el comando `/banner` contra el logger dado.\n *\n * @param args - Tipo de banner solicitado. Vacío = mostrar banner actual.\n * @param logger - Instancia destino cuyo banner se actualiza/muestra.\n */\n execute(args: string, logger: Logger): void {\n if (!args) {\n logger.showBanner();\n return;\n }\n\n if (args in BANNER_VARIANTS) {\n logger.setBannerType(args as BannerType);\n logger.showBanner();\n } else {\n logger.error(`Invalid banner type: ${args}. Available: ${Object.keys(BANNER_VARIANTS).join(', ')}`);\n }\n }\n}","/**\n * @fileoverview Status and demo commands for Advanced Logger CLI\n */\n\nimport type { ICommand } from '../CommandProcessor.js';\nimport type { Logger } from '../../Logger.js';\n\n/**\n * Comando `/status` del CLI runtime del {@link Logger}. Vuelca la\n * configuración vigente y algunas estadísticas (theme, verbosity, flags\n * de features, handler count, bufferSize) en una tabla agrupada dentro\n * de la consola. Es de solo lectura: no muta el logger.\n *\n * @example\n * // Inspeccionar el estado actual del logger\n * // > /status\n *\n * @see {@link Logger.getConfig} fuente de los datos mostrados.\n */\nexport class StatusCommand implements ICommand {\n name = 'status';\n description = 'Show current logger status and configuration';\n usage = '/status';\n\n /**\n * Ejecuta el comando `/status` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia de la que se lee la configuración.\n */\n execute(_args: string, logger: Logger): void {\n const config = logger.getConfig();\n const statusData = {\n theme: config.theme ? config.theme : 'default',\n verbosity: config.verbosity,\n colors: config.enableColors,\n timestamps: config.enableTimestamps,\n stackTrace: config.enableStackTrace,\n globalPrefix: config.globalPrefix ? config.globalPrefix : 'none',\n bannerType: config.bannerType ? config.bannerType : 'simple',\n handlers: logger.getHandlers().length,\n bufferSize: config.bufferSize ? config.bufferSize : 1000\n };\n\n logger.group('⚙️ Logger Configuration');\n logger.table(statusData);\n logger.groupEnd();\n }\n}\n\n/**\n * Comando `/reset` del CLI runtime del {@link Logger}. Restaura la\n * configuración a sus defaults de fábrica vía {@link Logger.resetConfig}.\n * No resetea handlers ni transports registrados — solo config.\n *\n * @example\n * // Volver a la configuración por defecto\n * // > /reset\n *\n * @see {@link Logger.resetConfig} para el método subyacente.\n */\nexport class ResetCommand implements ICommand {\n name = 'reset';\n description = 'Reset logger configuration to defaults';\n usage = '/reset';\n\n /**\n * Ejecuta el comando `/reset` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia cuya configuración se resetea.\n */\n execute(_args: string, logger: Logger): void {\n logger.resetConfig();\n }\n}\n\n/**\n * Comando `/demo` del CLI runtime del {@link Logger}. Ejecuta una\n * demostración integral de las capacidades del logger: todos los niveles\n * de log (debug → critical), tablas, timers (`time`/`timeEnd`), SVG inline\n * y mensajes animados. Útil para validar que el styling funciona en un\n * entorno nuevo o tras un cambio de tema.\n *\n * @example\n * // Lanzar la demo completa\n * // > /demo\n *\n * @see {@link Logger} para cada feature individual (`table`, `time`,\n * `logWithSVG`, `logAnimated`, ...).\n */\nexport class DemoCommand implements ICommand {\n name = 'demo';\n description = 'Show comprehensive feature demonstration';\n usage = '/demo';\n\n /**\n * Ejecuta el comando `/demo` contra el logger dado.\n *\n * @param _args - Ignorado (comando sin parámetros).\n * @param logger - Instancia sobre la que se ejecutan los ejemplos.\n */\n execute(_args: string, logger: Logger): void {\n logger.group('🎪 Advanced Logger Demo');\n\n // Basic logging demo\n logger.debug('Debug message with detailed information');\n logger.info('Informational message about system state');\n logger.warn('Warning about deprecated feature');\n logger.error('Error processing user request');\n logger.success('Operation completed successfully');\n logger.critical('Critical system failure detected');\n\n // Advanced features demo\n logger.group('📊 Advanced Features Demo');\n\n // Table demo\n logger.table([\n { feature: 'Styled Console', status: '✅ Active', performance: 'Excellent' },\n { feature: 'Theme System', status: '✅ Active', performance: 'Great' },\n { feature: 'CLI Interface', status: '✅ Active', performance: 'Good' },\n { feature: 'Export System', status: '✅ Active', performance: 'Excellent' }\n ]);\n\n // Timer demo\n logger.time('demo-operation');\n setTimeout(() => {\n logger.timeEnd('demo-operation');\n }, 100);\n\n // SVG demo\n logger.logWithSVG('SVG Demo');\n\n // Animated demo\n logger.logAnimated('🌟 Animated Logger Demo 🌟', 2);\n\n logger.groupEnd();\n logger.groupEnd();\n\n logger.info('Demo completed! Check the console for styled output.');\n }\n}\n","/**\n * @fileoverview Help system del CLI del logger. Expone {@link HelpCommand},\n * que renderiza un panel ASCII con la lista completa de comandos, opciones de\n * configuración, filtros de export y ejemplos de uso.\n */\n\nimport type { ICommand } from './CommandProcessor.js';\nimport type { Logger } from '../Logger.js';\nimport { StyleBuilder } from '../styling/index.js';\n\n/**\n * Comando `/help`: renderiza en consola el panel de ayuda del CLI con todos\n * los comandos disponibles, opciones de configuración, filtros de export y\n * ejemplos. El panel usa un gradient claro con {@link StyleBuilder} y los\n * quick tips se agrupan vía `logger.group`.\n *\n * Registrado por defecto por {@link createDefaultCLI}.\n *\n * @example\n * ```ts\n * const cli = createDefaultCLI();\n * await cli.processCommand('/help', logger);\n * // Imprime el panel ASCII con gradient + grupo \"Quick Tips\".\n * ```\n *\n * @see {@link ICommand}\n * @see {@link createDefaultCLI}\n */\nexport class HelpCommand implements ICommand {\n name = 'help';\n description = 'Show CLI help and available commands';\n usage = '/help [command]';\n\n /**\n * Renderiza el panel de ayuda completo. Actualmente ignora `_args`: el\n * `usage` declara `/help [command]` (sub-comando opcional) pero la\n * implementación siempre muestra el panel global.\n *\n * @param {string} _args - Argumentos opcionales (reservado para ayuda por\n * sub-comando; sin uso actual).\n * @param {Logger} logger - Logger activo; se usa solo para `group`/`info`\n * de los quick tips.\n * @returns {void}\n */\n execute(_args: string, logger: Logger): void {\n const helpStyle = new StyleBuilder()\n .bg('linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)')\n .color('#495057')\n .padding('15px 20px')\n .rounded('8px')\n .border('1px solid #dee2e6')\n .font('Monaco, Consolas, monospace')\n .size('13px')\n .build();\n\n const helpText = `\n╭─────────────── ADVANCED LOGGER CLI COMMANDS ─────────────────╮\n│ │\n│ CONFIGURATION │\n│ /config Show current configuration │\n│ /config {json} Apply JSON configuration │\n│ /config key=val Apply key-value configuration │\n│ /themes Show available themes │\n│ /banners Show available banner types │\n│ /banner [type] Change/show banner type │\n│ /status Show logger status & buffer stats │\n│ /demo Show feature demonstration │\n│ /reset Reset to default configuration │\n│ │\n│ EXPORT & CLIPBOARD │\n│ /export <format> Export logs (json|csv|md|plain|html) │\n│ /copy <format> Copy logs to clipboard │\n│ /buffer-size N Set log buffer size │\n│ /buffer-info Show buffer statistics │\n│ /clear-buffer Clear stored logs │\n│ │\n│ EXPORT FILTERS (for export/copy commands) │\n│ --level error,warn Filter by log levels │\n│ --since 2h Logs from last 2 hours │\n│ --until 1h Logs until 1 hour ago │\n│ --prefix API,DB Filter by prefixes │\n│ --exclude-prefix INT Exclude prefixes │\n│ --last 50 Last 50 logs only │\n│ --first 25 First 25 logs only │\n│ --search \"error\" Search in log messages │\n│ --with-stack Only logs with stack traces │\n│ --errors-only Only error + critical logs │\n│ --group-by level Group by level/prefix/hour │\n│ │\n│ EXPORT OPTIONS │\n│ --minimal Minimal output format │\n│ --compact Remove extra whitespace │\n│ --styled Include styling (HTML format) │\n│ │\n├──────────────────── CONFIGURATION OPTIONS ─────────────────┤\n│ │\n│ theme: default | dark | light | neon | minimal | cyberpunk│\n│ bannerType: simple | ascii | unicode | svg | animated │\n│ verbosity: debug | info | warn | error | critical | silent│\n│ enableColors: true | false │\n│ enableTimestamps: true | false │\n│ enableStackTrace: true | false │\n│ globalPrefix: \"string\" │\n│ bufferSize: number (50-10000) │\n│ │\n├──────────────────────── EXAMPLES ──────────────────────────┤\n│ │\n│ Basic Configuration: │\n│ /config {\"theme\":\"dark\",\"verbosity\":\"debug\"} │\n│ /config theme=neon,bufferSize=2000 │\n│ /banner animated Change to animated banner │\n│ │\n│ Export Examples: │\n│ /export json --level=error,warn --last=25 │\n│ /export csv --since=2h --prefix=API │\n│ /export markdown --group-by=level --errors-only │\n│ /export html --styled --since=1h │\n│ │\n│ Clipboard Examples: │\n│ /copy plain --minimal --last=10 │\n│ /copy json --search=\"authentication\" --compact │\n│ /copy csv --since=30m --exclude-prefix=DEBUG │\n│ │\n│ Buffer Management: │\n│ /buffer-size 5000 Increase buffer to 5000 logs │\n│ /buffer-info Show detailed buffer statistics │\n│ /clear-buffer Clear all stored logs │\n│ │\n│ Time Formats: │\n│ --since=2h 2 hours ago │\n│ --since=30m 30 minutes ago │\n│ --since=1d 1 day ago │\n│ --since=\"2024-01-01T10:00:00Z\" Specific ISO date │\n│ │\n╰─────────────────────────────────────────────────────────────╯`;\n\n console.log(`%c${helpText}`, helpStyle);\n\n // Show quick tips\n logger.group('💡 Quick Tips');\n const tips = [\n 'Use /demo to see all logger features in action',\n 'Logs are automatically stored in a circular buffer for export',\n 'Export formats: JSON (structured), CSV (Excel), Markdown (readable), Plain (simple), HTML (styled)',\n 'Time filters support relative (2h, 30m) and absolute (ISO) formats',\n 'Combine multiple filters: /export json --level=error --since=1h --search=\"auth\"',\n 'Use /copy for quick clipboard access instead of /export'\n ];\n \n tips.forEach(tip => {\n logger.info(`• ${tip}`);\n });\n logger.groupEnd();\n }\n}","/**\n * @fileoverview Punto de entrada del subsistema CLI del logger. Re-exporta el\n * processor, los comandos estándar y expone {@link createDefaultCLI} como\n * factory principal. El CLI no es un binario standalone — se invoca desde\n * código vía `logger.cli()` o desde la devtools vía `window.cli()` (cuando el\n * modo interactivo está activo).\n */\n\n// Core CLI system\nexport { CommandProcessor, type ICommand } from './CommandProcessor.js';\nimport { CommandProcessor } from './CommandProcessor.js';\n\n// Commands\nexport { ConfigCommand } from './commands/ConfigCommand.js';\nexport { ThemesCommand, BannersCommand, BannerCommand } from './commands/ThemeCommand.js';\nexport { StatusCommand, ResetCommand, DemoCommand } from './commands/ExportCommand.js';\n\n// Help system\nexport { HelpCommand } from './help.js';\n\n// Import all commands\nimport { HelpCommand } from './help.js';\nimport { ConfigCommand } from './commands/ConfigCommand.js';\nimport { ThemesCommand, BannersCommand, BannerCommand } from './commands/ThemeCommand.js';\nimport { StatusCommand, ResetCommand, DemoCommand } from './commands/ExportCommand.js';\n\n/**\n * Crea un {@link CommandProcessor} con los 8 comandos estándar ya registrados:\n * `help`, `config`, `themes`, `banners`, `banner`, `status`, `reset` y\n * `demo`. Es el factory canónico — los consumidores normalmente no construyen\n * un `CommandProcessor` vacío a mano, ya que este no trae comandos cargados.\n *\n * @returns {CommandProcessor} Processor listo para usar, sin modo interactivo activo.\n *\n * @example\n * ```ts\n * const cli = createDefaultCLI();\n * await cli.processCommand('/help', logger);\n * await cli.processCommand('/config theme=neon', logger);\n * ```\n *\n * @example\n * ```ts\n * // Modo interactivo en el navegador: expone `window.cli`\n * const cli = createDefaultCLI();\n * cli.enterInteractiveMode(logger);\n * // desde devtools: cli('themes') → procesa '/themes'\n * ```\n *\n * @see {@link CommandProcessor}\n * @see {@link HelpCommand}\n */\nexport function createDefaultCLI(): CommandProcessor {\n const processor = new CommandProcessor();\n\n // Register all default commands\n processor.registerCommand(new HelpCommand());\n processor.registerCommand(new ConfigCommand());\n processor.registerCommand(new ThemesCommand());\n processor.registerCommand(new BannersCommand());\n processor.registerCommand(new BannerCommand());\n processor.registerCommand(new StatusCommand());\n processor.registerCommand(new ResetCommand());\n processor.registerCommand(new DemoCommand());\n\n return processor;\n}","/**\n * @fileoverview TransportBridge — facade de TransportManager.\n * Encapsula el lifecycle de transports: add, remove, flush, close.\n *\n * @internal\n */\n\nimport type { TransportTarget } from '../types/index.js';\nimport { TransportManager } from '../transports/index.js';\n\n/**\n * Resultado de añadir un transport.\n */\nexport interface AddTransportResult {\n /** ID único del transport. */\n id: string;\n /** La instancia de TransportManager (creada al primer add). */\n manager: TransportManager;\n}\n\n/**\n * Bridge para la gestión del lifecycle de transports.\n *\n * @internal\n */\nexport interface TransportBridge {\n /** Añade un transport y devuelve su ID. */\n addTransport(target: TransportTarget): string;\n /** Elimina un transport por ID. Devuelve `true` si se eliminó. */\n removeTransport(id: string): boolean;\n /** Fuerza el flush de todos los buffers de transports. */\n flushTransports(): Promise<void>;\n /** Cierra todos los transports de forma graceful. */\n closeTransports(): Promise<void>;\n /** Devuelve el manager subyacente (o `undefined` si nunca se usó). */\n getTransportManager(): TransportManager | undefined;\n /** Escribe un transport record (fire-and-forget). No-op si el manager no está inicializado. */\n writeRecord(record: Parameters<TransportManager['write']>[0]): void;\n}\n\n/**\n * Crea una instancia de {@link TransportBridge}.\n *\n * @internal\n */\nexport function createTransportBridge(): TransportBridge {\n let transportManager: TransportManager | undefined;\n\n return {\n addTransport(target: TransportTarget): string {\n if (!transportManager) {\n transportManager = new TransportManager();\n }\n return transportManager.add(target);\n },\n\n removeTransport(id: string): boolean {\n return transportManager?.remove(id) ?? false;\n },\n\n async flushTransports(): Promise<void> {\n await transportManager?.flush();\n },\n\n async closeTransports(): Promise<void> {\n await transportManager?.close();\n },\n\n getTransportManager(): TransportManager | undefined {\n return transportManager;\n },\n\n writeRecord(record): void {\n if (!transportManager) return;\n // Fire-and-forget — nunca rompe el sync log path.\n transportManager.write(record).catch(() => {});\n }\n };\n}\n","/**\n * @fileoverview SpanRuntime — runtime de spans del trio API\n * `event` / `span` / `startSpan`.\n *\n * Vive en transports/ porque es la extensión del pipeline de dispatch: los\n * {@link SpanRecord} que produce viajan por el {@link TransportManager} junto\n * a los log records, enrutados por kind (`accepts`).\n *\n * Tres responsabilidades:\n * - **ALS singleton del módulo**: un único `AsyncLocalStorage<SpanRecord>`\n * compartido por TODAS las instancias de Logger — \"qué instancia lleva el\n * span\" es ambiguo con MDC por-instancia, el span activo es una propiedad\n * del call stack, no del logger.\n * - **Generación de ids** conforme a W3C Trace Context (traceId 16 bytes →\n * 32 hex, spanId 8 bytes → 16 hex) vía `crypto.getRandomValues`.\n * - **Leak-safety**: registry de spans abiertos; en flush/shutdown se\n * fuerzan a `end()` con `incomplete: true` y se exportan — nunca se tiran.\n */\n\nimport type { Span, SpanAttributes, SpanRecord } from '../types/index.js';\nimport { resolveAsyncLocalStorage, type AsyncLocalStorageLike } from '../utils/asyncLocalStorage.js';\n\n/**\n * Forma mínima del `AsyncLocalStorage` de `node:async_hooks` que usa el\n * runtime. Undefined en browser sin polyfill.\n */\ntype SpanALS = AsyncLocalStorageLike<SpanRecord>;\n\n/**\n * ALS singleton del módulo — compartido por todas las instancias de Logger.\n *\n * Resolución por capas (global → `process.getBuiltinModule` → `require`,\n * undefined en browser) delegada al helper compartido\n * {@link resolveAsyncLocalStorage} — ver su doc para el detalle de capas.\n * `context/LogContext.ts` usa el mismo helper para su ALS de MDC.\n *\n * Se crea lazy en el primer `runWithActiveSpan`: cargar `node:async_hooks`\n * cuesta ~2,2 MB de RSS en bun, y `getActiveSpan` se consulta en cada\n * dispatch de log — resolverlo al importar se lo cobraría a todo proceso\n * que loguea, use spans o no.\n */\nlet activeSpanStore: SpanALS | undefined;\nlet spanStoreActivated = false;\n\nfunction activateSpanStore(): SpanALS | undefined {\n if (!spanStoreActivated) {\n spanStoreActivated = true;\n activeSpanStore = resolveAsyncLocalStorage<SpanRecord>();\n }\n return activeSpanStore;\n}\n\n/**\n * Span activo en el call stack corriente (dentro de `span(fn)`), si lo hay.\n * Lo consumen la correlación log→span (`TransportRecord.traceId/spanId`) y la\n * resolución de `parentSpanId` en spans hijos.\n *\n * Sin `run()` previo el store estaría vacío igual, así que el guard por\n * flag es observable-identico a consultar el ALS real.\n */\nexport function getActiveSpan(): SpanRecord | undefined {\n if (!spanStoreActivated) return undefined;\n return activeSpanStore?.getStore();\n}\n\n/**\n * Ejecuta `fn` con `record` como span activo. Sin ALS disponible (browser),\n * ejecuta `fn` directamente — sin correlación pero funcional.\n */\nexport function runWithActiveSpan<R>(record: SpanRecord, fn: () => R): R {\n const store = activateSpanStore();\n return store ? store.run(record, fn) : fn();\n}\n\n/** Nanosegundos Unix actuales como string decimal (formato OTLP). */\nexport function nowUnixNano(): string {\n return String(BigInt(Date.now()) * 1_000_000n);\n}\n\n/**\n * Hex aleatorio de `bytes` bytes. Usa `crypto.getRandomValues`; sin\n * `crypto` (runtimes exóticos) degrada a `Math.random` — suficiente para ids\n * de correlación, no para secrets.\n */\nfunction randomHex(bytes: number): string {\n const cryptoObj = (globalThis as { crypto?: { getRandomValues?: (buf: Uint8Array) => Uint8Array } }).crypto;\n if (cryptoObj?.getRandomValues) {\n const buf = new Uint8Array(bytes);\n cryptoObj.getRandomValues(buf);\n let out = '';\n for (const b of buf) {\n out += b.toString(16).padStart(2, '0');\n }\n return out;\n }\n let out = '';\n for (let i = 0; i < bytes * 2; i++) {\n out += Math.floor(Math.random() * 16).toString(16);\n }\n return out;\n}\n\n/** Trace id W3C: 16 bytes → 32 chars hex. */\nexport function generateTraceId(): string {\n return randomHex(16);\n}\n\n/** Span id W3C: 8 bytes → 16 chars hex. */\nexport function generateSpanId(): string {\n return randomHex(8);\n}\n\ninterface OpenSpanEntry {\n record: SpanRecord;\n /** End normal: cierra el span con su duración real. */\n end: () => void;\n /** End forzado por flush: marca `incomplete: true` antes de cerrar. */\n forceEnd: () => void;\n}\n\n/**\n * Registry de spans abiertos (leak-safety). Cubre tanto los de `startSpan()`\n * (externally-ended, el caso del handoff) como los de `span(fn)` en curso:\n * si un flush llega mid-flight, es mejor exportar el span incompleto que\n * tirarlo. El doble-`end()` es no-op, así que el cierre natural posterior no\n * duplica el export.\n */\nconst openSpans = new Map<SpanRecord, OpenSpanEntry>();\n\n/**\n * Crea el record de span y su {@link Span} handle. El handle registra el\n * span en el registry de abiertos; `onEnd` se invoca una única vez, con el\n * record final (duración real o `incomplete: true`), para su export al\n * pipeline de transports.\n *\n * `end()` solo fija `endTimeUnixNano` si no se fijó antes — así los\n * point-spans (`event()`) pueden fijar `end = start` exacto.\n *\n * @param name - Nombre de la operación.\n * @param attributes - Attributes iniciales (copia propia del record).\n * @param scope - Scope del logger emisor.\n * @param onEnd - Callback de export; recibe el record cerrado.\n * @returns El record (para el ALS store) y el handle del span.\n */\nexport function createSpan(\n name: string,\n attributes: SpanAttributes | undefined,\n scope: string,\n onEnd: (record: SpanRecord) => void\n): { record: SpanRecord; span: Span } {\n const parent = getActiveSpan();\n\n const record: SpanRecord = {\n kind: 'span',\n traceId: parent?.traceId ?? generateTraceId(),\n spanId: generateSpanId(),\n parentSpanId: parent?.spanId,\n name,\n spanKind: 1,\n startTimeUnixNano: nowUnixNano(),\n endTimeUnixNano: '0',\n attributes: { ...(attributes ?? {}) },\n scope\n };\n\n let ended = false;\n\n const finish = (): void => {\n if (ended) return;\n ended = true;\n openSpans.delete(record);\n onEnd(record);\n };\n\n openSpans.set(record, {\n record,\n end: finish,\n forceEnd: (): void => {\n if (ended) return;\n record.incomplete = true;\n if (record.endTimeUnixNano === '0') {\n record.endTimeUnixNano = nowUnixNano();\n }\n finish();\n }\n });\n\n const handle: Span = {\n traceId: record.traceId,\n spanId: record.spanId,\n set(key: string, value: string | number | boolean): Span {\n record.attributes[key] = value;\n return handle;\n },\n end(attributes?: SpanAttributes): void {\n if (attributes) {\n Object.assign(record.attributes, attributes);\n }\n if (ended) return;\n if (record.endTimeUnixNano === '0') {\n record.endTimeUnixNano = nowUnixNano();\n }\n finish();\n },\n fail(err: unknown): void {\n if (ended) return;\n record.status = {\n code: 2,\n message: err instanceof Error ? err.message : String(err)\n };\n this.end();\n }\n };\n\n return { record, span: handle };\n}\n\n/**\n * Emite un point-span (`event()`): start = end exactamente, sin registro en\n * abiertos tras el cierre — no hay leak posible. El `parentSpanId` se resuelve\n * contra el span activo si existe, pero NO fija contexto ALS.\n */\nexport function emitEventSpan(\n name: string,\n attributes: SpanAttributes | undefined,\n scope: string,\n onEnd: (record: SpanRecord) => void\n): void {\n const { record, span } = createSpan(name, attributes, scope, onEnd);\n record.endTimeUnixNano = record.startTimeUnixNano;\n span.end();\n}\n\n/**\n * Fuerza el cierre de todos los spans abiertos (`incomplete: true`) y los\n * exporta vía el `onEnd` de cada uno. Lo invocan `flushTransports()` /\n * `closeTransports()` / `cleanup()` ANTES del flush real — un span abierto\n * nunca se tira en shutdown.\n *\n * @returns Los records forzados a cerrar (para diagnóstico/tests).\n */\nexport function forceCloseOpenSpans(): SpanRecord[] {\n // Snapshot: forceEnd muta el Map durante la iteración.\n const snapshot = [...openSpans.values()];\n for (const entry of snapshot) {\n entry.forceEnd();\n }\n return snapshot.map(entry => entry.record);\n}\n\n/** Número de spans actualmente abiertos (expuesto para tests/diagnóstico). */\nexport function openSpanCount(): number {\n return openSpans.size;\n}\n","/**\n * @fileoverview TerminalBridge — integración de terminal CLI.\n * Encapsula detección de TTY, renderizado de primitivas CLI y fallback a\n * server-mode para entornos non-TTY.\n *\n * @internal\n */\n\nimport type { CLILogLevel, ISpinnerHandle, IBoxOptions, ITableOptions } from '../types/index.js';\nimport { renderStep } from '../playground/step.js';\nimport { renderHeader } from '../playground/header.js';\nimport { renderDivider } from '../playground/divider.js';\nimport { renderBox } from '../playground/box.js';\nimport { renderTable } from '../playground/cli-table.js';\nimport { SpinnerManager, NoopSpinner } from '../playground/spinner.js';\nimport { ServerFallback } from '../playground/server-fallback.js';\nimport { getColorCapability, isRunningInTerminal } from '../utils/environment-detector.js';\nimport type { LoggerConfig } from '../types/index.js';\nimport type { Logger } from '../Logger.js';\n\n/**\n * Bridge para operaciones de terminal CLI.\n *\n * @internal\n */\nexport interface TerminalBridge {\n /** Muestra un indicador de progreso tipo step. */\n step(current: number, total: number, message: string): void;\n /** Muestra un header con estilo. */\n header(title: string, subtitle?: string): void;\n /** Muestra un divider horizontal. */\n divider(): void;\n /** Emite una línea en blanco. */\n blank(): void;\n /** Renderiza contenido dentro de un box con border. */\n box(content: string, options?: IBoxOptions): void;\n /** Renderiza un array de objetos como tabla ASCII. */\n cliTable(rows: Record<string, unknown>[], options?: ITableOptions): void;\n /** Crea un handle de spinner. */\n spinner(message: string): ISpinnerHandle;\n /** Indica si las primitivas CLI deben mostrarse. */\n getShowPrimitives(): boolean;\n /** Define si las primitivas CLI deben mostrarse. */\n setShowPrimitives(show: boolean): void;\n /** Devuelve la instancia del server fallback (lazy). */\n getServerFallback(): ServerFallback;\n /** Devuelve `true` si se ejecuta en un TTY. */\n isInTerminal(): boolean;\n}\n\ninterface ITerminalBridgeCtorOptions {\n config: LoggerConfig;\n getLogger: () => Logger;\n}\n\n/**\n * Crea un {@link TerminalBridge} usando un getter para evitar referencias\n * circulares en la construcción.\n *\n * @internal\n */\nexport function createTerminalBridge(options: ITerminalBridgeCtorOptions): TerminalBridge {\n let _showPrimitives = true;\n let _serverFallback: ServerFallback | undefined;\n\n return {\n step(current: number, total: number, message: string): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().step(current, total, message);\n return;\n }\n const colorCap = getColorCapability();\n const output = renderStep(current, total, message, colorCap);\n process.stderr.write(output + '\\n');\n },\n\n header(title: string, subtitle?: string): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().header(title, subtitle);\n return;\n }\n const output = renderHeader(title, subtitle);\n process.stderr.write(output + '\\n');\n },\n\n divider(): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().divider();\n return;\n }\n const output = renderDivider();\n process.stderr.write(output + '\\n');\n },\n\n blank(): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().blank();\n return;\n }\n process.stderr.write('\\n');\n },\n\n box(content: string, opts?: IBoxOptions): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().box(content, opts);\n return;\n }\n const colorCap = getColorCapability();\n const output = renderBox(content, opts, colorCap);\n process.stderr.write(output + '\\n');\n },\n\n cliTable(rows: Record<string, unknown>[], opts?: ITableOptions): void {\n if (!_showPrimitives) return;\n if (!isRunningInTerminal()) {\n this.getServerFallback().cliTable(rows, opts);\n return;\n }\n const colorCap = getColorCapability();\n const output = renderTable(rows, opts, colorCap);\n process.stderr.write(output + '\\n');\n },\n\n spinner(message: string): ISpinnerHandle {\n const logger = options.getLogger();\n if (!isRunningInTerminal() || options.config.outputMode === 'silent') {\n return new NoopSpinner(message, logger);\n }\n return new SpinnerManager(message, options.config, logger);\n },\n\n getShowPrimitives(): boolean {\n return _showPrimitives;\n },\n\n setShowPrimitives(show: boolean): void {\n _showPrimitives = show;\n },\n\n getServerFallback(): ServerFallback {\n if (!_serverFallback) {\n _serverFallback = new ServerFallback(options.getLogger());\n }\n return _serverFallback;\n },\n\n isInTerminal(): boolean {\n return isRunningInTerminal();\n }\n };\n}\n","/**\n * @fileoverview Logger avanzado con arquitectura modular y API simplificada\n * \n * Sistema de logging profesional con estilos CSS avanzados, temas adaptativos,\n * badges automáticos, contextos temporales y exportación de datos.\n */\n\n// Type imports\nimport type {\n LogLevel,\n LogTag,\n Verbosity,\n ThemeVariant,\n BannerType,\n LoggerConfig,\n TimerEntry,\n ILogHandler,\n LogMetadata,\n StyleOptions,\n Bindings,\n SerializerFn,\n HookEvent,\n HookCallback,\n MiddlewareFn,\n TransportTarget,\n TransportRecord,\n ILogResourceRef,\n StackInfo,\n LogStyles,\n ILogAttributes,\n LogAttributeValue,\n Span,\n SpanAttributes\n} from './types/index.js';\n\nimport { LOG_LEVELS } from './types/index.js';\nimport {\n LOG_LEVEL_TO_SEVERITY_NUMBER,\n LOG_LEVEL_TO_SEVERITY_TEXT,\n type ILogResource as ITransportLogResource\n} from './types/index.js';\n\n// Enterprise features\nimport { SerializerRegistry } from './serializers/index.js';\nimport { HookManager } from './hooks/index.js';\nimport { TransportManager } from './transports/index.js';\n\n// Utility imports\nimport { parseStackTrace } from './utils/stackTrace.js';\nimport { formatTimestamp } from './utils/timestamps.js';\nimport { createStyledOutput, setupThemeChangeListener } from './utils/output.js';\nimport { getEnvironment, getColorCapability, isRunningInTerminal } from './utils/environment-detector.js';\nimport { formatBadge } from './terminal/formatter.js';\n\n// Styling imports\nimport {\n THEME_PRESETS,\n THEME_BANNERS,\n displayInitBanner,\n StylePresets,\n StyleBuilder\n} from './styling/index.js';\n\n// Smart presets and dynamic scoped loggers\nimport { getSmartPreset, getAvailablePresets, hasPreset } from './styling/SmartPresets.js';\n\n// Scoped loggers (static import for performance)\nimport { ScopedLogger, APILogger, ComponentLogger } from './ScopedLogger.js';\n\n// CLI imports\nimport { createDefaultCLI, type CommandProcessor } from './cli/index.js';\n\n// Constants\nimport { DEFAULT_CONFIG, CLI_LEVEL_MAP } from './constants.js';\n\n// CLI Primitives\nimport type { CLILogLevel, ISpinnerHandle, IBoxOptions, ITableOptions } from './types/index.js';\n\n// Bridge imports\nimport { createLogContext, type LogContext } from './context/LogContext.js';\nimport { createTransportBridge, type TransportBridge } from './transports/TransportBridge.js';\nimport {\n getActiveSpan,\n runWithActiveSpan,\n createSpan,\n emitEventSpan,\n forceCloseOpenSpans\n} from './transports/SpanRuntime.js';\nimport { createHookBridge, type HookBridge } from './hooks/HookBridge.js';\nimport { createSerializerBridge, type SerializerBridge } from './serializers/SerializerBridge.js';\nimport { createTerminalBridge, type TerminalBridge } from './playground/TerminalBridge.js';\nimport { createStyleManager, type StyleManager } from './styles/StyleManager.js';\n\n/**\n * Estilos del tema activo actual\n * @private\n */\nlet LEVEL_STYLES = THEME_PRESETS.default;\n\n/**\n * Clase principal Logger con capacidades avanzadas de logging\n * \n * @class Logger\n * @description Sistema completo de logging con temas, badges, contextos y exportación.\n * Detecta automáticamente el tema claro/oscuro del navegador.\n * \n * @example\n * // Uso básico sin configuración\n * import logger from '@mks2508/better-logger';\n * logger.info('Aplicación iniciada');\n * logger.success('Conexión establecida');\n * \n * @example\n * // Aplicar un preset temático\n * logger.preset('cyberpunk');\n * logger.warn('Advertencia con estilo neón');\n * \n * @example\n * // Logger con scope para componentes\n * const auth = logger.component('Autenticación');\n * auth.info('Usuario intentando login');\n * auth.success('Login exitoso');\n * \n */\nexport class Logger {\n private config: LoggerConfig;\n private scopedPrefix?: string;\n private handlers: ILogHandler[] = [];\n private timers: Map<string, TimerEntry> = new Map();\n private groupDepth: number = 0;\n private cliProcessor?: CommandProcessor;\n private themeChangeListener?: (() => void) | null;\n private badgeList: string[] = [];\n private displaySettings = {\n showTimestamp: true,\n showLocation: true,\n showBadges: true\n };\n\n private serializerBridge: SerializerBridge;\n private hookBridge: HookBridge;\n private logContext: LogContext;\n private transportBridge: TransportBridge;\n /** Fijado por `success()` para que `log()` salte su propio dispatch. */\n private _successTagDispatched = false;\n private styleManager: StyleManager;\n\n /** Controla si las CLI primitives (step, box, header, ...) deben renderizarse. */\n private _showPrimitives = true;\n private terminalBridge: TerminalBridge;\n\n /**\n * Referencia activa al smart-preset (fijada por `preset()`). Tipada como\n * `unknown` para mantener limpia la surface pública; la consume\n * `createStyledOutput`.\n */\n private _activePreset?: unknown;\n /**\n * Nombre del smart-preset activo. Se guarda aparte para que la detección\n * de cambio de tema pueda re-renderizar sin re-ejecutar el body del preset.\n */\n private _activePresetName?: string;\n /**\n * Overrides aplicados por el último `customize()`. Se conservan para que\n * `createStyledOutput` los lea después.\n */\n private _customization?: unknown;\n\n /**\n * Bindings propios de este logger (provenientes de llamadas a `child()`).\n * Source of truth única de la contribución de este logger a la cadena de contexto.\n * @private\n */\n private _bindings: Record<string, unknown> = {};\n\n /**\n * Referencia al record de contexto mergueado del parent en el momento en\n * que se creó este logger. Junto con `_bindings`, forma la cadena de\n * contexto. `undefined` para el logger raíz.\n * @private\n */\n private _parentContextRecord: Record<string, unknown> | undefined;\n\n /**\n * Crea una nueva instancia del Logger\n * \n * @param {Partial<LoggerConfig>} config - Configuración opcional del logger\n * \n * @example\n * // Logger con configuración personalizada\n * const logger = new Logger({\n * theme: 'neon',\n * globalPrefix: 'MiApp',\n * verbosity: 'debug',\n * bufferSize: 1000\n * });\n */\n constructor(config: Partial<LoggerConfig> = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n };\n\n // Enterprise features\n this.serializerBridge = createSerializerBridge();\n this.hookBridge = createHookBridge();\n\n // LogContext bridge\n this.logContext = createLogContext({\n initialResource: this.config.resource,\n childLoggerFactory: (childConfig: Partial<LoggerConfig>): Logger => {\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n return new Logger({ ...this.config, ...childConfig });\n },\n // Captura el contexto mergueado completo del parent en el momento\n // de creación del child, para que los child loggers puedan construir\n // la cadena correctamente.\n getParentContextRecord: () => this._captureMergedContext()\n });\n\n // TransportBridge\n this.transportBridge = createTransportBridge();\n\n // StyleManager bridge\n this.styleManager = createStyleManager();\n\n // TerminalBridge lazy — usa getter para evitar circular ref\n this.terminalBridge = createTerminalBridge({\n config: this.config,\n getLogger: () => this\n });\n\n // CLI processor lazy.\n // Los consumers que usan `logger.cli(...)` pagan el setup en el momento de la llamada.\n this.cliProcessor = createDefaultCLI();\n\n // Set up theme change listener si auto-detection está habilitado\n if (this.config.autoDetectTheme) {\n this.setupAutoThemeDetection();\n }\n }\n\n // ===== PRIVATE HELPER METHODS =====\n \n /**\n * Configura la detección automática de tema con listener de cambios\n * @private\n * @description Detecta automáticamente si el navegador está en modo claro u oscuro\n */\n private setupAutoThemeDetection(): void {\n // Limpia el listener existente si lo hay\n if (this.themeChangeListener) {\n this.themeChangeListener();\n this.themeChangeListener = null;\n }\n\n // Set up nuevo listener\n this.themeChangeListener = setupThemeChangeListener((theme) => {\n // Theme cambió — los logs usarán automáticamente los nuevos colores en la próxima llamada.\n // No hace falta actualizar nada: los colores se resuelven dinámicamente.\n this.debug(`DevTools theme changed to: ${theme}`);\n });\n }\n\n // ===== CONFIGURATION METHODS =====\n\n /**\n * Obtiene la configuración actual del logger\n * \n * @returns {LoggerConfig} Configuración completa actual\n * \n * @example\n * const config = logger.getConfig();\n * console.log('Verbosidad actual:', config.verbosity);\n * console.log('Tema actual:', config.theme);\n * \n */\n getConfig(): LoggerConfig {\n return { ...this.config };\n }\n\n /**\n * Actualiza la configuración del logger\n * \n * @param {Partial<LoggerConfig>} updates - Propiedades a actualizar\n * \n * @example\n * logger.updateConfig({\n * verbosity: 'debug',\n * enableTimestamps: false,\n * theme: 'cyberpunk'\n * });\n * \n */\n updateConfig(updates: Partial<LoggerConfig>): void {\n const previousAutoDetect = this.config.autoDetectTheme;\n this.config = { ...this.config, ...updates };\n \n // Handle de cambios de auto-detection\n if (updates.autoDetectTheme !== undefined && updates.autoDetectTheme !== previousAutoDetect) {\n if (updates.autoDetectTheme) {\n this.setupAutoThemeDetection();\n } else if (this.themeChangeListener) {\n this.themeChangeListener();\n this.themeChangeListener = null;\n }\n }\n }\n\n /**\n * Establece el prefijo global para todos los mensajes de log\n * \n * @param {string} prefix - Prefijo a usar\n * \n * @example\n * logger.setGlobalPrefix('MiApp');\n * logger.info('Iniciado'); // [MiApp] Iniciado\n * \n */\n setGlobalPrefix(prefix: string): void {\n this.config.globalPrefix = prefix;\n }\n\n /**\n * Establece el nivel de verbosidad para filtrar la salida de logs\n * \n * @param {Verbosity} level - Nivel mínimo a mostrar ('debug' | 'info' | 'warn' | 'error' | 'critical' | 'silent')\n * \n * @example\n * logger.setVerbosity('warn'); // Solo muestra warn, error y critical\n * logger.setVerbosity('debug'); // Muestra todos los niveles\n * logger.setVerbosity('silent'); // No muestra nada\n * \n */\n setVerbosity(level: Verbosity): void {\n this.config.verbosity = level;\n }\n\n /**\n * Establece el tema del logger\n * \n * @param {ThemeVariant} theme - Tema a aplicar ('default' | 'dark' | 'light' | 'neon' | 'minimal' | 'cyberpunk')\n * \n * @example\n * logger.setTheme('neon'); // Tema con colores neón\n * logger.setTheme('minimal'); // Tema minimalista\n * logger.setTheme('cyberpunk'); // Tema cyberpunk con efectos\n * \n */\n setTheme(theme: ThemeVariant): void {\n // Primero comprueba si es un smart preset\n if (hasPreset(theme)) {\n this.preset(theme);\n return;\n }\n\n // Fallback al sistema de temas legacy — delega al StyleManager para\n // mantener el LEVEL_STYLES module-level sincronizado con el bridge.\n const applied = this.styleManager.setTheme(theme);\n if (applied) {\n this.config.theme = theme;\n\n // Muestra el banner específico del theme a través del writer\n // centralizado para respetar los outputMode silent/custom.\n const bannersRecord = THEME_BANNERS as Record<string, { simple: string; style: string }>;\n if (theme in bannersRecord) {\n const themeBanner = bannersRecord[theme];\n if (themeBanner) {\n this.writeOutput(`%c${themeBanner.simple}`, 'info', [themeBanner.style], []);\n }\n }\n\n this.success(`Theme changed to: ${theme}`);\n } else {\n this.error(`Invalid theme: ${theme}. Available:`, [...getAvailablePresets(), ...Object.keys(THEME_PRESETS)]);\n }\n }\n\n /**\n * Establece el tipo de banner para mostrar en la inicialización\n * \n * @param {BannerType} bannerType - Tipo de banner ('simple' | 'ascii' | 'unicode' | 'svg' | 'animated')\n * \n * @example\n * logger.setBannerType('ascii'); // Banner con arte ASCII\n * logger.setBannerType('unicode'); // Banner con caracteres Unicode\n * logger.setBannerType('animated'); // Banner con animación\n * \n */\n setBannerType(bannerType: BannerType): void {\n this.config.bannerType = bannerType;\n this.success(`Banner type changed to: ${bannerType}`);\n }\n\n /**\n * Ejecuta `fn` dentro de un scope AsyncLocalStorage donde `bindings` se\n * merguean al contexto para todas las llamadas de log dentro de `fn`.\n *\n * Sin `fn` (el shape legacy de setter): no-op por backwards compatibility.\n * Preferir `child()` para bindings persistentes o `withContextAsync()`\n * para callbacks async.\n *\n * @param bindings - Pares key-value a adjuntar durante la ejecución de `fn`\n * @param fn - Función sincrónica opcional a ejecutar con los bindings en scope\n * @returns El valor de retorno de `fn`, o `undefined` si no se pasa `fn`\n *\n * @example\n * // Callback sincrónico scoped\n * logger.withContext({ requestId: 'r-42' }, () => {\n * doWork(); // los logs de aquí ven requestId en attributes\n * });\n *\n * @example\n * // Binding persistente: usar child()\n * const reqLog = logger.child({ requestId: 'r-42' });\n * reqLog.info('handling request'); // attributes incluye requestId\n *\n * @see {@link child} para una copia inmutable con el contexto mergueado\n * @see {@link withContextAsync} para la variante con callback async\n */\n withContext<R>(bindings: Record<string, unknown>, fn?: () => R): R | undefined {\n return this.logContext.withContext(bindings, fn);\n }\n\n /**\n * Variante async de `withContext`. Ejecuta `fn` dentro de un scope\n * AsyncLocalStorage para que los bindings estén disponibles a todas las\n * llamadas de log async dentro de `fn`.\n *\n * @param bindings - Pares key-value a adjuntar durante la ejecución de `fn`\n * @param fn - Función async a ejecutar con los bindings en scope\n * @returns El valor de retorno de `fn`\n *\n * @example\n * await logger.withContextAsync({ requestId: 'r-42' }, async () => {\n * await fetchData(); // los logs de aquí ven requestId en attributes\n * });\n *\n * @see {@link child} para un child logger persistente\n * @see {@link withContext} para la variante con callback sincrónico\n */\n withContextAsync<R>(bindings: Record<string, unknown>, fn: () => Promise<R>): Promise<R> {\n return this.logContext.withContextAsync(bindings, fn);\n }\n\n /**\n * Devuelve una copia inmutable de este logger con el contexto extra bound.\n * Las llamadas futuras sobre el child emiten con el contexto mergueado,\n * sin mutar al parent — el patrón canónico de MDC.\n *\n * @param extra - Pares key-value a adjuntar (requestId, userId, ...)\n * @returns Un nuevo Logger con el contexto mergueado\n *\n * @example\n * const reqLog = logger.child({ requestId: req.id });\n * reqLog.info('start'); // emite attributes: { requestId }\n * logger.info('unrelated'); // NO afectado — el contexto del parent queda intacto\n *\n */\n child(extra: Record<string, unknown>): Logger {\n // LogContext.child() crea el child Logger vía factory y captura el\n // snapshot de _getContextRecord() del parent (contexto parent + ALS)\n // en __parentSnapshot sobre el child. Aquí lo recogemos y lo\n // asignamos a _parentContextRecord, y luego fijamos los _bindings del child.\n const childLogger = this.logContext.child(extra) as unknown as Logger;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const snapshot = (childLogger as any)['__parentSnapshot'] as Record<string, unknown> | undefined;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (childLogger as any)._parentContextRecord = snapshot ?? {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (childLogger as any)._bindings = extra;\n return childLogger;\n }\n\n /**\n * Descarta todas las keys del contexto bound. Tras esta llamada, los\n * records emitidos dejan de llevar `attributes` hasta que\n * {@link withContext} o {@link child} restablezcan uno.\n *\n * @returns La misma instancia del logger, ahora sin contexto\n */\n clearContext(): this {\n this.logContext.clearContext();\n return this;\n }\n\n /**\n * Snapshot del contexto bound. El objeto devuelto es una shallow copy:\n * mutarlo NO afecta lo que emiten las llamadas de log posteriores.\n *\n * @returns Un snapshot read-only del contexto actual\n */\n getContext(): Readonly<Record<string, unknown>> {\n // Devuelve la cadena de contexto (snapshot del parent + bindings propios),\n // SIN incluir el scope ALS (que es transitorio). Esto replica lo que usa\n // dispatchToTransports para attributes, pero sin el overlay de ALS.\n let merged: Record<string, unknown> = this._parentContextRecord ?? {};\n if (this._bindings && Object.keys(this._bindings).length > 0) {\n merged = { ...merged, ...this._bindings };\n }\n return merged;\n }\n\n /**\n * Actualiza el resource OTel por defecto (service.name, version, env).\n * Se persiste en el campo `resource` de cada record emitido, salvo que\n * el propio record lo override.\n *\n * @param resource - Resource OTel parcial a merguear con el actual\n * @returns La misma instancia del logger, para chaining\n *\n * @example\n * logger.setResource({ 'service.name': 'api', 'service.version': '1.2.3' });\n *\n */\n setResource(resource: Partial<ILogResourceRef>): this {\n this.logContext.setResource(resource);\n return this;\n return this;\n }\n\n /**\n * Reinicia el logger a la configuración por defecto\n * \n * @example\n * logger.resetConfig();\n * // Todo vuelve a la configuración inicial\n * \n */\n resetConfig(): void {\n // Clean up del theme listener\n if (this.themeChangeListener) {\n this.themeChangeListener();\n this.themeChangeListener = null;\n }\n\n this.config = { ...DEFAULT_CONFIG };\n this.styleManager.resetStyles();\n\n // Re-setup auto theme detection si está habilitado en la config por defecto\n if (this.config.autoDetectTheme) {\n this.setupAutoThemeDetection();\n }\n \n this.success('Logger configuration reset to defaults');\n }\n\n /**\n * Método de limpieza para eliminar listeners y liberar recursos.\n *\n * Vacía los transports (drain), limpia timers, suelta la lista de\n * handlers legacy, resetea el group depth y limpia el context.\n * Seguro de invocar múltiples veces.\n *\n * @example\n * // Antes de cerrar la aplicación\n * await logger.cleanup();\n *\n */\n async cleanup(): Promise<void> {\n if (this.themeChangeListener) {\n try {\n this.themeChangeListener();\n } catch {\n // Listener cleanup es best-effort\n }\n this.themeChangeListener = null;\n }\n\n // Drain del queue de transports en cleanup. Los spans aún abiertos se\n // fuerzan a cerrar (incomplete) para no perderlos en el drain.\n forceCloseOpenSpans();\n await this.transportBridge.closeTransports();\n\n // Suelta las refs de handlers para que el GC los pueda recolectar.\n this.handlers.length = 0;\n // Reset del mutable runtime state\n this.timers.clear();\n this.badgeList = [];\n this.logContext.clearContext();\n this.groupDepth = 0;\n }\n\n\n // ===== SIMPLIFIED API =====\n\n /**\n * Aplica un preset inteligente - funciona perfectamente sin configuración\n * \n * @param {string} name - Nombre del preset a aplicar\n * \n * @example\n * // Presets disponibles\n * logger.preset('default'); // Limpio y adaptativo\n * logger.preset('cyberpunk'); // Colores neón, efectos brillantes\n * logger.preset('glassmorphism'); // Efectos de blur modernos\n * logger.preset('minimal'); // Minimalista y elegante\n * logger.preset('debug'); // Modo desarrollo detallado\n * logger.preset('production'); // Enfocado en producción\n * \n */\n preset(name: string): void {\n if (!hasPreset(name)) {\n this.error(`Unknown preset: ${name}. Available presets:`, getAvailablePresets());\n return;\n }\n\n const presetConfig = getSmartPreset(name);\n if (presetConfig) {\n // Aplica la configuración del smart preset\n this.displaySettings.showTimestamp = presetConfig.timestamp?.show ?? true;\n this.displaySettings.showLocation = presetConfig.location?.show ?? true;\n\n // Guarda la config del preset para que la use createStyledOutput\n this._activePreset = presetConfig;\n this._activePresetName = name;\n\n // Solo muestra el mensaje de success en navegador para evitar verbose terminal logs\n if (getEnvironment() === 'browser') {\n this.success(`Applied preset: ${name}`);\n }\n }\n }\n\n /**\n * Lista todos los presets disponibles\n * \n * @returns {string[]} Array con nombres de presets disponibles\n * \n * @example\n * const disponibles = logger.presets();\n * console.log(disponibles); // ['default', 'cyberpunk', 'glassmorphism', ...]\n * \n */\n presets(): string[] {\n return getAvailablePresets();\n }\n\n // ===== TOGGLE METHODS =====\n\n /**\n * Oculta el timestamp en los logs\n * \n * @example\n * logger.hideTimestamp();\n * logger.info('Sin marca de tiempo'); // Sin timestamp visible\n * \n */\n hideTimestamp(): this {\n this.displaySettings.showTimestamp = false;\n return this;\n }\n\n /**\n * Muestra el timestamp en los logs\n * \n * @example\n * logger.showTimestamp();\n * logger.info('Con marca de tiempo'); // [2024-01-15 10:30:45] Con marca de tiempo\n * \n */\n showTimestamp(): this {\n this.displaySettings.showTimestamp = true;\n return this;\n }\n\n /**\n * Oculta la información de ubicación (archivo:línea) en los logs\n * \n * @example\n * logger.hideLocation();\n * logger.debug('Sin ubicación'); // Sin mostrar archivo:línea\n * \n */\n hideLocation(): this {\n this.displaySettings.showLocation = false;\n return this;\n }\n\n /**\n * Muestra la información de ubicación (archivo:línea) en los logs\n * \n * @example\n * logger.showLocation();\n * logger.debug('Con ubicación'); // app.js:42 Con ubicación\n * \n */\n showLocation(): this {\n this.displaySettings.showLocation = true;\n return this;\n }\n\n /**\n * Oculta los badges en los logs\n * \n * @example\n * logger.hideBadges();\n * const api = logger.api('REST');\n * api.info('Sin badges'); // Sin mostrar [API] [REST]\n * \n */\n hideBadges(): this {\n this.displaySettings.showBadges = false;\n return this;\n }\n\n /**\n * Muestra los badges en los logs\n *\n * @example\n * logger.showBadges();\n * const api = logger.api('GraphQL');\n * api.info('Con badges'); // [API] [GraphQL] Con badges\n *\n */\n showBadges(): this {\n this.displaySettings.showBadges = true;\n return this;\n }\n\n /**\n * Establece múltiples badges para los logs\n *\n * @param {string[]} badges - Array de badges a mostrar\n * @returns {this} Logger instance para encadenamiento\n *\n * @example\n * logger.badges(['v3', 'stable']).info('Release publicado');\n * logger.badges(['API', 'v2']).warn('Endpoint deprecado');\n *\n */\n badges(badges: string[]): this {\n this.badgeList = [...badges];\n return this;\n }\n\n /**\n * Añade un badge individual a la lista\n *\n * @param {string} badge - Badge a añadir\n * @returns {this} Logger instance para encadenamiento\n *\n * @example\n * logger.badge('DEBUG').badge('AUTH').info('Token validado');\n *\n */\n badge(badge: string): this {\n if (!this.badgeList.includes(badge)) {\n this.badgeList.push(badge);\n }\n return this;\n }\n\n /**\n * Limpia todos los badges activos\n *\n * @returns {this} Logger instance para encadenamiento\n *\n * @example\n * logger.clearBadges().info('Sin badges');\n *\n */\n clearBadges(): this {\n this.badgeList = [];\n return this;\n }\n\n // ===== SCOPED LOGGERS =====\n\n /**\n * Crea un logger scoped para un componente o módulo del dominio.\n *\n * El `ComponentLogger` resultante prepends un badge `[name]` a cada\n * mensaje y comparte configuración, transports y hooks con el logger\n * padre. Útil para trazar el origen de los logs en apps con muchos\n * módulos (Auth, DB, Cache, ...).\n *\n * @param {string} name - Nombre del componente que aparecerá como badge\n * @returns {ComponentLogger} Logger scoped para el componente\n *\n * @example\n * const auth = logger.component('Auth');\n * auth.info('Validando token'); // [Auth] Validando token\n * auth.success('Token válido');\n *\n * @see {@link api} para loggers de endpoints REST/GraphQL\n * @see {@link scope} para un scope genérico sin badge de componente\n */\n component(name: string): ComponentLogger {\n return new ComponentLogger(this, name);\n }\n\n /**\n * Crea un logger scoped para un endpoint o surface de API.\n *\n * Como `component()` pero con styling orientado a APIs (badge `[API]`\n * por defecto más el nombre del sub-scope). Útil para distinguir\n * tráfico REST vs GraphQL vs WebSocket en los logs.\n *\n * @param {string} name - Nombre de la API o surface (p.ej. `'REST'`, `'GraphQL'`)\n * @returns {APILogger} Logger scoped para la API\n *\n * @example\n * const rest = logger.api('REST');\n * rest.info('GET /users/42'); // [API] [REST] GET /users/42\n *\n * @see {@link component} para loggers de componentes de dominio\n */\n api(name: string): APILogger {\n return new APILogger(this, name);\n }\n\n /**\n * Crea un logger scoped genérico con un prefijo.\n *\n * Variante minimal de `component()` / `api()`: solo aplica un prefijo\n * de scope sin badges ni styling especial. Útil para sub-módulos que\n * no encajan en las categorías de `component`/`api`.\n *\n * @param {string} name - Texto del prefijo de scope\n * @returns {ScopedLogger} Logger con el scope aplicado\n *\n * @example\n * const db = logger.scope('db');\n * db.info('Pool conectado'); // [db] Pool conectado\n *\n * @see {@link component} y {@link api} para variantes con badges\n */\n scope(name: string): ScopedLogger {\n return new ScopedLogger(this, name);\n }\n\n // ===== SIMPLE CUSTOMIZATION =====\n\n /**\n * Personalización simple con configuración mínima\n * \n * @param {Object} overrides - Opciones de personalización\n * @param {Object} overrides.message - Configuración del mensaje\n * @param {Object} overrides.timestamp - Configuración del timestamp\n * @param {Object} overrides.location - Configuración de ubicación\n * @param {Object} overrides.level - Configuración del nivel\n * @param {Object} overrides.prefix - Configuración del prefijo\n * @param {string} overrides.spacing - Espaciado: 'compact' | 'normal' | 'spacious'\n * \n * @example\n * logger.customize({\n * message: { color: '#00ff00', size: '16px' },\n * timestamp: { show: false },\n * spacing: 'compact'\n * });\n * \n */\n customize(overrides: {\n message?: { color?: string; font?: string; size?: string };\n timestamp?: { show?: boolean; color?: string };\n location?: { show?: boolean; color?: string };\n level?: { uppercase?: boolean; style?: string };\n prefix?: { show?: boolean; style?: string };\n spacing?: 'compact' | 'normal' | 'spacious';\n }): void {\n // Aplica los overrides simples\n if (overrides.timestamp?.show !== undefined) {\n this.displaySettings.showTimestamp = overrides.timestamp.show;\n }\n if (overrides.location?.show !== undefined) {\n this.displaySettings.showLocation = overrides.location.show;\n }\n if (overrides.prefix?.show !== undefined) {\n // Se manejará al integrar con el preset system\n }\n\n // Guarda la customization para que la use createStyledOutput\n this._customization = overrides;\n this.success('Customization applied');\n }\n\n // ===== HANDLER MANAGEMENT =====\n\n /**\n * Añade un handler personalizado para extender funcionalidad\n * \n * @param {ILogHandler} handler - Handler que implementa ILogHandler\n *\n * @example\n * // Handler personalizado para enviar logs a servidor\n * logger.addHandler({\n * handle(level, message, args, metadata) {\n * fetch('/logs', { method: 'POST', body: JSON.stringify({ level, message }) });\n * }\n * });\n *\n * @example\n * // Para escribir a archivo, usa `addTransport` con un `FileTransport`\n * logger.addTransport({ target: new FileTransport({ destination: 'app.log' }) });\n *\n */\n addHandler(handler: ILogHandler): void {\n this.handlers.push(handler);\n }\n\n /**\n * Obtiene todos los handlers registrados\n * \n * @returns {ILogHandler[]} Array de handlers activos\n */\n getHandlers(): ILogHandler[] {\n return [...this.handlers];\n }\n\n // ===== SERIALIZERS =====\n\n /**\n * Añade un serializador personalizado para un tipo específico\n *\n * @param type - Constructor del tipo a serializar\n * @param serializer - Función de serialización\n * @param priority - Prioridad (mayor = primero)\n *\n * @example\n * logger.addSerializer(Error, (err) => ({\n * name: err.name,\n * message: err.message,\n * stack: err.stack?.split('\\n').slice(0, 5)\n * }));\n *\n */\n addSerializer<T>(\n type: new (...args: unknown[]) => T,\n serializer: SerializerFn<T>,\n priority?: number\n ): void {\n this.serializerBridge.addSerializer(type, serializer, priority);\n }\n\n /**\n * Elimina un serializador registrado\n *\n * @param type - Constructor del tipo a remover\n * @returns true si se eliminó\n *\n */\n removeSerializer<T>(type: new (...args: unknown[]) => T): boolean {\n return this.serializerBridge.removeSerializer(type);\n }\n\n /**\n * Obtiene el registry de serializadores\n *\n * @returns SerializerRegistry\n */\n getSerializerRegistry(): SerializerRegistry {\n return this.serializerBridge.getSerializerRegistry();\n }\n\n // ===== HOOKS & MIDDLEWARE =====\n\n /**\n * Registra un hook para un evento\n *\n * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'\n * @param callback - Función a ejecutar\n * @param priority - Prioridad (mayor = primero)\n * @returns Función para desregistrar\n *\n * @example\n * const unsubscribe = logger.on('beforeLog', (entry) => {\n * entry.correlationId = getCorrelationId();\n * return entry;\n * });\n *\n */\n on(event: HookEvent, callback: HookCallback, priority?: number): () => void {\n return this.hookBridge.on(event, callback, priority);\n }\n\n /**\n * Registra un hook que se ejecuta solo una vez\n *\n * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'\n * @param callback - Función a ejecutar\n * @param priority - Prioridad (mayor = primero)\n * @returns Función para desregistrar\n *\n */\n once(event: HookEvent, callback: HookCallback, priority?: number): () => void {\n return this.hookBridge.once(event, callback, priority);\n }\n\n /**\n * Elimina un hook registrado\n *\n * @param event - Evento del hook\n * @param callback - Callback a remover\n * @returns true si se eliminó\n *\n */\n off(event: HookEvent, callback: HookCallback): boolean {\n return this.hookBridge.off(event, callback);\n }\n\n /**\n * Añade un middleware al pipeline\n *\n * @param middleware - Función middleware\n * @param priority - Prioridad (mayor = primero)\n * @returns Función para desregistrar\n *\n * @example\n * logger.use((entry, next) => {\n * entry.requestId = asyncLocalStorage.getStore()?.requestId;\n * next();\n * });\n *\n */\n use(middleware: MiddlewareFn, priority?: number): () => void {\n return this.hookBridge.use(middleware, priority);\n }\n\n /**\n * Obtiene el HookManager\n *\n * @returns HookManager\n */\n getHookManager(): HookManager {\n return this.hookBridge.getHookManager();\n }\n\n // ===== TRANSPORTS =====\n\n /**\n * Añade un transport para envío de logs\n *\n * @param target - Configuración del transport\n * @returns ID único del transport\n *\n * @example\n * // File transport\n * logger.addTransport({\n * target: 'file',\n * options: { destination: '/var/log/app.log' }\n * });\n *\n * @example\n * // HTTP transport con batching\n * logger.addTransport({\n * target: 'http',\n * options: {\n * url: 'https://logs.example.com',\n * batchSize: 100,\n * flushInterval: 5000\n * },\n * level: 'warn'\n * });\n *\n */\n addTransport(target: TransportTarget): string {\n return this.transportBridge.addTransport(target);\n }\n\n /**\n * Elimina un transport\n *\n * @param id - ID del transport a remover\n * @returns true si se eliminó\n *\n */\n removeTransport(id: string): boolean {\n return this.transportBridge.removeTransport(id);\n }\n\n /**\n * Fuerza el flush de todos los transports. Antes de flushear, cierra los\n * spans aún abiertos (`incomplete: true`) y los encola para export — un\n * span abierto nunca se tira en un flush.\n *\n * @returns Promise que resuelve cuando todos los buffers están vaciados\n *\n */\n async flushTransports(): Promise<void> {\n forceCloseOpenSpans();\n await this.transportBridge.flushTransports();\n }\n\n /**\n * Cierra todos los transports. Como en {@link flushTransports}, primero\n * fuerza el cierre de los spans abiertos para que viajen en el flush\n * final del close.\n *\n * @returns Promise que resuelve cuando todos están cerrados\n *\n */\n async closeTransports(): Promise<void> {\n forceCloseOpenSpans();\n await this.transportBridge.closeTransports();\n }\n\n /**\n * Obtiene el TransportManager\n *\n * @returns TransportManager o undefined si no hay transports\n */\n getTransportManager(): TransportManager | undefined {\n return this.transportBridge.getTransportManager();\n }\n\n // ===== CORE LOGGING METHODS =====\n\n /**\n * Verifica si un nivel de log debe mostrarse según la verbosidad actual.\n * @private\n * @param {LogLevel} level - Nivel de log a verificar\n * @returns {boolean} True si debe mostrarse, false si no\n */\n private shouldLog(level: LogLevel): boolean {\n if (this.config.verbosity === 'silent') return false;\n return LOG_LEVELS[level] >= LOG_LEVELS[this.config.verbosity as LogLevel];\n }\n\n /**\n * Tag pendiente de inyectar en el siguiente `TransportRecord` emitido\n * por `log()`. Lo fijan `success()` y `logWithBindingsAndTag()` antes\n * de delegar; `log()` lo consume y lo resetea a `undefined`.\n *\n * @internal\n */\n protected _dispatchTag: string | undefined;\n\n /** @internal Expone el contexto base mergueado (sin ALS) a la closure de la child factory de LogContext. */\n _captureMergedContext(): Record<string, unknown> {\n // Devuelve el contexto base sin ALS — ALS es transitorio y no debe\n // quedar baked en _parentContextRecord en el momento de crear el child.\n let merged: Record<string, unknown> = this._parentContextRecord ?? {};\n if (this._bindings && Object.keys(this._bindings).length > 0) {\n merged = { ...merged, ...this._bindings };\n }\n return merged;\n }\n\n /**\n * Construye y despacha un `TransportRecord` al {@link TransportManager}\n * (no-op si no hay transports registrados). Lo comparten todos los\n * caminos de log — `log()`, `success()` y los métodos visuales como\n * `table()` / `group()` / `time()` — para que toda emisión atraviese\n * el mismo pipeline de transports.\n *\n * @protected\n * @param {LogLevel} level - Nivel canónico (trace/debug/info/warn/error/critical)\n * @param {string} message - Mensaje final, post-hook\n * @param {string | undefined} prefix - Prefijo efectivo (global + scope)\n * @param {StackInfo | null} stackInfo - Ubicación del caller, opcional\n * @param {Partial<TransportRecord>} [extra] - Campos extra a mergear en el record\n * (p.ej. `{ tag: 'success' }` o `attributes` adicionales)\n */\n protected dispatchToTransports(\n level: LogLevel,\n message: string,\n prefix: string | undefined,\n stackInfo: StackInfo | null,\n extra?: Partial<TransportRecord>\n ): void {\n const record: TransportRecord = {\n level,\n levelValue: LOG_LEVELS[level],\n severityNumber: LOG_LEVEL_TO_SEVERITY_NUMBER[level],\n severityText: LOG_LEVEL_TO_SEVERITY_TEXT[level],\n time: Date.now(),\n msg: message,\n prefix,\n location: stackInfo\n ? {\n file: stackInfo.file,\n line: stackInfo.line,\n column: stackInfo.column,\n function: stackInfo.function\n }\n : undefined,\n attributes: Object.keys(this.logContext._getContextRecord()).length > 0\n ? toLogAttributes(this.logContext._getContextRecord())\n : undefined,\n resource: this.logContext._getResource()\n ? { ...this.logContext._getResource() } as Partial<ITransportLogResource>\n : undefined,\n ...extra\n };\n\n // Correlación log→span: si hay un span activo en el ALS del módulo,\n // el record hereda su traceId/spanId (los campos ya existían en\n // TransportRecord; ahora se pueblan → correlación gratis en backends).\n const activeSpan = getActiveSpan();\n if (activeSpan && !record.traceId) {\n record.traceId = activeSpan.traceId;\n record.spanId = activeSpan.spanId;\n }\n\n // Fire-and-forget vía bridge — nunca rompe el path de log sincrónico.\n this.transportBridge.writeRecord(record);\n }\n\n /**\n * Obtiene el prefijo efectivo (global + scope)\n * @private\n * @returns {string | undefined} Prefijo combinado o undefined\n */\n private getEffectivePrefix(): string | undefined {\n const parts = [this.config.globalPrefix, this.scopedPrefix].filter(Boolean);\n return parts.length > 0 ? parts.join(':') : undefined;\n }\n\n /**\n * Método central de logging. Espera el hook pipeline `beforeLog`\n * antes de despachar a consola y transports, para que redacciones\n * o enriquecimientos (PII, correlation IDs) se reflejen en el\n * mensaje emitido.\n *\n * Los callers fire-and-forget (p.ej. `logger.info(...)` sin `await`)\n * siguen funcionando: el `Promise<void>` resultante se descarta.\n * Se recomienda `await` cuando los hooks `beforeLog` mutan `message`.\n *\n * El tag opcional (`TransportRecord.tag`) NO se pasa como argumento:\n * se establece vía `_dispatchTag` (ver `success()` y\n * {@link logWithBindingsAndTag}) antes de invocar este método.\n *\n * @protected\n * @param {LogLevel} level - Nivel del log\n * @param {unknown[]} args - Argumentos a loggear (mensaje + datos)\n * @returns {Promise<void>} Promesa que resuelve al completar el dispatch\n *\n */\n protected async log(level: LogLevel, ...args: unknown[]): Promise<void> {\n if (!this.shouldLog(level)) return;\n\n // Comprueba _dispatchTag ANTES de procesar los args para que el tag\n // NO termine en additionalArgs. success() lo fija en vez de pasar\n // 'success' como arg.\n const dispatchTag = this._dispatchTag;\n this._dispatchTag = undefined;\n\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n const prefix = this.getEffectivePrefix();\n const timestamp = formatTimestamp();\n\n const serializedArgs = args.map(arg => this.serializerBridge.getSerializerRegistry().serialize(arg));\n\n let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : '';\n if (this.badgeList.length > 0 && this.displaySettings.showBadges) {\n const badgePrefix = this.badgeList.map(b => `[${b}]`).join('');\n message = badgePrefix + ' ' + message;\n }\n const additionalArgs = serializedArgs.slice(1);\n\n const hookEntry = {\n level,\n message,\n args: serializedArgs,\n timestamp,\n prefix,\n stackInfo: stackInfo ?? undefined\n };\n\n // Await de los hooks beforeLog para que las redacciones / enriquecimientos\n // se reflejen en el mensaje emitido.\n let processed;\n try {\n processed = await this.hookBridge.getHookManager().emit('beforeLog', hookEntry);\n } catch (error) {\n // El Hook manager ya dispara onError por su cuenta; cae a los\n // valores pre-hook para que la llamada de log no se rompa.\n // eslint-disable-next-line no-console\n console.error('HookManager beforeLog failed:', error);\n processed = hookEntry;\n }\n message = processed.message;\n\n const [format, ...styles] = createStyledOutput(\n level,\n this.styleManager.getStyles(),\n prefix,\n message,\n this.displaySettings.showLocation ? stackInfo : null,\n this.config.autoDetectTheme,\n this._activePreset as LogStyles | undefined,\n this._activePresetName\n );\n\n const groupIndent = ' '.repeat(this.groupDepth);\n const finalFormat = groupIndent + format;\n\n this.writeOutput(finalFormat, level, styles, additionalArgs);\n\n const metadata: LogMetadata = {\n timestamp,\n level,\n prefix,\n stackInfo: stackInfo ?? undefined\n };\n\n this.handlers.forEach(handler => {\n try {\n handler.handle(level, message, serializedArgs, metadata);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Log handler failed:', error);\n }\n });\n\n // Si se fijó dispatchTag (por success()), despacha con él.\n if (dispatchTag !== undefined) {\n this.dispatchToTransports(level, message, prefix, stackInfo, { tag: dispatchTag as LogTag });\n } else {\n this.dispatchToTransports(level, message, prefix, stackInfo);\n }\n\n // Fire-and-forget de afterLog — las mutaciones after-side no cambian\n // el mensaje que ya está en pantalla, así que no bloqueamos con él.\n this.hookBridge.getHookManager().emit('afterLog', processed).catch(() => {});\n }\n\n /**\n * Emite un log aplicando bindings (badges, scope) al prefijo del\n * mensaje antes de delegar en {@link Logger.log}.\n *\n * No es API pública de consumo: existe para que `ScopedLogger`\n * (`component()` / `api()` / `scope()`) pueda reutilizar el pipeline\n * central de `log()` sin duplicar la lógica de styling/badges.\n *\n * @internal\n * @param {Bindings} bindings - Bindings de scope (badges, scope name, ...)\n * @param {LogLevel} level - Nivel de log\n * @param {unknown[]} args - Argumentos a loggear\n * @returns {Promise<void>} Promesa del dispatch\n *\n * @see {@link logWithBindingsAndTag} para la variante con `tag`\n */\n logWithBindings(bindings: Bindings, level: LogLevel, ...args: unknown[]): Promise<void> {\n if (!this.shouldLog(level)) return Promise.resolve();\n\n let prefix = '';\n const colorCapability = getColorCapability();\n\n if (bindings.badges?.length) {\n prefix += bindings.badges.map(b => formatBadge(b, 'pill', colorCapability, '#00ff88')).join(' ') + ' ';\n }\n if (bindings.scope) {\n prefix += formatBadge(bindings.scope, 'pill', colorCapability, '#00ffff') + ' ';\n }\n\n if (prefix && args.length > 0) {\n args[0] = prefix + String(args[0]);\n }\n\n return this.log(level, ...args);\n }\n\n /**\n * Como {@link logWithBindings} pero fija `_dispatchTag` antes de\n * delegar, para que `log()` despache el `TransportRecord` con el\n * tag indicado. Lo usa `ScopedLogger.success()` para propagar\n * `tag: 'success'` a través del pipeline normal de `log()`.\n *\n * @internal\n * @param {Bindings} bindings - Bindings de scope (badges, scope name, ...)\n * @param {LogLevel} level - Nivel de log\n * @param {LogTag} tag - Tag a inyectar en el `TransportRecord`\n * @param {unknown[]} args - Argumentos a loggear\n * @returns {Promise<void>} Promesa del dispatch\n */\n logWithBindingsAndTag(bindings: Bindings, level: LogLevel, tag: LogTag, ...args: unknown[]): Promise<void> {\n this._dispatchTag = tag;\n return this.logWithBindings(bindings, level, ...args);\n }\n\n /**\n * Registra mensajes de debug (nivel más verboso junto a `trace`).\n * Pensado para diagnóstico de desarrollo: valores intermedios, flags\n * de control flow, estado interno. Devuelve `Promise<void>`.\n *\n * Filtrado por defecto cuando `verbosity > 'debug'` (ver `setVerbosity`).\n *\n * @param {unknown[]} args - Mensaje + datos a inspeccionar\n * @returns {Promise<void>} Promesa del dispatch\n *\n * @example\n * logger.debug('Estado interno:', { conn, queueSize });\n * logger.debug('Entrando en branch X');\n *\n * @see {@link trace} para diagnósticos aún más granulares\n * @see {@link setVerbosity} para controlar el nivel mínimo visible\n */\n debug(...args: unknown[]): Promise<void> {\n return this.log('debug', ...args);\n }\n\n /**\n * Registra mensajes informativos. El `await` retorna cuando el hook\n * `beforeLog` y el dispatch a transports han terminado.\n *\n * @param args - Mensajes y datos informativos\n *\n * @example\n * logger.info('Servidor iniciado en puerto 3000');\n * await logger.info('Procesando', totalItems, 'elementos'); // espera hooks\n *\n */\n info(...args: unknown[]): Promise<void> {\n return this.log('info', ...args);\n }\n\n /**\n * Registra mensajes de advertencia.\n *\n * @param args - Mensajes de advertencia\n *\n */\n warn(...args: unknown[]): Promise<void> {\n return this.log('warn', ...args);\n }\n\n /**\n * Registra mensajes de error.\n *\n * @param args - Mensaje de error y stack traces\n *\n */\n error(...args: unknown[]): Promise<void> {\n return this.log('error', ...args);\n }\n\n /**\n * Registra mensajes de éxito. Mapeado internamente a nivel `info` con\n * styling de success y `record.tag = 'success'` para que los transports\n * puedan distinguirlo (sin perder info semantics para filtering).\n *\n * @param args - Mensaje + datos adicionales\n *\n * @example\n * logger.success('Base de datos conectada');\n * logger.success('Usuario creado con ID:', userId);\n * logger.success('✓ Tests pasados: 42/42');\n *\n */\n async success(...args: unknown[]): Promise<void> {\n if (!this.shouldLog('info')) return;\n\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n const prefix = this.getEffectivePrefix();\n const timestamp = formatTimestamp();\n const serializedArgs = args.map(arg => this.serializerBridge.getSerializerRegistry().serialize(arg));\n let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : '';\n if (this.badgeList.length > 0 && this.displaySettings.showBadges) {\n const badgePrefix = this.badgeList.map(b => `[${b}]`).join('');\n message = badgePrefix + ' ' + message;\n }\n const additionalArgs = serializedArgs.slice(1);\n\n const hookEntry = {\n level: 'info' as LogLevel,\n message,\n args: serializedArgs,\n timestamp,\n prefix,\n stackInfo: stackInfo ?? undefined\n };\n\n // Await de beforeLog para que las redacciones se propaguen (match con log())\n try {\n const processed = await this.hookBridge.getHookManager().emit('beforeLog', hookEntry);\n message = processed.message;\n } catch {\n // El Hook manager ya disparó onError\n }\n\n const [format, ...styles] = createStyledOutput(\n 'info',\n this.styleManager.getStyles(),\n prefix,\n message,\n this.displaySettings.showLocation ? stackInfo : null,\n this.config.autoDetectTheme,\n this._activePreset as LogStyles | undefined,\n this._activePresetName\n );\n\n const successStyle = this.styleManager.getStyles().success;\n const emoji = successStyle?.emoji ?? '✅';\n const label = successStyle?.label ?? 'SUCCESS';\n const successFormat = format.replace(/ℹ️ INFO/, `${emoji} ${label}`);\n\n const groupIndent = ' '.repeat(this.groupDepth);\n const finalFormat = groupIndent + successFormat;\n\n this.writeOutput(finalFormat, 'info', styles, additionalArgs);\n\n const metadata: LogMetadata = {\n timestamp,\n level: 'info',\n prefix,\n stackInfo: stackInfo ?? undefined\n };\n this.handlers.forEach(handler => {\n try {\n handler.handle('info', message, args, metadata);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Log handler failed:', error);\n }\n });\n\n // Fija _dispatchTag para que log() despache con el tag.\n // 'success' NO se pasa como arg (evita que aparezca en additionalArgs).\n this._dispatchTag = 'success';\n await this.log('info', ...args);\n\n this.hookBridge.getHookManager().emit('afterLog', hookEntry).catch(() => {});\n }\n\n /**\n * Registra información de trace (nivel más bajo, debajo de debug).\n * Alineado con OpenTelemetry `TRACE` severity (1-4).\n *\n * @param args - Datos muy verbosos (entrada/salida de funciones, valores intermedios)\n *\n * @example\n * logger.trace('Entrando en función processData');\n * logger.trace('Variables intermedias:', { a, b, c });\n *\n */\n trace(...args: unknown[]): void {\n this.log('trace', ...args);\n }\n\n /**\n * Registra errores críticos (prioridad más alta).\n *\n * @param args - Errores críticos del sistema\n *\n * @example\n * await logger.critical('Sistema caído - reinicio inmediato requerido');\n *\n */\n critical(...args: unknown[]): Promise<void> {\n return this.log('critical', ...args);\n }\n\n // ===== SPANS / TRACES (trio API) =====\n\n /**\n * Emite un **point-span**: un span con `start = end` para completion\n * signals y eventos puntuales (una operación instantánea, un hito).\n * No registra contexto activo ni puede leakear — se exporta de inmediato.\n *\n * El nombre `event` (y no `trace`) es deliberado: `trace` es un log level\n * (el -1) y está reservado.\n *\n * @param {string} name - Nombre del evento (`job.completed`, `cache.flushed`, ...).\n * @param {SpanAttributes} [attributes] - Attributes del span.\n *\n * @example\n * logger.event('build.finished', { status: 'ok', durationMs: 4200 });\n *\n * @see {@link span} para intervalos con work-block\n * @see {@link startSpan} para intervalos externally-ended\n */\n event(name: string, attributes?: SpanAttributes): void {\n emitEventSpan(name, attributes, this._spanScopeName(), record => {\n this.transportBridge.writeRecord(record);\n });\n }\n\n /**\n * Ejecuta `fn` dentro de un span de intervalo. El span queda **activo en\n * el AsyncLocalStorage del módulo** mientras `fn` corre: los logs emitidos\n * dentro heredan su `traceId`/`spanId`, y los spans hijos lo toman como\n * `parentSpanId`.\n *\n * Al retornar `fn` el span se cierra automáticamente; si `fn` lanza, se\n * marca `status {code: 2}` con el mensaje del error (`fail`) y la\n * excepción se relanza intacta.\n *\n * @typeParam T - Tipo resuelto por `fn`.\n * @param {string} name - Nombre de la operación.\n * @param {(s: Span) => T | Promise<T>} fn - Work-block a medir.\n * @returns {Promise<T>} Lo que resuelve `fn`.\n * @throws {unknown} Relanza cualquier error de `fn` tras marcar el span fallido.\n *\n * @example\n * await logger.span('db.migrate', { target: 'v2' }, async (s) => {\n * await runMigrations();\n * s.set('tables', 14);\n * });\n *\n * @see {@link event} para point-spans\n * @see {@link startSpan} para spans externally-ended (poll/callback)\n */\n span<T>(name: string, fn: (s: Span) => T | Promise<T>): Promise<T>;\n span<T>(name: string, attributes: SpanAttributes, fn: (s: Span) => T | Promise<T>): Promise<T>;\n span<T>(\n name: string,\n fnOrAttributes: ((s: Span) => T | Promise<T>) | SpanAttributes,\n maybeFn?: (s: Span) => T | Promise<T>\n ): Promise<T> {\n const { attributes, fn } = resolveSpanArgs(fnOrAttributes, maybeFn);\n return this._runSpan(name, attributes, this._spanScopeName(), fn);\n }\n\n /**\n * Inicia un span de intervalo **externally-ended**: devuelve el handle y\n * NO fija contexto ALS (el cierre ocurre fuera del bloque léxico — p.ej.\n * un `cli.spawn` que se cierra desde un poll o callback externo).\n *\n * Si el span no se cierra antes de `flushTransports()` / shutdown, el\n * flush lo fuerza a cerrar con `incomplete: true` y lo exporta — nunca\n * se tira.\n *\n * @param {string} name - Nombre de la operación.\n * @param {SpanAttributes} [attributes] - Attributes iniciales.\n * @returns {Span} Handle con `set`/`end`/`fail` y los ids del span.\n *\n * @example\n * const s = logger.startSpan('spawn.build', { cmd: 'make' });\n * proc.on('exit', code => {\n * if (code === 0) s.end({ exitCode: code });\n * else s.fail(new Error(`exit ${code}`));\n * });\n *\n * @see {@link span} para el caso con work-block\n */\n startSpan(name: string, attributes?: SpanAttributes): Span {\n return this._startSpan(name, attributes, this._spanScopeName());\n }\n\n /**\n * Scope por defecto de los spans emitidos por este logger (el\n * `globalPrefix`, o `'root'`).\n * @internal\n */\n _spanScopeName(): string {\n return this.config.globalPrefix || 'root';\n }\n\n /**\n * Emite un point-span con scope explícito. Lo consume\n * {@link ScopedLogger.event}, que pasa su scope compuesto.\n * @internal\n */\n _emitSpanEvent(name: string, attributes: SpanAttributes | undefined, scope: string): void {\n emitEventSpan(name, attributes, scope, record => {\n this.transportBridge.writeRecord(record);\n });\n }\n\n /**\n * Crea un span externally-ended con scope explícito. Lo consume\n * {@link ScopedLogger.startSpan}.\n * @internal\n */\n _startSpan(name: string, attributes: SpanAttributes | undefined, scope: string): Span {\n const { span } = createSpan(name, attributes, scope, record => {\n this.transportBridge.writeRecord(record);\n });\n return span;\n }\n\n /**\n * Corre `fn` dentro de un span activo en el ALS con scope explícito.\n * Lo consume {@link ScopedLogger.span}.\n * @internal\n */\n async _runSpan<T>(\n name: string,\n attributes: SpanAttributes | undefined,\n scope: string,\n fn: (s: Span) => T | Promise<T>\n ): Promise<T> {\n const { record, span } = createSpan(name, attributes, scope, r => {\n this.transportBridge.writeRecord(r);\n });\n try {\n const result = await runWithActiveSpan(record, () => fn(span));\n span.end();\n return result;\n } catch (error) {\n span.fail(error);\n throw error;\n }\n }\n\n // ===== ADVANCED LOGGING FEATURES =====\n\n /**\n * Muestra datos en formato de tabla. Pasa por la pipeline completa\n * (outputMode-respecting writeOutput + transports + hooks).\n *\n * @param data - Array de objetos o matriz\n * @param columns - Columnas específicas a mostrar (opcional)\n *\n * @example\n * logger.table([{ id: 1, nombre: 'Juan' }, { id: 2, nombre: 'María' }]);\n *\n */\n table(data: unknown, columns?: string[]): void {\n if (!this.shouldLog('info')) return;\n const prefix = this.getEffectivePrefix();\n const tableStyle = StylePresets.accent().build();\n\n const headerLabel = `📊 TABLE${prefix ? ` [${prefix}]` : ''}`;\n const format = `%c${headerLabel}`;\n const styles = [tableStyle];\n\n // Emite el header vía el writer centralizado\n this.writeOutput(format, 'info', styles, []);\n\n // console.table no respeta outputMode — pero aún así queremos que\n // los datos fluyan a los transports. Solución: serializa los datos\n // como segundo argumento para que los transports observen un payload estructurado.\n const additionalArgs = [data, ...(columns ? [columns] : [])];\n if (this.config.outputMode !== 'silent') {\n if (columns) {\n console.table(data, columns);\n } else {\n console.table(data);\n }\n }\n\n const message = `table:${Array.isArray(data) ? `${data.length} rows` : 'data'}`;\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', message, prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'table',\n 'logger.data': JSON.stringify(data).slice(0, 4096),\n ...(columns ? { 'logger.columns': columns.join(',') } : {})\n }\n });\n }\n\n /**\n * Inicia un grupo colapsable en la consola. Emite un marker a\n * transports con `attributes.logger.visual = 'groupStart'` para que\n * backends puedan reconstruir la jerarquía.\n *\n * @param label - Etiqueta del grupo\n * @param collapsed - Si el grupo inicia colapsado (default: false)\n *\n * @example\n * logger.group('Procesando usuarios');\n * logger.info('Usuario 1 procesado');\n * logger.groupEnd();\n *\n */\n group(label: string, collapsed: boolean = false): void {\n const groupStyle = new StyleBuilder()\n .bg('linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%)')\n .color('#1565c0')\n .border('1px solid #90caf9')\n .padding('4px 12px')\n .rounded('6px')\n .bold()\n .build();\n\n const format = `%c📁 ${label}`;\n\n if (this.config.outputMode !== 'silent') {\n if (collapsed) {\n console.groupCollapsed(format, groupStyle);\n } else {\n console.group(format, groupStyle);\n }\n }\n\n this.groupDepth++;\n\n // Emite un record sintético de info que marca el boundary del group\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', `group:start:${label}`, prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'groupStart',\n 'logger.group.label': label,\n 'logger.group.collapsed': collapsed,\n 'logger.group.depth': this.groupDepth\n }\n });\n }\n\n /**\n * Finaliza el grupo actual de la consola. Emite un marker a transports\n * simétrico al `group()` start, para que backends puedan cerrar la\n * jerarquía correctamente.\n *\n * @example\n * logger.group('Operaciones');\n * logger.info('Operación 1');\n * logger.groupEnd();\n *\n */\n groupEnd(): void {\n if (this.groupDepth > 0) {\n this.groupDepth--;\n if (this.config.outputMode !== 'silent') {\n console.groupEnd();\n }\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', 'group:end', prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'groupEnd',\n 'logger.group.depth': this.groupDepth\n }\n });\n }\n }\n\n // ===== PERFORMANCE TIMING =====\n\n /**\n * Inicia un temporizador con la etiqueta dada\n * \n * @param {string} label - Etiqueta identificadora del temporizador\n * \n * @example\n * logger.time('proceso-datos');\n * // ... operación costosa ...\n * logger.timeEnd('proceso-datos'); // ⏱️ Timer ended: proceso-datos - 1523.45ms\n * \n */\n time(label: string): void {\n const timer: TimerEntry = {\n label,\n startTime: (typeof performance !== 'undefined' ? performance : Date).now()\n };\n this.timers.set(label, timer);\n\n const timerStyle = StylePresets.warning().build();\n const format = `%c⏱️ Timer started: ${label}`;\n this.writeOutput(format, 'debug', [timerStyle], []);\n }\n\n /**\n * Finaliza un temporizador y muestra el tiempo transcurrido\n *\n * @param {string} label - Etiqueta del temporizador a finalizar\n * @returns {number} Milisegundos transcurridos, o `-1` si no se encuentra el timer\n *\n * @example\n * logger.time('consulta-db');\n * await consultarBaseDatos();\n * const elapsed = logger.timeEnd('consulta-db'); // ⏱️ Timer ended: consulta-db - 234.56ms\n *\n */\n timeEnd(label: string): number {\n const timer = this.timers.get(label);\n if (!timer) {\n this.warn(`Timer '${label}' does not exist`);\n return -1;\n }\n\n const now = (typeof performance !== 'undefined' ? performance : Date).now();\n const elapsed = now - timer.startTime;\n this.timers.delete(label);\n\n const timerStyle = StylePresets.success().build();\n const format = `%c⏱️ Timer ended: ${label} - ${elapsed.toFixed(2)}ms`;\n this.writeOutput(format, 'info', [timerStyle], []);\n\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', `timer:${label}`, prefix, stackInfo, {\n tag: 'success',\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'timer',\n 'logger.timer.label': label,\n 'logger.timer.elapsedMs': elapsed\n }\n });\n\n return elapsed;\n }\n\n // ===== ADVANCED VISUAL FEATURES =====\n\n /**\n * Muestra un banner con el tipo especificado o configurado\n * \n * @param {BannerType} bannerType - Tipo de banner (opcional)\n * \n * @example\n * logger.showBanner('ascii'); // Banner ASCII art\n * logger.showBanner('unicode'); // Banner con caracteres Unicode\n * logger.showBanner('svg'); // Banner con gráfico SVG\n * logger.showBanner(); // Usa el tipo configurado\n * \n */\n showBanner(bannerType?: BannerType): void {\n const effectiveBannerType = bannerType ? bannerType : this.config.bannerType;\n displayInitBanner(effectiveBannerType);\n }\n\n /**\n * Registra mensaje con imagen SVG de fondo\n * \n * @param {string} message - Mensaje a mostrar\n * @param {string} svgContent - Contenido SVG personalizado (opcional)\n * @param {StyleOptions} options - Opciones de estilo (ancho, alto, padding)\n * \n * @example\n * // SVG automático con gradiente\n * logger.logWithSVG('🎆 Bienvenido a Better Logger');\n * \n * @example\n * // SVG personalizado\n * const customSVG = '<svg>...</svg>';\n * logger.logWithSVG('Logo', customSVG, { width: 400, height: 100 });\n * \n */\n logWithSVG(message: string, svgContent?: string, options: StyleOptions = {}): void {\n if (!this.shouldLog('info')) return;\n const { width = 300, height = 60, padding = '30px 150px' } = options;\n\n let svgDataUri = '';\n if (svgContent) {\n const encodedSVG = encodeURIComponent(svgContent);\n svgDataUri = `data:image/svg+xml,${encodedSVG}`;\n } else {\n const defaultSVG = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${width} ${height}'><defs><linearGradient id='grad' x1='0%' y1='0%' x2='100%' y2='0%'><stop offset='0%' style='stop-color:%23667eea'/><stop offset='100%' style='stop-color:%23764ba2'/></linearGradient></defs><rect width='100%' height='100%' fill='url(%23grad)' rx='4'/><text x='${width/2}' y='${height/2 + 5}' text-anchor='middle' fill='white' font-family='monospace' font-size='14' font-weight='bold'>${message}</text></svg>`;\n svgDataUri = `data:image/svg+xml,${encodeURIComponent(defaultSVG)}`;\n }\n\n const svgStyle = new StyleBuilder()\n .bg(`url(\"${svgDataUri}\") no-repeat center center`)\n .padding(padding)\n .color('transparent')\n .rounded('4px')\n .build();\n\n this.writeOutput(`%c${message}`, 'info', [svgStyle], []);\n\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', `svg:${message}`, prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'svg',\n 'logger.svg.width': width,\n 'logger.svg.height': height\n }\n });\n }\n\n /**\n * Registra mensaje con gradiente animado de fondo\n * \n * @param {string} message - Mensaje a animar\n * @param {number} duration - Duración de la animación en segundos (default: 3)\n * \n * @example\n * logger.logAnimated('🌈 Animación en progreso');\n * logger.logAnimated('Cargando...', 5); // Animación de 5 segundos\n * \n */\n logAnimated(message: string, duration: number = 3): void {\n if (!this.shouldLog('info')) return;\n\n // DOM-guard: las animaciones solo tienen sentido en un entorno de navegador real.\n if (typeof document !== 'undefined') {\n if (!document.getElementById('logger-animations')) {\n const style = document.createElement('style');\n style.id = 'logger-animations';\n style.textContent = `\n @keyframes loggerGradient {\n 0% { background-position: 0% 50%; }\n 50% { background-position: 100% 50%; }\n 100% { background-position: 0% 50%; }\n }\n `;\n document.head.appendChild(style);\n }\n }\n\n const animatedStyle = new StyleBuilder()\n .bg('linear-gradient(-45deg, #667eea, #764ba2, #667eea, #764ba2)')\n .css('background-size', '400% 400%')\n .color('#ffffff')\n .padding('12px 20px')\n .rounded('8px')\n .bold()\n .font('Monaco, Consolas, monospace')\n .animation(`loggerGradient ${duration}s ease infinite`)\n .display('inline-block')\n .build();\n\n this.writeOutput(`%c${message}`, 'info', [animatedStyle], []);\n\n const prefix = this.getEffectivePrefix();\n const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;\n this.dispatchToTransports('info', `animated:${message}`, prefix, stackInfo, {\n attributes: {\n ...this.logContext._getContextRecord(),\n 'logger.visual': 'animated',\n 'logger.animation.durationSec': duration\n }\n });\n }\n\n // ===== CLI PRIMITIVES (v5.0) =====\n\n /**\n * Muestra un indicador de progreso de pasos en la terminal\n *\n * @param {number} current - Número de paso actual\n * @param {number} total - Número total de pasos\n * @param {string} message - Descripción del paso\n *\n * @example\n * logger.step(1, 5, 'Analyzing repository...');\n * logger.step(2, 5, 'Generating commit message...');\n *\n */\n step(current: number, total: number, message: string): void {\n this.terminalBridge.step(current, total, message);\n }\n\n /**\n * Muestra un header con estilo y subtítulo opcional\n *\n * @param {string} title - Texto del título principal\n * @param {string} subtitle - Subtítulo opcional (se renderiza atenuado)\n *\n * @example\n * logger.header('Commit Wizard', 'v2.0.0');\n *\n */\n header(title: string, subtitle?: string): void {\n this.terminalBridge.header(title, subtitle);\n }\n\n /**\n * Muestra una línea divisoria horizontal\n *\n * @example\n * logger.divider();\n *\n */\n divider(): void {\n this.terminalBridge.divider();\n }\n\n /**\n * Emite una línea en blanco\n *\n * @example\n * logger.blank();\n *\n */\n blank(): void {\n this.terminalBridge.blank();\n }\n\n /**\n * Renderiza contenido dentro de un box con borde\n *\n * @param {string} content - String de contenido (puede contener newlines)\n * @param {IBoxOptions} options - Opciones de renderizado del box\n *\n * @example\n * logger.box('3 commits generated\\nProvider: Groq', { title: 'Done', borderColor: '#00ff00' });\n *\n */\n box(content: string, options?: IBoxOptions): void {\n this.terminalBridge.box(content, options);\n }\n\n /**\n * Renderiza un array de objetos como una tabla ASCII formateada.\n * Distinto del método `table()` existente, que usa `console.table`.\n *\n * @param {Record<string, unknown>[]} rows - Array de objetos fila\n * @param {ITableOptions} options - Opciones de renderizado de la tabla\n *\n * @example\n * logger.cliTable([\n * { provider: 'Groq', status: 'Available', model: 'llama-3.3-70b' },\n * { provider: 'Gemini', status: 'Configured', model: 'gemini-2.5-flash' },\n * ]);\n *\n */\n cliTable(rows: Record<string, unknown>[], options?: ITableOptions): void {\n this.terminalBridge.cliTable(rows, options);\n }\n\n /**\n * Crea un handle de spinner para mostrar progreso durante operaciones async.\n * Devuelve un `NoopSpinner` en entornos non-TTY.\n *\n * @param {string} message - Texto inicial del spinner\n * @returns {ISpinnerHandle} Controller del spinner\n *\n * @example\n * const s = logger.spinner('Analyzing repository...');\n * s.start();\n * await analyzeRepo();\n * s.succeed('Analysis complete (1.2s)');\n *\n */\n spinner(message: string): ISpinnerHandle {\n return this.terminalBridge.spinner(message);\n }\n\n /**\n * Fija el nivel de verbosidad del CLI, controlando a la vez la verbosidad\n * de logs y la visibilidad de las primitives\n *\n * @param {CLILogLevel} level - Nivel de log del CLI\n *\n * @example\n * logger.setCLILevel('quiet'); // Solo errors, sin CLI primitives\n * logger.setCLILevel('verbose'); // Debug logs + todas las CLI primitives\n *\n */\n setCLILevel(level: CLILogLevel): void {\n const mapping = CLI_LEVEL_MAP[level];\n this.setVerbosity(mapping.verbosity);\n this.terminalBridge.setShowPrimitives(mapping.showPrimitives);\n this.config.cliLevel = level;\n }\n\n /**\n * Devuelve el nivel de log del CLI actual\n * @returns {CLILogLevel} Nivel de log del CLI actual\n */\n get cliLevel(): CLILogLevel {\n return this.config.cliLevel ?? 'normal';\n }\n\n // ===== OUTPUT WRITER SYSTEM =====\n\n /**\n * Escribe output formateado al destino configurado.\n * Respeta la configuración `outputMode` para output a consola, silencioso o custom.\n *\n * @private\n * @param {string} message - Mensaje de log formateado\n * @param {LogLevel} level - Nivel de log\n * @param {string[]} styles - Estilos CSS para la consola del navegador\n * @param {unknown[]} additionalArgs - Argumentos adicionales a loggear\n */\n private writeOutput(\n message: string,\n level: LogLevel,\n styles: string[],\n additionalArgs: unknown[]\n ): void {\n const mode = this.config.outputMode ?? 'console';\n\n // Silent mode: sin output\n if (mode === 'silent') {\n return;\n }\n\n // Custom mode: usa el writer configurado\n if (mode === 'custom' && this.config.outputWriter) {\n const fullMessage = additionalArgs.length > 0\n ? `${message} ${additionalArgs.map(a => String(a)).join(' ')}`\n : message;\n this.config.outputWriter.write(fullMessage, level, styles);\n return;\n }\n\n // Default: output a consola\n if (additionalArgs.length > 0) {\n console.log(message, ...styles, ...additionalArgs);\n } else {\n console.log(message, ...styles);\n }\n }\n\n // ===== CLI SYSTEM =====\n\n /**\n * Procesador de comandos CLI para configuración y exportación del logger\n * \n * @param {string} command - Comando CLI a ejecutar\n * @returns {Promise<void>}\n * \n * @example\n * // Comandos disponibles\n * await logger.cli('export json'); // Exporta logs en JSON\n * await logger.cli('export csv'); // Exporta logs en CSV\n * await logger.cli('theme list'); // Lista temas disponibles\n * await logger.cli('theme set neon'); // Cambia al tema neon\n * await logger.cli('config show'); // Muestra configuración actual\n * await logger.cli('history clear'); // Limpia historial de logs\n * await logger.cli('status'); // Muestra estado del logger\n * await logger.cli('help'); // Muestra ayuda de comandos\n * \n */\n async cli(command: string): Promise<void> {\n if (!this.cliProcessor) {\n this.error('CLI processor not initialized');\n return;\n }\n\n await this.cliProcessor.processCommand(command, this);\n }\n}\n\n/**\n * Instancia singleton lazy — se inicializa en la primera llamada a\n * {@link getDefaultLogger}, no al importar el módulo.\n *\n * @private\n */\nlet _defaultLogger: Logger | null = null;\n\n/**\n * Crea el singleton del Logger por defecto de forma lazy.\n *\n * El singleton se construye solo en la primera llamada, de modo que\n * importar el módulo nunca ejecuta `new Logger(...)` ni\n * `displayInitBanner()`. Así los imports del módulo quedan side-effect free.\n *\n * @returns La instancia compartida de Logger\n */\nfunction getDefaultLogger(): Logger {\n if (!_defaultLogger) {\n _defaultLogger = new Logger({\n verbosity: 'info',\n enableColors: true,\n enableTimestamps: true,\n enableStackTrace: true,\n cliLevel: 'normal'\n });\n\n // Muestra el init banner solo en el primer uso real, no en el import.\n try {\n if (typeof window !== 'undefined' || typeof document !== 'undefined') {\n displayInitBanner();\n }\n } catch {\n // Fail silencioso si no se puede mostrar el banner (SSR, workers, etc.)\n }\n }\n return _defaultLogger;\n}\n\n/**\n * Resetea el singleton por defecto. Limpia la instancia cacheada para que la\n * próxima llamada a `getDefaultLogger()` la reconstruya desde defaults. Útil\n * para tests y escenarios de hot reload.\n *\n */\nexport function resetDefaultLogger(): void {\n if (_defaultLogger) {\n // Cleanup best-effort; el user puede tener ya una referencia y\n // querer drenar logs pendientes a propósito.\n void _defaultLogger.cleanup().catch(() => {});\n }\n _defaultLogger = null;\n}\n\n/**\n * Lazy default export — every property access defers to `getDefaultLogger()`.\n * Sin side-effects al importar el módulo (la primera llamada al singleton\n * se produce en el primer acceso a una propiedad, no en el `import`).\n *\n * @example\n * import logger from 'better-logger';\n * logger.info('hello'); // first call here triggers singleton init\n */\nconst loggerProxy: Logger = new Proxy({} as Logger, {\n get(_target, prop, receiver) {\n const instance = getDefaultLogger();\n const value = Reflect.get(instance, prop, receiver);\n return typeof value === 'function' ? value.bind(instance) : value;\n }\n});\n\nexport default loggerProxy;\n\n// ===== Internal converters =====\n\n/**\n * Estrecha un contexto free-form `Record<string, unknown>` a un bag tipado\n * `ILogAttributes`. Los shapes desconocidos caen a strings JSON-encoded,\n * lo que mantiene conforme al transport OTLP (cada valor cae en un slot tipado).\n *\n * @param input - Contexto suministrado por el usuario (típicamente `Logger.context`).\n * @returns Un nuevo bag de attributes que satisface `ILogAttributes`.\n */\nfunction toLogAttributes(input: Record<string, unknown>): ILogAttributes {\n const out: Record<string, LogAttributeValue> = {};\n for (const [key, value] of Object.entries(input)) {\n const mapped = toAttributeValue(value);\n if (mapped !== undefined) {\n out[key] = mapped;\n }\n }\n return out;\n}\n\nfunction toAttributeValue(value: unknown): LogAttributeValue | undefined {\n if (value === null || value === undefined) return undefined;\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return value;\n }\n if (Array.isArray(value)) {\n const values: LogAttributeValue[] = [];\n for (const item of value) {\n const mapped = toAttributeValue(item);\n if (mapped !== undefined) values.push(mapped);\n }\n return values;\n }\n // Plain objects → fallback a string JSON (el transport OTLP lo maneja)\n try {\n return JSON.stringify(value);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resuelve los argumentos del overload `span(name, fn?)` /\n * `span(name, attributes, fn)` a `{ attributes, fn }`.\n *\n * @internal Compartido con `ScopedLogger.span`; no es API pública.\n */\nexport function resolveSpanArgs<T>(\n fnOrAttributes: ((s: Span) => T | Promise<T>) | SpanAttributes,\n maybeFn?: (s: Span) => T | Promise<T>\n): { attributes: SpanAttributes | undefined; fn: (s: Span) => T | Promise<T> } {\n if (typeof fnOrAttributes === 'function') {\n return { attributes: undefined, fn: fnOrAttributes };\n }\n if (typeof maybeFn === 'function') {\n return { attributes: fnOrAttributes, fn: maybeFn };\n }\n throw new TypeError('span(name, …): se requiere una función fn');\n}\n\n/**\n * Métodos individuales exportados para conveniencia\n * @description Todos los métodos están correctamente enlazados al singleton lazy\n */\nexport const debug = (...args: unknown[]) => getDefaultLogger().debug(...args);\nexport const info = (...args: unknown[]) => getDefaultLogger().info(...args);\nexport const warn = (...args: unknown[]) => getDefaultLogger().warn(...args);\nexport const error = (...args: unknown[]) => getDefaultLogger().error(...args);\nexport const success = (...args: unknown[]) => getDefaultLogger().success(...args);\nexport const trace = (...args: unknown[]) => getDefaultLogger().trace(...args);\nexport const critical = (...args: unknown[]) => getDefaultLogger().critical(...args);\nexport const table = (data: unknown, columns?: string[]) => getDefaultLogger().table(data, columns);\nexport const group = (label: string, collapsed?: boolean) => getDefaultLogger().group(label, collapsed);\nexport const groupEnd = () => getDefaultLogger().groupEnd();\nexport const time = (label: string) => getDefaultLogger().time(label);\nexport const timeEnd = (label: string) => getDefaultLogger().timeEnd(label);\nexport const event = (name: string, attributes?: SpanAttributes): void =>\n getDefaultLogger().event(name, attributes);\nexport const startSpan = (name: string, attributes?: SpanAttributes): Span =>\n getDefaultLogger().startSpan(name, attributes);\nexport function span<T>(name: string, fn: (s: Span) => T | Promise<T>): Promise<T>;\nexport function span<T>(name: string, attributes: SpanAttributes, fn: (s: Span) => T | Promise<T>): Promise<T>;\nexport function span<T>(\n name: string,\n fnOrAttributes: SpanAttributes | ((s: Span) => T | Promise<T>),\n maybeFn?: (s: Span) => T | Promise<T>\n): Promise<T> {\n return getDefaultLogger().span(\n name,\n fnOrAttributes as SpanAttributes,\n maybeFn as (s: Span) => T | Promise<T>\n );\n}\nexport const setGlobalPrefix = (prefix: string) => getDefaultLogger().setGlobalPrefix(prefix);\nexport const setVerbosity = (level: Verbosity) => getDefaultLogger().setVerbosity(level);\nexport const addHandler = (handler: ILogHandler) => getDefaultLogger().addHandler(handler);\nexport const setTheme = (theme: ThemeVariant) => getDefaultLogger().setTheme(theme);\nexport const setBannerType = (bannerType: BannerType) => getDefaultLogger().setBannerType(bannerType);\nexport const showBanner = (bannerType?: BannerType) => getDefaultLogger().showBanner(bannerType);\nexport const logWithSVG = (message: string, svgContent?: string, options?: StyleOptions) =>\n getDefaultLogger().logWithSVG(message, svgContent, options);\nexport const logAnimated = (message: string, duration?: number) =>\n getDefaultLogger().logAnimated(message, duration);\nexport const cli = (command: string) => getDefaultLogger().cli(command);\nexport const cleanup = () => getDefaultLogger().cleanup();\n\n// Simplified API exports\nexport const preset = (name: string) => getDefaultLogger().preset(name);\nexport const presets = () => getDefaultLogger().presets();\nexport const hideTimestamp = () => getDefaultLogger().hideTimestamp();\nexport const showTimestamp = () => getDefaultLogger().showTimestamp();\nexport const hideLocation = () => getDefaultLogger().hideLocation();\nexport const showLocation = () => getDefaultLogger().showLocation();\nexport const hideBadges = () => getDefaultLogger().hideBadges();\nexport const showBadges = () => getDefaultLogger().showBadges();\nexport const badges = (badgeList: string[]) => getDefaultLogger().badges(badgeList);\nexport const badge = (badgeName: string) => getDefaultLogger().badge(badgeName);\nexport const clearBadges = () => getDefaultLogger().clearBadges();\nexport const component = (name: string) => getDefaultLogger().component(name);\nexport const api = (name: string) => getDefaultLogger().api(name);\nexport const scope = (name: string) => getDefaultLogger().scope(name);\nexport const customize = (overrides: Parameters<Logger['customize']>[0]) => getDefaultLogger().customize(overrides);\n\n// Enterprise features exports\nexport const addSerializer = <T>(\n type: new (...args: unknown[]) => T,\n serializer: SerializerFn<T>,\n priority?: number\n) => getDefaultLogger().addSerializer(type, serializer, priority);\nexport const removeSerializer = <T>(type: new (...args: unknown[]) => T) =>\n getDefaultLogger().removeSerializer(type);\nexport const on = (event: HookEvent, callback: HookCallback, priority?: number) =>\n getDefaultLogger().on(event, callback, priority);\nexport const once = (event: HookEvent, callback: HookCallback, priority?: number) =>\n getDefaultLogger().once(event, callback, priority);\nexport const off = (event: HookEvent, callback: HookCallback) =>\n getDefaultLogger().off(event, callback);\nexport const use = (middleware: MiddlewareFn, priority?: number) =>\n getDefaultLogger().use(middleware, priority);\nexport const addTransport = (target: TransportTarget) =>\n getDefaultLogger().addTransport(target);\nexport const removeTransport = (id: string) =>\n getDefaultLogger().removeTransport(id);\nexport const flushTransports = () =>\n getDefaultLogger().flushTransports();\nexport const closeTransports = () =>\n getDefaultLogger().closeTransports();\n\n// Re-export utilities\nexport { StyleBuilder, StylePresets as Styles } from './styling/index.js';\n\n// Re-export enterprise features\nexport { SerializerRegistry } from './serializers/index.js';\nexport { HookManager } from './hooks/index.js';\nexport { TransportManager, ConsoleTransport, FileTransport, HttpTransport } from './transports/index.js';\n","/**\n * @fileoverview Better Logger — default entry point.\n *\n * Re-exports `Logger`, the scoped loggers, subpath-style bridges, and\n * cross-runtime styling/utility helpers. Side-effect free at import.\n */\n\n// Main Logger class with all features\nimport { Logger } from './Logger.js';\nimport type {\n LogLevel,\n Verbosity,\n ThemeVariant,\n BannerType,\n StyleOptions,\n ILogHandler,\n CLILogLevel,\n IBoxOptions,\n ITableOptions,\n Span,\n SpanAttributes,\n} from './types/index.js';\n\n// Lazy singleton - se inicializa solo cuando se necesita\nlet _logger: Logger | null = null;\n\nfunction getLogger(): Logger {\n if (!_logger) {\n _logger = new Logger();\n }\n return _logger;\n}\n\n/**\n * Main `Logger` class — orchestrator for styling, transports, hooks,\n * serializers, MDC, and CLI primitives. Construct directly or use the\n * default singleton below.\n */\nexport { Logger };\n\n/**\n * Default Logger singleton (lazy). Use this for the common case.\n */\nexport default getLogger();\n\n/**\n * Top-level log methods bound to the default singleton.\n */\nexport const debug = (...args: unknown[]) => getLogger().debug(...args);\nexport const info = (...args: unknown[]) => getLogger().info(...args);\nexport const warn = (...args: unknown[]) => getLogger().warn(...args);\nexport const error = (...args: unknown[]) => getLogger().error(...args);\nexport const success = (...args: unknown[]) => getLogger().success(...args);\nexport const critical = (...args: unknown[]) => getLogger().critical(...args);\nexport const trace = (...args: unknown[]) => getLogger().trace(...args);\nexport const table = (data: unknown, columns?: string[]) => getLogger().table(data, columns);\nexport const group = (label: string, collapsed?: boolean) => getLogger().group(label, collapsed);\nexport const groupEnd = () => getLogger().groupEnd();\nexport const time = (label: string) => getLogger().time(label);\nexport const timeEnd = (label: string) => getLogger().timeEnd(label);\nexport const event = (name: string, attributes?: SpanAttributes): void =>\n getLogger().event(name, attributes);\nexport const startSpan = (name: string, attributes?: SpanAttributes): Span =>\n getLogger().startSpan(name, attributes);\nexport function span<T>(name: string, fn: (s: Span) => T | Promise<T>): Promise<T>;\nexport function span<T>(name: string, attributes: SpanAttributes, fn: (s: Span) => T | Promise<T>): Promise<T>;\nexport function span<T>(\n name: string,\n fnOrAttributes: SpanAttributes | ((s: Span) => T | Promise<T>),\n maybeFn?: (s: Span) => T | Promise<T>\n): Promise<T> {\n return getLogger().span(\n name,\n fnOrAttributes as SpanAttributes,\n maybeFn as (s: Span) => T | Promise<T>\n );\n}\nexport const setGlobalPrefix = (prefix: string) => getLogger().setGlobalPrefix(prefix);\nexport const scope = (name: string) => getLogger().scope(name);\nexport const component = (name: string) => getLogger().component(name);\nexport const api = (name: string) => getLogger().api(name);\nexport const badges = (badgeList: string[]) => getLogger().badges(badgeList);\nexport const badge = (badgeName: string) => getLogger().badge(badgeName);\nexport const clearBadges = () => getLogger().clearBadges();\nexport const setVerbosity = (level: Verbosity) => getLogger().setVerbosity(level);\nexport const addHandler = (handler: ILogHandler) => getLogger().addHandler(handler);\nexport const setTheme = (theme: ThemeVariant) => getLogger().setTheme(theme);\nexport const setBannerType = (bannerType: BannerType) => getLogger().setBannerType(bannerType);\nexport const showBanner = (bannerType?: BannerType) => getLogger().showBanner(bannerType);\nexport const logWithSVG = (message: string, svgContent?: string, options?: StyleOptions) =>\n getLogger().logWithSVG(message, svgContent, options);\nexport const logAnimated = (message: string, duration?: number) =>\n getLogger().logAnimated(message, duration);\nexport const cli = (command: string) => getLogger().cli(command);\n\n// Type exports\nexport type {\n LogLevel,\n Verbosity,\n ThemeVariant,\n BannerType,\n StyleOptions,\n ILogHandler,\n LoggerConfig,\n LogMetadata,\n StackInfo,\n TimerEntry,\n TimerResult,\n OutputFormat,\n IScopedLogger,\n IAPILogger,\n IComponentLogger,\n Bindings,\n SerializerFn,\n SerializerContext,\n SerializerConfig,\n ISerializerRegistry,\n HookLogEntry,\n HookEvent,\n HookCallback,\n MiddlewareFn,\n IHookManager,\n TransportRecord,\n TransportOptions,\n TransportTarget,\n ITransport,\n TimestampFormat,\n ColumnAlign,\n ColumnConfig,\n LogOptions,\n CLILogLevel,\n ISpinnerHandle,\n IBoxOptions,\n ITableOptions,\n} from './types/index.js';\n\n// Styling utilities\nexport {\n StyleBuilder,\n StylePresets,\n THEME_PRESETS,\n THEME_BANNERS,\n BANNER_VARIANTS\n} from './styling/index.js';\n\n// Enterprise features — convenience wrappers bound to the singleton.\nimport type { SerializerFn, HookEvent, HookCallback, MiddlewareFn, TransportTarget } from './types/index.js';\nexport const addSerializer = <T>(\n type: new (...args: unknown[]) => T,\n serializer: SerializerFn<T>,\n priority?: number\n) => getLogger().addSerializer(type, serializer, priority);\nexport const removeSerializer = <T>(type: new (...args: unknown[]) => T) =>\n getLogger().removeSerializer(type);\nexport const on = (event: HookEvent, callback: HookCallback, priority?: number) =>\n getLogger().on(event, callback, priority);\nexport const once = (event: HookEvent, callback: HookCallback, priority?: number) =>\n getLogger().once(event, callback, priority);\nexport const off = (event: HookEvent, callback: HookCallback) =>\n getLogger().off(event, callback);\nexport const use = (middleware: MiddlewareFn, priority?: number) =>\n getLogger().use(middleware, priority);\nexport const addTransport = (target: TransportTarget) =>\n getLogger().addTransport(target);\nexport const removeTransport = (id: string) =>\n getLogger().removeTransport(id);\nexport const flushTransports = () =>\n getLogger().flushTransports();\nexport const closeTransports = () =>\n getLogger().closeTransports();\n\n// Scoped loggers\nexport {\n ScopedLogger,\n APILogger,\n ComponentLogger,\n ContextLogger\n} from './ScopedLogger.js';\n\n// Constants\nexport { DEFAULT_CONFIG } from './constants.js';\n\n// Utility exports\nexport {\n parseStackTrace,\n formatTimestamp,\n getConsoleMethod,\n createLogEntry,\n formatTablePlain,\n safeSerialize\n} from './utils/index.js';\n\n// ANSI color utilities\nexport {\n ansiStyle,\n ansiColor,\n ansiBackground,\n ansiBold,\n ansiDim,\n ansiUnderline,\n formatLogLevelANSI,\n formatSuccessANSI\n} from './utils/ansi-colors.js';\n\n// Environment detection\nexport {\n getEnvironment,\n isRunningInTerminal,\n supportsANSI,\n getColorCapability,\n getTerminalWidth,\n getTerminalHeight,\n getEnvironmentInfo,\n} from './utils/environment-detector.js';\n\nexport type { Environment } from './utils/environment-detector.js';\n"],"mappings":"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"}
|