@mks2508/better-logger 0.0.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 (41) hide show
  1. package/.claude/settings.local.json +13 -0
  2. package/CLAUDE.md +113 -0
  3. package/dist/assets/index-DxvJByYN.js +183 -0
  4. package/dist/index.html +334 -0
  5. package/dist/vite.svg +1 -0
  6. package/index.html +334 -0
  7. package/package.json +35 -0
  8. package/public/vite.svg +1 -0
  9. package/src/Logger.ts +577 -0
  10. package/src/Logger.ts.backup +1684 -0
  11. package/src/cli/CommandProcessor.ts +77 -0
  12. package/src/cli/commands/ConfigCommand.ts +93 -0
  13. package/src/cli/commands/ExportCommand.ts +271 -0
  14. package/src/cli/commands/StatusCommand.ts +111 -0
  15. package/src/cli/commands/ThemeCommand.ts +88 -0
  16. package/src/cli/help.ts +127 -0
  17. package/src/cli/index.ts +59 -0
  18. package/src/constants.ts +89 -0
  19. package/src/example.ts +88 -0
  20. package/src/handlers/AnalyticsLogHandler.ts +22 -0
  21. package/src/handlers/ExportLogHandler.ts +447 -0
  22. package/src/handlers/FileLogHandler.ts +30 -0
  23. package/src/handlers/RemoteLogHandler.ts +42 -0
  24. package/src/handlers/index.ts +8 -0
  25. package/src/index.ts +122 -0
  26. package/src/main.ts +126 -0
  27. package/src/style.css +96 -0
  28. package/src/styling/StyleBuilder.ts +305 -0
  29. package/src/styling/banners.ts +168 -0
  30. package/src/styling/index.ts +12 -0
  31. package/src/styling/themes.ts +235 -0
  32. package/src/types/core.ts +80 -0
  33. package/src/types/handlers.ts +95 -0
  34. package/src/types/index.ts +29 -0
  35. package/src/typescript.svg +1 -0
  36. package/src/utils/index.ts +18 -0
  37. package/src/utils/output.ts +127 -0
  38. package/src/utils/stackTrace.ts +66 -0
  39. package/src/utils/timestamps.ts +80 -0
  40. package/src/vite-env.d.ts +1 -0
  41. package/tsconfig.json +24 -0
