@mks2508/better-logger 0.18.2-alpha.1 → 0.18.3

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 (207) hide show
  1. package/README.md +38 -336
  2. package/dist/Logger.d.ts +356 -157
  3. package/dist/Logger.d.ts.map +1 -1
  4. package/dist/ScopedLogger.d.ts +549 -9
  5. package/dist/ScopedLogger.d.ts.map +1 -1
  6. package/dist/chunks/HookBridge-C-AvXmPD.cjs +504 -0
  7. package/dist/chunks/HookBridge-C-AvXmPD.cjs.map +1 -0
  8. package/dist/chunks/HookBridge-CI2PH79S.js +487 -0
  9. package/dist/chunks/HookBridge-CI2PH79S.js.map +1 -0
  10. package/dist/chunks/{LogContext-L7HzynFw.cjs → LogContext-BaMXleWj.cjs} +19 -4
  11. package/dist/chunks/LogContext-BaMXleWj.cjs.map +1 -0
  12. package/dist/chunks/LogContext-DZasm_P5.cjs +141 -0
  13. package/dist/chunks/LogContext-DZasm_P5.cjs.map +1 -0
  14. package/dist/chunks/{LogContext-Cwn-1Zzb.js → LogContext-DjlITOzZ.js} +19 -4
  15. package/dist/chunks/LogContext-DjlITOzZ.js.map +1 -0
  16. package/dist/chunks/LogContext-Dyzs61XG.js +136 -0
  17. package/dist/chunks/LogContext-Dyzs61XG.js.map +1 -0
  18. package/dist/chunks/SerializerBridge-Ba43Mk7j.js +393 -0
  19. package/dist/chunks/SerializerBridge-Ba43Mk7j.js.map +1 -0
  20. package/dist/chunks/SerializerBridge-C4a9Z37F.cjs +410 -0
  21. package/dist/chunks/SerializerBridge-C4a9Z37F.cjs.map +1 -0
  22. package/dist/chunks/{StyleManager-CIpd6wbO.cjs → StyleManager-DQ6UNRB-.cjs} +37 -11
  23. package/dist/chunks/StyleManager-DQ6UNRB-.cjs.map +1 -0
  24. package/dist/chunks/StyleManager-DjwAYbxE.js +113 -0
  25. package/dist/chunks/StyleManager-DjwAYbxE.js.map +1 -0
  26. package/dist/chunks/{core-PoT7RrTK.js → core-Blfi2klP.js} +1 -4
  27. package/dist/chunks/core-Blfi2klP.js.map +1 -0
  28. package/dist/chunks/{core-Dzz7agGa.cjs → core-CqS_UBzJ.cjs} +1 -4
  29. package/dist/chunks/core-CqS_UBzJ.cjs.map +1 -0
  30. package/dist/chunks/{environment-detector-CI3TrWK_.js → environment-detector-7NvnYUfr.js} +11 -11
  31. package/dist/chunks/environment-detector-7NvnYUfr.js.map +1 -0
  32. package/dist/chunks/{environment-detector-Cnn6wr6O.cjs → environment-detector-D-tHkKWA.cjs} +11 -11
  33. package/dist/chunks/environment-detector-D-tHkKWA.cjs.map +1 -0
  34. package/dist/chunks/server-fallback-CaCPjWby.cjs +119 -0
  35. package/dist/chunks/server-fallback-CaCPjWby.cjs.map +1 -0
  36. package/dist/chunks/server-fallback-jj0T6XaK.js +114 -0
  37. package/dist/chunks/server-fallback-jj0T6XaK.js.map +1 -0
  38. package/dist/chunks/{spinner-DNvxbM9a.cjs → spinner-BHyYEXsM.cjs} +319 -37
  39. package/dist/chunks/spinner-BHyYEXsM.cjs.map +1 -0
  40. package/dist/chunks/{spinner-D3FsF78o.js → spinner-BtkwpzYv.js} +319 -37
  41. package/dist/chunks/spinner-BtkwpzYv.js.map +1 -0
  42. package/dist/chunks/styling-CRw3KQW4.js +1592 -0
  43. package/dist/chunks/styling-CRw3KQW4.js.map +1 -0
  44. package/dist/chunks/styling-Cel2wPRy.cjs +1645 -0
  45. package/dist/chunks/styling-Cel2wPRy.cjs.map +1 -0
  46. package/dist/chunks/transports-BGfwwakw.js +1237 -0
  47. package/dist/chunks/transports-BGfwwakw.js.map +1 -0
  48. package/dist/chunks/transports-BZ-Mc2IT.cjs +1450 -0
  49. package/dist/chunks/transports-BZ-Mc2IT.cjs.map +1 -0
  50. package/dist/chunks/transports-DvaLAeGJ.js +1403 -0
  51. package/dist/chunks/transports-DvaLAeGJ.js.map +1 -0
  52. package/dist/chunks/transports-yK6CL0Ml.cjs +1278 -0
  53. package/dist/chunks/transports-yK6CL0Ml.cjs.map +1 -0
  54. package/dist/chunks/{utils-BqlFYocD.cjs → utils-W_cxqriN.cjs} +44 -37
  55. package/dist/chunks/utils-W_cxqriN.cjs.map +1 -0
  56. package/dist/chunks/{utils-VETbVpkR.js → utils-tKfBAWUM.js} +44 -37
  57. package/dist/chunks/utils-tKfBAWUM.js.map +1 -0
  58. package/dist/cli/CommandProcessor.d.ts +166 -19
  59. package/dist/cli/CommandProcessor.d.ts.map +1 -1
  60. package/dist/cli/commands/ConfigCommand.d.ts +36 -1
  61. package/dist/cli/commands/ConfigCommand.d.ts.map +1 -1
  62. package/dist/cli/commands/ExportCommand.d.ts +49 -3
  63. package/dist/cli/commands/ExportCommand.d.ts.map +1 -1
  64. package/dist/cli/commands/ThemeCommand.d.ts +62 -3
  65. package/dist/cli/commands/ThemeCommand.d.ts.map +1 -1
  66. package/dist/cli/help.d.ts +30 -2
  67. package/dist/cli/help.d.ts.map +1 -1
  68. package/dist/cli/index.d.ts +29 -2
  69. package/dist/cli/index.d.ts.map +1 -1
  70. package/dist/cli.cjs +2 -2
  71. package/dist/cli.js +2 -2
  72. package/dist/context/LogContext.d.ts +167 -70
  73. package/dist/context/LogContext.d.ts.map +1 -1
  74. package/dist/context.cjs +1 -1
  75. package/dist/context.js +1 -1
  76. package/dist/core.cjs +52 -29
  77. package/dist/core.cjs.map +1 -1
  78. package/dist/core.d.ts +50 -27
  79. package/dist/core.d.ts.map +1 -1
  80. package/dist/core.js +52 -29
  81. package/dist/core.js.map +1 -1
  82. package/dist/hooks/HookBridge.d.ts +15 -9
  83. package/dist/hooks/HookBridge.d.ts.map +1 -1
  84. package/dist/hooks/HookManager.d.ts +295 -2
  85. package/dist/hooks/HookManager.d.ts.map +1 -1
  86. package/dist/hooks.cjs +1 -1
  87. package/dist/hooks.js +1 -1
  88. package/dist/index.cjs +1415 -214
  89. package/dist/index.cjs.map +1 -1
  90. package/dist/index.d.ts +5 -1
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +1413 -215
  93. package/dist/index.js.map +1 -1
  94. package/dist/playground/TerminalBridge.d.ts +23 -16
  95. package/dist/playground/TerminalBridge.d.ts.map +1 -1
  96. package/dist/playground/box.d.ts +36 -5
  97. package/dist/playground/box.d.ts.map +1 -1
  98. package/dist/playground/cli-table.d.ts +41 -5
  99. package/dist/playground/cli-table.d.ts.map +1 -1
  100. package/dist/playground/divider.d.ts +22 -3
  101. package/dist/playground/divider.d.ts.map +1 -1
  102. package/dist/playground/header.d.ts +21 -4
  103. package/dist/playground/header.d.ts.map +1 -1
  104. package/dist/playground/server-fallback.d.ts +96 -9
  105. package/dist/playground/server-fallback.d.ts.map +1 -1
  106. package/dist/playground/spinner.d.ts +159 -10
  107. package/dist/playground/spinner.d.ts.map +1 -1
  108. package/dist/playground/step.d.ts +25 -6
  109. package/dist/playground/step.d.ts.map +1 -1
  110. package/dist/playground.cjs +1 -1
  111. package/dist/playground.js +1 -1
  112. package/dist/serializers/SerializerBridge.d.ts +13 -6
  113. package/dist/serializers/SerializerBridge.d.ts.map +1 -1
  114. package/dist/serializers/SerializerRegistry.d.ts +236 -0
  115. package/dist/serializers/SerializerRegistry.d.ts.map +1 -1
  116. package/dist/serializers.cjs +1 -1
  117. package/dist/serializers.js +1 -1
  118. package/dist/styles/StyleManager.d.ts +138 -31
  119. package/dist/styles/StyleManager.d.ts.map +1 -1
  120. package/dist/styles.cjs +2 -2
  121. package/dist/styles.js +2 -2
  122. package/dist/styling/SmartPresets.d.ts +100 -6
  123. package/dist/styling/SmartPresets.d.ts.map +1 -1
  124. package/dist/styling/StyleBuilder.d.ts +453 -32
  125. package/dist/styling/StyleBuilder.d.ts.map +1 -1
  126. package/dist/styling/banners.d.ts +83 -7
  127. package/dist/styling/banners.d.ts.map +1 -1
  128. package/dist/styling/themes.d.ts +41 -2
  129. package/dist/styling/themes.d.ts.map +1 -1
  130. package/dist/transports/ConsoleTransport.d.ts +95 -0
  131. package/dist/transports/ConsoleTransport.d.ts.map +1 -1
  132. package/dist/transports/FileTransport.d.ts +99 -18
  133. package/dist/transports/FileTransport.d.ts.map +1 -1
  134. package/dist/transports/HttpTransport.d.ts +135 -22
  135. package/dist/transports/HttpTransport.d.ts.map +1 -1
  136. package/dist/transports/OtlpTraceTransport.d.ts +118 -0
  137. package/dist/transports/OtlpTraceTransport.d.ts.map +1 -0
  138. package/dist/transports/OtlpTransport.d.ts +80 -37
  139. package/dist/transports/OtlpTransport.d.ts.map +1 -1
  140. package/dist/transports/SpanRuntime.d.ts +73 -0
  141. package/dist/transports/SpanRuntime.d.ts.map +1 -0
  142. package/dist/transports/TransportBridge.d.ts +19 -13
  143. package/dist/transports/TransportBridge.d.ts.map +1 -1
  144. package/dist/transports/TransportManager.d.ts +232 -10
  145. package/dist/transports/TransportManager.d.ts.map +1 -1
  146. package/dist/transports/index.d.ts +1 -0
  147. package/dist/transports/index.d.ts.map +1 -1
  148. package/dist/transports-module.d.ts +3 -1
  149. package/dist/transports-module.d.ts.map +1 -1
  150. package/dist/transports.cjs +2 -1
  151. package/dist/transports.js +2 -2
  152. package/dist/types/core.d.ts +155 -59
  153. package/dist/types/core.d.ts.map +1 -1
  154. package/dist/types/hooks.d.ts +92 -14
  155. package/dist/types/hooks.d.ts.map +1 -1
  156. package/dist/types/index.d.ts +1 -1
  157. package/dist/types/index.d.ts.map +1 -1
  158. package/dist/types/serializers.d.ts +72 -0
  159. package/dist/types/serializers.d.ts.map +1 -1
  160. package/dist/types/transports.d.ts +163 -39
  161. package/dist/types/transports.d.ts.map +1 -1
  162. package/dist/utils/ansi-colors.d.ts +15 -15
  163. package/dist/utils/asyncLocalStorage.d.ts +33 -0
  164. package/dist/utils/asyncLocalStorage.d.ts.map +1 -0
  165. package/dist/utils/environment-detector.d.ts +11 -11
  166. package/dist/utils/formatting.d.ts +8 -8
  167. package/dist/utils/output.d.ts +9 -9
  168. package/dist/utils/output.d.ts.map +1 -1
  169. package/dist/utils/stackTrace.d.ts +2 -2
  170. package/package.json +24 -25
  171. package/dist/chunks/HookBridge-CiRfR67f.cjs +0 -190
  172. package/dist/chunks/HookBridge-CiRfR67f.cjs.map +0 -1
  173. package/dist/chunks/HookBridge-SgMmbXZB.js +0 -173
  174. package/dist/chunks/HookBridge-SgMmbXZB.js.map +0 -1
  175. package/dist/chunks/LogContext-Cwn-1Zzb.js.map +0 -1
  176. package/dist/chunks/LogContext-L7HzynFw.cjs.map +0 -1
  177. package/dist/chunks/SerializerBridge-BaOQOb8q.cjs +0 -166
  178. package/dist/chunks/SerializerBridge-BaOQOb8q.cjs.map +0 -1
  179. package/dist/chunks/SerializerBridge-BkpQu5c9.js +0 -149
  180. package/dist/chunks/SerializerBridge-BkpQu5c9.js.map +0 -1
  181. package/dist/chunks/StyleManager-CIpd6wbO.cjs.map +0 -1
  182. package/dist/chunks/StyleManager-LCvVlVdx.js +0 -87
  183. package/dist/chunks/StyleManager-LCvVlVdx.js.map +0 -1
  184. package/dist/chunks/core-Dzz7agGa.cjs.map +0 -1
  185. package/dist/chunks/core-PoT7RrTK.js.map +0 -1
  186. package/dist/chunks/environment-detector-CI3TrWK_.js.map +0 -1
  187. package/dist/chunks/environment-detector-Cnn6wr6O.cjs.map +0 -1
  188. package/dist/chunks/server-fallback-BUKjdLS7.cjs +0 -42
  189. package/dist/chunks/server-fallback-BUKjdLS7.cjs.map +0 -1
  190. package/dist/chunks/server-fallback-BsuWH1Dk.js +0 -37
  191. package/dist/chunks/server-fallback-BsuWH1Dk.js.map +0 -1
  192. package/dist/chunks/spinner-D3FsF78o.js.map +0 -1
  193. package/dist/chunks/spinner-DNvxbM9a.cjs.map +0 -1
  194. package/dist/chunks/styling-84N8T97t.js +0 -941
  195. package/dist/chunks/styling-84N8T97t.js.map +0 -1
  196. package/dist/chunks/styling-Cg5saQ46.cjs +0 -994
  197. package/dist/chunks/styling-Cg5saQ46.cjs.map +0 -1
  198. package/dist/chunks/transports-BiDk345e.js +0 -715
  199. package/dist/chunks/transports-BiDk345e.js.map +0 -1
  200. package/dist/chunks/transports-COPWmlF1.cjs +0 -756
  201. package/dist/chunks/transports-COPWmlF1.cjs.map +0 -1
  202. package/dist/chunks/utils-BqlFYocD.cjs.map +0 -1
  203. package/dist/chunks/utils-VETbVpkR.js.map +0 -1
  204. package/dist/example.d.ts +0 -18
  205. package/dist/example.d.ts.map +0 -1
  206. package/dist/main.d.ts +0 -2
  207. package/dist/main.d.ts.map +0 -1
