@mks2508/better-logger 0.14.0-alpha.2 → 0.18.2-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (454) hide show
  1. package/README.md +289 -185
  2. package/dist/Logger.d.ts +576 -205
  3. package/dist/Logger.d.ts.map +1 -1
  4. package/dist/ScopedLogger.d.ts +48 -292
  5. package/dist/ScopedLogger.d.ts.map +1 -1
  6. package/dist/chunks/HookBridge-CiRfR67f.cjs +190 -0
  7. package/dist/chunks/HookBridge-CiRfR67f.cjs.map +1 -0
  8. package/dist/chunks/HookBridge-SgMmbXZB.js +173 -0
  9. package/dist/chunks/HookBridge-SgMmbXZB.js.map +1 -0
  10. package/dist/chunks/LogContext-Cwn-1Zzb.js +85 -0
  11. package/dist/chunks/LogContext-Cwn-1Zzb.js.map +1 -0
  12. package/dist/chunks/LogContext-L7HzynFw.cjs +90 -0
  13. package/dist/chunks/LogContext-L7HzynFw.cjs.map +1 -0
  14. package/dist/chunks/SerializerBridge-BaOQOb8q.cjs +166 -0
  15. package/dist/chunks/SerializerBridge-BaOQOb8q.cjs.map +1 -0
  16. package/dist/chunks/SerializerBridge-BkpQu5c9.js +149 -0
  17. package/dist/chunks/SerializerBridge-BkpQu5c9.js.map +1 -0
  18. package/dist/chunks/StyleManager-CIpd6wbO.cjs +92 -0
  19. package/dist/chunks/StyleManager-CIpd6wbO.cjs.map +1 -0
  20. package/dist/chunks/StyleManager-LCvVlVdx.js +87 -0
  21. package/dist/chunks/StyleManager-LCvVlVdx.js.map +1 -0
  22. package/dist/chunks/core-Dzz7agGa.cjs +39 -0
  23. package/dist/chunks/core-Dzz7agGa.cjs.map +1 -0
  24. package/dist/chunks/core-PoT7RrTK.js +34 -0
  25. package/dist/chunks/core-PoT7RrTK.js.map +1 -0
  26. package/dist/chunks/environment-detector-CI3TrWK_.js +110 -0
  27. package/dist/chunks/environment-detector-CI3TrWK_.js.map +1 -0
  28. package/dist/chunks/environment-detector-Cnn6wr6O.cjs +163 -0
  29. package/dist/chunks/environment-detector-Cnn6wr6O.cjs.map +1 -0
  30. package/dist/chunks/server-fallback-BUKjdLS7.cjs +42 -0
  31. package/dist/chunks/server-fallback-BUKjdLS7.cjs.map +1 -0
  32. package/dist/chunks/server-fallback-BsuWH1Dk.js +37 -0
  33. package/dist/chunks/server-fallback-BsuWH1Dk.js.map +1 -0
  34. package/dist/chunks/spinner-D3FsF78o.js +700 -0
  35. package/dist/chunks/spinner-D3FsF78o.js.map +1 -0
  36. package/dist/chunks/spinner-DNvxbM9a.cjs +747 -0
  37. package/dist/chunks/spinner-DNvxbM9a.cjs.map +1 -0
  38. package/dist/chunks/styling-84N8T97t.js +941 -0
  39. package/dist/chunks/styling-84N8T97t.js.map +1 -0
  40. package/dist/chunks/styling-Cg5saQ46.cjs +994 -0
  41. package/dist/chunks/styling-Cg5saQ46.cjs.map +1 -0
  42. package/dist/chunks/transports-BiDk345e.js +715 -0
  43. package/dist/chunks/transports-BiDk345e.js.map +1 -0
  44. package/dist/chunks/transports-COPWmlF1.cjs +756 -0
  45. package/dist/chunks/transports-COPWmlF1.cjs.map +1 -0
  46. package/dist/chunks/utils-BqlFYocD.cjs +698 -0
  47. package/dist/chunks/utils-BqlFYocD.cjs.map +1 -0
  48. package/dist/chunks/utils-VETbVpkR.js +579 -0
  49. package/dist/chunks/utils-VETbVpkR.js.map +1 -0
  50. package/dist/cli/commands/ExportCommand.d.ts +8 -26
  51. package/dist/cli/commands/ExportCommand.d.ts.map +1 -1
  52. package/dist/cli/index.d.ts +1 -2
  53. package/dist/cli/index.d.ts.map +1 -1
  54. package/dist/cli-module.d.ts +13 -0
  55. package/dist/cli-module.d.ts.map +1 -0
  56. package/dist/cli.cjs +11 -0
  57. package/dist/cli.js +3 -0
  58. package/dist/constants.d.ts +16 -47
  59. package/dist/constants.d.ts.map +1 -1
  60. package/dist/context/LogContext.d.ts +146 -0
  61. package/dist/context/LogContext.d.ts.map +1 -0
  62. package/dist/context/index.d.ts +6 -0
  63. package/dist/context/index.d.ts.map +1 -0
  64. package/dist/context-module.d.ts +6 -0
  65. package/dist/context-module.d.ts.map +1 -0
  66. package/dist/context.cjs +3 -0
  67. package/dist/context.js +2 -0
  68. package/dist/core.cjs +281 -2
  69. package/dist/core.cjs.map +1 -1
  70. package/dist/core.d.ts +6 -7
  71. package/dist/core.d.ts.map +1 -1
  72. package/dist/core.js +258 -314
  73. package/dist/core.js.map +1 -1
  74. package/dist/example.d.ts.map +1 -1
  75. package/dist/hooks/HookBridge.d.ts +26 -0
  76. package/dist/hooks/HookBridge.d.ts.map +1 -0
  77. package/dist/hooks/HookManager.d.ts +26 -0
  78. package/dist/hooks/HookManager.d.ts.map +1 -0
  79. package/dist/hooks/index.d.ts +7 -0
  80. package/dist/hooks/index.d.ts.map +1 -0
  81. package/dist/hooks-module.d.ts +7 -0
  82. package/dist/hooks-module.d.ts.map +1 -0
  83. package/dist/hooks.cjs +5 -0
  84. package/dist/hooks.js +2 -0
  85. package/dist/index.cjs +2522 -2
  86. package/dist/index.cjs.map +1 -1
  87. package/dist/index.d.ts +42 -130
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +2447 -158
  90. package/dist/index.js.map +1 -1
  91. package/dist/node-module.d.ts +10 -0
  92. package/dist/node-module.d.ts.map +1 -0
  93. package/dist/node.cjs +13 -0
  94. package/dist/node.cjs.map +1 -0
  95. package/dist/node.js +12 -0
  96. package/dist/node.js.map +1 -0
  97. package/dist/playground/TerminalBridge.d.ts +46 -0
  98. package/dist/playground/TerminalBridge.d.ts.map +1 -0
  99. package/dist/playground/box.d.ts +14 -0
  100. package/dist/playground/box.d.ts.map +1 -0
  101. package/dist/playground/cli-table.d.ts +14 -0
  102. package/dist/playground/cli-table.d.ts.map +1 -0
  103. package/dist/playground/divider.d.ts +10 -0
  104. package/dist/playground/divider.d.ts.map +1 -0
  105. package/dist/playground/header.d.ts +11 -0
  106. package/dist/playground/header.d.ts.map +1 -0
  107. package/dist/playground/index.d.ts +11 -0
  108. package/dist/playground/index.d.ts.map +1 -0
  109. package/dist/playground/server-fallback.d.ts +27 -0
  110. package/dist/playground/server-fallback.d.ts.map +1 -0
  111. package/dist/playground/spinner.d.ts +48 -0
  112. package/dist/playground/spinner.d.ts.map +1 -0
  113. package/dist/playground/step.d.ts +14 -0
  114. package/dist/playground/step.d.ts.map +1 -0
  115. package/dist/playground-module.d.ts +11 -0
  116. package/dist/playground-module.d.ts.map +1 -0
  117. package/dist/playground.cjs +9 -0
  118. package/dist/playground.js +2 -0
  119. package/dist/serializers/SerializerBridge.d.ts +21 -0
  120. package/dist/serializers/SerializerBridge.d.ts.map +1 -0
  121. package/dist/serializers/SerializerRegistry.d.ts +16 -0
  122. package/dist/serializers/SerializerRegistry.d.ts.map +1 -0
  123. package/dist/serializers/index.d.ts +7 -0
  124. package/dist/serializers/index.d.ts.map +1 -0
  125. package/dist/serializers-module.d.ts +7 -0
  126. package/dist/serializers-module.d.ts.map +1 -0
  127. package/dist/serializers.cjs +5 -0
  128. package/dist/serializers.js +2 -0
  129. package/dist/styles/StyleManager.d.ts +83 -0
  130. package/dist/styles/StyleManager.d.ts.map +1 -0
  131. package/dist/styles/index.d.ts +7 -0
  132. package/dist/styles/index.d.ts.map +1 -0
  133. package/dist/styles-module.d.ts +7 -0
  134. package/dist/styles-module.d.ts.map +1 -0
  135. package/dist/styles.cjs +7 -0
  136. package/dist/styles.js +3 -0
  137. package/dist/styling/banners.d.ts +6 -2
  138. package/dist/styling/banners.d.ts.map +1 -1
  139. package/dist/styling/index.d.ts +8 -3
  140. package/dist/styling/index.d.ts.map +1 -1
  141. package/dist/terminal/color-converter.d.ts +73 -0
  142. package/dist/terminal/color-converter.d.ts.map +1 -0
  143. package/dist/terminal/formatter.d.ts +23 -0
  144. package/dist/terminal/formatter.d.ts.map +1 -0
  145. package/dist/transports/ConsoleTransport.d.ts +9 -0
  146. package/dist/transports/ConsoleTransport.d.ts.map +1 -0
  147. package/dist/transports/FileTransport.d.ts +56 -0
  148. package/dist/transports/FileTransport.d.ts.map +1 -0
  149. package/dist/transports/HttpTransport.d.ts +67 -0
  150. package/dist/transports/HttpTransport.d.ts.map +1 -0
  151. package/dist/transports/OtlpTransport.d.ts +148 -0
  152. package/dist/transports/OtlpTransport.d.ts.map +1 -0
  153. package/dist/transports/TransportBridge.d.ts +37 -0
  154. package/dist/transports/TransportBridge.d.ts.map +1 -0
  155. package/dist/transports/TransportManager.d.ts +36 -0
  156. package/dist/transports/TransportManager.d.ts.map +1 -0
  157. package/dist/transports/index.d.ts +6 -0
  158. package/dist/transports/index.d.ts.map +1 -0
  159. package/dist/transports-module.d.ts +10 -0
  160. package/dist/transports-module.d.ts.map +1 -0
  161. package/dist/transports.cjs +7 -0
  162. package/dist/transports.js +2 -0
  163. package/dist/types/core.d.ts +188 -6
  164. package/dist/types/core.d.ts.map +1 -1
  165. package/dist/types/handlers.d.ts +0 -67
  166. package/dist/types/handlers.d.ts.map +1 -1
  167. package/dist/types/hooks.d.ts +60 -0
  168. package/dist/types/hooks.d.ts.map +1 -0
  169. package/dist/types/index.d.ts +7 -3
  170. package/dist/types/index.d.ts.map +1 -1
  171. package/dist/types/serializers.d.ts +25 -0
  172. package/dist/types/serializers.d.ts.map +1 -0
  173. package/dist/types/transports.d.ts +127 -0
  174. package/dist/types/transports.d.ts.map +1 -0
  175. package/dist/utils/ansi-colors.d.ts +115 -0
  176. package/dist/utils/ansi-colors.d.ts.map +1 -0
  177. package/dist/utils/environment-detector.d.ts +53 -0
  178. package/dist/utils/environment-detector.d.ts.map +1 -0
  179. package/dist/utils/formatting.d.ts +1 -0
  180. package/dist/utils/formatting.d.ts.map +1 -1
  181. package/dist/utils/index.d.ts +3 -2
  182. package/dist/utils/index.d.ts.map +1 -1
  183. package/dist/utils/output.d.ts +8 -11
  184. package/dist/utils/output.d.ts.map +1 -1
  185. package/dist/utils/stackTrace.d.ts.map +1 -1
  186. package/dist/utils/timestamps.d.ts +0 -12
  187. package/dist/utils/timestamps.d.ts.map +1 -1
  188. package/package.json +96 -21
  189. package/.claude/settings.local.json +0 -39
  190. package/.github/workflows/ci-quality.yml +0 -357
  191. package/.github/workflows/docs-demo.yml +0 -119
  192. package/.github/workflows/releases-core.yml +0 -512
  193. package/.github/workflows/releases-full.yml +0 -582
  194. package/.github/workflows-backup/ci.yml +0 -221
  195. package/.github/workflows-backup/nightly.yml +0 -196
  196. package/.github/workflows-backup/release-optimized.yml +0 -373
  197. package/.github/workflows-backup/release.yml +0 -269
  198. package/.release-notes-0.2.0.md +0 -129
  199. package/.yamllint +0 -28
  200. package/CHANGELOG.json +0 -865
  201. package/CLAUDE.md +0 -204
  202. package/bun.lock +0 -323
  203. package/demo.html +0 -847
  204. package/dist/.tsbuildinfo +0 -1
  205. package/dist/Logger.js +0 -1124
  206. package/dist/ScopedLogger.js +0 -426
  207. package/dist/chunks/Logger-Crw1woqR.js +0 -3464
  208. package/dist/chunks/Logger-Crw1woqR.js.map +0 -1
  209. package/dist/chunks/Logger-D_p3xnbq.js +0 -2
  210. package/dist/chunks/Logger-D_p3xnbq.js.map +0 -1
  211. package/dist/chunks/RemoteLogHandler-CjWpWZGl.js +0 -33
  212. package/dist/chunks/RemoteLogHandler-CjWpWZGl.js.map +0 -1
  213. package/dist/chunks/RemoteLogHandler-ymkQ97xl.js +0 -2
  214. package/dist/chunks/RemoteLogHandler-ymkQ97xl.js.map +0 -1
  215. package/dist/chunks/environment-Bxbnw4pd.js +0 -544
  216. package/dist/chunks/environment-Bxbnw4pd.js.map +0 -1
  217. package/dist/chunks/environment-Dm66zOML.js +0 -4
  218. package/dist/chunks/environment-Dm66zOML.js.map +0 -1
  219. package/dist/chunks/formatting-C0riPC5_.js +0 -95
  220. package/dist/chunks/formatting-C0riPC5_.js.map +0 -1
  221. package/dist/chunks/formatting-DNCAV66-.js +0 -2
  222. package/dist/chunks/formatting-DNCAV66-.js.map +0 -1
  223. package/dist/cli/CommandProcessor.js +0 -184
  224. package/dist/cli/commands/ConfigCommand.js +0 -88
  225. package/dist/cli/commands/ExportCommand.js +0 -243
  226. package/dist/cli/commands/HistoryCommand.d.ts +0 -50
  227. package/dist/cli/commands/HistoryCommand.d.ts.map +0 -1
  228. package/dist/cli/commands/HistoryCommand.js +0 -96
  229. package/dist/cli/commands/StatusCommand.d.ts +0 -33
  230. package/dist/cli/commands/StatusCommand.d.ts.map +0 -1
  231. package/dist/cli/commands/StatusCommand.js +0 -93
  232. package/dist/cli/commands/ThemeCommand.js +0 -79
  233. package/dist/cli/help.js +0 -118
  234. package/dist/cli/index.js +0 -46
  235. package/dist/constants.js +0 -159
  236. package/dist/example.js +0 -154
  237. package/dist/exports-module.d.ts +0 -203
  238. package/dist/exports-module.d.ts.map +0 -1
  239. package/dist/exports-module.js +0 -260
  240. package/dist/exports.cjs +0 -2
  241. package/dist/exports.cjs.map +0 -1
  242. package/dist/exports.js +0 -238
  243. package/dist/exports.js.map +0 -1
  244. package/dist/handlers/AnalyticsLogHandler.d.ts +0 -11
  245. package/dist/handlers/AnalyticsLogHandler.d.ts.map +0 -1
  246. package/dist/handlers/AnalyticsLogHandler.js +0 -19
  247. package/dist/handlers/ExportLogHandler.d.ts +0 -103
  248. package/dist/handlers/ExportLogHandler.d.ts.map +0 -1
  249. package/dist/handlers/ExportLogHandler.js +0 -516
  250. package/dist/handlers/FileLogHandler.d.ts +0 -36
  251. package/dist/handlers/FileLogHandler.d.ts.map +0 -1
  252. package/dist/handlers/FileLogHandler.js +0 -156
  253. package/dist/handlers/RemoteLogHandler.d.ts +0 -14
  254. package/dist/handlers/RemoteLogHandler.d.ts.map +0 -1
  255. package/dist/handlers/RemoteLogHandler.js +0 -37
  256. package/dist/handlers/index.d.ts +0 -8
  257. package/dist/handlers/index.d.ts.map +0 -1
  258. package/dist/handlers/index.js +0 -7
  259. package/dist/main.js +0 -139
  260. package/dist/styling/LogStyleBuilder.d.ts +0 -149
  261. package/dist/styling/LogStyleBuilder.d.ts.map +0 -1
  262. package/dist/styling/LogStyleBuilder.js +0 -289
  263. package/dist/styling/SemanticStyles.d.ts +0 -181
  264. package/dist/styling/SemanticStyles.d.ts.map +0 -1
  265. package/dist/styling/SemanticStyles.js +0 -339
  266. package/dist/styling/SmartPresets.js +0 -276
  267. package/dist/styling/StyleBuilder.js +0 -280
  268. package/dist/styling/banners.js +0 -155
  269. package/dist/styling/index.js +0 -9
  270. package/dist/styling/themes.js +0 -231
  271. package/dist/styling-module.d.ts +0 -185
  272. package/dist/styling-module.d.ts.map +0 -1
  273. package/dist/styling-module.js +0 -199
  274. package/dist/styling.cjs +0 -2
  275. package/dist/styling.cjs.map +0 -1
  276. package/dist/styling.js +0 -146
  277. package/dist/styling.js.map +0 -1
  278. package/dist/types/Logger.d.ts +0 -700
  279. package/dist/types/Logger.d.ts.map +0 -1
  280. package/dist/types/ScopedLogger.d.ts +0 -310
  281. package/dist/types/ScopedLogger.d.ts.map +0 -1
  282. package/dist/types/cli/CommandProcessor.d.ts +0 -100
  283. package/dist/types/cli/CommandProcessor.d.ts.map +0 -1
  284. package/dist/types/cli/commands/ConfigCommand.d.ts +0 -14
  285. package/dist/types/cli/commands/ConfigCommand.d.ts.map +0 -1
  286. package/dist/types/cli/commands/ExportCommand.d.ts +0 -48
  287. package/dist/types/cli/commands/ExportCommand.d.ts.map +0 -1
  288. package/dist/types/cli/commands/HistoryCommand.d.ts +0 -47
  289. package/dist/types/cli/commands/HistoryCommand.d.ts.map +0 -1
  290. package/dist/types/cli/commands/StatusCommand.d.ts +0 -30
  291. package/dist/types/cli/commands/StatusCommand.d.ts.map +0 -1
  292. package/dist/types/cli/commands/ThemeCommand.d.ts +0 -30
  293. package/dist/types/cli/commands/ThemeCommand.d.ts.map +0 -1
  294. package/dist/types/cli/help.d.ts +0 -12
  295. package/dist/types/cli/help.d.ts.map +0 -1
  296. package/dist/types/cli/index.d.ts +0 -15
  297. package/dist/types/cli/index.d.ts.map +0 -1
  298. package/dist/types/constants.d.ts +0 -119
  299. package/dist/types/constants.d.ts.map +0 -1
  300. package/dist/types/core.js +0 -28
  301. package/dist/types/example.d.ts +0 -18
  302. package/dist/types/example.d.ts.map +0 -1
  303. package/dist/types/exports-module.d.ts +0 -196
  304. package/dist/types/exports-module.d.ts.map +0 -1
  305. package/dist/types/handlers/AnalyticsLogHandler.d.ts +0 -8
  306. package/dist/types/handlers/AnalyticsLogHandler.d.ts.map +0 -1
  307. package/dist/types/handlers/ExportLogHandler.d.ts +0 -100
  308. package/dist/types/handlers/ExportLogHandler.d.ts.map +0 -1
  309. package/dist/types/handlers/FileLogHandler.d.ts +0 -33
  310. package/dist/types/handlers/FileLogHandler.d.ts.map +0 -1
  311. package/dist/types/handlers/RemoteLogHandler.d.ts +0 -11
  312. package/dist/types/handlers/RemoteLogHandler.d.ts.map +0 -1
  313. package/dist/types/handlers/index.d.ts +0 -8
  314. package/dist/types/handlers/index.d.ts.map +0 -1
  315. package/dist/types/handlers.js +0 -4
  316. package/dist/types/index.js +0 -4
  317. package/dist/types/main.d.ts +0 -2
  318. package/dist/types/main.d.ts.map +0 -1
  319. package/dist/types/styling/LogStyleBuilder.d.ts +0 -146
  320. package/dist/types/styling/LogStyleBuilder.d.ts.map +0 -1
  321. package/dist/types/styling/SemanticStyles.d.ts +0 -178
  322. package/dist/types/styling/SemanticStyles.d.ts.map +0 -1
  323. package/dist/types/styling/SmartPresets.d.ts +0 -22
  324. package/dist/types/styling/SmartPresets.d.ts.map +0 -1
  325. package/dist/types/styling/StyleBuilder.d.ts +0 -140
  326. package/dist/types/styling/StyleBuilder.d.ts.map +0 -1
  327. package/dist/types/styling/banners.d.ts +0 -42
  328. package/dist/types/styling/banners.d.ts.map +0 -1
  329. package/dist/types/styling/index.d.ts +0 -10
  330. package/dist/types/styling/index.d.ts.map +0 -1
  331. package/dist/types/styling/themes.d.ts +0 -7
  332. package/dist/types/styling/themes.d.ts.map +0 -1
  333. package/dist/types/styling-module.d.ts +0 -178
  334. package/dist/types/styling-module.d.ts.map +0 -1
  335. package/dist/types/types/core.d.ts +0 -221
  336. package/dist/types/types/core.d.ts.map +0 -1
  337. package/dist/types/types/handlers.d.ts +0 -85
  338. package/dist/types/types/handlers.d.ts.map +0 -1
  339. package/dist/types/types/index.d.ts +0 -7
  340. package/dist/types/types/index.d.ts.map +0 -1
  341. package/dist/types/utils/environment.d.ts +0 -47
  342. package/dist/types/utils/environment.d.ts.map +0 -1
  343. package/dist/types/utils/formatting.d.ts +0 -37
  344. package/dist/types/utils/formatting.d.ts.map +0 -1
  345. package/dist/types/utils/index.d.ts +0 -7
  346. package/dist/types/utils/index.d.ts.map +0 -1
  347. package/dist/types/utils/opentui-detection.d.ts +0 -34
  348. package/dist/types/utils/opentui-detection.d.ts.map +0 -1
  349. package/dist/types/utils/output.d.ts +0 -41
  350. package/dist/types/utils/output.d.ts.map +0 -1
  351. package/dist/types/utils/stackTrace.d.ts +0 -6
  352. package/dist/types/utils/stackTrace.d.ts.map +0 -1
  353. package/dist/types/utils/timestamps.d.ts +0 -20
  354. package/dist/types/utils/timestamps.d.ts.map +0 -1
  355. package/dist/utils/environment.d.ts +0 -47
  356. package/dist/utils/environment.d.ts.map +0 -1
  357. package/dist/utils/environment.js +0 -85
  358. package/dist/utils/formatting.js +0 -117
  359. package/dist/utils/index.js +0 -6
  360. package/dist/utils/opentui-detection.d.ts +0 -34
  361. package/dist/utils/opentui-detection.d.ts.map +0 -1
  362. package/dist/utils/opentui-detection.js +0 -116
  363. package/dist/utils/output.js +0 -150
  364. package/dist/utils/stackTrace.js +0 -81
  365. package/dist/utils/timestamps.js +0 -71
  366. package/dist/vite.svg +0 -1
  367. package/docs/API.md +0 -691
  368. package/docs/CORE.md +0 -264
  369. package/docs/DEVELOPMENT.md +0 -731
  370. package/docs/EXPORTS.md +0 -467
  371. package/docs/PACKAGES.md +0 -244
  372. package/docs/STYLING.md +0 -405
  373. package/docs/_config.yml +0 -36
  374. package/docs/index.md +0 -179
  375. package/examples/README.md +0 -208
  376. package/examples/basic-logging.js +0 -75
  377. package/examples/data-export.js +0 -234
  378. package/examples/package.json +0 -16
  379. package/examples/performance-timing.js +0 -170
  380. package/examples/simplified-api.js +0 -124
  381. package/examples/styling-themes.js +0 -207
  382. package/index.html +0 -358
  383. package/packages/core/package.json +0 -57
  384. package/packages/exports/package.json +0 -41
  385. package/packages/nodejs-opentui/README.md +0 -232
  386. package/packages/nodejs-opentui/package.json +0 -72
  387. package/packages/nodejs-opentui/src/LogRenderer.ts +0 -171
  388. package/packages/nodejs-opentui/src/OpenTUILogHandler.ts +0 -178
  389. package/packages/nodejs-opentui/src/components/LogBadge.tsx +0 -131
  390. package/packages/nodejs-opentui/src/index.ts +0 -133
  391. package/packages/nodejs-opentui/src/types.ts +0 -158
  392. package/packages/nodejs-opentui/tsconfig.json +0 -20
  393. package/packages/styling/package.json +0 -41
  394. package/project-utils/README.md +0 -172
  395. package/project-utils/auto-release-gemini.ts +0 -1193
  396. package/project-utils/auto-release-ui.ts +0 -1329
  397. package/project-utils/commit-generator.ts +0 -1385
  398. package/project-utils/commit-ui.ts +0 -264
  399. package/project-utils/git-utils.ts +0 -199
  400. package/project-utils/github-release-manager.ts +0 -466
  401. package/project-utils/project-config.ts +0 -260
  402. package/project-utils/prompt-templates.js +0 -345
  403. package/project-utils/prompt-templates.ts +0 -422
  404. package/project-utils/version-manager.ts +0 -1078
  405. package/public/vite.svg +0 -1
  406. package/src/Logger.ts +0 -1276
  407. package/src/ScopedLogger.ts +0 -454
  408. package/src/cli/CommandProcessor.ts +0 -248
  409. package/src/cli/commands/ConfigCommand.ts +0 -93
  410. package/src/cli/commands/ExportCommand.ts +0 -276
  411. package/src/cli/commands/HistoryCommand.ts +0 -117
  412. package/src/cli/commands/StatusCommand.ts +0 -112
  413. package/src/cli/commands/ThemeCommand.ts +0 -88
  414. package/src/cli/help.ts +0 -127
  415. package/src/cli/index.ts +0 -71
  416. package/src/constants.ts +0 -171
  417. package/src/core.ts +0 -393
  418. package/src/example.ts +0 -210
  419. package/src/exports-module.ts +0 -311
  420. package/src/handlers/AnalyticsLogHandler.ts +0 -22
  421. package/src/handlers/ExportLogHandler.ts +0 -609
  422. package/src/handlers/FileLogHandler.ts +0 -169
  423. package/src/handlers/RemoteLogHandler.ts +0 -42
  424. package/src/handlers/index.ts +0 -8
  425. package/src/index.ts +0 -209
  426. package/src/main.ts +0 -196
  427. package/src/style.css +0 -96
  428. package/src/styling/LogStyleBuilder.ts +0 -355
  429. package/src/styling/SemanticStyles.ts +0 -380
  430. package/src/styling/SmartPresets.ts +0 -288
  431. package/src/styling/StyleBuilder.ts +0 -319
  432. package/src/styling/banners.ts +0 -168
  433. package/src/styling/index.ts +0 -27
  434. package/src/styling/themes.ts +0 -235
  435. package/src/styling-module.ts +0 -244
  436. package/src/types/core.ts +0 -236
  437. package/src/types/handlers.ts +0 -95
  438. package/src/types/index.ts +0 -35
  439. package/src/typescript.svg +0 -1
  440. package/src/utils/environment.ts +0 -94
  441. package/src/utils/formatting.ts +0 -142
  442. package/src/utils/index.ts +0 -21
  443. package/src/utils/opentui-detection.ts +0 -138
  444. package/src/utils/output.ts +0 -185
  445. package/src/utils/stackTrace.ts +0 -95
  446. package/src/utils/timestamps.ts +0 -80
  447. package/src/vite-env.d.ts +0 -1
  448. package/test-core-browser.html +0 -237
  449. package/test-core-node.js +0 -63
  450. package/tests/test-conflict-resolution.ts +0 -391
  451. package/tests/validate-workflows.sh +0 -131
  452. package/tests/yaml-autofix.sh +0 -146
  453. package/tsconfig.json +0 -50
  454. package/vite.config.ts +0 -223