@@ -0,0 +1,447 @@
1
+ /**
2
+ * @fileoverview Export and clipboard log handler for Advanced Logger
3
+ */
4
+
5
+ import type {
6
+ ILogHandler,
7
+ LogLevel,
8
+ LogMetadata,
9
+ LogEntry,
10
+ ExportFilters,
11
+ ExportOptions,
12
+ ExportResult,
13
+ BufferStats,
14
+ ExportFormat
15
+ } from '../types/index.js';
16
+ import { parseTimeInput, formatDisplayTime, safeStringify, escapeHtml, generateLogId } from '../utils/index.js';
17
+ import { BUFFER_LIMITS } from '../constants.js';
18
+
19
+ /**
20
+ * Export log handler with circular buffer and multiple export formats
21
+ */
22
+ export class ExportLogHandler implements ILogHandler {
23
+ private buffer: LogEntry[] = [];
24
+ private maxSize: number;
25
+ private groupDepth: number = 0;
26
+ private currentGroup?: string;
27
+
28
+ constructor(maxSize: number = BUFFER_LIMITS.DEFAULT_SIZE) {
29
+ this.maxSize = Math.min(Math.max(maxSize, BUFFER_LIMITS.MIN_SIZE), BUFFER_LIMITS.MAX_SIZE);
30
+ }
31
+
32
+ /**
33
+ * Handle incoming log and store in buffer
34
+ */
35
+ handle(level: LogLevel, message: string, args: any[], metadata: LogMetadata): void {
36
+ const entry: LogEntry = {
37
+ id: generateLogId(),
38
+ timestamp: metadata.timestamp,
39
+ level,
40
+ prefix: metadata.prefix,
41
+ message,
42
+ args,
43
+ location: metadata.stackInfo,
44
+ groupInfo: this.groupDepth > 0 ? {
45
+ depth: this.groupDepth,
46
+ groupName: this.currentGroup
47
+ } : undefined
48
+ };
49
+
50
+ // Add to circular buffer
51
+ this.buffer.push(entry);
52
+ if (this.buffer.length > this.maxSize) {
53
+ this.buffer.shift(); // Remove oldest entry
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Set group tracking for nested logs
59
+ */
60
+ setGroupInfo(depth: number, groupName?: string): void {
61
+ this.groupDepth = depth;
62
+ this.currentGroup = groupName;
63
+ }
64
+
65
+ /**
66
+ * Get buffer statistics
67
+ */
68
+ getBufferStats(): BufferStats {
69
+ const levelCounts = this.buffer.reduce((acc, entry) => {
70
+ acc[entry.level] = (acc[entry.level] || 0) + 1;
71
+ return acc;
72
+ }, {} as Record<LogLevel, number>);
73
+
74
+ return {
75
+ size: this.buffer.length,
76
+ maxSize: this.maxSize,
77
+ usage: (this.buffer.length / this.maxSize) * 100,
78
+ oldestLog: this.buffer.length > 0 ? new Date(this.buffer[0].timestamp) : undefined,
79
+ newestLog: this.buffer.length > 0 ? new Date(this.buffer[this.buffer.length - 1].timestamp) : undefined,
80
+ levelCounts: {
81
+ ...{
82
+ debug: 0,
83
+ info: 0,
84
+ warn: 0,
85
+ error: 0,
86
+ critical: 0
87
+ },
88
+ ...levelCounts
89
+ }
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Clear the buffer
95
+ */
96
+ clearBuffer(): void {
97
+ this.buffer = [];
98
+ }
99
+
100
+ /**
101
+ * Set buffer size (with limits)
102
+ */
103
+ setBufferSize(size: number): void {
104
+ this.maxSize = Math.min(Math.max(size, BUFFER_LIMITS.MIN_SIZE), BUFFER_LIMITS.MAX_SIZE);
105
+
106
+ // Trim buffer if new size is smaller
107
+ if (this.buffer.length > this.maxSize) {
108
+ this.buffer = this.buffer.slice(-this.maxSize);
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Filter logs based on criteria
114
+ */
115
+ private filterLogs(filters: ExportFilters = {}): LogEntry[] {
116
+ let filtered = [...this.buffer];
117
+
118
+ // Filter by levels
119
+ if (filters.levels?.length) {
120
+ filtered = filtered.filter(entry => filters.levels!.includes(entry.level));
121
+ }
122
+
123
+ // Filter by prefixes
124
+ if (filters.prefixes?.length) {
125
+ filtered = filtered.filter(entry =>
126
+ entry.prefix && filters.prefixes!.includes(entry.prefix)
127
+ );
128
+ }
129
+
130
+ // Exclude prefixes
131
+ if (filters.excludePrefixes?.length) {
132
+ filtered = filtered.filter(entry =>
133
+ !entry.prefix || !filters.excludePrefixes!.includes(entry.prefix)
134
+ );
135
+ }
136
+
137
+ // Filter by time range
138
+ if (filters.since) {
139
+ const sinceDate = parseTimeInput(filters.since);
140
+ filtered = filtered.filter(entry => new Date(entry.timestamp) >= sinceDate);
141
+ }
142
+
143
+ if (filters.until) {
144
+ const untilDate = parseTimeInput(filters.until);
145
+ filtered = filtered.filter(entry => new Date(entry.timestamp) <= untilDate);
146
+ }
147
+
148
+ // Filter by stack trace presence
149
+ if (filters.withStackTrace) {
150
+ filtered = filtered.filter(entry => entry.location);
151
+ }
152
+
153
+ // Filter errors only
154
+ if (filters.errorsOnly) {
155
+ filtered = filtered.filter(entry => entry.level === 'error' || entry.level === 'critical');
156
+ }
157
+
158
+ // Search in messages
159
+ if (filters.search) {
160
+ const searchTerm = filters.search.toLowerCase();
161
+ filtered = filtered.filter(entry =>
162
+ entry.message.toLowerCase().includes(searchTerm) ||
163
+ entry.args.some(arg =>
164
+ String(arg).toLowerCase().includes(searchTerm)
165
+ )
166
+ );
167
+ }
168
+
169
+ // Limit results
170
+ if (filters.last) {
171
+ filtered = filtered.slice(-filters.last);
172
+ }
173
+
174
+ if (filters.first) {
175
+ filtered = filtered.slice(0, filters.first);
176
+ }
177
+
178
+ return filtered;
179
+ }
180
+
181
+ /**
182
+ * Export logs in JSON format
183
+ */
184
+ private exportJSON(logs: LogEntry[], options: ExportOptions): string {
185
+ const data = logs.map(entry => ({
186
+ timestamp: entry.timestamp,
187
+ level: entry.level,
188
+ prefix: entry.prefix,
189
+ message: entry.message,
190
+ ...(options.minimal ? {} : {
191
+ args: entry.args.slice(1),
192
+ location: entry.location,
193
+ groupInfo: entry.groupInfo
194
+ })
195
+ }));
196
+
197
+ return options.compact
198
+ ? JSON.stringify(data)
199
+ : JSON.stringify(data, null, 2);
200
+ }
201
+
202
+ /**
203
+ * Export logs in CSV format
204
+ */
205
+ private exportCSV(logs: LogEntry[], options: ExportOptions): string {
206
+ const headers = options.minimal
207
+ ? ['Timestamp', 'Level', 'Prefix', 'Message']
208
+ : ['Timestamp', 'Level', 'Prefix', 'Message', 'File', 'Line', 'Args'];
209
+
210
+ const rows = logs.map(entry => {
211
+ const baseRow = [
212
+ formatDisplayTime(new Date(entry.timestamp), 'full'),
213
+ entry.level.toUpperCase(),
214
+ entry.prefix || '',
215
+ `"${entry.message.replace(/"/g, '""')}"`
216
+ ];
217
+
218
+ if (!options.minimal) {
219
+ baseRow.push(
220
+ entry.location?.file || '',
221
+ entry.location?.line?.toString() || '',
222
+ `"${safeStringify(entry.args.slice(1)).replace(/"/g, '""')}"`
223
+ );
224
+ }
225
+
226
+ return baseRow;
227
+ });
228
+
229
+ return [headers.join(','), ...rows.map(row => row.join(','))].join('\n');
230
+ }
231
+
232
+ /**
233
+ * Export logs in Markdown format
234
+ */
235
+ private exportMarkdown(logs: LogEntry[], options: ExportOptions): string {
236
+ const now = new Date();
237
+ let content = `# Log Export - ${formatDisplayTime(now, 'full')}\n\n`;
238
+
239
+ // Add summary if not minimal
240
+ if (!options.minimal) {
241
+ const summary = this.getBufferStats();
242
+ content += `## Summary\n`;
243
+ content += `- **Total logs**: ${logs.length}\n`;
244
+ content += `- **Errors**: ${summary.levelCounts.error + summary.levelCounts.critical}\n`;
245
+ content += `- **Warnings**: ${summary.levelCounts.warn}\n\n`;
246
+ }
247
+
248
+ // Group by level if specified
249
+ if (options.groupBy === 'level') {
250
+ const grouped = logs.reduce((acc, entry) => {
251
+ if (!acc[entry.level]) acc[entry.level] = [];
252
+ acc[entry.level].push(entry);
253
+ return acc;
254
+ }, {} as Record<string, LogEntry[]>);
255
+
256
+ Object.entries(grouped).forEach(([level, entries]) => {
257
+ const emoji = this.getLevelEmoji(level as LogLevel);
258
+ content += `## ${emoji} ${level.toUpperCase()} (${entries.length})\n\n`;
259
+
260
+ entries.forEach(entry => {
261
+ const time = formatDisplayTime(new Date(entry.timestamp), 'time-only');
262
+ const location = entry.location ? ` (${entry.location.file}:${entry.location.line})` : '';
263
+ const prefix = entry.prefix ? ` **${entry.prefix}**:` : '';
264
+ content += `- \`${time}\`${prefix} ${entry.message}${location}\n`;
265
+ });
266
+ content += '\n';
267
+ });
268
+ } else {
269
+ content += '## Logs\n\n';
270
+ logs.forEach(entry => {
271
+ const time = formatDisplayTime(new Date(entry.timestamp), 'time-only');
272
+ const emoji = this.getLevelEmoji(entry.level);
273
+ const location = entry.location ? ` (${entry.location.file}:${entry.location.line})` : '';
274
+ const prefix = entry.prefix ? ` **${entry.prefix}**:` : '';
275
+ content += `- \`${time}\` ${emoji}${prefix} ${entry.message}${location}\n`;
276
+ });
277
+ }
278
+
279
+ return content;
280
+ }
281
+
282
+ /**
283
+ * Export logs in plain text format
284
+ */
285
+ private exportPlain(logs: LogEntry[], options: ExportOptions): string {
286
+ return logs.map(entry => {
287
+ const time = formatDisplayTime(new Date(entry.timestamp), options.minimal ? 'time-only' : 'short');
288
+ const level = entry.level.toUpperCase().padEnd(8);
289
+ const prefix = entry.prefix ? `[${entry.prefix}] ` : '';
290
+ const location = (!options.minimal && entry.location) ? ` (${entry.location.file}:${entry.location.line})` : '';
291
+
292
+ return `${time} ${level} ${prefix}${entry.message}${location}`;
293
+ }).join('\n');
294
+ }
295
+
296
+ /**
297
+ * Export logs in HTML format
298
+ */
299
+ private exportHTML(logs: LogEntry[], _options: ExportOptions): string {
300
+ const title = `Log Export - ${formatDisplayTime(new Date(), 'full')}`;
301
+
302
+ let html = `<!DOCTYPE html>
303
+ <html lang="en">
304
+ <head>
305
+ <meta charset="UTF-8">
306
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
307
+ <title>${title}</title>
308
+ <style>
309
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 20px; line-height: 1.6; }
310
+ .header { border-bottom: 2px solid #ddd; padding-bottom: 20px; margin-bottom: 20px; }
311
+ .log-entry { margin: 5px 0; padding: 8px; border-radius: 4px; font-family: 'Monaco', 'Consolas', monospace; }
312
+ .timestamp { color: #666; font-size: 0.9em; }
313
+ .level { font-weight: bold; padding: 2px 6px; border-radius: 3px; margin: 0 8px; }
314
+ .prefix { background: #2d3748; color: #e2e8f0; padding: 2px 6px; border-radius: 3px; margin: 0 8px; }
315
+ .location { color: #718096; font-size: 0.9em; }
316
+ .debug { background: #f0f4ff; }
317
+ .info { background: #f0f9ff; }
318
+ .warn { background: #fffbeb; }
319
+ .error { background: #fef2f2; }
320
+ .critical { background: #fef2f2; border-left: 4px solid #dc2626; }
321
+ .level.debug { background: #667eea; color: white; }
322
+ .level.info { background: #74b9ff; color: white; }
323
+ .level.warn { background: #fdcb6e; color: #2d3436; }
324
+ .level.error { background: #e84393; color: white; }
325
+ .level.critical { background: #ff3838; color: white; }
326
+ </style>
327
+ </head>
328
+ <body>
329
+ <div class="header">
330
+ <h1>${title}</h1>
331
+ <p>Generated by Advanced Logger v2.0.0</p>
332
+ </div>
333
+ <div class="logs">`;
334
+
335
+ logs.forEach(entry => {
336
+ const time = formatDisplayTime(new Date(entry.timestamp), 'full');
337
+ const location = entry.location ? ` <span class="location">(${escapeHtml(entry.location.file)}:${entry.location.line})</span>` : '';
338
+ const prefix = entry.prefix ? ` <span class="prefix">${escapeHtml(entry.prefix)}</span>` : '';
339
+
340
+ html += `
341
+ <div class="log-entry ${entry.level}">
342
+ <span class="timestamp">${time}</span>
343
+ <span class="level ${entry.level}">${entry.level.toUpperCase()}</span>
344
+ ${prefix}
345
+ <span class="message">${escapeHtml(entry.message)}</span>
346
+ ${location}
347
+ </div>`;
348
+ });
349
+
350
+ html += `
351
+ </div>
352
+ </body>
353
+ </html>`;
354
+
355
+ return html;
356
+ }
357
+
358
+ /**
359
+ * Get emoji for log level
360
+ */
361
+ private getLevelEmoji(level: LogLevel): string {
362
+ const emojis = {
363
+ debug: '🐞',
364
+ info: 'ℹ️',
365
+ warn: '⚠️',
366
+ error: '❌',
367
+ critical: '🔥'
368
+ };
369
+ return emojis[level] || '';
370
+ }
371
+
372
+ /**
373
+ * Main export function
374
+ */
375
+ export(format: ExportFormat, filters: ExportFilters = {}, options: ExportOptions = {}): ExportResult {
376
+ const filteredLogs = this.filterLogs(filters);
377
+
378
+ let data: string;
379
+ switch (format) {
380
+ case 'json':
381
+ data = this.exportJSON(filteredLogs, options);
382
+ break;
383
+ case 'csv':
384
+ data = this.exportCSV(filteredLogs, options);
385
+ break;
386
+ case 'markdown':
387
+ data = this.exportMarkdown(filteredLogs, options);
388
+ break;
389
+ case 'plain':
390
+ data = this.exportPlain(filteredLogs, options);
391
+ break;
392
+ case 'html':
393
+ data = this.exportHTML(filteredLogs, options);
394
+ break;
395
+ default:
396
+ throw new Error(`Unsupported export format: ${format}`);
397
+ }
398
+
399
+ return {
400
+ format,
401
+ data,
402
+ metadata: {
403
+ totalLogs: this.buffer.length,
404
+ filteredLogs: filteredLogs.length,
405
+ exportedAt: new Date().toISOString(),
406
+ filters,
407
+ options
408
+ }
409
+ };
410
+ }
411
+
412
+ /**
413
+ * Copy to clipboard with fallback
414
+ */
415
+ async copyToClipboard(format: ExportFormat, filters: ExportFilters = {}, options: ExportOptions = {}): Promise<boolean> {
416
+ const result = this.export(format, filters, options);
417
+
418
+ try {
419
+ if (navigator.clipboard && window.isSecureContext) {
420
+ await navigator.clipboard.writeText(result.data);
421
+ return true;
422
+ } else {
423
+ // Fallback for non-secure contexts
424
+ const textArea = document.createElement('textarea');
425
+ textArea.value = result.data;
426
+ textArea.style.position = 'fixed';
427
+ textArea.style.opacity = '0';
428
+ document.body.appendChild(textArea);
429
+ textArea.focus();
430
+ textArea.select();
431
+ const success = document.execCommand('copy');
432
+ document.body.removeChild(textArea);
433
+ return success;
434
+ }
435
+ } catch (error) {
436
+ console.error('Failed to copy to clipboard:', error);
437
+ return false;
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Get all logs (for debugging)
443
+ */
444
+ getAllLogs(): LogEntry[] {
445
+ return [...this.buffer];
446
+ }
447
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @fileoverview File-based log handler for Advanced Logger
3
+ */
4
+
5
+ import type { ILogHandler, LogLevel, LogMetadata } from '../types/index.js';
6
+
7
+ /**
8
+ * File-based log handler for persistent logging
9
+ */
10
+ export class FileLogHandler implements ILogHandler {
11
+ private filename: string;
12
+
13
+ constructor(filename: string = 'app.log') {
14
+ this.filename = filename;
15
+ }
16
+
17
+ handle(level: LogLevel, message: string, args: any[], metadata: LogMetadata): void {
18
+ const logEntry = {
19
+ filename: this.filename,
20
+ timestamp: metadata.timestamp,
21
+ level: level.toUpperCase(),
22
+ prefix: metadata.prefix,
23
+ message,
24
+ args: args.slice(1),
25
+ location: metadata.stackInfo,
26
+ };
27
+
28
+ console.debug('File log entry:', logEntry);
29
+ }
30
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @fileoverview Remote log handler for Advanced Logger
3
+ */
4
+
5
+ import type { ILogHandler, LogLevel, LogMetadata } from '../types/index.js';
6
+
7
+ /**
8
+ * Remote log handler for sending logs to external services
9
+ */
10
+ export class RemoteLogHandler implements ILogHandler {
11
+ private endpoint: string;
12
+ private apiKey?: string;
13
+
14
+ constructor(endpoint: string, apiKey?: string) {
15
+ this.endpoint = endpoint;
16
+ this.apiKey = apiKey;
17
+ }
18
+
19
+ async handle(level: LogLevel, message: string, args: any[], metadata: LogMetadata): Promise<void> {
20
+ try {
21
+ const payload = {
22
+ timestamp: metadata.timestamp,
23
+ level,
24
+ message,
25
+ prefix: metadata.prefix,
26
+ location: metadata.stackInfo,
27
+ additional: args.slice(1),
28
+ };
29
+
30
+ await fetch(this.endpoint, {
31
+ method: 'POST',
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ ...(this.apiKey && { 'Authorization': `Bearer ${this.apiKey}` }),
35
+ },
36
+ body: JSON.stringify(payload),
37
+ });
38
+ } catch (error) {
39
+ // Silently fail to avoid infinite logging loops
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Log handlers exports for Advanced Logger
3
+ */
4
+
5
+ export { FileLogHandler } from './FileLogHandler.js';
6
+ export { RemoteLogHandler } from './RemoteLogHandler.js';
7
+ export { AnalyticsLogHandler } from './AnalyticsLogHandler.js';
8
+ export { ExportLogHandler } from './ExportLogHandler.js';
package/src/index.ts ADDED
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @fileoverview Advanced Logger - Main exports
3
+ * @version 2.0.0
4
+ */
5
+
6
+ // Main Logger class and default instance
7
+ export { Logger } from './Logger.js';
8
+ export { default } from './Logger.js';
9
+
10
+ // Individual logger method exports for convenience (bound to default instance)
11
+ import defaultLogger from './Logger.js';
12
+
13
+ export const debug = (...args: any[]) => defaultLogger.debug(...args);
14
+ export const info = (...args: any[]) => defaultLogger.info(...args);
15
+ export const warn = (...args: any[]) => defaultLogger.warn(...args);
16
+ export const error = (...args: any[]) => defaultLogger.error(...args);
17
+ export const success = (...args: any[]) => defaultLogger.success(...args);
18
+ export const trace = (...args: any[]) => defaultLogger.trace(...args);
19
+ export const critical = (...args: any[]) => defaultLogger.critical(...args);
20
+ export const table = (data: any, columns?: string[]) => defaultLogger.table(data, columns);
21
+ export const group = (label: string, collapsed?: boolean) => defaultLogger.group(label, collapsed);
22
+ export const groupEnd = () => defaultLogger.groupEnd();
23
+ export const time = (label: string) => defaultLogger.time(label);
24
+ export const timeEnd = (label: string) => defaultLogger.timeEnd(label);
25
+ export const setGlobalPrefix = (prefix: string) => defaultLogger.setGlobalPrefix(prefix);
26
+ export const createScopedLogger = (prefix: string) => defaultLogger.createScopedLogger(prefix);
27
+ export const setVerbosity = (level: any) => defaultLogger.setVerbosity(level);
28
+ export const addHandler = (handler: any) => defaultLogger.addHandler(handler);
29
+ export const setTheme = (theme: any) => defaultLogger.setTheme(theme);
30
+ export const setBannerType = (bannerType: any) => defaultLogger.setBannerType(bannerType);
31
+ export const showBanner = (bannerType?: any) => defaultLogger.showBanner(bannerType);
32
+ export const logWithSVG = (message: string, svgContent?: string, options?: any) =>
33
+ defaultLogger.logWithSVG(message, svgContent, options);
34
+ export const logAnimated = (message: string, duration?: number) =>
35
+ defaultLogger.logAnimated(message, duration);
36
+ export const cli = (command: string) => defaultLogger.cli(command);
37
+
38
+ // Type exports
39
+ export type {
40
+ LogLevel,
41
+ Verbosity,
42
+ ThemeVariant,
43
+ BannerType,
44
+ ExportFormat,
45
+ LoggerConfig,
46
+ ILogHandler,
47
+ LogMetadata,
48
+ LogEntry,
49
+ ExportFilters,
50
+ ExportOptions,
51
+ ExportResult,
52
+ BufferStats,
53
+ StackInfo,
54
+ TimerEntry,
55
+ StyleOptions
56
+ } from './types/index.js';
57
+
58
+ // Styling utilities
59
+ export {
60
+ StyleBuilder,
61
+ $,
62
+ StylePresets,
63
+ THEME_PRESETS,
64
+ BANNER_VARIANTS,
65
+ THEME_BANNERS
66
+ } from './styling/index.js';
67
+
68
+ // Handler exports
69
+ export {
70
+ FileLogHandler,
71
+ RemoteLogHandler,
72
+ AnalyticsLogHandler,
73
+ ExportLogHandler
74
+ } from './handlers/index.js';
75
+
76
+ // CLI exports
77
+ export {
78
+ CommandProcessor,
79
+ createDefaultCLI,
80
+ type ICommand
81
+ } from './cli/index.js';
82
+
83
+ // Constants
84
+ export {
85
+ DEFAULT_CONFIG,
86
+ BUFFER_LIMITS,
87
+ EXPORT_FORMATS,
88
+ CLI_COMMANDS,
89
+ TIME_UNITS
90
+ } from './constants.js';
91
+
92
+ // Utility exports
93
+ export {
94
+ parseStackTrace,
95
+ formatTimestamp,
96
+ parseTimeInput,
97
+ parseRelativeTime,
98
+ formatDisplayTime,
99
+ generateLogId,
100
+ escapeHtml,
101
+ safeStringify
102
+ } from './utils/index.js';
103
+
104
+ // Legacy Styles export for backward compatibility
105
+ import { StyleBuilder, StylePresets } from './styling/index.js';
106
+
107
+ /**
108
+ * Advanced styling utilities for external use (legacy compatibility)
109
+ */
110
+ export const Styles = {
111
+ /**
112
+ * Creates a new StyleBuilder instance
113
+ */
114
+ create(): StyleBuilder {
115
+ return new StyleBuilder();
116
+ },
117
+
118
+ /**
119
+ * Pre-defined common styles
120
+ */
121
+ presets: StylePresets,
122
+ };