@@ -0,0 +1,410 @@
1
+ //#region src/serializers/SerializerRegistry.ts
2
+ /**
3
+ * Configuración por defecto del registry. Se merguea con la config que reciba
4
+ * el constructor (gana la del caller).
5
+ *
6
+ * @internal Constante de módulo; no es API pública.
7
+ */
8
+ const DEFAULT_CONFIG = {
9
+ maxDepth: 5,
10
+ circular: "placeholder",
11
+ preserveUndefined: false
12
+ };
13
+ /**
14
+ * Registry de serializers tipados por constructor.
15
+ *
16
+ * Mantiene un mapa ordenado por `priority` (mayor primero) de serializers
17
+ * registrados para clases específicas. El método {@link SerializerRegistry.serialize}
18
+ * recorre objetos de forma recursiva aplicando el serializer que matchee por
19
+ * `instanceof`, con dos guardas de seguridad:
20
+ *
21
+ * - **Depth guard**: corta la recursión al llegar a `maxDepth` y emite el
22
+ * placeholder `'[Max Depth]'`.
23
+ * - **Circular ref**: lleva un `WeakSet` de objetos visitados en el path actual;
24
+ * al re-encontrar uno aplica la estrategia de `circular` (`placeholder` por
25
+ * default).
26
+ *
27
+ * Implementa {@link ISerializerRegistry}. Suele usarse vía el singleton de
28
+ * {@link getDefaultSerializerRegistry}, expuesto al Logger a través del
29
+ * {@link SerializerBridge}.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const registry = new SerializerRegistry({ maxDepth: 3 });
34
+ *
35
+ * registry.add(URL, (url: URL) => ({
36
+ * href: url.href,
37
+ * origin: url.origin
38
+ * }), 60);
39
+ *
40
+ * const safe = registry.serialize(someMaybeCyclicObject);
41
+ * ```
42
+ *
43
+ * @see {@link ISerializerRegistry} para el contrato interface.
44
+ * @see {@link SerializerConfig} para las opciones del constructor.
45
+ */
46
+ var SerializerRegistry = class {
47
+ serializers = /* @__PURE__ */ new Map();
48
+ config;
49
+ /**
50
+ * Crea un registry nuevo con los serializers builtin ya registrados
51
+ * (Error, Date, RegExp, Map, Set, Buffer cuando está disponible).
52
+ *
53
+ * @param {SerializerConfig} config - Overrides sobre {@link DEFAULT_CONFIG}.
54
+ * - `maxDepth` (default `5`): profundidad máxima de anidamiento antes del
55
+ * placeholder `'[Max Depth]'`.
56
+ * - `circular` (default `'placeholder'`): qué hacer ante una referencia
57
+ * circular. `'placeholder'` emite `'[Circular]'`, `'skip'` omite la key
58
+ * (devuelve `undefined`), `'error'` lanza.
59
+ * - `preserveUndefined` (default `false`): si `true` deja `undefined`
60
+ * textual; si `false` lo reemplaza por `'[undefined]'` (más seguro para
61
+ * JSON / transporte).
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * // Defaults (depth 5, circular → placeholder)
66
+ * const a = new SerializerRegistry();
67
+ *
68
+ * // Estricto: lanza ante ciclo, conservar undefined
69
+ * const b = new SerializerRegistry({
70
+ * maxDepth: 10,
71
+ * circular: 'error',
72
+ * preserveUndefined: true
73
+ * });
74
+ * ```
75
+ */
76
+ constructor(config = {}) {
77
+ this.config = {
78
+ ...DEFAULT_CONFIG,
79
+ ...config
80
+ };
81
+ this.registerDefaults();
82
+ }
83
+ /**
84
+ * Registra los serializers builtin con sus prioridades. Invocado por el
85
+ * constructor; no es API pública.
86
+ *
87
+ * Defaults (mayor priority = gana primero en `instanceof`):
88
+ *
89
+ * | Tipo | Priority | Salida |
90
+ * |----------|----------|------------------------------------------------|
91
+ * | `Error` | 100 | `{ name, message, stack[], cause? }` |
92
+ * | `Date` | 90 | `{ iso, timestamp }` |
93
+ * | `RegExp` | 90 | `{ pattern, flags }` |
94
+ * | `Map` | 80 | `{ __type:'Map', entries }` |
95
+ * | `Set` | 80 | `{ __type:'Set', values[] }` |
96
+ * | `Buffer` | 70 | `{ __type:'Buffer', length, preview }` (Node) |
97
+ *
98
+ * @internal
99
+ */
100
+ registerDefaults() {
101
+ this.add(Error, (err) => ({
102
+ name: err.name,
103
+ message: err.message,
104
+ stack: err.stack?.split("\n").slice(0, 10),
105
+ ...err.cause ? { cause: this.serialize(err.cause) } : {}
106
+ }), 100);
107
+ this.add(Date, (date) => ({
108
+ iso: date.toISOString(),
109
+ timestamp: date.getTime()
110
+ }), 90);
111
+ this.add(RegExp, (regex) => ({
112
+ pattern: regex.source,
113
+ flags: regex.flags
114
+ }), 90);
115
+ this.add(Map, (map, ctx) => {
116
+ const obj = {};
117
+ map.forEach((value, key) => {
118
+ const keyStr = typeof key === "object" ? JSON.stringify(key) : String(key);
119
+ obj[keyStr] = this.serializeInternal(value, {
120
+ ...ctx,
121
+ depth: ctx.depth + 1,
122
+ path: [...ctx.path, keyStr]
123
+ });
124
+ });
125
+ return {
126
+ __type: "Map",
127
+ entries: obj
128
+ };
129
+ }, 80);
130
+ this.add(Set, (set, ctx) => ({
131
+ __type: "Set",
132
+ values: Array.from(set).map((v, i) => this.serializeInternal(v, {
133
+ ...ctx,
134
+ depth: ctx.depth + 1,
135
+ path: [...ctx.path, `[${i}]`]
136
+ }))
137
+ }), 80);
138
+ if (typeof Buffer !== "undefined") this.add(Buffer, (buf) => ({
139
+ __type: "Buffer",
140
+ length: buf.length,
141
+ preview: buf.slice(0, 50).toString("hex")
142
+ }), 70);
143
+ }
144
+ /**
145
+ * Registra (o reemplaza) el serializer para una clase constructora.
146
+ *
147
+ * Si ya existía un serializer para `type`, se sobrescribe. La `priority`
148
+ * sólo ordena de cara al lookup por `instanceof` hecho en
149
+ * {@link SerializerRegistry.getAll} — útil cuando una subclass debería
150
+ * matchear antes que su superclass (p.ej. `TypeError` antes que `Error`).
151
+ *
152
+ * @param {new (...args: any[]) => T} type - Constructor de la clase a matchear.
153
+ * @param {SerializerFn<T>} serializer - Función que recibe la instancia y el
154
+ * {@link SerializerContext} (depth, path, seen); devuelve una representación
155
+ * serializable.
156
+ * @param {number} [priority=50] - Orden de lookup (mayor = primero). Los
157
+ * defaults builtin usan 70–100.
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * registry.add(
162
+ * URL,
163
+ * (url: URL, ctx) => ({ href: url.href, origin: url.origin }),
164
+ * 60
165
+ * );
166
+ * ```
167
+ */
168
+ add(type, serializer, priority = 50) {
169
+ this.serializers.set(type, {
170
+ type,
171
+ serializer,
172
+ priority
173
+ });
174
+ }
175
+ /**
176
+ * Elimina el serializer registrado para `type`.
177
+ *
178
+ * @param {new (...args: any[]) => T} type - Constructor a remover.
179
+ * @returns `true` si existía y fue removido, `false` si no había registro.
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * registry.remove(Date); // → true (estaba registrado por defecto)
184
+ * registry.remove(Date); // → false (ya no está)
185
+ * ```
186
+ */
187
+ remove(type) {
188
+ return this.serializers.delete(type);
189
+ }
190
+ /**
191
+ * Indica si hay un serializer registrado para `type`.
192
+ *
193
+ * @param {new (...args: any[]) => T} type - Constructor a consultar.
194
+ * @returns `true` si `type` está registrado.
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * if (!registry.has(CustomError)) {
199
+ * registry.add(CustomError, serializeCustomError, 95);
200
+ * }
201
+ * ```
202
+ */
203
+ has(type) {
204
+ return this.serializers.has(type);
205
+ }
206
+ /**
207
+ * Devuelve todas las entradas registradas, ordenadas por `priority`
208
+ * descendente (mayor priority primero). Este es el orden en el que
209
+ * {@link SerializerRegistry.serialize} los prueba vía `instanceof`.
210
+ *
211
+ * @returns {SerializerEntry[]} Array de entradas ordenadas por prioridad.
212
+ *
213
+ * @example
214
+ * ```ts
215
+ * const entries = registry.getAll();
216
+ * console.log(entries.map(e => [e.type.name, e.priority]));
217
+ * // [['Error', 100], ['Date', 90], ['RegExp', 90], ['Map', 80], ...]
218
+ * ```
219
+ *
220
+ * @see {@link SerializerEntry}
221
+ */
222
+ getAll() {
223
+ return Array.from(this.serializers.values()).sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50));
224
+ }
225
+ /**
226
+ * Busca el primer serializer cuyo `type` matchee `value instanceof type`,
227
+ * recorriendo las entradas en orden de prioridad descendente.
228
+ *
229
+ * @internal Helper del pipeline interno; no es API pública.
230
+ * @param value - Valor a testear.
231
+ * @returns Entrada matcheante, o `null` si ninguna aplica.
232
+ */
233
+ findSerializer(value) {
234
+ const sorted = this.getAll();
235
+ for (const entry of sorted) if (value instanceof entry.type) return entry;
236
+ return null;
237
+ }
238
+ /**
239
+ * Pipeline interno de serialización recursiva. Es el core de
240
+ * {@link SerializerRegistry.serialize}; no es API pública pero se documenta
241
+ * aquí para mantener la semántica del pipeline en un solo lugar.
242
+ *
243
+ * Orden de guardas (cada una corta la recursión):
244
+ *
245
+ * 1. `null` / `undefined` — directo (respeta `preserveUndefined`).
246
+ * 2. `function` — placeholder `'[Function: name]'`.
247
+ * 3. Primitiva no-objeto — se devuelve tal cual.
248
+ * 4. **Depth guard**: si `depth >= maxDepth` → `'[Max Depth]'`.
249
+ * 5. **Circular**: si `value` ya está en el `WeakSet` `seen` del contexto,
250
+ * aplica `circular` (`placeholder` / `skip` / `error`).
251
+ * 6. Se marca en `seen`, se busca serializer por `instanceof`; si matchea,
252
+ * se delega (el serializer puede recursar via `ctx`).
253
+ * 7. Si es array, mapea cada item incrementando depth y extendiendo path.
254
+ * 8. Si es plain object, itera keys recursivamente.
255
+ *
256
+ * @internal
257
+ * @param value - Valor a serializar.
258
+ * @param context - Estado de recursión (depth, path, seen, maxDepth).
259
+ * @returns Valor serializable (puede ser primitiva, objeto, array o placeholder).
260
+ * @throws {Error} Sólo si `circular: 'error'` y se detecta ciclo.
261
+ */
262
+ serializeInternal(value, context) {
263
+ if (value === null) return null;
264
+ if (value === void 0) return this.config.preserveUndefined ? void 0 : "[undefined]";
265
+ if (typeof value === "function") return `[Function: ${value.name || "anonymous"}]`;
266
+ if (typeof value !== "object") return value;
267
+ if (context.depth >= this.config.maxDepth) return "[Max Depth]";
268
+ if (context.seen.has(value)) switch (this.config.circular) {
269
+ case "error": throw new Error(`Circular reference at ${context.path.join(".")}`);
270
+ case "skip": return;
271
+ default: return "[Circular]";
272
+ }
273
+ context.seen.add(value);
274
+ const serializer = this.findSerializer(value);
275
+ if (serializer) return serializer.serializer(value, context);
276
+ if (Array.isArray(value)) return value.map((item, i) => this.serializeInternal(item, {
277
+ ...context,
278
+ depth: context.depth + 1,
279
+ path: [...context.path, `[${i}]`]
280
+ }));
281
+ const result = {};
282
+ for (const [key, val] of Object.entries(value)) result[key] = this.serializeInternal(val, {
283
+ ...context,
284
+ depth: context.depth + 1,
285
+ path: [...context.path, key]
286
+ });
287
+ return result;
288
+ }
289
+ /**
290
+ * Serializa un valor arbitrario a una representación segura para transporte
291
+ * (JSON, remote log, OTLP, etc.).
292
+ *
293
+ * Entry point público del pipeline. Construye un {@link SerializerContext}
294
+ * fresco (depth 0, path vacío, `WeakSet` nuevo para detección de ciclos),
295
+ * merguea overrides de `config` sobre los del constructor y delega a
296
+ * {@link SerializerRegistry.serializeInternal}.
297
+ *
298
+ * @param {any} value - Valor a serializar. Cualquier tipo.
299
+ * @param {SerializerConfig} [config] - Overrides puntuales para esta llamada
300
+ * (no mutan la config del registry). Útil para, p.ej., subir `maxDepth`
301
+ * sólo en un log concreto.
302
+ * @returns {any} Valor serializable. Para objetos sin serializer registrado
303
+ * se devuelve un plain object; para tipos builtin, la shape definida en
304
+ * {@link SerializerRegistry.registerDefaults}; para los cortes de
305
+ * profundidad o circular, los placeholders `'[Max Depth]'` / `'[Circular]'`.
306
+ * @throws {Error} Sólo si `circular: 'error'` y se detecta una referencia circular.
307
+ *
308
+ * @example
309
+ * ```ts
310
+ * // Objetos simples
311
+ * registry.serialize({ a: 1, b: [2, 3] });
312
+ * // → { a: 1, b: [2, 3] }
313
+ *
314
+ * // Errores (serializer builtin)
315
+ * registry.serialize(new Error('boom'));
316
+ * // → { name: 'Error', message: 'boom', stack: [...] }
317
+ *
318
+ * // Referencia circular → placeholder
319
+ * const o: any = {};
320
+ * o.self = o;
321
+ * registry.serialize(o); // → { self: '[Circular]' }
322
+ *
323
+ * // Override puntual de maxDepth
324
+ * registry.serialize(deepObj, { maxDepth: 2 });
325
+ * ```
326
+ *
327
+ * @see {@link SerializerRegistry.serializeInternal} para el detalle del pipeline.
328
+ */
329
+ serialize(value, config) {
330
+ const mergedConfig = {
331
+ ...this.config,
332
+ ...config
333
+ };
334
+ return this.serializeInternal(value, {
335
+ depth: 0,
336
+ maxDepth: mergedConfig.maxDepth,
337
+ path: [],
338
+ seen: /* @__PURE__ */ new WeakSet()
339
+ });
340
+ }
341
+ };
342
+ /**
343
+ * Cache del singleton de {@link SerializerRegistry}. Module-private.
344
+ *
345
+ * @internal
346
+ */
347
+ let _defaultRegistry = null;
348
+ /**
349
+ * Devuelve el singleton de {@link SerializerRegistry} (lo crea con config
350
+ * default en la primera llamada). Es la vía canónica de obtener el registry
351
+ * compartido que usa el Logger internamente.
352
+ *
353
+ * @returns {SerializerRegistry} Instancia singleton.
354
+ *
355
+ * @example
356
+ * ```ts
357
+ * import { getDefaultSerializerRegistry } from '@mks2508/better-logger/serializers';
358
+ *
359
+ * const registry = getDefaultSerializerRegistry();
360
+ * if (!registry.has(CustomError)) {
361
+ * registry.add(CustomError, (e) => ({ code: e.code, message: e.message }), 95);
362
+ * }
363
+ * ```
364
+ */
365
+ function getDefaultSerializerRegistry() {
366
+ if (!_defaultRegistry) _defaultRegistry = new SerializerRegistry();
367
+ return _defaultRegistry;
368
+ }
369
+ //#endregion
370
+ //#region src/serializers/SerializerBridge.ts
371
+ /**
372
+ * Crea una instancia de {@link SerializerBridge}.
373
+ *
374
+ * @internal
375
+ */
376
+ function createSerializerBridge() {
377
+ const serializerRegistry = new SerializerRegistry();
378
+ return {
379
+ addSerializer(type, serializer, priority) {
380
+ serializerRegistry.add(type, serializer, priority);
381
+ },
382
+ removeSerializer(type) {
383
+ return serializerRegistry.remove(type);
384
+ },
385
+ getSerializerRegistry() {
386
+ return serializerRegistry;
387
+ }
388
+ };
389
+ }
390
+ //#endregion
391
+ Object.defineProperty(exports, "SerializerRegistry", {
392
+ enumerable: true,
393
+ get: function() {
394
+ return SerializerRegistry;
395
+ }
396
+ });
397
+ Object.defineProperty(exports, "createSerializerBridge", {
398
+ enumerable: true,
399
+ get: function() {
400
+ return createSerializerBridge;
401
+ }
402
+ });
403
+ Object.defineProperty(exports, "getDefaultSerializerRegistry", {
404
+ enumerable: true,
405
+ get: function() {
406
+ return getDefaultSerializerRegistry;
407
+ }
408
+ });
409
+
410
+ //# sourceMappingURL=SerializerBridge-C4a9Z37F.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SerializerBridge-C4a9Z37F.cjs","names":[],"sources":["../../src/serializers/SerializerRegistry.ts","../../src/serializers/SerializerBridge.ts"],"sourcesContent":["/**\n * @fileoverview Registry de serializers con control de profundidad, detección\n * de referencias circulares y soporte para tipos builtin (Error, Date, RegExp,\n * Map, Set, Buffer). Implementa {@link ISerializerRegistry}.\n */\nimport type {\n SerializerFn,\n SerializerContext,\n SerializerEntry,\n SerializerConfig,\n ISerializerRegistry\n} from '../types/index.js';\n\n/**\n * Configuración por defecto del registry. Se merguea con la config que reciba\n * el constructor (gana la del caller).\n *\n * @internal Constante de módulo; no es API pública.\n */\nconst DEFAULT_CONFIG: Required<SerializerConfig> = {\n maxDepth: 5,\n circular: 'placeholder',\n preserveUndefined: false\n};\n\n/**\n * Registry de serializers tipados por constructor.\n *\n * Mantiene un mapa ordenado por `priority` (mayor primero) de serializers\n * registrados para clases específicas. El método {@link SerializerRegistry.serialize}\n * recorre objetos de forma recursiva aplicando el serializer que matchee por\n * `instanceof`, con dos guardas de seguridad:\n *\n * - **Depth guard**: corta la recursión al llegar a `maxDepth` y emite el\n * placeholder `'[Max Depth]'`.\n * - **Circular ref**: lleva un `WeakSet` de objetos visitados en el path actual;\n * al re-encontrar uno aplica la estrategia de `circular` (`placeholder` por\n * default).\n *\n * Implementa {@link ISerializerRegistry}. Suele usarse vía el singleton de\n * {@link getDefaultSerializerRegistry}, expuesto al Logger a través del\n * {@link SerializerBridge}.\n *\n * @example\n * ```ts\n * const registry = new SerializerRegistry({ maxDepth: 3 });\n *\n * registry.add(URL, (url: URL) => ({\n * href: url.href,\n * origin: url.origin\n * }), 60);\n *\n * const safe = registry.serialize(someMaybeCyclicObject);\n * ```\n *\n * @see {@link ISerializerRegistry} para el contrato interface.\n * @see {@link SerializerConfig} para las opciones del constructor.\n */\nexport class SerializerRegistry implements ISerializerRegistry {\n private serializers: Map<Function, SerializerEntry> = new Map();\n private config: Required<SerializerConfig>;\n\n /**\n * Crea un registry nuevo con los serializers builtin ya registrados\n * (Error, Date, RegExp, Map, Set, Buffer cuando está disponible).\n *\n * @param {SerializerConfig} config - Overrides sobre {@link DEFAULT_CONFIG}.\n * - `maxDepth` (default `5`): profundidad máxima de anidamiento antes del\n * placeholder `'[Max Depth]'`.\n * - `circular` (default `'placeholder'`): qué hacer ante una referencia\n * circular. `'placeholder'` emite `'[Circular]'`, `'skip'` omite la key\n * (devuelve `undefined`), `'error'` lanza.\n * - `preserveUndefined` (default `false`): si `true` deja `undefined`\n * textual; si `false` lo reemplaza por `'[undefined]'` (más seguro para\n * JSON / transporte).\n *\n * @example\n * ```ts\n * // Defaults (depth 5, circular → placeholder)\n * const a = new SerializerRegistry();\n *\n * // Estricto: lanza ante ciclo, conservar undefined\n * const b = new SerializerRegistry({\n * maxDepth: 10,\n * circular: 'error',\n * preserveUndefined: true\n * });\n * ```\n */\n constructor(config: SerializerConfig = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.registerDefaults();\n }\n\n /**\n * Registra los serializers builtin con sus prioridades. Invocado por el\n * constructor; no es API pública.\n *\n * Defaults (mayor priority = gana primero en `instanceof`):\n *\n * | Tipo | Priority | Salida |\n * |----------|----------|------------------------------------------------|\n * | `Error` | 100 | `{ name, message, stack[], cause? }` |\n * | `Date` | 90 | `{ iso, timestamp }` |\n * | `RegExp` | 90 | `{ pattern, flags }` |\n * | `Map` | 80 | `{ __type:'Map', entries }` |\n * | `Set` | 80 | `{ __type:'Set', values[] }` |\n * | `Buffer` | 70 | `{ __type:'Buffer', length, preview }` (Node) |\n *\n * @internal\n */\n private registerDefaults(): void {\n this.add(Error, (err: Error) => ({\n name: err.name,\n message: err.message,\n stack: err.stack?.split('\\n').slice(0, 10),\n ...(err.cause ? { cause: this.serialize(err.cause) } : {})\n }), 100);\n\n this.add(Date, (date: Date) => ({\n iso: date.toISOString(),\n timestamp: date.getTime()\n }), 90);\n\n this.add(RegExp, (regex: RegExp) => ({\n pattern: regex.source,\n flags: regex.flags\n }), 90);\n\n this.add(Map, (map: Map<any, any>, ctx) => {\n const obj: Record<string, any> = {};\n map.forEach((value, key) => {\n const keyStr = typeof key === 'object' ? JSON.stringify(key) : String(key);\n obj[keyStr] = this.serializeInternal(value, {\n ...ctx,\n depth: ctx.depth + 1,\n path: [...ctx.path, keyStr]\n });\n });\n return { __type: 'Map', entries: obj };\n }, 80);\n\n this.add(Set, (set: Set<any>, ctx) => ({\n __type: 'Set',\n values: Array.from(set).map((v, i) =>\n this.serializeInternal(v, {\n ...ctx,\n depth: ctx.depth + 1,\n path: [...ctx.path, `[${i}]`]\n })\n )\n }), 80);\n\n if (typeof Buffer !== 'undefined') {\n this.add(Buffer as any, (buf: Buffer) => ({\n __type: 'Buffer',\n length: buf.length,\n preview: buf.slice(0, 50).toString('hex')\n }), 70);\n }\n }\n\n /**\n * Registra (o reemplaza) el serializer para una clase constructora.\n *\n * Si ya existía un serializer para `type`, se sobrescribe. La `priority`\n * sólo ordena de cara al lookup por `instanceof` hecho en\n * {@link SerializerRegistry.getAll} — útil cuando una subclass debería\n * matchear antes que su superclass (p.ej. `TypeError` antes que `Error`).\n *\n * @param {new (...args: any[]) => T} type - Constructor de la clase a matchear.\n * @param {SerializerFn<T>} serializer - Función que recibe la instancia y el\n * {@link SerializerContext} (depth, path, seen); devuelve una representación\n * serializable.\n * @param {number} [priority=50] - Orden de lookup (mayor = primero). Los\n * defaults builtin usan 70–100.\n *\n * @example\n * ```ts\n * registry.add(\n * URL,\n * (url: URL, ctx) => ({ href: url.href, origin: url.origin }),\n * 60\n * );\n * ```\n */\n add<T>(\n type: new (...args: any[]) => T,\n serializer: SerializerFn<T>,\n priority: number = 50\n ): void {\n this.serializers.set(type, { type, serializer, priority });\n }\n\n /**\n * Elimina el serializer registrado para `type`.\n *\n * @param {new (...args: any[]) => T} type - Constructor a remover.\n * @returns `true` si existía y fue removido, `false` si no había registro.\n *\n * @example\n * ```ts\n * registry.remove(Date); // → true (estaba registrado por defecto)\n * registry.remove(Date); // → false (ya no está)\n * ```\n */\n remove<T>(type: new (...args: any[]) => T): boolean {\n return this.serializers.delete(type);\n }\n\n /**\n * Indica si hay un serializer registrado para `type`.\n *\n * @param {new (...args: any[]) => T} type - Constructor a consultar.\n * @returns `true` si `type` está registrado.\n *\n * @example\n * ```ts\n * if (!registry.has(CustomError)) {\n * registry.add(CustomError, serializeCustomError, 95);\n * }\n * ```\n */\n has<T>(type: new (...args: any[]) => T): boolean {\n return this.serializers.has(type);\n }\n\n /**\n * Devuelve todas las entradas registradas, ordenadas por `priority`\n * descendente (mayor priority primero). Este es el orden en el que\n * {@link SerializerRegistry.serialize} los prueba vía `instanceof`.\n *\n * @returns {SerializerEntry[]} Array de entradas ordenadas por prioridad.\n *\n * @example\n * ```ts\n * const entries = registry.getAll();\n * console.log(entries.map(e => [e.type.name, e.priority]));\n * // [['Error', 100], ['Date', 90], ['RegExp', 90], ['Map', 80], ...]\n * ```\n *\n * @see {@link SerializerEntry}\n */\n getAll(): SerializerEntry[] {\n return Array.from(this.serializers.values())\n .sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50));\n }\n\n /**\n * Busca el primer serializer cuyo `type` matchee `value instanceof type`,\n * recorriendo las entradas en orden de prioridad descendente.\n *\n * @internal Helper del pipeline interno; no es API pública.\n * @param value - Valor a testear.\n * @returns Entrada matcheante, o `null` si ninguna aplica.\n */\n private findSerializer(value: any): SerializerEntry | null {\n const sorted = this.getAll();\n for (const entry of sorted) {\n if (value instanceof entry.type) {\n return entry;\n }\n }\n return null;\n }\n\n /**\n * Pipeline interno de serialización recursiva. Es el core de\n * {@link SerializerRegistry.serialize}; no es API pública pero se documenta\n * aquí para mantener la semántica del pipeline en un solo lugar.\n *\n * Orden de guardas (cada una corta la recursión):\n *\n * 1. `null` / `undefined` — directo (respeta `preserveUndefined`).\n * 2. `function` — placeholder `'[Function: name]'`.\n * 3. Primitiva no-objeto — se devuelve tal cual.\n * 4. **Depth guard**: si `depth >= maxDepth` → `'[Max Depth]'`.\n * 5. **Circular**: si `value` ya está en el `WeakSet` `seen` del contexto,\n * aplica `circular` (`placeholder` / `skip` / `error`).\n * 6. Se marca en `seen`, se busca serializer por `instanceof`; si matchea,\n * se delega (el serializer puede recursar via `ctx`).\n * 7. Si es array, mapea cada item incrementando depth y extendiendo path.\n * 8. Si es plain object, itera keys recursivamente.\n *\n * @internal\n * @param value - Valor a serializar.\n * @param context - Estado de recursión (depth, path, seen, maxDepth).\n * @returns Valor serializable (puede ser primitiva, objeto, array o placeholder).\n * @throws {Error} Sólo si `circular: 'error'` y se detecta ciclo.\n */\n private serializeInternal(value: any, context: SerializerContext): any {\n if (value === null) return null;\n if (value === undefined) return this.config.preserveUndefined ? undefined : '[undefined]';\n if (typeof value === 'function') return `[Function: ${value.name || 'anonymous'}]`;\n if (typeof value !== 'object') return value;\n\n if (context.depth >= this.config.maxDepth) {\n return '[Max Depth]';\n }\n\n if (context.seen.has(value)) {\n switch (this.config.circular) {\n case 'error':\n throw new Error(`Circular reference at ${context.path.join('.')}`);\n case 'skip':\n return undefined;\n case 'placeholder':\n default:\n return '[Circular]';\n }\n }\n context.seen.add(value);\n\n const serializer = this.findSerializer(value);\n if (serializer) {\n return serializer.serializer(value, context);\n }\n\n if (Array.isArray(value)) {\n return value.map((item, i) =>\n this.serializeInternal(item, {\n ...context,\n depth: context.depth + 1,\n path: [...context.path, `[${i}]`]\n })\n );\n }\n\n const result: Record<string, any> = {};\n for (const [key, val] of Object.entries(value)) {\n result[key] = this.serializeInternal(val, {\n ...context,\n depth: context.depth + 1,\n path: [...context.path, key]\n });\n }\n return result;\n }\n\n /**\n * Serializa un valor arbitrario a una representación segura para transporte\n * (JSON, remote log, OTLP, etc.).\n *\n * Entry point público del pipeline. Construye un {@link SerializerContext}\n * fresco (depth 0, path vacío, `WeakSet` nuevo para detección de ciclos),\n * merguea overrides de `config` sobre los del constructor y delega a\n * {@link SerializerRegistry.serializeInternal}.\n *\n * @param {any} value - Valor a serializar. Cualquier tipo.\n * @param {SerializerConfig} [config] - Overrides puntuales para esta llamada\n * (no mutan la config del registry). Útil para, p.ej., subir `maxDepth`\n * sólo en un log concreto.\n * @returns {any} Valor serializable. Para objetos sin serializer registrado\n * se devuelve un plain object; para tipos builtin, la shape definida en\n * {@link SerializerRegistry.registerDefaults}; para los cortes de\n * profundidad o circular, los placeholders `'[Max Depth]'` / `'[Circular]'`.\n * @throws {Error} Sólo si `circular: 'error'` y se detecta una referencia circular.\n *\n * @example\n * ```ts\n * // Objetos simples\n * registry.serialize({ a: 1, b: [2, 3] });\n * // → { a: 1, b: [2, 3] }\n *\n * // Errores (serializer builtin)\n * registry.serialize(new Error('boom'));\n * // → { name: 'Error', message: 'boom', stack: [...] }\n *\n * // Referencia circular → placeholder\n * const o: any = {};\n * o.self = o;\n * registry.serialize(o); // → { self: '[Circular]' }\n *\n * // Override puntual de maxDepth\n * registry.serialize(deepObj, { maxDepth: 2 });\n * ```\n *\n * @see {@link SerializerRegistry.serializeInternal} para el detalle del pipeline.\n */\n serialize(value: any, config?: SerializerConfig): any {\n const mergedConfig = { ...this.config, ...config };\n return this.serializeInternal(value, {\n depth: 0,\n maxDepth: mergedConfig.maxDepth,\n path: [],\n seen: new WeakSet()\n });\n }\n}\n\n/**\n * Cache del singleton de {@link SerializerRegistry}. Module-private.\n *\n * @internal\n */\nlet _defaultRegistry: SerializerRegistry | null = null;\n\n/**\n * Devuelve el singleton de {@link SerializerRegistry} (lo crea con config\n * default en la primera llamada). Es la vía canónica de obtener el registry\n * compartido que usa el Logger internamente.\n *\n * @returns {SerializerRegistry} Instancia singleton.\n *\n * @example\n * ```ts\n * import { getDefaultSerializerRegistry } from '@mks2508/better-logger/serializers';\n *\n * const registry = getDefaultSerializerRegistry();\n * if (!registry.has(CustomError)) {\n * registry.add(CustomError, (e) => ({ code: e.code, message: e.message }), 95);\n * }\n * ```\n */\nexport function getDefaultSerializerRegistry(): SerializerRegistry {\n if (!_defaultRegistry) {\n _defaultRegistry = new SerializerRegistry();\n }\n return _defaultRegistry;\n}\n","/**\n * @fileoverview SerializerBridge — facade de SerializerRegistry.\n * Encapsula registro, eliminación y acceso al registry de serializers.\n *\n * @internal\n */\n\nimport type { SerializerFn } from '../types/index.js';\nimport { SerializerRegistry } from './index.js';\n\n/**\n * Bridge para la gestión de serializers.\n *\n * @internal\n */\nexport interface SerializerBridge {\n /** Añade un serializer para un tipo. */\n addSerializer<T>(type: new (...args: unknown[]) => T, serializer: SerializerFn<T>, priority?: number): void;\n /** Elimina el serializer asociado a un tipo. Devuelve `true` si se eliminó. */\n removeSerializer<T>(type: new (...args: unknown[]) => T): boolean;\n /** Devuelve el registry subyacente. */\n getSerializerRegistry(): SerializerRegistry;\n}\n\n/**\n * Crea una instancia de {@link SerializerBridge}.\n *\n * @internal\n */\nexport function createSerializerBridge(): SerializerBridge {\n const serializerRegistry = new SerializerRegistry();\n\n return {\n addSerializer<T>(type: new (...args: unknown[]) => T, serializer: SerializerFn<T>, priority?: number): void {\n serializerRegistry.add(type, serializer, priority);\n },\n\n removeSerializer<T>(type: new (...args: unknown[]) => T): boolean {\n return serializerRegistry.remove(type);\n },\n\n getSerializerRegistry(): SerializerRegistry {\n return serializerRegistry;\n }\n };\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
- const require_styling = require("./styling-Cg5saQ46.cjs");
1
+ const require_styling = require("./styling-Cel2wPRy.cjs");
2
2
  //#region src/styles/StyleManager.ts