package/dist/index.js CHANGED
@@ -1,160 +1,2449 @@
1
+ import { t as LOG_LEVELS } from "./chunks/core-PoT7RrTK.js";
2
+ import { o as LOG_LEVEL_TO_SEVERITY_NUMBER, s as LOG_LEVEL_TO_SEVERITY_TEXT, t as TransportManager } from "./chunks/transports-BiDk345e.js";
3
+ import { _ as DEFAULT_CONFIG, a as safeSerialize, b as parseStackTrace, c as ansiBackground, d as ansiDim, f as ansiStyle, g as CLI_LEVEL_MAP, h as formatSuccessANSI, i as getConsoleMethod, l as ansiBold, m as formatLogLevelANSI, o as createStyledOutput, p as ansiUnderline, r as formatTablePlain, s as setupThemeChangeListener, t as createLogEntry, u as ansiColor, y as formatTimestamp } from "./chunks/utils-VETbVpkR.js";
4
+ import { a as THEME_BANNERS, c as StyleBuilder, i as BANNER_VARIANTS, l as StylePresets, n as getSmartPreset, o as displayInitBanner, r as hasPreset, s as THEME_PRESETS, t as getAvailablePresets } from "./chunks/styling-84N8T97t.js";
5
+ import { a as getTerminalWidth, c as isRunningInTerminal, i as getTerminalHeight, l as supportsANSI, n as getEnvironment, r as getEnvironmentInfo, t as getColorCapability } from "./chunks/environment-detector-CI3TrWK_.js";
6
+ import { a as renderDivider, c as formatBadge, i as renderBox, n as SpinnerManager, o as renderHeader, r as renderTable, s as renderStep, t as NoopSpinner } from "./chunks/spinner-D3FsF78o.js";
7
+ import { t as createLogContext } from "./chunks/LogContext-Cwn-1Zzb.js";
8
+ import { t as createHookBridge } from "./chunks/HookBridge-SgMmbXZB.js";
9
+ import { t as createSerializerBridge } from "./chunks/SerializerBridge-BkpQu5c9.js";
10
+ import { t as ServerFallback } from "./chunks/server-fallback-BsuWH1Dk.js";
11
+ import { t as createStyleManager } from "./chunks/StyleManager-LCvVlVdx.js";
12
+ //#region src/ScopedLogger.ts
13
+ var ScopedLogger = class {
14
+ parent;
15
+ scopeName;
16
+ badgeList = [];
17
+ contextStack = [];
18
+ _timers;
19
+ constructor(parent, scopeName) {
20
+ this.parent = parent;
21
+ this.scopeName = scopeName;
22
+ }
23
+ get timers() {
24
+ if (!this._timers) this._timers = /* @__PURE__ */ new Map();
25
+ return this._timers;
26
+ }
27
+ getBindings() {
28
+ return {
29
+ scope: this.getScopePrefix(),
30
+ badges: this.badgeList.length > 0 ? [...this.badgeList] : void 0
31
+ };
32
+ }
33
+ getScopePrefix() {
34
+ if (this.contextStack.length === 0) return this.scopeName;
35
+ return [this.scopeName, ...this.contextStack].join(":");
36
+ }
37
+ badges(badges) {
38
+ this.badgeList = [...badges];
39
+ return this;
40
+ }
41
+ badge(badge) {
42
+ if (!this.badgeList.includes(badge)) this.badgeList.push(badge);
43
+ return this;
44
+ }
45
+ clearBadges() {
46
+ this.badgeList = [];
47
+ return this;
48
+ }
49
+ style(presetName) {
50
+ this.parent.setTheme(presetName);
51
+ return this;
52
+ }
53
+ context(contextName) {
54
+ return new ContextLogger(this, contextName);
55
+ }
56
+ time(label) {
57
+ this.timers.set(label, {
58
+ label: `${this.scopeName}:${label}`,
59
+ startTime: performance.now()
60
+ });
61
+ }
62
+ timeEnd(label) {
63
+ const timer = this.timers.get(label);
64
+ if (!timer) {
65
+ this.warn(`Timer '${label}' not found`);
66
+ return;
67
+ }
68
+ const elapsed = performance.now() - timer.startTime;
69
+ this.timers.delete(label);
70
+ this.success(`Timer: ${label} - ${elapsed.toFixed(2)}ms`);
71
+ return elapsed;
72
+ }
73
+ debug(...args) {
74
+ this.parent.logWithBindings(this.getBindings(), "debug", ...args);
75
+ }
76
+ info(...args) {
77
+ this.parent.logWithBindings(this.getBindings(), "info", ...args);
78
+ }
79
+ warn(...args) {
80
+ this.parent.logWithBindings(this.getBindings(), "warn", ...args);
81
+ }
82
+ error(...args) {
83
+ this.parent.logWithBindings(this.getBindings(), "error", ...args);
84
+ }
85
+ success(...args) {
86
+ const bindings = this.getBindings();
87
+ this.parent.logWithBindingsAndTag(bindings, "info", "success", ...args);
88
+ }
89
+ critical(...args) {
90
+ this.parent.logWithBindings(this.getBindings(), "critical", ...args);
91
+ }
92
+ trace(...args) {
93
+ this.parent.logWithBindings(this.getBindings(), "trace", ...args);
94
+ }
95
+ /** @see Logger.step */
96
+ step(current, total, message) {
97
+ this.parent.step(current, total, message);
98
+ }
99
+ /** @see Logger.header */
100
+ header(title, subtitle) {
101
+ this.parent.header(title, subtitle);
102
+ }
103
+ /** @see Logger.divider */
104
+ divider() {
105
+ this.parent.divider();
106
+ }
107
+ /** @see Logger.blank */
108
+ blank() {
109
+ this.parent.blank();
110
+ }
111
+ /** @see Logger.box */
112
+ box(content, options) {
113
+ this.parent.box(content, options);
114
+ }
115
+ /** @see Logger.cliTable */
116
+ cliTable(rows, options) {
117
+ this.parent.cliTable(rows, options);
118
+ }
119
+ /** @see Logger.spinner */
120
+ spinner(message) {
121
+ return this.parent.spinner(message);
122
+ }
123
+ /** @see Logger.setCLILevel */
124
+ setCLILevel(level) {
125
+ this.parent.setCLILevel(level);
126
+ }
127
+ _pushContext(context) {
128
+ this.contextStack.push(context);
129
+ }
130
+ _popContext() {
131
+ this.contextStack.pop();
132
+ }
133
+ };
134
+ var APILogger = class extends ScopedLogger {
135
+ constructor(parent, apiName) {
136
+ super(parent, `API:${apiName}`);
137
+ this.badge("API");
138
+ }
139
+ slow(message, duration) {
140
+ this.badge("SLOW");
141
+ const msg = duration ? `${message} (${duration}ms)` : message;
142
+ this.warn(msg);
143
+ }
144
+ rateLimit(message) {
145
+ this.badge("RATE_LIMIT");
146
+ this.warn(message);
147
+ }
148
+ auth(message) {
149
+ this.badge("AUTH");
150
+ this.error(message);
151
+ }
152
+ deprecated(message) {
153
+ this.badge("DEPRECATED");
154
+ this.warn(message);
155
+ }
156
+ };
157
+ var ComponentLogger = class extends ScopedLogger {
158
+ constructor(parent, componentName) {
159
+ super(parent, componentName);
160
+ this.badge("COMPONENT");
161
+ }
162
+ lifecycle(event, message) {
163
+ this.badge("LIFECYCLE");
164
+ const msg = message ? `${event}: ${message}` : event;
165
+ this.info(msg);
166
+ }
167
+ stateChange(from, to, data) {
168
+ this.badge("STATE");
169
+ const msg = `${from} → ${to}`;
170
+ if (data) this.info(msg, data);
171
+ else this.info(msg);
172
+ }
173
+ propsChange(changes) {
174
+ this.badge("PROPS");
175
+ this.debug("Props changed:", changes);
176
+ }
177
+ };
178
+ var ContextLogger = class {
179
+ parentLogger;
180
+ contextName;
181
+ constructor(parentLogger, contextName) {
182
+ this.parentLogger = parentLogger;
183
+ this.contextName = contextName;
184
+ }
185
+ run(fn) {
186
+ this.parentLogger._pushContext(this.contextName);
187
+ try {
188
+ return fn();
189
+ } finally {
190
+ this.parentLogger._popContext();
191
+ }
192
+ }
193
+ async runAsync(fn) {
194
+ this.parentLogger._pushContext(this.contextName);
195
+ try {
196
+ return await fn();
197
+ } finally {
198
+ this.parentLogger._popContext();
199
+ }
200
+ }
201
+ start() {
202
+ this.parentLogger._pushContext(this.contextName);
203
+ }
204
+ end() {
205
+ this.parentLogger._popContext();
206
+ }
207
+ debug(...args) {
208
+ this.parentLogger.debug(...args);
209
+ }
210
+ info(...args) {
211
+ this.parentLogger.info(...args);
212
+ }
213
+ warn(...args) {
214
+ this.parentLogger.warn(...args);
215
+ }
216
+ error(...args) {
217
+ this.parentLogger.error(...args);
218
+ }
219
+ success(...args) {
220
+ this.parentLogger.success(...args);
221
+ }
222
+ critical(...args) {
223
+ this.parentLogger.critical(...args);
224
+ }
225
+ };
226
+ //#endregion
227
+ //#region src/cli/CommandProcessor.ts
228
+ /**
229
+ * CLI command processor
230
+ */
231
+ var CommandProcessor = class {
232
+ commands = /* @__PURE__ */ new Map();
233
+ aliases = /* @__PURE__ */ new Map();
234
+ plugins = /* @__PURE__ */ new Map();
235
+ history = [];
236
+ maxHistorySize = 100;
237
+ isInteractiveMode = false;
238
+ /**
239
+ * Register a command
240
+ */
241
+ registerCommand(command) {
242
+ this.commands.set(command.name, command);
243
+ if (command.aliases) for (const alias of command.aliases) this.aliases.set(alias, command.name);
244
+ }
245
+ /**
246
+ * Register a plugin
247
+ */
248
+ registerPlugin(plugin, logger) {
249
+ if (this.plugins.has(plugin.name)) throw new Error(`Plugin ${plugin.name} is already registered`);
250
+ this.plugins.set(plugin.name, plugin);
251
+ for (const command of plugin.commands) this.registerCommand(command);
252
+ if (plugin.initialize && logger) plugin.initialize(this, logger);
253
+ }
254
+ /**
255
+ * Unregister a plugin
256
+ */
257
+ unregisterPlugin(pluginName) {
258
+ const plugin = this.plugins.get(pluginName);
259
+ if (!plugin) return;
260
+ for (const command of plugin.commands) {
261
+ this.commands.delete(command.name);
262
+ if (command.aliases) for (const alias of command.aliases) this.aliases.delete(alias);
263
+ }
264
+ if (plugin.cleanup) plugin.cleanup();
265
+ this.plugins.delete(pluginName);
266
+ }
267
+ /**
268
+ * Get all registered commands
269
+ */
270
+ getCommands() {
271
+ return Array.from(this.commands.values());
272
+ }
273
+ /**
274
+ * Get a specific command
275
+ */
276
+ getCommand(name) {
277
+ let command = this.commands.get(name);
278
+ if (command) return command;
279
+ const aliasTarget = this.aliases.get(name);
280
+ if (aliasTarget) return this.commands.get(aliasTarget);
281
+ }
282
+ /**
283
+ * Get command history
284
+ */
285
+ getHistory() {
286
+ return [...this.history];
287
+ }
288
+ /**
289
+ * Clear command history
290
+ */
291
+ clearHistory() {
292
+ this.history = [];
293
+ }
294
+ /**
295
+ * Get registered plugins
296
+ */
297
+ getPlugins() {
298
+ return Array.from(this.plugins.values());
299
+ }
300
+ /**
301
+ * Enter interactive mode
302
+ */
303
+ enterInteractiveMode(logger) {
304
+ this.isInteractiveMode = true;
305
+ logger.info("🔧 Interactive CLI mode activated. Type /exit to quit, /help for commands.");
306
+ if (typeof window !== "undefined") this.setupBrowserInteractiveMode(logger);
307
+ }
308
+ /**
309
+ * Exit interactive mode
310
+ */
311
+ exitInteractiveMode() {
312
+ this.isInteractiveMode = false;
313
+ }
314
+ /**
315
+ * Setup browser interactive mode
316
+ */
317
+ setupBrowserInteractiveMode(logger) {
318
+ window.cli = (commandString) => {
319
+ return this.processCommand(`/${commandString}`, logger);
320
+ };
321
+ logger.info("💡 Use cli(\"command\") to execute CLI commands in browser console.");
322
+ }
323
+ /**
324
+ * Process a CLI command
325
+ */
326
+ async processCommand(commandString, logger) {
327
+ if (!commandString.startsWith("/")) {
328
+ logger.error("Invalid command. Commands must start with /");
329
+ this.addToHistory(commandString, false);
330
+ return;
331
+ }
332
+ const parts = commandString.slice(1).split(" ");
333
+ const commandName = parts[0] || "";
334
+ const args = parts.slice(1).join(" ");
335
+ const command = this.getCommand(commandName);
336
+ if (!command) {
337
+ logger.error(`Unknown command: ${commandName}. Type /help for available commands.`);
338
+ const suggestions = this.getSuggestions(commandName);
339
+ if (suggestions.length > 0) logger.info(`📋 Did you mean: ${suggestions.slice(0, 3).join(", ")}?`);
340
+ this.addToHistory(commandString, false);
341
+ return;
342
+ }
343
+ try {
344
+ await command.execute(args || "", logger);
345
+ this.addToHistory(commandString, true);
346
+ } catch (error) {
347
+ logger.error(`Command '${commandName}' failed:`, error);
348
+ this.addToHistory(commandString, false);
349
+ }
350
+ }
351
+ /**
352
+ * Add command to history
353
+ */
354
+ addToHistory(command, success) {
355
+ this.history.unshift({
356
+ command,
357
+ timestamp: /* @__PURE__ */ new Date(),
358
+ success
359
+ });
360
+ if (this.history.length > this.maxHistorySize) this.history = this.history.slice(0, this.maxHistorySize);
361
+ }
362
+ /**
363
+ * Get command suggestions for partial matches
364
+ */
365
+ getSuggestions(partial) {
366
+ return Array.from(this.commands.keys()).filter((name) => name.startsWith(partial));
367
+ }
368
+ };
369
+ //#endregion
370
+ //#region src/cli/commands/ConfigCommand.ts
371
+ /**
372
+ * Configuration command handler
373
+ */
374
+ var ConfigCommand = class {
375
+ name = "config";
376
+ description = "Show or update logger configuration";
377
+ usage = "/config [json|key=value,...]";
378
+ execute(args, logger) {
379
+ if (!args) {
380
+ this.showStatus(logger);
381
+ return;
382
+ }
383
+ try {
384
+ if (args.startsWith("{")) {
385
+ const config = JSON.parse(args);
386
+ this.applyConfig(config, logger);
387
+ } else {
388
+ const pairs = args.split(",").map((pair) => pair.trim().split("="));
389
+ const config = {};
390
+ pairs.forEach(([key, value]) => {
391
+ if (key && value) config[key.trim()] = value.trim().replace(/["']/g, "");
392
+ });
393
+ this.applyConfig(config, logger);
394
+ }
395
+ } catch (error) {
396
+ logger.error("Invalid config format. Use JSON or key=value pairs:", error);
397
+ logger.info("Examples: /config {\"theme\":\"dark\"} or /config theme=neon,verbosity=debug");
398
+ }
399
+ }
400
+ showStatus(logger) {
401
+ const statusData = {
402
+ theme: logger.getConfig().theme || "default",
403
+ verbosity: logger.getConfig().verbosity,
404
+ colors: logger.getConfig().enableColors,
405
+ timestamps: logger.getConfig().enableTimestamps,
406
+ stackTrace: logger.getConfig().enableStackTrace,
407
+ globalPrefix: logger.getConfig().globalPrefix || "none",
408
+ bannerType: logger.getConfig().bannerType || "simple",
409
+ handlers: logger.getHandlers().length
410
+ };
411
+ logger.group("⚙️ Logger Configuration");
412
+ logger.table(statusData);
413
+ logger.groupEnd();
414
+ }
415
+ applyConfig(config, logger) {
416
+ const validKeys = [
417
+ "theme",
418
+ "verbosity",
419
+ "enableColors",
420
+ "enableTimestamps",
421
+ "enableStackTrace",
422
+ "globalPrefix",
423
+ "bannerType"
424
+ ];
425
+ const applied = [];
426
+ Object.entries(config).forEach(([key, value]) => {
427
+ if (validKeys.includes(key)) if (key === "theme" && typeof value === "string") {
428
+ logger.setTheme(value);
429
+ applied.push(`${key}=${value}`);
430
+ } else if (key === "bannerType" && typeof value === "string") {
431
+ logger.setBannerType(value);
432
+ applied.push(`${key}=${value}`);
433
+ } else if (key === "verbosity") {
434
+ logger.setVerbosity(value);
435
+ applied.push(`${key}=${value}`);
436
+ } else if (key === "globalPrefix") {
437
+ logger.setGlobalPrefix(value);
438
+ applied.push(`${key}=${value}`);
439
+ } else {
440
+ logger.updateConfig({ [key]: value });
441
+ applied.push(`${key}=${value}`);
442
+ }
443
+ else logger.warn(`Invalid config key: ${key}`);
444
+ });
445
+ if (applied.length > 0) logger.success(`Configuration updated: ${applied.join(", ")}`);
446
+ }
447
+ };
448
+ //#endregion
449
+ //#region src/cli/commands/ThemeCommand.ts
450
+ /**
451
+ * Themes command - show available themes
452
+ */
453
+ var ThemesCommand = class {
454
+ name = "themes";
455
+ description = "Show available theme presets";
456
+ usage = "/themes";
457
+ execute(_args, logger) {
458
+ logger.group("🎨 Available Themes");
459
+ Object.keys(THEME_PRESETS).forEach((themeName) => {
460
+ const preview = THEME_PRESETS[themeName];
461
+ const previewStyle = new StyleBuilder().bg(preview.info.background).color(preview.info.color).padding("4px 8px").rounded("4px").border(preview.info.border).build();
462
+ console.log(`%c${themeName}`, previewStyle, `- ${themeName} theme preview`);
463
+ });
464
+ logger.groupEnd();
465
+ }
466
+ };
467
+ /**
468
+ * Banners command - show available banner types
469
+ */
470
+ var BannersCommand = class {
471
+ name = "banners";
472
+ description = "Show available banner types";
473
+ usage = "/banners";
474
+ execute(_args, logger) {
475
+ logger.group("🖼️ Available Banner Types");
476
+ Object.keys(BANNER_VARIANTS).forEach((bannerName) => {
477
+ const banner = BANNER_VARIANTS[bannerName];
478
+ console.log(`%c${bannerName}`, "font-weight: bold; color: #667eea;");
479
+ console.log(`%cPreview:`, "color: #666; font-size: 12px;");
480
+ if (bannerName === "simple") console.log(`%c${banner.text}`, banner.style);
481
+ else if (bannerName === "ascii") console.log(`%c${banner.text.split("\n").slice(1, 4).join("\n")}...`, "font-family: monospace; color: #667eea; font-size: 10px;");
482
+ else if (bannerName === "unicode") console.log(`%c${banner.text}`, banner.style);
483
+ else console.log(`%c${bannerName} banner`, "color: #666; font-style: italic;");
484
+ });
485
+ logger.groupEnd();
486
+ }
487
+ };
488
+ /**
489
+ * Banner command - change/show banner type
490
+ */
491
+ var BannerCommand = class {
492
+ name = "banner";
493
+ description = "Change or show current banner type";
494
+ usage = "/banner [type]";
495
+ execute(args, logger) {
496
+ if (!args) {
497
+ logger.showBanner();
498
+ return;
499
+ }
500
+ if (args in BANNER_VARIANTS) {
501
+ logger.setBannerType(args);
502
+ logger.showBanner();
503
+ } else logger.error(`Invalid banner type: ${args}. Available: ${Object.keys(BANNER_VARIANTS).join(", ")}`);
504
+ }
505
+ };
506
+ //#endregion
507
+ //#region src/cli/commands/ExportCommand.ts
508
+ /**
509
+ * Status command - show logger configuration and statistics
510
+ */
511
+ var StatusCommand = class {
512
+ name = "status";
513
+ description = "Show current logger status and configuration";
514
+ usage = "/status";
515
+ execute(_args, logger) {
516
+ const config = logger.getConfig();
517
+ const statusData = {
518
+ theme: config.theme ? config.theme : "default",
519
+ verbosity: config.verbosity,
520
+ colors: config.enableColors,
521
+ timestamps: config.enableTimestamps,
522
+ stackTrace: config.enableStackTrace,
523
+ globalPrefix: config.globalPrefix ? config.globalPrefix : "none",
524
+ bannerType: config.bannerType ? config.bannerType : "simple",
525
+ handlers: logger.getHandlers().length,
526
+ bufferSize: config.bufferSize ? config.bufferSize : 1e3
527
+ };
528
+ logger.group("⚙️ Logger Configuration");
529
+ logger.table(statusData);
530
+ logger.groupEnd();
531
+ }
532
+ };
1
533
  /**
2
- * @fileoverview Better Logger - Librería completa con todas las características
3
- * @version 0.3.0
4
- * @since 2024
5
- *
6
- * Punto de entrada principal que proporciona la experiencia completa de Better Logger
7
- * con características avanzadas incluyendo estilos CSS, soporte SVG, animaciones,
8
- * capacidades de exportación y logging remoto.
9
- *
10
- * @module @mks2508/better-logger
11
- */
12
- // Main Logger class with all features
13
- import { Logger } from './Logger.js';
14
- // Create singleton instance with all features enabled
15
- const logger = new Logger();
16
- /**
17
- * Clase principal Logger con conjunto completo de características
18
- *
19
- * @example
20
- * // Importación y uso básico
21
- * import { Logger } from '@mks2508/better-logger';
22
- *
23
- * const logger = new Logger();
24
- * logger.preset('cyberpunk'); // Aplicar preset completo
25
- * logger.info('¡Hola mundo!');
26
- *
27
- * @example
28
- * // Logger con scope para componentes
29
- * const auth = logger.component('Auth');
30
- * auth.info('Usuario autenticando...');
31
- * auth.success('Login exitoso');
32
- *
33
- * @example
34
- * // Logger para APIs con badges
35
- * const api = logger.api('GraphQL');
36
- * api.badges(['v2', 'cached']).info('Query ejecutada');
37
- *
38
- * @since 0.3.0
39
- */
40
- export { Logger };
41
- /**
42
- * Instancia singleton del logger lista para usar
43
- * @default
44
- *
45
- * @example
46
- * // Uso directo sin crear instancia
47
- * import logger from '@mks2508/better-logger';
48
- *
49
- * logger.info('Aplicación iniciada');
50
- * logger.success('Conexión establecida');
51
- * logger.warn('Memoria al 80%');
52
- * logger.error('Fallo en conexión');
53
- */
54
- export default logger;
55
- /**
56
- * Métodos de logging individuales (enlazados al singleton)
57
- *
58
- * @example
59
- * // Importar solo los métodos necesarios
60
- * import { info, error, success } from '@mks2508/better-logger';
61
- *
62
- * info('Proceso iniciado');
63
- * success('✓ Completado exitosamente');
64
- * error('Error:', errorDetails);
65
- *
66
- * @since 0.3.0
67
- */
68
- export const debug = (...args) => logger.debug(...args);
69
- export const info = (...args) => logger.info(...args);
70
- export const warn = (...args) => logger.warn(...args);
71
- export const error = (...args) => logger.error(...args);
72
- export const success = (...args) => logger.success(...args);
73
- export const critical = (...args) => logger.critical(...args);
74
- export const trace = (...args) => logger.trace(...args);
75
- export const table = (data, columns) => logger.table(data, columns);
76
- export const group = (label, collapsed) => logger.group(label, collapsed);
77
- export const groupEnd = () => logger.groupEnd();
78
- export const time = (label) => logger.time(label);
79
- export const timeEnd = (label) => logger.timeEnd(label);
80
- export const setGlobalPrefix = (prefix) => logger.setGlobalPrefix(prefix);
81
- export const scope = (prefix) => logger.scope(prefix);
82
- export const setVerbosity = (level) => logger.setVerbosity(level);
83
- export const addHandler = (handler) => logger.addHandler(handler);
84
- export const setTheme = (theme) => logger.setTheme(theme);
85
- export const setBannerType = (bannerType) => logger.setBannerType(bannerType);
86
- export const showBanner = (bannerType) => logger.showBanner(bannerType);
87
- export const logWithSVG = (message, svgContent, options) => logger.logWithSVG(message, svgContent, options);
88
- export const logAnimated = (message, duration) => logger.logAnimated(message, duration);
89
- export const cli = (command) => logger.cli(command);
90
- // Styling utilities
91
- export { StyleBuilder, StylePresets, THEME_PRESETS, THEME_BANNERS, BANNER_VARIANTS } from './styling/index.js';
92
- // Handler exports
93
- export { FileLogHandler, RemoteLogHandler, AnalyticsLogHandler } from './handlers/index.js';
94
- // Constants
95
- export { DEFAULT_CONFIG } from './constants.js';
96
- // Utility exports
97
- export { parseStackTrace, formatTimestamp } from './utils/index.js';
98
- /**
99
- * Utilidades de estilo para crear estilos personalizados de consola
100
- *
101
- * @example
102
- * // Crear estilo personalizado
103
- * import { createStyle, stylePresets } from '@mks2508/better-logger';
104
- *
105
- * const miEstilo = createStyle()
106
- * .bg('linear-gradient(45deg, #ff6b6b, #feca57)')
107
- * .color('white')
108
- * .padding('10px')
109
- * .rounded('8px')
110
- * .bold()
111
- * .build();
112
- *
113
- * console.log('%cMensaje estilizado', miEstilo);
114
- *
115
- * @example
116
- * // Usar presets predefinidos
117
- * console.log('%cÉxito!', stylePresets.success);
118
- * console.log('%cError!', stylePresets.error);
119
- *
120
- * @since 0.3.0
121
- */
122
- import { StyleBuilder, StylePresets } from './styling/index.js';
123
- /**
124
- * Crea una nueva instancia de StyleBuilder para estilos personalizados de consola
125
- *
126
- * @returns {StyleBuilder} Constructor de estilos encadenable
127
- *
128
- * @example
129
- * const estilo = createStyle()
130
- * .gradient('#667eea', '#764ba2')
131
- * .color('white')
132
- * .padding('8px 16px')
133
- * .rounded('4px')
134
- * .shadow('0 2px 4px rgba(0,0,0,0.2)')
135
- * .build();
136
- *
137
- * @since 0.3.0
138
- */
139
- export const createStyle = () => new StyleBuilder();
140
- /**
141
- * Presets de estilo predefinidos para casos de uso comunes
142
- *
143
- * @constant {Object} stylePresets
144
- *
145
- * @example
146
- * console.log('%cOperación exitosa', stylePresets.success);
147
- * console.log('%cAdvertencia', stylePresets.warning);
148
- * console.log('%cError crítico', stylePresets.error);
149
- * console.log('%cInformación', stylePresets.info);
150
- * console.log('%cDestacado', stylePresets.accent);
151
- *
152
- * @since 0.3.0
153
- */
154
- export const stylePresets = {
155
- success: StylePresets.success().build(),
156
- error: StylePresets.error().build(),
157
- warning: StylePresets.warning().build(),
158
- info: StylePresets.info().build(),
159
- accent: StylePresets.accent().build(),
534
+ * Reset command - reset logger to defaults
535
+ */
536
+ var ResetCommand = class {
537
+ name = "reset";
538
+ description = "Reset logger configuration to defaults";
539
+ usage = "/reset";
540
+ execute(_args, logger) {
541
+ logger.resetConfig();
542
+ }
160
543
  };
544
+ /**
545
+ * Demo command - show logger feature demonstration
546
+ */
547
+ var DemoCommand = class {
548
+ name = "demo";
549
+ description = "Show comprehensive feature demonstration";
550
+ usage = "/demo";
551
+ execute(_args, logger) {
552
+ logger.group("🎪 Advanced Logger Demo");
553
+ logger.debug("Debug message with detailed information");
554
+ logger.info("Informational message about system state");
555
+ logger.warn("Warning about deprecated feature");
556
+ logger.error("Error processing user request");
557
+ logger.success("Operation completed successfully");
558
+ logger.critical("Critical system failure detected");
559
+ logger.group("📊 Advanced Features Demo");
560
+ logger.table([
561
+ {
562
+ feature: "Styled Console",
563
+ status: "✅ Active",
564
+ performance: "Excellent"
565
+ },
566
+ {
567
+ feature: "Theme System",
568
+ status: "✅ Active",
569
+ performance: "Great"
570
+ },
571
+ {
572
+ feature: "CLI Interface",
573
+ status: "✅ Active",
574
+ performance: "Good"
575
+ },
576
+ {
577
+ feature: "Export System",
578
+ status: "✅ Active",
579
+ performance: "Excellent"
580
+ }
581
+ ]);
582
+ logger.time("demo-operation");
583
+ setTimeout(() => {
584
+ logger.timeEnd("demo-operation");
585
+ }, 100);
586
+ logger.logWithSVG("SVG Demo");
587
+ logger.logAnimated("🌟 Animated Logger Demo 🌟", 2);
588
+ logger.groupEnd();
589
+ logger.groupEnd();
590
+ logger.info("Demo completed! Check the console for styled output.");
591
+ }
592
+ };
593
+ //#endregion
594
+ //#region src/cli/help.ts
595
+ /**
596
+ * Help command - show comprehensive CLI help
597
+ */
598
+ var HelpCommand = class {
599
+ name = "help";
600
+ description = "Show CLI help and available commands";
601
+ usage = "/help [command]";
602
+ execute(_args, logger) {
603
+ const helpStyle = new StyleBuilder().bg("linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)").color("#495057").padding("15px 20px").rounded("8px").border("1px solid #dee2e6").font("Monaco, Consolas, monospace").size("13px").build();
604
+ console.log(`%c
605
+ ╭─────────────── ADVANCED LOGGER CLI COMMANDS ─────────────────╮
606
+ │ │
607
+ │ CONFIGURATION │
608
+ │ /config Show current configuration │
609
+ │ /config {json} Apply JSON configuration │
610
+ │ /config key=val Apply key-value configuration │
611
+ │ /themes Show available themes │
612
+ │ /banners Show available banner types │
613
+ │ /banner [type] Change/show banner type │
614
+ │ /status Show logger status & buffer stats │
615
+ │ /demo Show feature demonstration │
616
+ │ /reset Reset to default configuration │
617
+ │ │
618
+ │ EXPORT & CLIPBOARD │
619
+ │ /export <format> Export logs (json|csv|md|plain|html) │
620
+ │ /copy <format> Copy logs to clipboard │
621
+ │ /buffer-size N Set log buffer size │
622
+ │ /buffer-info Show buffer statistics │
623
+ │ /clear-buffer Clear stored logs │
624
+ │ │
625
+ │ EXPORT FILTERS (for export/copy commands) │
626
+ │ --level error,warn Filter by log levels │
627
+ │ --since 2h Logs from last 2 hours │
628
+ │ --until 1h Logs until 1 hour ago │
629
+ │ --prefix API,DB Filter by prefixes │
630
+ │ --exclude-prefix INT Exclude prefixes │
631
+ │ --last 50 Last 50 logs only │
632
+ │ --first 25 First 25 logs only │
633
+ │ --search "error" Search in log messages │
634
+ │ --with-stack Only logs with stack traces │
635
+ │ --errors-only Only error + critical logs │
636
+ │ --group-by level Group by level/prefix/hour │
637
+ │ │
638
+ │ EXPORT OPTIONS │
639
+ │ --minimal Minimal output format │
640
+ │ --compact Remove extra whitespace │
641
+ │ --styled Include styling (HTML format) │
642
+ │ │
643
+ ├──────────────────── CONFIGURATION OPTIONS ─────────────────┤
644
+ │ │
645
+ │ theme: default | dark | light | neon | minimal | cyberpunk│
646
+ │ bannerType: simple | ascii | unicode | svg | animated │
647
+ │ verbosity: debug | info | warn | error | critical | silent│
648
+ │ enableColors: true | false │
649
+ │ enableTimestamps: true | false │
650
+ │ enableStackTrace: true | false │
651
+ │ globalPrefix: "string" │
652
+ │ bufferSize: number (50-10000) │
653
+ │ │
654
+ ├──────────────────────── EXAMPLES ──────────────────────────┤
655
+ │ │
656
+ │ Basic Configuration: │
657
+ │ /config {"theme":"dark","verbosity":"debug"} │
658
+ │ /config theme=neon,bufferSize=2000 │
659
+ │ /banner animated Change to animated banner │
660
+ │ │
661
+ │ Export Examples: │
662
+ │ /export json --level=error,warn --last=25 │
663
+ │ /export csv --since=2h --prefix=API │
664
+ │ /export markdown --group-by=level --errors-only │
665
+ │ /export html --styled --since=1h │
666
+ │ │
667
+ │ Clipboard Examples: │
668
+ │ /copy plain --minimal --last=10 │
669
+ │ /copy json --search="authentication" --compact │
670
+ │ /copy csv --since=30m --exclude-prefix=DEBUG │
671
+ │ │
672
+ │ Buffer Management: │
673
+ │ /buffer-size 5000 Increase buffer to 5000 logs │
674
+ │ /buffer-info Show detailed buffer statistics │
675
+ │ /clear-buffer Clear all stored logs │
676
+ │ │
677
+ │ Time Formats: │
678
+ │ --since=2h 2 hours ago │
679
+ │ --since=30m 30 minutes ago │
680
+ │ --since=1d 1 day ago │
681
+ │ --since="2024-01-01T10:00:00Z" Specific ISO date │
682
+ │ │
683
+ ╰─────────────────────────────────────────────────────────────╯`, helpStyle);
684
+ logger.group("💡 Quick Tips");
685
+ [
686
+ "Use /demo to see all logger features in action",
687
+ "Logs are automatically stored in a circular buffer for export",
688
+ "Export formats: JSON (structured), CSV (Excel), Markdown (readable), Plain (simple), HTML (styled)",
689
+ "Time filters support relative (2h, 30m) and absolute (ISO) formats",
690
+ "Combine multiple filters: /export json --level=error --since=1h --search=\"auth\"",
691
+ "Use /copy for quick clipboard access instead of /export"
692
+ ].forEach((tip) => {
693
+ logger.info(`• ${tip}`);
694
+ });
695
+ logger.groupEnd();
696
+ }
697
+ };
698
+ //#endregion
699
+ //#region src/cli/index.ts
700
+ /**
701
+ * Create and configure default CLI processor
702
+ */
703
+ function createDefaultCLI() {
704
+ const processor = new CommandProcessor();
705
+ processor.registerCommand(new HelpCommand());
706
+ processor.registerCommand(new ConfigCommand());
707
+ processor.registerCommand(new ThemesCommand());
708
+ processor.registerCommand(new BannersCommand());
709
+ processor.registerCommand(new BannerCommand());
710
+ processor.registerCommand(new StatusCommand());
711
+ processor.registerCommand(new ResetCommand());
712
+ processor.registerCommand(new DemoCommand());
713
+ return processor;
714
+ }
715
+ //#endregion
716
+ //#region src/transports/TransportBridge.ts
717
+ /**
718
+ * Creates a TransportBridge instance.
719
+ */
720
+ function createTransportBridge() {
721
+ let transportManager;
722
+ return {
723
+ addTransport(target) {
724
+ if (!transportManager) transportManager = new TransportManager();
725
+ return transportManager.add(target);
726
+ },
727
+ removeTransport(id) {
728
+ return transportManager?.remove(id) ?? false;
729
+ },
730
+ async flushTransports() {
731
+ await transportManager?.flush();
732
+ },
733
+ async closeTransports() {
734
+ await transportManager?.close();
735
+ },
736
+ getTransportManager() {
737
+ return transportManager;
738
+ },
739
+ writeRecord(record) {
740
+ if (!transportManager) return;
741
+ transportManager.write(record).catch(() => {});
742
+ }
743
+ };
744
+ }
745
+ //#endregion
746
+ //#region src/playground/TerminalBridge.ts
747
+ /**
748
+ * Creates a TerminalBridge using a getter to avoid circular reference at construction.
749
+ */
750
+ function createTerminalBridge(options) {
751
+ let _showPrimitives = true;
752
+ let _serverFallback;
753
+ return {
754
+ step(current, total, message) {
755
+ if (!_showPrimitives) return;
756
+ if (!isRunningInTerminal()) {
757
+ this.getServerFallback().step(current, total, message);
758
+ return;
759
+ }
760
+ const output = renderStep(current, total, message, getColorCapability());
761
+ process.stderr.write(output + "\n");
762
+ },
763
+ header(title, subtitle) {
764
+ if (!_showPrimitives) return;
765
+ if (!isRunningInTerminal()) {
766
+ this.getServerFallback().header(title, subtitle);
767
+ return;
768
+ }
769
+ const output = renderHeader(title, subtitle);
770
+ process.stderr.write(output + "\n");
771
+ },
772
+ divider() {
773
+ if (!_showPrimitives) return;
774
+ if (!isRunningInTerminal()) {
775
+ this.getServerFallback().divider();
776
+ return;
777
+ }
778
+ const output = renderDivider();
779
+ process.stderr.write(output + "\n");
780
+ },
781
+ blank() {
782
+ if (!_showPrimitives) return;
783
+ if (!isRunningInTerminal()) {
784
+ this.getServerFallback().blank();
785
+ return;
786
+ }
787
+ process.stderr.write("\n");
788
+ },
789
+ box(content, opts) {
790
+ if (!_showPrimitives) return;
791
+ if (!isRunningInTerminal()) {
792
+ this.getServerFallback().box(content, opts);
793
+ return;
794
+ }
795
+ const output = renderBox(content, opts, getColorCapability());
796
+ process.stderr.write(output + "\n");
797
+ },
798
+ cliTable(rows, opts) {
799
+ if (!_showPrimitives) return;
800
+ if (!isRunningInTerminal()) {
801
+ this.getServerFallback().cliTable(rows, opts);
802
+ return;
803
+ }
804
+ const output = renderTable(rows, opts, getColorCapability());
805
+ process.stderr.write(output + "\n");
806
+ },
807
+ spinner(message) {
808
+ const logger = options.getLogger();
809
+ if (!isRunningInTerminal() || options.config.outputMode === "silent") return new NoopSpinner(message, logger);
810
+ return new SpinnerManager(message, options.config, logger);
811
+ },
812
+ getShowPrimitives() {
813
+ return _showPrimitives;
814
+ },
815
+ setShowPrimitives(show) {
816
+ _showPrimitives = show;
817
+ },
818
+ getServerFallback() {
819
+ if (!_serverFallback) _serverFallback = new ServerFallback(options.getLogger());
820
+ return _serverFallback;
821
+ },
822
+ isInTerminal() {
823
+ return isRunningInTerminal();
824
+ }
825
+ };
826
+ }
827
+ //#endregion
828
+ //#region src/Logger.ts
829
+ THEME_PRESETS.default;
830
+ /**
831
+ * Clase principal Logger con capacidades avanzadas de logging
832
+ *
833
+ * @class Logger
834
+ * @description Sistema completo de logging con temas, badges, contextos y exportación.
835
+ * Detecta automáticamente el tema claro/oscuro del navegador.
836
+ *
837
+ * @example
838
+ * // Uso básico sin configuración
839
+ * import logger from '@mks2508/better-logger';
840
+ * logger.info('Aplicación iniciada');
841
+ * logger.success('Conexión establecida');
842
+ *
843
+ * @example
844
+ * // Aplicar un preset temático
845
+ * logger.preset('cyberpunk');
846
+ * logger.warn('Advertencia con estilo neón');
847
+ *
848
+ * @example
849
+ * // Logger con scope para componentes
850
+ * const auth = logger.component('Autenticación');
851
+ * auth.info('Usuario intentando login');
852
+ * auth.success('Login exitoso');
853
+ *
854
+ */
855
+ var Logger = class Logger {
856
+ config;
857
+ scopedPrefix;
858
+ handlers = [];
859
+ timers = /* @__PURE__ */ new Map();
860
+ groupDepth = 0;
861
+ cliProcessor;
862
+ themeChangeListener;
863
+ badgeList = [];
864
+ displaySettings = {
865
+ showTimestamp: true,
866
+ showLocation: true,
867
+ showBadges: true
868
+ };
869
+ serializerBridge;
870
+ hookBridge;
871
+ logContext;
872
+ transportBridge;
873
+ /** Set during success() so log() skips its own dispatch (N2 fix). */
874
+ _successTagDispatched = false;
875
+ styleManager;
876
+ /** Whether CLI primitives (step, box, header, etc.) should be shown*/
877
+ _showPrimitives = true;
878
+ terminalBridge;
879
+ /**
880
+ * Active smart-preset reference (set by `preset()`). Typed as `unknown`
881
+ * to keep the public surface clean; consumed by `createStyledOutput`.
882
+ */
883
+ _activePreset;
884
+ /**
885
+ * Name of the active smart-preset. Stored separately so theme-change
886
+ * detection can re-render without re-running the preset body.
887
+ */
888
+ _activePresetName;
889
+ /**
890
+ * Last-applied `customize()` overrides. Stored for later read by
891
+ * `createStyledOutput`.
892
+ */
893
+ _customization;
894
+ /**
895
+ * This logger's own context bindings (from child() calls).
896
+ * Single source of truth for this logger's contribution to the context chain.
897
+ * @private
898
+ */
899
+ _bindings = {};
900
+ /**
901
+ * Reference to the parent's merged context record at the time this logger
902
+ * was created. Together with _bindings, forms the context chain.
903
+ * Undefined for the root logger.
904
+ * @private
905
+ */
906
+ _parentContextRecord;
907
+ /**
908
+ * Crea una nueva instancia del Logger
909
+ *
910
+ * @param {Partial<LoggerConfig>} config - Configuración opcional del logger
911
+ *
912
+ * @example
913
+ * // Logger con configuración personalizada
914
+ * const logger = new Logger({
915
+ * theme: 'neon',
916
+ * globalPrefix: 'MiApp',
917
+ * verbosity: 'debug',
918
+ * bufferSize: 1000
919
+ * });
920
+ */
921
+ constructor(config = {}) {
922
+ this.config = {
923
+ ...DEFAULT_CONFIG,
924
+ ...config
925
+ };
926
+ this.serializerBridge = createSerializerBridge();
927
+ this.hookBridge = createHookBridge();
928
+ this.logContext = createLogContext({
929
+ initialResource: this.config.resource,
930
+ childLoggerFactory: (childConfig) => {
931
+ return new Logger({
932
+ ...this.config,
933
+ ...childConfig
934
+ });
935
+ },
936
+ getParentContextRecord: () => this._captureMergedContext()
937
+ });
938
+ this.transportBridge = createTransportBridge();
939
+ this.styleManager = createStyleManager();
940
+ this.terminalBridge = createTerminalBridge({
941
+ config: this.config,
942
+ getLogger: () => this
943
+ });
944
+ this.cliProcessor = createDefaultCLI();
945
+ if (this.config.autoDetectTheme) this.setupAutoThemeDetection();
946
+ }
947
+ /**
948
+ * Configura la detección automática de tema con listener de cambios
949
+ * @private
950
+ * @description Detecta automáticamente si el navegador está en modo claro u oscuro
951
+ */
952
+ setupAutoThemeDetection() {
953
+ if (this.themeChangeListener) {
954
+ this.themeChangeListener();
955
+ this.themeChangeListener = null;
956
+ }
957
+ this.themeChangeListener = setupThemeChangeListener((theme) => {
958
+ this.debug(`DevTools theme changed to: ${theme}`);
959
+ });
960
+ }
961
+ /**
962
+ * Obtiene la configuración actual del logger
963
+ *
964
+ * @returns {LoggerConfig} Configuración completa actual
965
+ *
966
+ * @example
967
+ * const config = logger.getConfig();
968
+ * console.log('Verbosidad actual:', config.verbosity);
969
+ * console.log('Tema actual:', config.theme);
970
+ *
971
+ */
972
+ getConfig() {
973
+ return { ...this.config };
974
+ }
975
+ /**
976
+ * Actualiza la configuración del logger
977
+ *
978
+ * @param {Partial<LoggerConfig>} updates - Propiedades a actualizar
979
+ *
980
+ * @example
981
+ * logger.updateConfig({
982
+ * verbosity: 'debug',
983
+ * enableTimestamps: false,
984
+ * theme: 'cyberpunk'
985
+ * });
986
+ *
987
+ */
988
+ updateConfig(updates) {
989
+ const previousAutoDetect = this.config.autoDetectTheme;
990
+ this.config = {
991
+ ...this.config,
992
+ ...updates
993
+ };
994
+ if (updates.autoDetectTheme !== void 0 && updates.autoDetectTheme !== previousAutoDetect) {
995
+ if (updates.autoDetectTheme) this.setupAutoThemeDetection();
996
+ else if (this.themeChangeListener) {
997
+ this.themeChangeListener();
998
+ this.themeChangeListener = null;
999
+ }
1000
+ }
1001
+ }
1002
+ /**
1003
+ * Establece el prefijo global para todos los mensajes de log
1004
+ *
1005
+ * @param {string} prefix - Prefijo a usar
1006
+ *
1007
+ * @example
1008
+ * logger.setGlobalPrefix('MiApp');
1009
+ * logger.info('Iniciado'); // [MiApp] Iniciado
1010
+ *
1011
+ */
1012
+ setGlobalPrefix(prefix) {
1013
+ this.config.globalPrefix = prefix;
1014
+ }
1015
+ /**
1016
+ * Establece el nivel de verbosidad para filtrar la salida de logs
1017
+ *
1018
+ * @param {Verbosity} level - Nivel mínimo a mostrar ('debug' | 'info' | 'warn' | 'error' | 'critical' | 'silent')
1019
+ *
1020
+ * @example
1021
+ * logger.setVerbosity('warn'); // Solo muestra warn, error y critical
1022
+ * logger.setVerbosity('debug'); // Muestra todos los niveles
1023
+ * logger.setVerbosity('silent'); // No muestra nada
1024
+ *
1025
+ */
1026
+ setVerbosity(level) {
1027
+ this.config.verbosity = level;
1028
+ }
1029
+ /**
1030
+ * Establece el tema del logger
1031
+ *
1032
+ * @param {ThemeVariant} theme - Tema a aplicar ('default' | 'dark' | 'light' | 'neon' | 'minimal' | 'cyberpunk')
1033
+ *
1034
+ * @example
1035
+ * logger.setTheme('neon'); // Tema con colores neón
1036
+ * logger.setTheme('minimal'); // Tema minimalista
1037
+ * logger.setTheme('cyberpunk'); // Tema cyberpunk con efectos
1038
+ *
1039
+ */
1040
+ setTheme(theme) {
1041
+ if (hasPreset(theme)) {
1042
+ this.preset(theme);
1043
+ return;
1044
+ }
1045
+ if (this.styleManager.setTheme(theme)) {
1046
+ this.config.theme = theme;
1047
+ const bannersRecord = THEME_BANNERS;
1048
+ if (theme in bannersRecord) {
1049
+ const themeBanner = bannersRecord[theme];
1050
+ if (themeBanner) this.writeOutput(`%c${themeBanner.simple}`, "info", [themeBanner.style], []);
1051
+ }
1052
+ this.success(`Theme changed to: ${theme}`);
1053
+ } else this.error(`Invalid theme: ${theme}. Available:`, [...getAvailablePresets(), ...Object.keys(THEME_PRESETS)]);
1054
+ }
1055
+ /**
1056
+ * Establece el tipo de banner para mostrar en la inicialización
1057
+ *
1058
+ * @param {BannerType} bannerType - Tipo de banner ('simple' | 'ascii' | 'unicode' | 'svg' | 'animated')
1059
+ *
1060
+ * @example
1061
+ * logger.setBannerType('ascii'); // Banner con arte ASCII
1062
+ * logger.setBannerType('unicode'); // Banner con caracteres Unicode
1063
+ * logger.setBannerType('animated'); // Banner con animación
1064
+ *
1065
+ */
1066
+ setBannerType(bannerType) {
1067
+ this.config.bannerType = bannerType;
1068
+ this.success(`Banner type changed to: ${bannerType}`);
1069
+ }
1070
+ /**
1071
+ * Runs `fn` within an AsyncLocalStorage scope where `bindings` are
1072
+ * merged into the context for all log calls inside `fn`.
1073
+ *
1074
+ * Without `fn` (the old setter shape): no-op for backwards compatibility.
1075
+ * Prefer `child()` for persistent bindings or `withContextAsync()` for
1076
+ * async callbacks.
1077
+ *
1078
+ * @param bindings - Key-value pairs to attach for the duration of `fn`
1079
+ * @param fn - Optional synchronous function to run with scoped bindings
1080
+ * @returns The return value of `fn`, or undefined if no fn provided
1081
+ *
1082
+ * @example
1083
+ * // Scoped synchronous callback
1084
+ * logger.withContext({ requestId: 'r-42' }, () => {
1085
+ * doWork(); // logs inside see requestId in attributes
1086
+ * });
1087
+ *
1088
+ * @example
1089
+ * // Persistent binding: use child()
1090
+ * const reqLog = logger.child({ requestId: 'r-42' });
1091
+ * reqLog.info('handling request'); // attributes include requestId
1092
+ *
1093
+ * @see {@link child} for an immutable copy with the merged context
1094
+ * @see {@link withContextAsync} for async callback variant
1095
+ */
1096
+ withContext(bindings, fn) {
1097
+ return this.logContext.withContext(bindings, fn);
1098
+ }
1099
+ /**
1100
+ * Async variant of `withContext`. Runs `fn` within an AsyncLocalStorage
1101
+ * scope so bindings are available to all async log calls inside `fn`.
1102
+ *
1103
+ * @param bindings - Key-value pairs to attach for the duration of `fn`
1104
+ * @param fn - Async function to run with the scoped bindings
1105
+ * @returns The return value of `fn`
1106
+ *
1107
+ * @example
1108
+ * await logger.withContextAsync({ requestId: 'r-42' }, async () => {
1109
+ * await fetchData(); // logs inside see requestId in attributes
1110
+ * });
1111
+ *
1112
+ * @see {@link child} for a persistent child logger
1113
+ * @see {@link withContext} for synchronous callback variant
1114
+ */
1115
+ withContextAsync(bindings, fn) {
1116
+ return this.logContext.withContextAsync(bindings, fn);
1117
+ }
1118
+ /**
1119
+ * Returns an immutable copy of this logger with the extra context bound.
1120
+ * Future calls on the child emit with the merged context, without
1121
+ * mutating the parent — the canonical MDC pattern.
1122
+ *
1123
+ * @param extra - Key-value pairs to attach (requestId, userId, ...)
1124
+ * @returns A new Logger with merged context
1125
+ *
1126
+ * @example
1127
+ * const reqLog = logger.child({ requestId: req.id });
1128
+ * reqLog.info('start'); // emits attributes: { requestId }
1129
+ * logger.info('unrelated'); // NOT affected — parent's context untouched
1130
+ *
1131
+ */
1132
+ child(extra) {
1133
+ const childLogger = this.logContext.child(extra);
1134
+ childLogger._parentContextRecord = childLogger["__parentSnapshot"] ?? {};
1135
+ childLogger._bindings = extra;
1136
+ return childLogger;
1137
+ }
1138
+ /**
1139
+ * Drops every key from the bound context. After this call, emitted
1140
+ * records no longer carry `attributes` until {@link withContext} or
1141
+ * {@link child} re-establish one.
1142
+ *
1143
+ * @returns The same logger instance, now context-free
1144
+ */
1145
+ clearContext() {
1146
+ this.logContext.clearContext();
1147
+ return this;
1148
+ }
1149
+ /**
1150
+ * Snapshot of the bound context. Returned object is a shallow copy:
1151
+ * mutating it does NOT affect what subsequent log calls emit.
1152
+ *
1153
+ * @returns A read-only snapshot of the current context
1154
+ */
1155
+ getContext() {
1156
+ let merged = this._parentContextRecord ?? {};
1157
+ if (this._bindings && Object.keys(this._bindings).length > 0) merged = {
1158
+ ...merged,
1159
+ ...this._bindings
1160
+ };
1161
+ return merged;
1162
+ }
1163
+ /**
1164
+ * Updates the default OTel resource (service.name, version, env).
1165
+ * Persisted into every emitted record's `resource` field unless the
1166
+ * record itself overrides it.
1167
+ *
1168
+ * @param resource - Partial OTel resource to merge into the current one
1169
+ * @returns The same logger instance, for chaining
1170
+ *
1171
+ * @example
1172
+ * logger.setResource({ 'service.name': 'api', 'service.version': '1.2.3' });
1173
+ *
1174
+ */
1175
+ setResource(resource) {
1176
+ this.logContext.setResource(resource);
1177
+ return this;
1178
+ }
1179
+ /**
1180
+ * Reinicia el logger a la configuración por defecto
1181
+ *
1182
+ * @example
1183
+ * logger.resetConfig();
1184
+ * // Todo vuelve a la configuración inicial
1185
+ *
1186
+ */
1187
+ resetConfig() {
1188
+ if (this.themeChangeListener) {
1189
+ this.themeChangeListener();
1190
+ this.themeChangeListener = null;
1191
+ }
1192
+ this.config = { ...DEFAULT_CONFIG };
1193
+ this.styleManager.resetStyles();
1194
+ if (this.config.autoDetectTheme) this.setupAutoThemeDetection();
1195
+ this.success("Logger configuration reset to defaults");
1196
+ }
1197
+ /**
1198
+ * Método de limpieza para eliminar listeners y liberar recursos
1199
+ *
1200
+ * @example
1201
+ * // Antes de cerrar la aplicación
1202
+ * logger.cleanup();
1203
+ *
1204
+ */
1205
+ /**
1206
+ * Tears down every resource held by this Logger. Safe to call multiple
1207
+ * times. Fixed in 5.1.0 to fully drain transports + clear timers +
1208
+ * drop the legacy handler list + reset group depth + clear context.
1209
+ *
1210
+ * @example
1211
+ * await logger.cleanup(); // before process exit / hot reload
1212
+ *
1213
+ */
1214
+ async cleanup() {
1215
+ if (this.themeChangeListener) {
1216
+ try {
1217
+ this.themeChangeListener();
1218
+ } catch {}
1219
+ this.themeChangeListener = null;
1220
+ }
1221
+ await this.transportBridge.closeTransports();
1222
+ this.handlers.length = 0;
1223
+ this.timers.clear();
1224
+ this.badgeList = [];
1225
+ this.logContext.clearContext();
1226
+ this.groupDepth = 0;
1227
+ }
1228
+ /**
1229
+ * Aplica un preset inteligente - funciona perfectamente sin configuración
1230
+ *
1231
+ * @param {string} name - Nombre del preset a aplicar
1232
+ *
1233
+ * @example
1234
+ * // Presets disponibles
1235
+ * logger.preset('default'); // Limpio y adaptativo
1236
+ * logger.preset('cyberpunk'); // Colores neón, efectos brillantes
1237
+ * logger.preset('glassmorphism'); // Efectos de blur modernos
1238
+ * logger.preset('minimal'); // Minimalista y elegante
1239
+ * logger.preset('debug'); // Modo desarrollo detallado
1240
+ * logger.preset('production'); // Optimizado para producción
1241
+ *
1242
+ */
1243
+ preset(name) {
1244
+ if (!hasPreset(name)) {
1245
+ this.error(`Unknown preset: ${name}. Available presets:`, getAvailablePresets());
1246
+ return;
1247
+ }
1248
+ const presetConfig = getSmartPreset(name);
1249
+ if (presetConfig) {
1250
+ this.displaySettings.showTimestamp = presetConfig.timestamp?.show ?? true;
1251
+ this.displaySettings.showLocation = presetConfig.location?.show ?? true;
1252
+ this._activePreset = presetConfig;
1253
+ this._activePresetName = name;
1254
+ if (getEnvironment() === "browser") this.success(`Applied preset: ${name}`);
1255
+ }
1256
+ }
1257
+ /**
1258
+ * Lista todos los presets disponibles
1259
+ *
1260
+ * @returns {string[]} Array con nombres de presets disponibles
1261
+ *
1262
+ * @example
1263
+ * const disponibles = logger.presets();
1264
+ * console.log(disponibles); // ['default', 'cyberpunk', 'glassmorphism', ...]
1265
+ *
1266
+ */
1267
+ presets() {
1268
+ return getAvailablePresets();
1269
+ }
1270
+ /**
1271
+ * Oculta el timestamp en los logs
1272
+ *
1273
+ * @example
1274
+ * logger.hideTimestamp();
1275
+ * logger.info('Sin marca de tiempo'); // Sin timestamp visible
1276
+ *
1277
+ */
1278
+ hideTimestamp() {
1279
+ this.displaySettings.showTimestamp = false;
1280
+ return this;
1281
+ }
1282
+ /**
1283
+ * Muestra el timestamp en los logs
1284
+ *
1285
+ * @example
1286
+ * logger.showTimestamp();
1287
+ * logger.info('Con marca de tiempo'); // [2024-01-15 10:30:45] Con marca de tiempo
1288
+ *
1289
+ */
1290
+ showTimestamp() {
1291
+ this.displaySettings.showTimestamp = true;
1292
+ return this;
1293
+ }
1294
+ /**
1295
+ * Oculta la información de ubicación (archivo:línea) en los logs
1296
+ *
1297
+ * @example
1298
+ * logger.hideLocation();
1299
+ * logger.debug('Sin ubicación'); // Sin mostrar archivo:línea
1300
+ *
1301
+ */
1302
+ hideLocation() {
1303
+ this.displaySettings.showLocation = false;
1304
+ return this;
1305
+ }
1306
+ /**
1307
+ * Muestra la información de ubicación (archivo:línea) en los logs
1308
+ *
1309
+ * @example
1310
+ * logger.showLocation();
1311
+ * logger.debug('Con ubicación'); // app.js:42 Con ubicación
1312
+ *
1313
+ */
1314
+ showLocation() {
1315
+ this.displaySettings.showLocation = true;
1316
+ return this;
1317
+ }
1318
+ /**
1319
+ * Oculta los badges en los logs
1320
+ *
1321
+ * @example
1322
+ * logger.hideBadges();
1323
+ * const api = logger.api('REST');
1324
+ * api.info('Sin badges'); // Sin mostrar [API] [REST]
1325
+ *
1326
+ */
1327
+ hideBadges() {
1328
+ this.displaySettings.showBadges = false;
1329
+ return this;
1330
+ }
1331
+ /**
1332
+ * Muestra los badges en los logs
1333
+ *
1334
+ * @example
1335
+ * logger.showBadges();
1336
+ * const api = logger.api('GraphQL');
1337
+ * api.info('Con badges'); // [API] [GraphQL] Con badges
1338
+ *
1339
+ */
1340
+ showBadges() {
1341
+ this.displaySettings.showBadges = true;
1342
+ return this;
1343
+ }
1344
+ /**
1345
+ * Establece múltiples badges para los logs
1346
+ *
1347
+ * @param {string[]} badges - Array de badges a mostrar
1348
+ * @returns {this} Logger instance para encadenamiento
1349
+ *
1350
+ * @example
1351
+ * logger.badges(['v3', 'stable']).info('Release publicado');
1352
+ * logger.badges(['API', 'v2']).warn('Endpoint deprecado');
1353
+ *
1354
+ */
1355
+ badges(badges) {
1356
+ this.badgeList = [...badges];
1357
+ return this;
1358
+ }
1359
+ /**
1360
+ * Añade un badge individual a la lista
1361
+ *
1362
+ * @param {string} badge - Badge a añadir
1363
+ * @returns {this} Logger instance para encadenamiento
1364
+ *
1365
+ * @example
1366
+ * logger.badge('DEBUG').badge('AUTH').info('Token validado');
1367
+ *
1368
+ */
1369
+ badge(badge) {
1370
+ if (!this.badgeList.includes(badge)) this.badgeList.push(badge);
1371
+ return this;
1372
+ }
1373
+ /**
1374
+ * Limpia todos los badges activos
1375
+ *
1376
+ * @returns {this} Logger instance para encadenamiento
1377
+ *
1378
+ * @example
1379
+ * logger.clearBadges().info('Sin badges');
1380
+ *
1381
+ */
1382
+ clearBadges() {
1383
+ this.badgeList = [];
1384
+ return this;
1385
+ }
1386
+ component(name) {
1387
+ return new ComponentLogger(this, name);
1388
+ }
1389
+ api(name) {
1390
+ return new APILogger(this, name);
1391
+ }
1392
+ scope(name) {
1393
+ return new ScopedLogger(this, name);
1394
+ }
1395
+ /**
1396
+ * Personalización simple con configuración mínima
1397
+ *
1398
+ * @param {Object} overrides - Opciones de personalización
1399
+ * @param {Object} overrides.message - Configuración del mensaje
1400
+ * @param {Object} overrides.timestamp - Configuración del timestamp
1401
+ * @param {Object} overrides.location - Configuración de ubicación
1402
+ * @param {Object} overrides.level - Configuración del nivel
1403
+ * @param {Object} overrides.prefix - Configuración del prefijo
1404
+ * @param {string} overrides.spacing - Espaciado: 'compact' | 'normal' | 'spacious'
1405
+ *
1406
+ * @example
1407
+ * logger.customize({
1408
+ * message: { color: '#00ff00', size: '16px' },
1409
+ * timestamp: { show: false },
1410
+ * spacing: 'compact'
1411
+ * });
1412
+ *
1413
+ */
1414
+ customize(overrides) {
1415
+ if (overrides.timestamp?.show !== void 0) this.displaySettings.showTimestamp = overrides.timestamp.show;
1416
+ if (overrides.location?.show !== void 0) this.displaySettings.showLocation = overrides.location.show;
1417
+ if (overrides.prefix?.show !== void 0) {}
1418
+ this._customization = overrides;
1419
+ this.success("Customization applied");
1420
+ }
1421
+ /**
1422
+ * Añade un handler personalizado para extender funcionalidad
1423
+ *
1424
+ * @param {ILogHandler} handler - Handler que implementa ILogHandler
1425
+ *
1426
+ * @example
1427
+ * // Handler personalizado para enviar logs a servidor
1428
+ * logger.addHandler({
1429
+ * handle(level, message, args, metadata) {
1430
+ * fetch('/logs', { method: 'POST', body: JSON.stringify({ level, message }) });
1431
+ * }
1432
+ * });
1433
+ *
1434
+ * @example
1435
+ * // Para escribir a archivo, usa `addTransport` con un `FileTransport`
1436
+ * logger.addTransport({ target: new FileTransport({ destination: 'app.log' }) });
1437
+ *
1438
+ */
1439
+ addHandler(handler) {
1440
+ this.handlers.push(handler);
1441
+ }
1442
+ /**
1443
+ * Obtiene todos los handlers registrados
1444
+ *
1445
+ * @returns {ILogHandler[]} Array de handlers activos
1446
+ */
1447
+ getHandlers() {
1448
+ return [...this.handlers];
1449
+ }
1450
+ /**
1451
+ * Añade un serializador personalizado para un tipo específico
1452
+ *
1453
+ * @param type - Constructor del tipo a serializar
1454
+ * @param serializer - Función de serialización
1455
+ * @param priority - Prioridad (mayor = primero)
1456
+ *
1457
+ * @example
1458
+ * logger.addSerializer(Error, (err) => ({
1459
+ * name: err.name,
1460
+ * message: err.message,
1461
+ * stack: err.stack?.split('\n').slice(0, 5)
1462
+ * }));
1463
+ *
1464
+ */
1465
+ addSerializer(type, serializer, priority) {
1466
+ this.serializerBridge.addSerializer(type, serializer, priority);
1467
+ }
1468
+ /**
1469
+ * Elimina un serializador registrado
1470
+ *
1471
+ * @param type - Constructor del tipo a remover
1472
+ * @returns true si se eliminó
1473
+ *
1474
+ */
1475
+ removeSerializer(type) {
1476
+ return this.serializerBridge.removeSerializer(type);
1477
+ }
1478
+ /**
1479
+ * Obtiene el registry de serializadores
1480
+ *
1481
+ * @returns SerializerRegistry
1482
+ */
1483
+ getSerializerRegistry() {
1484
+ return this.serializerBridge.getSerializerRegistry();
1485
+ }
1486
+ /**
1487
+ * Registra un hook para un evento
1488
+ *
1489
+ * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
1490
+ * @param callback - Función a ejecutar
1491
+ * @param priority - Prioridad (mayor = primero)
1492
+ * @returns Función para desregistrar
1493
+ *
1494
+ * @example
1495
+ * const unsubscribe = logger.on('beforeLog', (entry) => {
1496
+ * entry.correlationId = getCorrelationId();
1497
+ * return entry;
1498
+ * });
1499
+ *
1500
+ */
1501
+ on(event, callback, priority) {
1502
+ return this.hookBridge.on(event, callback, priority);
1503
+ }
1504
+ /**
1505
+ * Registra un hook que se ejecuta solo una vez
1506
+ *
1507
+ * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
1508
+ * @param callback - Función a ejecutar
1509
+ * @param priority - Prioridad (mayor = primero)
1510
+ * @returns Función para desregistrar
1511
+ *
1512
+ */
1513
+ once(event, callback, priority) {
1514
+ return this.hookBridge.once(event, callback, priority);
1515
+ }
1516
+ /**
1517
+ * Elimina un hook registrado
1518
+ *
1519
+ * @param event - Evento del hook
1520
+ * @param callback - Callback a remover
1521
+ * @returns true si se eliminó
1522
+ *
1523
+ */
1524
+ off(event, callback) {
1525
+ return this.hookBridge.off(event, callback);
1526
+ }
1527
+ /**
1528
+ * Añade un middleware al pipeline
1529
+ *
1530
+ * @param middleware - Función middleware
1531
+ * @param priority - Prioridad (mayor = primero)
1532
+ * @returns Función para desregistrar
1533
+ *
1534
+ * @example
1535
+ * logger.use((entry, next) => {
1536
+ * entry.requestId = asyncLocalStorage.getStore()?.requestId;
1537
+ * next();
1538
+ * });
1539
+ *
1540
+ */
1541
+ use(middleware, priority) {
1542
+ return this.hookBridge.use(middleware, priority);
1543
+ }
1544
+ /**
1545
+ * Obtiene el HookManager
1546
+ *
1547
+ * @returns HookManager
1548
+ */
1549
+ getHookManager() {
1550
+ return this.hookBridge.getHookManager();
1551
+ }
1552
+ /**
1553
+ * Añade un transport para envío de logs
1554
+ *
1555
+ * @param target - Configuración del transport
1556
+ * @returns ID único del transport
1557
+ *
1558
+ * @example
1559
+ * // File transport
1560
+ * logger.addTransport({
1561
+ * target: 'file',
1562
+ * options: { destination: '/var/log/app.log' }
1563
+ * });
1564
+ *
1565
+ * @example
1566
+ * // HTTP transport con batching
1567
+ * logger.addTransport({
1568
+ * target: 'http',
1569
+ * options: {
1570
+ * url: 'https://logs.example.com',
1571
+ * batchSize: 100,
1572
+ * flushInterval: 5000
1573
+ * },
1574
+ * level: 'warn'
1575
+ * });
1576
+ *
1577
+ */
1578
+ addTransport(target) {
1579
+ return this.transportBridge.addTransport(target);
1580
+ }
1581
+ /**
1582
+ * Elimina un transport
1583
+ *
1584
+ * @param id - ID del transport a remover
1585
+ * @returns true si se eliminó
1586
+ *
1587
+ */
1588
+ removeTransport(id) {
1589
+ return this.transportBridge.removeTransport(id);
1590
+ }
1591
+ /**
1592
+ * Fuerza el flush de todos los transports
1593
+ *
1594
+ * @returns Promise que resuelve cuando todos los buffers están vaciados
1595
+ *
1596
+ */
1597
+ async flushTransports() {
1598
+ await this.transportBridge.flushTransports();
1599
+ }
1600
+ /**
1601
+ * Cierra todos los transports
1602
+ *
1603
+ * @returns Promise que resuelve cuando todos están cerrados
1604
+ *
1605
+ */
1606
+ async closeTransports() {
1607
+ await this.transportBridge.closeTransports();
1608
+ }
1609
+ /**
1610
+ * Obtiene el TransportManager
1611
+ *
1612
+ * @returns TransportManager o undefined si no hay transports
1613
+ */
1614
+ getTransportManager() {
1615
+ return this.transportBridge.getTransportManager();
1616
+ }
1617
+ /**
1618
+ * Verifica si un nivel de log debe mostrarse según la verbosidad actual.
1619
+ * @private
1620
+ * @param {LogLevel} level - Nivel de log a verificar
1621
+ * @returns {boolean} True si debe mostrarse, false si no
1622
+ */
1623
+ shouldLog(level) {
1624
+ if (this.config.verbosity === "silent") return false;
1625
+ return LOG_LEVELS[level] >= LOG_LEVELS[this.config.verbosity];
1626
+ }
1627
+ /**
1628
+ * Builds and dispatches a `TransportRecord` to the {@link TransportManager}
1629
+ * (no-op if no transports are registered). Shared by every log path —
1630
+ * `log()`, `success()`, and visual methods like `table()` / `group()` /
1631
+ * `time()` — so all emissions hit the same transport pipeline.
1632
+ *
1633
+ * @param level - The canonical log level (trace/debug/info/warn/error/critical)
1634
+ * @param message - Final, post-hook message text
1635
+ * @param prefix - Effective prefix (global + scope)
1636
+ * @param stackInfo - Optional caller location
1637
+ * @param extra - Optional fields to merge into the record (e.g. `{ tag: 'success' }`)
1638
+ */
1639
+ _dispatchTag;
1640
+ /**
1641
+ * Computes the fully-merged context for this logger.
1642
+ *
1643
+ * The context chain is built at child-creation time: each child stores
1644
+ * its parent's fully-merged context (at that moment) as _parentContextRecord.
1645
+ * This means _parentContextRecord already contains all ancestors' bindings
1646
+ * in the correct precedence order (root first, nearest child last).
1647
+ *
1648
+ * Merge order (later wins):
1649
+ * 1. _parentContextRecord — parent's merged context snapshot at creation time
1650
+ * 2. _bindings — this logger's own bindings (child() calls)
1651
+ * 3. ALS store — withContext/withContextAsync scope (highest priority)
1652
+ *
1653
+ * @internal
1654
+ * @returns The merged context record
1655
+ */
1656
+ _getMergedContext() {
1657
+ let merged = this._parentContextRecord ?? {};
1658
+ if (this._bindings && Object.keys(this._bindings).length > 0) merged = {
1659
+ ...merged,
1660
+ ...this._bindings
1661
+ };
1662
+ const alsContext = this.logContext._getAlsStore?.() ?? {};
1663
+ if (alsContext && Object.keys(alsContext).length > 0) merged = {
1664
+ ...merged,
1665
+ ...alsContext
1666
+ };
1667
+ return merged;
1668
+ }
1669
+ /** @internal Exposes base merged context (no ALS) to LogContext child factory closure. */
1670
+ _captureMergedContext() {
1671
+ let merged = this._parentContextRecord ?? {};
1672
+ if (this._bindings && Object.keys(this._bindings).length > 0) merged = {
1673
+ ...merged,
1674
+ ...this._bindings
1675
+ };
1676
+ return merged;
1677
+ }
1678
+ dispatchToTransports(level, message, prefix, stackInfo, extra) {
1679
+ const record = {
1680
+ level,
1681
+ levelValue: LOG_LEVELS[level],
1682
+ severityNumber: LOG_LEVEL_TO_SEVERITY_NUMBER[level],
1683
+ severityText: LOG_LEVEL_TO_SEVERITY_TEXT[level],
1684
+ time: Date.now(),
1685
+ msg: message,
1686
+ prefix,
1687
+ location: stackInfo ? {
1688
+ file: stackInfo.file,
1689
+ line: stackInfo.line,
1690
+ column: stackInfo.column,
1691
+ function: stackInfo.function
1692
+ } : void 0,
1693
+ attributes: Object.keys(this.logContext._getContextRecord()).length > 0 ? toLogAttributes(this.logContext._getContextRecord()) : void 0,
1694
+ resource: this.logContext._getResource() ? { ...this.logContext._getResource() } : void 0,
1695
+ ...extra
1696
+ };
1697
+ this.transportBridge.writeRecord(record);
1698
+ }
1699
+ /**
1700
+ * Obtiene el prefijo efectivo (global + scope)
1701
+ * @private
1702
+ * @returns {string | undefined} Prefijo combinado o undefined
1703
+ */
1704
+ getEffectivePrefix() {
1705
+ const parts = [this.config.globalPrefix, this.scopedPrefix].filter(Boolean);
1706
+ return parts.length > 0 ? parts.join(":") : void 0;
1707
+ }
1708
+ /**
1709
+ * Método central de logging. Awaits the `beforeLog` hook pipeline
1710
+ * synchronously (so redactions / enrichments are reflected in the
1711
+ * emitted message before console + transport dispatch).
1712
+ *
1713
+ * Fire-and-forget callers (e.g. `logger.info(...)` without `await`)
1714
+ * still work — the resulting `Promise<void>` is dropped on the floor.
1715
+ * Awaiting is recommended when `beforeLog` hooks mutate `message`
1716
+ * (e.g. PII redaction, correlation IDs).
1717
+ *
1718
+ * @protected
1719
+ * @param level - Nivel del log
1720
+ * @param args - Argumentos a loggear
1721
+ * @returns Promise that resolves once the record has been dispatched
1722
+ *
1723
+ */
1724
+ /**
1725
+ * Protected logging method. Awaits the `beforeLog` hook pipeline
1726
+ * synchronously (so redactions / enrichments are reflected in the
1727
+ * emitted message before console + transport dispatch).
1728
+ *
1729
+ * Fire-and-forget callers (e.g. `logger.info(...)` without `await`)
1730
+ * still work — the resulting `Promise<void>` is dropped on the floor.
1731
+ * Awaiting is recommended when `beforeLog` hooks mutate `message`
1732
+ * (e.g. PII redaction, correlation IDs).
1733
+ *
1734
+ * @protected
1735
+ * @param level - Nivel del log
1736
+ * @param args - Argumentos a loggear
1737
+ * @param tag - Optional tag forwarded to `dispatchToTransports` as
1738
+ * `TransportRecord.tag` (e.g. `'success'` for success records).
1739
+ * @returns Promise that resolves once the record has been dispatched
1740
+ *
1741
+ */
1742
+ async log(level, ...args) {
1743
+ if (!this.shouldLog(level)) return;
1744
+ const dispatchTag = this._dispatchTag;
1745
+ this._dispatchTag = void 0;
1746
+ const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
1747
+ const prefix = this.getEffectivePrefix();
1748
+ const timestamp = formatTimestamp();
1749
+ const serializedArgs = args.map((arg) => this.serializerBridge.getSerializerRegistry().serialize(arg));
1750
+ let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : "";
1751
+ if (this.badgeList.length > 0 && this.displaySettings.showBadges) message = this.badgeList.map((b) => `[${b}]`).join("") + " " + message;
1752
+ const additionalArgs = serializedArgs.slice(1);
1753
+ const hookEntry = {
1754
+ level,
1755
+ message,
1756
+ args: serializedArgs,
1757
+ timestamp,
1758
+ prefix,
1759
+ stackInfo: stackInfo ?? void 0
1760
+ };
1761
+ let processed;
1762
+ try {
1763
+ processed = await this.hookBridge.getHookManager().emit("beforeLog", hookEntry);
1764
+ } catch (error) {
1765
+ console.error("HookManager beforeLog failed:", error);
1766
+ processed = hookEntry;
1767
+ }
1768
+ message = processed.message;
1769
+ const [format, ...styles] = createStyledOutput(level, this.styleManager.getStyles(), prefix, message, this.displaySettings.showLocation ? stackInfo : null, this.config.autoDetectTheme, this._activePreset, this._activePresetName);
1770
+ const finalFormat = " ".repeat(this.groupDepth) + format;
1771
+ this.writeOutput(finalFormat, level, styles, additionalArgs);
1772
+ const metadata = {
1773
+ timestamp,
1774
+ level,
1775
+ prefix,
1776
+ stackInfo: stackInfo ?? void 0
1777
+ };
1778
+ this.handlers.forEach((handler) => {
1779
+ try {
1780
+ handler.handle(level, message, serializedArgs, metadata);
1781
+ } catch (error) {
1782
+ console.error("Log handler failed:", error);
1783
+ }
1784
+ });
1785
+ if (dispatchTag !== void 0) this.dispatchToTransports(level, message, prefix, stackInfo, { tag: dispatchTag });
1786
+ else this.dispatchToTransports(level, message, prefix, stackInfo);
1787
+ this.hookBridge.getHookManager().emit("afterLog", processed).catch(() => {});
1788
+ }
1789
+ logWithBindings(bindings, level, ...args) {
1790
+ if (!this.shouldLog(level)) return Promise.resolve();
1791
+ let prefix = "";
1792
+ const colorCapability = getColorCapability();
1793
+ if (bindings.badges?.length) prefix += bindings.badges.map((b) => formatBadge(b, "pill", colorCapability, "#00ff88")).join(" ") + " ";
1794
+ if (bindings.scope) prefix += formatBadge(bindings.scope, "pill", colorCapability, "#00ffff") + " ";
1795
+ if (prefix && args.length > 0) args[0] = prefix + String(args[0]);
1796
+ return this.log(level, ...args);
1797
+ }
1798
+ /**
1799
+ * Like `logWithBindings()` but sets _dispatchTag first so that
1800
+ * `log()` dispatches with the tag. Used by ScopedLogger.success()
1801
+ * to propagate tag:'success' through the normal log() pipeline.
1802
+ */
1803
+ logWithBindingsAndTag(bindings, level, tag, ...args) {
1804
+ this._dispatchTag = tag;
1805
+ return this.logWithBindings(bindings, level, ...args);
1806
+ }
1807
+ debug(...args) {
1808
+ return this.log("debug", ...args);
1809
+ }
1810
+ /**
1811
+ * Registra mensajes informativos. Devuelve `Promise<void>` desde 5.1.0.
1812
+ *
1813
+ * @param args - Mensajes y datos informativos
1814
+ *
1815
+ * @example
1816
+ * logger.info('Servidor iniciado en puerto 3000');
1817
+ * await logger.info('Procesando', totalItems, 'elementos'); // espera hooks
1818
+ *
1819
+ */
1820
+ info(...args) {
1821
+ return this.log("info", ...args);
1822
+ }
1823
+ /**
1824
+ * Registra mensajes de advertencia. Devuelve `Promise<void>` desde 5.1.0.
1825
+ *
1826
+ * @param args - Mensajes de advertencia
1827
+ *
1828
+ */
1829
+ warn(...args) {
1830
+ return this.log("warn", ...args);
1831
+ }
1832
+ /**
1833
+ * Registra mensajes de error. Devuelve `Promise<void>` desde 5.1.0.
1834
+ *
1835
+ * @param args - Mensaje de error y stack traces
1836
+ *
1837
+ */
1838
+ error(...args) {
1839
+ return this.log("error", ...args);
1840
+ }
1841
+ /**
1842
+ * Registra mensajes de éxito. Mapeado internamente a nivel `info` con
1843
+ * styling de success y `record.tag = 'success'` para que los transports
1844
+ * puedan distinguirlo (sin perder info semantics para filtering).
1845
+ *
1846
+ * @param args - Mensaje + datos adicionales
1847
+ *
1848
+ * @example
1849
+ * logger.success('Base de datos conectada');
1850
+ * logger.success('Usuario creado con ID:', userId);
1851
+ * logger.success('✓ Tests pasados: 42/42');
1852
+ *
1853
+ */
1854
+ async success(...args) {
1855
+ if (!this.shouldLog("info")) return;
1856
+ const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
1857
+ const prefix = this.getEffectivePrefix();
1858
+ const timestamp = formatTimestamp();
1859
+ const serializedArgs = args.map((arg) => this.serializerBridge.getSerializerRegistry().serialize(arg));
1860
+ let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : "";
1861
+ if (this.badgeList.length > 0 && this.displaySettings.showBadges) message = this.badgeList.map((b) => `[${b}]`).join("") + " " + message;
1862
+ const additionalArgs = serializedArgs.slice(1);
1863
+ const hookEntry = {
1864
+ level: "info",
1865
+ message,
1866
+ args: serializedArgs,
1867
+ timestamp,
1868
+ prefix,
1869
+ stackInfo: stackInfo ?? void 0
1870
+ };
1871
+ try {
1872
+ message = (await this.hookBridge.getHookManager().emit("beforeLog", hookEntry)).message;
1873
+ } catch {}
1874
+ const [format, ...styles] = createStyledOutput("info", this.styleManager.getStyles(), prefix, message, this.displaySettings.showLocation ? stackInfo : null, this.config.autoDetectTheme, this._activePreset, this._activePresetName);
1875
+ const successStyle = this.styleManager.getStyles().success;
1876
+ const emoji = successStyle?.emoji ?? "✅";
1877
+ const label = successStyle?.label ?? "SUCCESS";
1878
+ const successFormat = format.replace(/ℹ️ INFO/, `${emoji} ${label}`);
1879
+ const finalFormat = " ".repeat(this.groupDepth) + successFormat;
1880
+ this.writeOutput(finalFormat, "info", styles, additionalArgs);
1881
+ const metadata = {
1882
+ timestamp,
1883
+ level: "info",
1884
+ prefix,
1885
+ stackInfo: stackInfo ?? void 0
1886
+ };
1887
+ this.handlers.forEach((handler) => {
1888
+ try {
1889
+ handler.handle("info", message, args, metadata);
1890
+ } catch (error) {
1891
+ console.error("Log handler failed:", error);
1892
+ }
1893
+ });
1894
+ this._dispatchTag = "success";
1895
+ await this.log("info", ...args);
1896
+ this.hookBridge.getHookManager().emit("afterLog", hookEntry).catch(() => {});
1897
+ }
1898
+ /**
1899
+ * Registra información de trace (nivel más bajo, debajo de debug).
1900
+ * Alineado con OpenTelemetry `TRACE` severity (1-4).
1901
+ *
1902
+ * @param args - Datos muy verbosos (entrada/salida de funciones, valores intermedios)
1903
+ *
1904
+ * @example
1905
+ * logger.trace('Entrando en función processData');
1906
+ * logger.trace('Variables intermedias:', { a, b, c });
1907
+ *
1908
+ */
1909
+ trace(...args) {
1910
+ this.log("trace", ...args);
1911
+ }
1912
+ /**
1913
+ * Registra errores críticos (prioridad más alta). Devuelve `Promise<void>` desde 5.1.0.
1914
+ *
1915
+ * @param args - Errores críticos del sistema
1916
+ *
1917
+ * @example
1918
+ * await logger.critical('Sistema caído - reinicio inmediato requerido');
1919
+ *
1920
+ */
1921
+ critical(...args) {
1922
+ return this.log("critical", ...args);
1923
+ }
1924
+ /**
1925
+ * Muestra datos en formato de tabla. Pasa por la pipeline completa
1926
+ * (outputMode-respecting writeOutput + transports + hooks).
1927
+ *
1928
+ * @param data - Array de objetos o matriz
1929
+ * @param columns - Columnas específicas a mostrar (opcional)
1930
+ *
1931
+ * @example
1932
+ * logger.table([{ id: 1, nombre: 'Juan' }, { id: 2, nombre: 'María' }]);
1933
+ *
1934
+ */
1935
+ table(data, columns) {
1936
+ if (!this.shouldLog("info")) return;
1937
+ const prefix = this.getEffectivePrefix();
1938
+ const tableStyle = StylePresets.accent().build();
1939
+ const format = `%c${`📊 TABLE${prefix ? ` [${prefix}]` : ""}`}`;
1940
+ const styles = [tableStyle];
1941
+ this.writeOutput(format, "info", styles, []);
1942
+ [...columns ? [columns] : []];
1943
+ if (this.config.outputMode !== "silent") if (columns) console.table(data, columns);
1944
+ else console.table(data);
1945
+ const message = `table:${Array.isArray(data) ? `${data.length} rows` : "data"}`;
1946
+ const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
1947
+ this.dispatchToTransports("info", message, prefix, stackInfo, { attributes: {
1948
+ ...this.logContext._getContextRecord(),
1949
+ "logger.visual": "table",
1950
+ "logger.data": JSON.stringify(data).slice(0, 4096),
1951
+ ...columns ? { "logger.columns": columns.join(",") } : {}
1952
+ } });
1953
+ }
1954
+ /**
1955
+ * Inicia un grupo colapsable en la consola. Emite un marker a
1956
+ * transports con `attributes.logger.visual = 'groupStart'` para que
1957
+ * backends puedan reconstruir la jerarquía.
1958
+ *
1959
+ * @param label - Etiqueta del grupo
1960
+ * @param collapsed - Si el grupo inicia colapsado (default: false)
1961
+ *
1962
+ * @example
1963
+ * logger.group('Procesando usuarios');
1964
+ * logger.info('Usuario 1 procesado');
1965
+ * logger.groupEnd();
1966
+ *
1967
+ */
1968
+ group(label, collapsed = false) {
1969
+ const groupStyle = new StyleBuilder().bg("linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%)").color("#1565c0").border("1px solid #90caf9").padding("4px 12px").rounded("6px").bold().build();
1970
+ const format = `%c📁 ${label}`;
1971
+ if (this.config.outputMode !== "silent") if (collapsed) console.groupCollapsed(format, groupStyle);
1972
+ else console.group(format, groupStyle);
1973
+ this.groupDepth++;
1974
+ const prefix = this.getEffectivePrefix();
1975
+ const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
1976
+ this.dispatchToTransports("info", `group:start:${label}`, prefix, stackInfo, { attributes: {
1977
+ ...this.logContext._getContextRecord(),
1978
+ "logger.visual": "groupStart",
1979
+ "logger.group.label": label,
1980
+ "logger.group.collapsed": collapsed,
1981
+ "logger.group.depth": this.groupDepth
1982
+ } });
1983
+ }
1984
+ /**
1985
+ * Finaliza el grupo actual de la consola. Emite un marker a transports
1986
+ * simétrico al `group()` start, para que backends puedan cerrar la
1987
+ * jerarquía correctamente.
1988
+ *
1989
+ * @example
1990
+ * logger.group('Operaciones');
1991
+ * logger.info('Operación 1');
1992
+ * logger.groupEnd();
1993
+ *
1994
+ */
1995
+ groupEnd() {
1996
+ if (this.groupDepth > 0) {
1997
+ this.groupDepth--;
1998
+ if (this.config.outputMode !== "silent") console.groupEnd();
1999
+ const prefix = this.getEffectivePrefix();
2000
+ const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
2001
+ this.dispatchToTransports("info", "group:end", prefix, stackInfo, { attributes: {
2002
+ ...this.logContext._getContextRecord(),
2003
+ "logger.visual": "groupEnd",
2004
+ "logger.group.depth": this.groupDepth
2005
+ } });
2006
+ }
2007
+ }
2008
+ /**
2009
+ * Inicia un temporizador con la etiqueta dada
2010
+ *
2011
+ * @param {string} label - Etiqueta identificadora del temporizador
2012
+ *
2013
+ * @example
2014
+ * logger.time('proceso-datos');
2015
+ * // ... operación costosa ...
2016
+ * logger.timeEnd('proceso-datos'); // ⏱️ Timer ended: proceso-datos - 1523.45ms
2017
+ *
2018
+ */
2019
+ time(label) {
2020
+ const timer = {
2021
+ label,
2022
+ startTime: (typeof performance !== "undefined" ? performance : Date).now()
2023
+ };
2024
+ this.timers.set(label, timer);
2025
+ const timerStyle = StylePresets.warning().build();
2026
+ const format = `%c⏱️ Timer started: ${label}`;
2027
+ this.writeOutput(format, "debug", [timerStyle], []);
2028
+ }
2029
+ /**
2030
+ * Finaliza un temporizador y muestra el tiempo transcurrido
2031
+ *
2032
+ * @param {string} label - Etiqueta del temporizador a finalizar
2033
+ * @returns {number} Elapsed milliseconds, or -1 if timer not found
2034
+ *
2035
+ * @example
2036
+ * logger.time('consulta-db');
2037
+ * await consultarBaseDatos();
2038
+ * const elapsed = logger.timeEnd('consulta-db'); // ⏱️ Timer ended: consulta-db - 234.56ms
2039
+ *
2040
+ */
2041
+ timeEnd(label) {
2042
+ const timer = this.timers.get(label);
2043
+ if (!timer) {
2044
+ this.warn(`Timer '${label}' does not exist`);
2045
+ return -1;
2046
+ }
2047
+ const elapsed = (typeof performance !== "undefined" ? performance : Date).now() - timer.startTime;
2048
+ this.timers.delete(label);
2049
+ const timerStyle = StylePresets.success().build();
2050
+ const format = `%c⏱️ Timer ended: ${label} - ${elapsed.toFixed(2)}ms`;
2051
+ this.writeOutput(format, "info", [timerStyle], []);
2052
+ const prefix = this.getEffectivePrefix();
2053
+ const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
2054
+ this.dispatchToTransports("info", `timer:${label}`, prefix, stackInfo, {
2055
+ tag: "success",
2056
+ attributes: {
2057
+ ...this.logContext._getContextRecord(),
2058
+ "logger.visual": "timer",
2059
+ "logger.timer.label": label,
2060
+ "logger.timer.elapsedMs": elapsed
2061
+ }
2062
+ });
2063
+ return elapsed;
2064
+ }
2065
+ /**
2066
+ * Muestra un banner con el tipo especificado o configurado
2067
+ *
2068
+ * @param {BannerType} bannerType - Tipo de banner (opcional)
2069
+ *
2070
+ * @example
2071
+ * logger.showBanner('ascii'); // Banner ASCII art
2072
+ * logger.showBanner('unicode'); // Banner con caracteres Unicode
2073
+ * logger.showBanner('svg'); // Banner con gráfico SVG
2074
+ * logger.showBanner(); // Usa el tipo configurado
2075
+ *
2076
+ */
2077
+ showBanner(bannerType) {
2078
+ displayInitBanner(bannerType ? bannerType : this.config.bannerType);
2079
+ }
2080
+ /**
2081
+ * Registra mensaje con imagen SVG de fondo
2082
+ *
2083
+ * @param {string} message - Mensaje a mostrar
2084
+ * @param {string} svgContent - Contenido SVG personalizado (opcional)
2085
+ * @param {StyleOptions} options - Opciones de estilo (ancho, alto, padding)
2086
+ *
2087
+ * @example
2088
+ * // SVG automático con gradiente
2089
+ * logger.logWithSVG('🎆 Bienvenido a Better Logger');
2090
+ *
2091
+ * @example
2092
+ * // SVG personalizado
2093
+ * const customSVG = '<svg>...</svg>';
2094
+ * logger.logWithSVG('Logo', customSVG, { width: 400, height: 100 });
2095
+ *
2096
+ */
2097
+ logWithSVG(message, svgContent, options = {}) {
2098
+ if (!this.shouldLog("info")) return;
2099
+ const { width = 300, height = 60, padding = "30px 150px" } = options;
2100
+ let svgDataUri = "";
2101
+ if (svgContent) svgDataUri = `data:image/svg+xml,${encodeURIComponent(svgContent)}`;
2102
+ else {
2103
+ 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>`;
2104
+ svgDataUri = `data:image/svg+xml,${encodeURIComponent(defaultSVG)}`;
2105
+ }
2106
+ const svgStyle = new StyleBuilder().bg(`url("${svgDataUri}") no-repeat center center`).padding(padding).color("transparent").rounded("4px").build();
2107
+ this.writeOutput(`%c${message}`, "info", [svgStyle], []);
2108
+ const prefix = this.getEffectivePrefix();
2109
+ const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
2110
+ this.dispatchToTransports("info", `svg:${message}`, prefix, stackInfo, { attributes: {
2111
+ ...this.logContext._getContextRecord(),
2112
+ "logger.visual": "svg",
2113
+ "logger.svg.width": width,
2114
+ "logger.svg.height": height
2115
+ } });
2116
+ }
2117
+ /**
2118
+ * Registra mensaje con gradiente animado de fondo
2119
+ *
2120
+ * @param {string} message - Mensaje a animar
2121
+ * @param {number} duration - Duración de la animación en segundos (default: 3)
2122
+ *
2123
+ * @example
2124
+ * logger.logAnimated('🌈 Animación en progreso');
2125
+ * logger.logAnimated('Cargando...', 5); // Animación de 5 segundos
2126
+ *
2127
+ */
2128
+ logAnimated(message, duration = 3) {
2129
+ if (!this.shouldLog("info")) return;
2130
+ if (typeof document !== "undefined") {
2131
+ if (!document.getElementById("logger-animations")) {
2132
+ const style = document.createElement("style");
2133
+ style.id = "logger-animations";
2134
+ style.textContent = `
2135
+ @keyframes loggerGradient {
2136
+ 0% { background-position: 0% 50%; }
2137
+ 50% { background-position: 100% 50%; }
2138
+ 100% { background-position: 0% 50%; }
2139
+ }
2140
+ `;
2141
+ document.head.appendChild(style);
2142
+ }
2143
+ }
2144
+ const animatedStyle = new StyleBuilder().bg("linear-gradient(-45deg, #667eea, #764ba2, #667eea, #764ba2)").css("background-size", "400% 400%").color("#ffffff").padding("12px 20px").rounded("8px").bold().font("Monaco, Consolas, monospace").animation(`loggerGradient ${duration}s ease infinite`).display("inline-block").build();
2145
+ this.writeOutput(`%c${message}`, "info", [animatedStyle], []);
2146
+ const prefix = this.getEffectivePrefix();
2147
+ const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
2148
+ this.dispatchToTransports("info", `animated:${message}`, prefix, stackInfo, { attributes: {
2149
+ ...this.logContext._getContextRecord(),
2150
+ "logger.visual": "animated",
2151
+ "logger.animation.durationSec": duration
2152
+ } });
2153
+ }
2154
+ /**
2155
+ * Displays a step progress indicator in the terminal
2156
+ *
2157
+ * @param {number} current - Current step number
2158
+ * @param {number} total - Total number of steps
2159
+ * @param {string} message - Step description
2160
+ *
2161
+ * @example
2162
+ * logger.step(1, 5, 'Analyzing repository...');
2163
+ * logger.step(2, 5, 'Generating commit message...');
2164
+ *
2165
+ */
2166
+ step(current, total, message) {
2167
+ this.terminalBridge.step(current, total, message);
2168
+ }
2169
+ /**
2170
+ * Displays a styled header with optional subtitle
2171
+ *
2172
+ * @param {string} title - Main title text
2173
+ * @param {string} subtitle - Optional subtitle (rendered dimmed)
2174
+ *
2175
+ * @example
2176
+ * logger.header('Commit Wizard', 'v2.0.0');
2177
+ *
2178
+ */
2179
+ header(title, subtitle) {
2180
+ this.terminalBridge.header(title, subtitle);
2181
+ }
2182
+ /**
2183
+ * Displays a horizontal divider line
2184
+ *
2185
+ * @example
2186
+ * logger.divider();
2187
+ *
2188
+ */
2189
+ divider() {
2190
+ this.terminalBridge.divider();
2191
+ }
2192
+ /**
2193
+ * Outputs a blank line
2194
+ *
2195
+ * @example
2196
+ * logger.blank();
2197
+ *
2198
+ */
2199
+ blank() {
2200
+ this.terminalBridge.blank();
2201
+ }
2202
+ /**
2203
+ * Renders content inside a bordered box
2204
+ *
2205
+ * @param {string} content - Content string (may contain newlines)
2206
+ * @param {IBoxOptions} options - Box rendering options
2207
+ *
2208
+ * @example
2209
+ * logger.box('3 commits generated\nProvider: Groq', { title: 'Done', borderColor: '#00ff00' });
2210
+ *
2211
+ */
2212
+ box(content, options) {
2213
+ this.terminalBridge.box(content, options);
2214
+ }
2215
+ /**
2216
+ * Renders an array of objects as a formatted ASCII table.
2217
+ * Note: This is distinct from the existing table() method which uses console.table.
2218
+ *
2219
+ * @param {Record<string, unknown>[]} rows - Array of row objects
2220
+ * @param {ITableOptions} options - Table rendering options
2221
+ *
2222
+ * @example
2223
+ * logger.cliTable([
2224
+ * { provider: 'Groq', status: 'Available', model: 'llama-3.3-70b' },
2225
+ * { provider: 'Gemini', status: 'Configured', model: 'gemini-2.5-flash' },
2226
+ * ]);
2227
+ *
2228
+ */
2229
+ cliTable(rows, options) {
2230
+ this.terminalBridge.cliTable(rows, options);
2231
+ }
2232
+ /**
2233
+ * Creates a spinner handle for showing progress during async operations.
2234
+ * Returns a NoopSpinner in non-TTY environments.
2235
+ *
2236
+ * @param {string} message - Initial spinner text
2237
+ * @returns {ISpinnerHandle} Spinner controller
2238
+ *
2239
+ * @example
2240
+ * const s = logger.spinner('Analyzing repository...');
2241
+ * s.start();
2242
+ * await analyzeRepo();
2243
+ * s.succeed('Analysis complete (1.2s)');
2244
+ *
2245
+ */
2246
+ spinner(message) {
2247
+ return this.terminalBridge.spinner(message);
2248
+ }
2249
+ /**
2250
+ * Sets the CLI verbosity level, controlling both log verbosity and primitive visibility
2251
+ *
2252
+ * @param {CLILogLevel} level - CLI log level
2253
+ *
2254
+ * @example
2255
+ * logger.setCLILevel('quiet'); // Only errors, no CLI primitives
2256
+ * logger.setCLILevel('verbose'); // Debug logs + all CLI primitives
2257
+ *
2258
+ */
2259
+ setCLILevel(level) {
2260
+ const mapping = CLI_LEVEL_MAP[level];
2261
+ this.setVerbosity(mapping.verbosity);
2262
+ this.terminalBridge.setShowPrimitives(mapping.showPrimitives);
2263
+ this.config.cliLevel = level;
2264
+ }
2265
+ /**
2266
+ * Returns the current CLI log level
2267
+ * @returns {CLILogLevel} Current CLI log level
2268
+ */
2269
+ get cliLevel() {
2270
+ return this.config.cliLevel ?? "normal";
2271
+ }
2272
+ /**
2273
+ * Writes formatted output to the configured destination.
2274
+ * Respects outputMode configuration for console, silent, or custom output.
2275
+ *
2276
+ * @private
2277
+ * @param {string} message - Formatted log message
2278
+ * @param {LogLevel} level - Log level
2279
+ * @param {string[]} styles - CSS styles for browser console
2280
+ * @param {unknown[]} additionalArgs - Additional arguments to log
2281
+ */
2282
+ writeOutput(message, level, styles, additionalArgs) {
2283
+ const mode = this.config.outputMode ?? "console";
2284
+ if (mode === "silent") return;
2285
+ if (mode === "custom" && this.config.outputWriter) {
2286
+ const fullMessage = additionalArgs.length > 0 ? `${message} ${additionalArgs.map((a) => String(a)).join(" ")}` : message;
2287
+ this.config.outputWriter.write(fullMessage, level, styles);
2288
+ return;
2289
+ }
2290
+ if (additionalArgs.length > 0) console.log(message, ...styles, ...additionalArgs);
2291
+ else console.log(message, ...styles);
2292
+ }
2293
+ /**
2294
+ * Procesador de comandos CLI para configuración y exportación del logger
2295
+ *
2296
+ * @param {string} command - Comando CLI a ejecutar
2297
+ * @returns {Promise<void>}
2298
+ *
2299
+ * @example
2300
+ * // Comandos disponibles
2301
+ * await logger.cli('export json'); // Exporta logs en JSON
2302
+ * await logger.cli('export csv'); // Exporta logs en CSV
2303
+ * await logger.cli('theme list'); // Lista temas disponibles
2304
+ * await logger.cli('theme set neon'); // Cambia al tema neon
2305
+ * await logger.cli('config show'); // Muestra configuración actual
2306
+ * await logger.cli('history clear'); // Limpia historial de logs
2307
+ * await logger.cli('status'); // Muestra estado del logger
2308
+ * await logger.cli('help'); // Muestra ayuda de comandos
2309
+ *
2310
+ */
2311
+ async cli(command) {
2312
+ if (!this.cliProcessor) {
2313
+ this.error("CLI processor not initialized");
2314
+ return;
2315
+ }
2316
+ await this.cliProcessor.processCommand(command, this);
2317
+ }
2318
+ };
2319
+ /**
2320
+ /**
2321
+ * Lazy singleton instance — initialised on first call to {@link getDefaultLogger},
2322
+ * not on module import. Fixes BUG-N11 (eager side-effect at import time).
2323
+ *
2324
+ * @private
2325
+ */
2326
+ let _defaultLogger = null;
2327
+ /**
2328
+ * Lazily creates the default Logger singleton.
2329
+ *
2330
+ * The singleton is only built on first call, so importing the module
2331
+ * never executes `new Logger(...)` or `displayInitBanner()`. This keeps
2332
+ * module imports side-effect free.
2333
+ *
2334
+ * @returns The shared Logger instance
2335
+ */
2336
+ function getDefaultLogger() {
2337
+ if (!_defaultLogger) {
2338
+ _defaultLogger = new Logger({
2339
+ verbosity: "info",
2340
+ enableColors: true,
2341
+ enableTimestamps: true,
2342
+ enableStackTrace: true,
2343
+ cliLevel: "normal"
2344
+ });
2345
+ try {
2346
+ if (typeof window !== "undefined" || typeof document !== "undefined") displayInitBanner();
2347
+ } catch {}
2348
+ }
2349
+ return _defaultLogger;
2350
+ }
2351
+ new Proxy({}, { get(_target, prop, receiver) {
2352
+ const instance = getDefaultLogger();
2353
+ const value = Reflect.get(instance, prop, receiver);
2354
+ return typeof value === "function" ? value.bind(instance) : value;
2355
+ } });
2356
+ /**
2357
+ * Narrow a free-form `Record<string, unknown>` context into a typed
2358
+ * `ILogAttributes` bag. Unknown shapes fall back to JSON-encoded strings,
2359
+ * which keeps the OTLP transport happy (every value lands in a typed slot).
2360
+ *
2361
+ * @param input - The user-supplied context (typically `Logger.context`).
2362
+ * @returns A new attribute bag matching `ILogAttributes`.
2363
+ */
2364
+ function toLogAttributes(input) {
2365
+ const out = {};
2366
+ for (const [key, value] of Object.entries(input)) {
2367
+ const mapped = toAttributeValue(value);
2368
+ if (mapped !== void 0) out[key] = mapped;
2369
+ }
2370
+ return out;
2371
+ }
2372
+ function toAttributeValue(value) {
2373
+ if (value === null || value === void 0) return void 0;
2374
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
2375
+ if (Array.isArray(value)) {
2376
+ const values = [];
2377
+ for (const item of value) {
2378
+ const mapped = toAttributeValue(item);
2379
+ if (mapped !== void 0) values.push(mapped);
2380
+ }
2381
+ return values;
2382
+ }
2383
+ try {
2384
+ return JSON.stringify(value);
2385
+ } catch {
2386
+ return;
2387
+ }
2388
+ }
2389
+ //#endregion
2390
+ //#region src/index.ts
2391
+ /**
2392
+ * @fileoverview Better Logger — default entry point.
2393
+ *
2394
+ * Re-exports `Logger`, the scoped loggers, subpath-style bridges, and
2395
+ * cross-runtime styling/utility helpers. Side-effect free at import.
2396
+ */
2397
+ let _logger = null;
2398
+ function getLogger() {
2399
+ if (!_logger) _logger = new Logger();
2400
+ return _logger;
2401
+ }
2402
+ /**
2403
+ * Default Logger singleton (lazy). Use this for the common case.
2404
+ */
2405
+ var src_default = getLogger();
2406
+ /**
2407
+ * Top-level log methods bound to the default singleton.
2408
+ */
2409
+ const debug = (...args) => getLogger().debug(...args);
2410
+ const info = (...args) => getLogger().info(...args);
2411
+ const warn = (...args) => getLogger().warn(...args);
2412
+ const error = (...args) => getLogger().error(...args);
2413
+ const success = (...args) => getLogger().success(...args);
2414
+ const critical = (...args) => getLogger().critical(...args);
2415
+ const trace = (...args) => getLogger().trace(...args);
2416
+ const table = (data, columns) => getLogger().table(data, columns);
2417
+ const group = (label, collapsed) => getLogger().group(label, collapsed);
2418
+ const groupEnd = () => getLogger().groupEnd();
2419
+ const time = (label) => getLogger().time(label);
2420
+ const timeEnd = (label) => getLogger().timeEnd(label);
2421
+ const setGlobalPrefix = (prefix) => getLogger().setGlobalPrefix(prefix);
2422
+ const scope = (name) => getLogger().scope(name);
2423
+ const component = (name) => getLogger().component(name);
2424
+ const api = (name) => getLogger().api(name);
2425
+ const badges = (badgeList) => getLogger().badges(badgeList);
2426
+ const badge = (badgeName) => getLogger().badge(badgeName);
2427
+ const clearBadges = () => getLogger().clearBadges();
2428
+ const setVerbosity = (level) => getLogger().setVerbosity(level);
2429
+ const addHandler = (handler) => getLogger().addHandler(handler);
2430
+ const setTheme = (theme) => getLogger().setTheme(theme);
2431
+ const setBannerType = (bannerType) => getLogger().setBannerType(bannerType);
2432
+ const showBanner = (bannerType) => getLogger().showBanner(bannerType);
2433
+ const logWithSVG = (message, svgContent, options) => getLogger().logWithSVG(message, svgContent, options);
2434
+ const logAnimated = (message, duration) => getLogger().logAnimated(message, duration);
2435
+ const cli = (command) => getLogger().cli(command);
2436
+ const addSerializer = (type, serializer, priority) => getLogger().addSerializer(type, serializer, priority);
2437
+ const removeSerializer = (type) => getLogger().removeSerializer(type);
2438
+ const on = (event, callback, priority) => getLogger().on(event, callback, priority);
2439
+ const once = (event, callback, priority) => getLogger().once(event, callback, priority);
2440
+ const off = (event, callback) => getLogger().off(event, callback);
2441
+ const use = (middleware, priority) => getLogger().use(middleware, priority);
2442
+ const addTransport = (target) => getLogger().addTransport(target);
2443
+ const removeTransport = (id) => getLogger().removeTransport(id);
2444
+ const flushTransports = () => getLogger().flushTransports();
2445
+ const closeTransports = () => getLogger().closeTransports();
2446
+ //#endregion
2447
+ export { APILogger, BANNER_VARIANTS, ComponentLogger, ContextLogger, DEFAULT_CONFIG, Logger, ScopedLogger, StyleBuilder, StylePresets, THEME_BANNERS, THEME_PRESETS, addHandler, addSerializer, addTransport, ansiBackground, ansiBold, ansiColor, ansiDim, ansiStyle, ansiUnderline, api, badge, badges, clearBadges, cli, closeTransports, component, createLogEntry, critical, debug, src_default as default, error, flushTransports, formatLogLevelANSI, formatSuccessANSI, formatTablePlain, formatTimestamp, getColorCapability, getConsoleMethod, getEnvironment, getEnvironmentInfo, getTerminalHeight, getTerminalWidth, group, groupEnd, info, isRunningInTerminal, logAnimated, logWithSVG, off, on, once, parseStackTrace, removeSerializer, removeTransport, safeSerialize, scope, setBannerType, setGlobalPrefix, setTheme, setVerbosity, showBanner, success, supportsANSI, table, time, timeEnd, trace, use, warn };
2448
+
2449
+ //# sourceMappingURL=index.js.map