3
3
  /**
4
- * @fileoverview StyleManager — style preset and display settings management.
5
- * Encapsulates active preset tracking, display toggles, and the
6
- * module-level LEVEL_STYLES variable.
4
+ * @fileoverview StyleManager — gestión de presets de estilo y display settings.
7
5
  *
8
- * Wired into Logger.ts in F4. Logger delegates style queries and theme
9
- * changes through this bridge so that the module-level LEVEL_STYLES stay
10
- * in sync across the module.
6
+ * Encapsula el tracking del preset activo, los toggles de visibilidad del
7
+ * output (timestamp, location, badges) y la variable de módulo
8
+ * {@link LEVEL_STYLES}. El Logger delega en este bridge la resolución de
9
+ * estilos y los cambios de theme para mantener sincronizado el estado
10
+ * compartido a nivel módulo.
11
11
  */
12
12
  function createDefaultDisplaySettings() {
13
13
  return {
@@ -17,7 +17,27 @@ function createDefaultDisplaySettings() {
17
17
  };
18
18
  }
19
19
  /**
20
- * Creates a StyleManager instance.
20
+ * Crea una instancia de {@link StyleManager} con display settings por defecto
21
+ * (o los overrides que se pasen en `options`).
22
+ *
23
+ * Cada instancia mantiene su propio estado de preset/customization/display,
24
+ * pero la backing store de estilos activos ({@link LEVEL_STYLES}) es
25
+ * module-scoped: dos StyleManagers comparten la misma vista de LEVEL_STYLES.
26
+ *
27
+ * @param options - Overrides opcionales para los display settings iniciales.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const sm = createStyleManager({
32
+ * initialDisplaySettings: { showTimestamp: false, showBadges: true }
33
+ * });
34
+ *
35
+ * sm.applyPreset('cyberpunk'); // aplica preset + ajusta toggles
36
+ * sm.setTheme('dark'); // muta LEVEL_STYLES (global al módulo)
37
+ * console.log(sm.getStyles()); // lee el LEVEL_STYLES vigente
38
+ * ```
39
+ *
40
+ * @see {@link StyleManager} para el contrato completo del bridge.
21
41
  */
22
42
  function createStyleManager(options = {}) {
23
43
  const displaySettings = createDefaultDisplaySettings();
@@ -77,8 +97,14 @@ function createStyleManager(options = {}) {
77
97
  };
78
98
  }
79
99
  /**
80
- * Module-level active styles — shared across all Logger instances.
81
- * Exported so Logger can reference it directly.
100
+ * Variable de módulo con el set de estilos activo, compartida por todas las
101
+ * instancias de Logger/StyleManager que importan este módulo. Se exporta
102
+ * `let` para que el Logger la pueda leer directamente sin pasar por el bridge.
103
+ *
104
+ * **Mutadores**: {@link StyleManager.setTheme} y {@link StyleManager.resetStyles}
105
+ * (o el {@link resetStyles} exportado de este módulo) reasignan esta variable.
106
+ * Cualquier referencia capturada con anterioridad queda stale — siempre leer
107
+ * vía `LEVEL_STYLES` en punto de uso, no cacheandola.
82
108
  */
83
109
  let LEVEL_STYLES = require_styling.THEME_PRESETS.default;
84
110
  //#endregion
@@ -89,4 +115,4 @@ Object.defineProperty(exports, "createStyleManager", {
89
115
  }
90
116
  });
91
117
 
92
- //# sourceMappingURL=StyleManager-CIpd6wbO.cjs.map
118
+ //# sourceMappingURL=StyleManager-DQ6UNRB-.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StyleManager-DQ6UNRB-.cjs","names":["hasPreset","getSmartPreset","getAvailablePresets","THEME_PRESETS","themeRecord"],"sources":["../../src/styles/StyleManager.ts"],"sourcesContent":["/**\n * @fileoverview StyleManager — gestión de presets de estilo y display settings.\n *\n * Encapsula el tracking del preset activo, los toggles de visibilidad del\n * output (timestamp, location, badges) y la variable de módulo\n * {@link LEVEL_STYLES}. El Logger delega en este bridge la resolución de\n * estilos y los cambios de theme para mantener sincronizado el estado\n * compartido a nivel módulo.\n */\n\nimport {\n THEME_PRESETS,\n type StylePresets,\n type StyleBuilder\n} from '../styling/index.js';\nimport { getSmartPreset, getAvailablePresets, hasPreset } from '../styling/SmartPresets.js';\nimport type { ThemeVariant, LogStyles } from '../types/index.js';\n\n/**\n * Re-export de `StyleBuilder` para consumo interno del Logger dentro de este\n * paquete. La API pública de styling vive en `../styling/index.ts`; este\n * re-export existe únicamente para evitar un segundo import cruzado desde\n * Logger.ts. No considerar parte del surface público de este módulo.\n *\n * @internal\n */\nexport { StyleBuilder } from '../styling/index.js';\n\n/**\n * Toggles de visibilidad que controlan qué metadatos acompañan a cada línea\n * de log en la salida formateada. Cada preset inteligente\n * (via {@link StyleManager.applyPreset}) puede imponer sus propios defaults\n * sobreescribiendo estos valores.\n */\nexport interface DisplaySettings {\n /** Muestra (o no) el timestamp ISO al inicio de cada línea. */\n showTimestamp: boolean;\n /** Muestra (o no) la ubicación del caller (file:line) parseada del stack. */\n showLocation: boolean;\n /** Muestra (o no) los badges de scope/nivel junto al mensaje. */\n showBadges: boolean;\n}\n\n/**\n * Snapshot del estado interno que el StyleManager trackea en closure:\n * preset activo, overrides de `customize()` y display settings vigentes.\n * Útil para serializar/inspeccionar el estado de styling sin exponer la\n * implementación del bridge.\n */\nexport interface PresetState {\n /** Config de estilos resuelta (referencia a {@link LEVEL_STYLES}). */\n styles: typeof THEME_PRESETS.default;\n /** Config del smart-preset activo (si lo hay). */\n activePreset: unknown;\n /** Nombre del smart-preset activo (si lo hay). */\n activePresetName: string | undefined;\n /** Últimos overrides aplicados via `customize()`. */\n customization: unknown;\n /** Toggles de visibilidad del output. */\n displaySettings: DisplaySettings;\n}\n\n/**\n * Opciones de construcción para {@link createStyleManager}.\n */\nexport interface IStyleManagerOptions {\n /** Display settings iniciales (parciales: se merguean sobre los defaults). */\n initialDisplaySettings?: Partial<DisplaySettings>;\n}\n\n/**\n * Bridge que gestiona presets de estilo, display settings y el ciclo de\n * theme switching para un Logger.\n *\n * Encapsula el estado de styling en una closure para que el Logger no\n * tenga que mantener boilerplate propio. La implementación por defecto\n * (ver {@link createStyleManager}) opera sobre la variable de módulo\n * compartida {@link LEVEL_STYLES}: esto significa que `setTheme()` y\n * `resetStyles()` mutan estado global visible para TODAS las instancias\n * de Logger que comparten el módulo. Cada Logger construye su propio\n * StyleManager, pero la backing store de estilos activos es module-scoped\n * — está pensado así para que cambiar de theme una vez afecte a toda la\n * app, pero conviene saberlo al instanciar múltiples loggers con intents\n * distintos.\n */\nexport interface StyleManager {\n /**\n * Devuelve un shallow clone de los display settings vigentes, de modo\n * que el caller pueda leerlos sin riesgo de mutar el estado interno.\n */\n getDisplaySettings(): DisplaySettings;\n /**\n * Aplica un smart-preset por nombre. Si el preset existe, actualiza los\n * toggles de display (`showTimestamp`/`showLocation`) según la config\n * del preset y memoriza su nombre/config para que el renderer pueda\n * regenerar el output si cambia el theme.\n *\n * @param name - Identificador del preset (ver {@link getAvailablePresets}).\n * @returns `true` si el preset existe y se aplicó, `false` si no se encontró.\n */\n applyPreset(name: string): boolean;\n /**\n * Lista los identificadores de todos los smart-presets registrados.\n * Útil para alimentar un selector de UI o validar input de usuario.\n */\n getAvailablePresets(): string[];\n /**\n * Devuelve la referencia actual a {@link LEVEL_STYLES}. Como es\n * module-scoped, refleja el último `setTheme()`/`resetStyles()` aunque\n * provenga de otra instancia.\n */\n getStyles(): typeof THEME_PRESETS.default;\n /** Devuelve la config cruda del smart-preset activo (o `undefined`). */\n getActivePreset(): unknown;\n /** Nombre del smart-preset activo — útil para logging diagnóstico. */\n getActivePresetName(): string | undefined;\n /** Último override aplicado via `Logger.customize()` (si lo hubo). */\n getCustomization(): unknown;\n /**\n * Persiste overrides de customización para que el renderer los consuma\n * en el próximo render. No muta {@link LEVEL_STYLES}.\n */\n setCustomization(overrides: unknown): void;\n /**\n * Resuelve (sin mutar nada) el set de estilos que correspondería a un\n * theme dado. Si el theme no existe en {@link THEME_PRESETS}, cae al\n * preset `default`. Útil para previsualizar un theme sin aplicarlo.\n *\n * @param theme - Variante de theme soportada por {@link THEME_PRESETS}.\n */\n resolveThemeStyle(theme: ThemeVariant): typeof THEME_PRESETS.default;\n /**\n * Aplica el theme mutando la variable de módulo {@link LEVEL_STYLES}.\n *\n * **Side-effect global**: como `LEVEL_STYLES` se comparte entre todas\n * las instancias de Logger del módulo, este cambio es visible para\n * cualquier Logger que haya en el proceso. No hay undo a nivel\n * instancia — llamar a {@link resetStyles} para volver al default.\n *\n * @param theme - Variante de theme soportada por {@link THEME_PRESETS}.\n * @returns `true` si el theme existe y se aplicó, `false` si no se encontró.\n */\n setTheme(theme: ThemeVariant): boolean;\n /**\n * Restablece {@link LEVEL_STYLES} al preset `default` de\n * {@link THEME_PRESETS}. Al igual que {@link setTheme}, afecta a todas\n * las instancias de Logger del módulo.\n */\n resetStyles(): void;\n}\n\nfunction createDefaultDisplaySettings(): DisplaySettings {\n return {\n showTimestamp: true,\n showLocation: true,\n showBadges: true\n };\n}\n\n/**\n * Crea una instancia de {@link StyleManager} con display settings por defecto\n * (o los overrides que se pasen en `options`).\n *\n * Cada instancia mantiene su propio estado de preset/customization/display,\n * pero la backing store de estilos activos ({@link LEVEL_STYLES}) es\n * module-scoped: dos StyleManagers comparten la misma vista de LEVEL_STYLES.\n *\n * @param options - Overrides opcionales para los display settings iniciales.\n *\n * @example\n * ```ts\n * const sm = createStyleManager({\n * initialDisplaySettings: { showTimestamp: false, showBadges: true }\n * });\n *\n * sm.applyPreset('cyberpunk'); // aplica preset + ajusta toggles\n * sm.setTheme('dark'); // muta LEVEL_STYLES (global al módulo)\n * console.log(sm.getStyles()); // lee el LEVEL_STYLES vigente\n * ```\n *\n * @see {@link StyleManager} para el contrato completo del bridge.\n */\nexport function createStyleManager(options: IStyleManagerOptions = {}): StyleManager {\n const displaySettings = createDefaultDisplaySettings();\n let activePreset: unknown;\n let activePresetName: string | undefined;\n let customization: unknown;\n\n return {\n getDisplaySettings(): DisplaySettings {\n return { ...displaySettings };\n },\n\n applyPreset(name: string): boolean {\n if (!hasPreset(name)) {\n return false;\n }\n\n const presetConfig = getSmartPreset(name);\n if (presetConfig) {\n displaySettings.showTimestamp = presetConfig.timestamp?.show ?? true;\n displaySettings.showLocation = presetConfig.location?.show ?? true;\n activePreset = presetConfig;\n activePresetName = name;\n }\n return true;\n },\n\n getAvailablePresets(): string[] {\n return getAvailablePresets();\n },\n\n getStyles(): typeof THEME_PRESETS.default {\n return LEVEL_STYLES;\n },\n\n getActivePreset(): unknown {\n return activePreset;\n },\n\n getActivePresetName(): string | undefined {\n return activePresetName;\n },\n\n getCustomization(): unknown {\n return customization;\n },\n\n setCustomization(overrides: unknown): void {\n customization = overrides;\n },\n\n resolveThemeStyle(theme: ThemeVariant): typeof THEME_PRESETS.default {\n if (theme in THEME_PRESETS) {\n const themeRecord = THEME_PRESETS as unknown as Record<string, typeof LEVEL_STYLES>;\n return themeRecord[theme] ?? THEME_PRESETS.default;\n }\n return THEME_PRESETS.default;\n },\n\n setTheme(theme: ThemeVariant): boolean {\n if (theme in THEME_PRESETS) {\n const themeRecord = THEME_PRESETS as unknown as Record<string, typeof LEVEL_STYLES>;\n const newStyles = themeRecord[theme];\n if (newStyles) {\n LEVEL_STYLES = newStyles;\n return true;\n }\n }\n return false;\n },\n\n resetStyles(): void {\n LEVEL_STYLES = THEME_PRESETS.default;\n }\n };\n}\n\n/**\n * Variable de módulo con el set de estilos activo, compartida por todas las\n * instancias de Logger/StyleManager que importan este módulo. Se exporta\n * `let` para que el Logger la pueda leer directamente sin pasar por el bridge.\n *\n * **Mutadores**: {@link StyleManager.setTheme} y {@link StyleManager.resetStyles}\n * (o el {@link resetStyles} exportado de este módulo) reasignan esta variable.\n * Cualquier referencia capturada con anterioridad queda stale — siempre leer\n * vía `LEVEL_STYLES` en punto de uso, no cacheandola.\n */\nexport let LEVEL_STYLES: typeof THEME_PRESETS.default = THEME_PRESETS.default;\n\n/**\n * Restablece {@link LEVEL_STYLES} al preset `default` de {@link THEME_PRESETS}.\n *\n * Equivalente a invocar {@link StyleManager.resetStyles} sobre cualquier\n * instancia, expuesto como función libre para que código externo al Logger\n * (CLIs, tooling, tests) pueda resetear el módulo sin tener que sostener una\n * referencia al StyleManager. Mismo side-effect global que `setTheme`.\n *\n * @example\n * ```ts\n * import { resetStyles } from '@mks2508/better-logger/styles';\n * resetStyles(); // vuelve al theme default para todos los loggers del módulo\n * ```\n */\nexport function resetStyles(): void {\n LEVEL_STYLES = THEME_PRESETS.default;\n}\n"],"mappings":";;;;;;;;;;;AAuJA,SAAS,+BAAgD;CACrD,OAAO;EACH,eAAe;EACf,cAAc;EACd,YAAY;CAChB;AACJ;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,mBAAmB,UAAgC,CAAC,GAAiB;CACjF,MAAM,kBAAkB,6BAA6B;CACrD,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,OAAO;EACH,qBAAsC;GAClC,OAAO,EAAE,GAAG,gBAAgB;EAChC;EAEA,YAAY,MAAuB;GAC/B,IAAI,CAACA,gBAAAA,UAAU,IAAI,GACf,OAAO;GAGX,MAAM,eAAeC,gBAAAA,eAAe,IAAI;GACxC,IAAI,cAAc;IACd,gBAAgB,gBAAgB,aAAa,WAAW,QAAQ;IAChE,gBAAgB,eAAe,aAAa,UAAU,QAAQ;IAC9D,eAAe;IACf,mBAAmB;GACvB;GACA,OAAO;EACX;EAEA,sBAAgC;GAC5B,OAAOC,gBAAAA,oBAAoB;EAC/B;EAEA,YAA0C;GACtC,OAAO;EACX;EAEA,kBAA2B;GACvB,OAAO;EACX;EAEA,sBAA0C;GACtC,OAAO;EACX;EAEA,mBAA4B;GACxB,OAAO;EACX;EAEA,iBAAiB,WAA0B;GACvC,gBAAgB;EACpB;EAEA,kBAAkB,OAAmD;GACjE,IAAI,SAASC,gBAAAA,eAET,OAAOC,gBAAAA,cAAY,UAAUD,gBAAAA,cAAc;GAE/C,OAAOA,gBAAAA,cAAc;EACzB;EAEA,SAAS,OAA8B;GACnC,IAAI,SAASA,gBAAAA,eAAe;IAExB,MAAM,YAAYC,gBAAAA,cAAY;IAC9B,IAAI,WAAW;KACX,eAAe;KACf,OAAO;IACX;GACJ;GACA,OAAO;EACX;EAEA,cAAoB;GAChB,eAAeD,gBAAAA,cAAc;EACjC;CACJ;AACJ;;;;;;;;;;;AAYA,IAAW,eAA6CA,gBAAAA,cAAc"}
@@ -0,0 +1,113 @@
1
+ import { n as getSmartPreset, r as hasPreset, s as THEME_PRESETS, t as getAvailablePresets } from "./styling-CRw3KQW4.js";
2
+ //#region src/styles/StyleManager.ts
3
+ /**
4
+ * @fileoverview StyleManager — gestión de presets de estilo y display settings.
5
+ *
6
+ * Encapsula el tracking del preset activo, los toggles de visibilidad del
7
+ * output (timestamp, location, badges) y la variable de módulo
8
+ * {@link LEVEL_STYLES}. El Logger delega en este bridge la resolución de
9
+ * estilos y los cambios de theme para mantener sincronizado el estado
10
+ * compartido a nivel módulo.
11
+ */
12
+ function createDefaultDisplaySettings() {
13
+ return {
14
+ showTimestamp: true,
15
+ showLocation: true,
16
+ showBadges: true
17
+ };
18
+ }
19
+ /**
20
+ * Crea una instancia de {@link StyleManager} con display settings por defecto
21
+ * (o los overrides que se pasen en `options`).
22
+ *
23
+ * Cada instancia mantiene su propio estado de preset/customization/display,
24
+ * pero la backing store de estilos activos ({@link LEVEL_STYLES}) es
25
+ * module-scoped: dos StyleManagers comparten la misma vista de LEVEL_STYLES.
26
+ *
27
+ * @param options - Overrides opcionales para los display settings iniciales.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const sm = createStyleManager({
32
+ * initialDisplaySettings: { showTimestamp: false, showBadges: true }
33
+ * });
34
+ *
35
+ * sm.applyPreset('cyberpunk'); // aplica preset + ajusta toggles
36
+ * sm.setTheme('dark'); // muta LEVEL_STYLES (global al módulo)
37
+ * console.log(sm.getStyles()); // lee el LEVEL_STYLES vigente
38
+ * ```
39
+ *
40
+ * @see {@link StyleManager} para el contrato completo del bridge.
41
+ */
42
+ function createStyleManager(options = {}) {
43
+ const displaySettings = createDefaultDisplaySettings();
44
+ let activePreset;
45
+ let activePresetName;
46
+ let customization;
47
+ return {
48
+ getDisplaySettings() {
49
+ return { ...displaySettings };
50
+ },
51
+ applyPreset(name) {
52
+ if (!hasPreset(name)) return false;
53
+ const presetConfig = getSmartPreset(name);
54
+ if (presetConfig) {
55
+ displaySettings.showTimestamp = presetConfig.timestamp?.show ?? true;
56
+ displaySettings.showLocation = presetConfig.location?.show ?? true;
57
+ activePreset = presetConfig;
58
+ activePresetName = name;
59
+ }
60
+ return true;
61
+ },
62
+ getAvailablePresets() {
63
+ return getAvailablePresets();
64
+ },
65
+ getStyles() {
66
+ return LEVEL_STYLES;
67
+ },
68
+ getActivePreset() {
69
+ return activePreset;
70
+ },
71
+ getActivePresetName() {
72
+ return activePresetName;
73
+ },
74
+ getCustomization() {
75
+ return customization;
76
+ },
77
+ setCustomization(overrides) {
78
+ customization = overrides;
79
+ },
80
+ resolveThemeStyle(theme) {
81
+ if (theme in THEME_PRESETS) return THEME_PRESETS[theme] ?? THEME_PRESETS.default;
82
+ return THEME_PRESETS.default;
83
+ },
84
+ setTheme(theme) {
85
+ if (theme in THEME_PRESETS) {
86
+ const newStyles = THEME_PRESETS[theme];
87
+ if (newStyles) {
88
+ LEVEL_STYLES = newStyles;
89
+ return true;
90
+ }
91
+ }
92
+ return false;
93
+ },
94
+ resetStyles() {
95
+ LEVEL_STYLES = THEME_PRESETS.default;
96
+ }
97
+ };
98
+ }
99
+ /**
100
+ * Variable de módulo con el set de estilos activo, compartida por todas las
101
+ * instancias de Logger/StyleManager que importan este módulo. Se exporta
102
+ * `let` para que el Logger la pueda leer directamente sin pasar por el bridge.
103
+ *
104
+ * **Mutadores**: {@link StyleManager.setTheme} y {@link StyleManager.resetStyles}
105
+ * (o el {@link resetStyles} exportado de este módulo) reasignan esta variable.
106
+ * Cualquier referencia capturada con anterioridad queda stale — siempre leer
107
+ * vía `LEVEL_STYLES` en punto de uso, no cacheandola.
108
+ */
109
+ let LEVEL_STYLES = THEME_PRESETS.default;
110
+ //#endregion
111
+ export { createStyleManager as t };
112
+
113
+ //# sourceMappingURL=StyleManager-DjwAYbxE.js.map