@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,235 @@
1
+ /**
2
+ * @fileoverview Theme presets for Advanced Logger
3
+ */
4
+
5
+ import type { ThemeVariant } from '../types/index.js';
6
+ import type { LevelStyleConfig } from '../utils/index.js';
7
+
8
+ /**
9
+ * Theme configurations for different visual styles
10
+ */
11
+ export const THEME_PRESETS: Record<ThemeVariant, Record<string, LevelStyleConfig>> = {
12
+ default: {
13
+ debug: {
14
+ emoji: '🐞', label: 'DEBUG',
15
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
16
+ color: '#ffffff', border: '1px solid #667eea',
17
+ shadow: '0 2px 4px rgba(102, 126, 234, 0.3)',
18
+ },
19
+ info: {
20
+ emoji: 'â„šī¸', label: 'INFO',
21
+ background: 'linear-gradient(135deg, #74b9ff 0%, #0984e3 100%)',
22
+ color: '#ffffff', border: '1px solid #74b9ff',
23
+ shadow: '0 2px 4px rgba(116, 185, 255, 0.3)',
24
+ },
25
+ warn: {
26
+ emoji: 'âš ī¸', label: 'WARN',
27
+ background: 'linear-gradient(135deg, #fdcb6e 0%, #e17055 100%)',
28
+ color: '#2d3436', border: '1px solid #fdcb6e',
29
+ shadow: '0 2px 4px rgba(253, 203, 110, 0.3)',
30
+ },
31
+ error: {
32
+ emoji: '❌', label: 'ERROR',
33
+ background: 'linear-gradient(135deg, #e84393 0%, #d63031 100%)',
34
+ color: '#ffffff', border: '1px solid #e84393',
35
+ shadow: '0 2px 4px rgba(232, 67, 147, 0.3)',
36
+ },
37
+ success: {
38
+ emoji: '✅', label: 'SUCCESS',
39
+ background: 'linear-gradient(135deg, #00b894 0%, #00a085 100%)',
40
+ color: '#ffffff', border: '1px solid #00b894',
41
+ shadow: '0 2px 4px rgba(0, 184, 148, 0.3)',
42
+ },
43
+ critical: {
44
+ emoji: 'đŸ”Ĩ', label: 'CRITICAL',
45
+ background: 'linear-gradient(135deg, #ff3838 0%, #ff1744 100%)',
46
+ color: '#ffffff', border: '2px solid #ff3838',
47
+ shadow: '0 4px 8px rgba(255, 56, 56, 0.5)',
48
+ },
49
+ },
50
+ dark: {
51
+ debug: {
52
+ emoji: '🌙', label: 'DEBUG',
53
+ background: 'linear-gradient(135deg, #2d3748 0%, #4a5568 100%)',
54
+ color: '#e2e8f0', border: '1px solid #4a5568',
55
+ shadow: '0 2px 4px rgba(45, 55, 72, 0.8)',
56
+ },
57
+ info: {
58
+ emoji: '💡', label: 'INFO',
59
+ background: 'linear-gradient(135deg, #1a202c 0%, #2d3748 100%)',
60
+ color: '#90cdf4', border: '1px solid #3182ce',
61
+ shadow: '0 2px 4px rgba(26, 32, 44, 0.8)',
62
+ },
63
+ warn: {
64
+ emoji: '⚡', label: 'WARN',
65
+ background: 'linear-gradient(135deg, #744210 0%, #975a16 100%)',
66
+ color: '#faf089', border: '1px solid #d69e2e',
67
+ shadow: '0 2px 4px rgba(116, 66, 16, 0.8)',
68
+ },
69
+ error: {
70
+ emoji: '💀', label: 'ERROR',
71
+ background: 'linear-gradient(135deg, #742a2a 0%, #9b2c2c 100%)',
72
+ color: '#feb2b2', border: '1px solid #e53e3e',
73
+ shadow: '0 2px 4px rgba(116, 42, 42, 0.8)',
74
+ },
75
+ success: {
76
+ emoji: 'đŸŽ¯', label: 'SUCCESS',
77
+ background: 'linear-gradient(135deg, #276749 0%, #2f855a 100%)',
78
+ color: '#9ae6b4', border: '1px solid #38a169',
79
+ shadow: '0 2px 4px rgba(39, 103, 73, 0.8)',
80
+ },
81
+ critical: {
82
+ emoji: 'đŸ’Ĩ', label: 'CRITICAL',
83
+ background: 'linear-gradient(135deg, #1a1a1a 0%, #ff0000 100%)',
84
+ color: '#ffffff', border: '2px solid #ff0000',
85
+ shadow: '0 4px 8px rgba(255, 0, 0, 0.9)',
86
+ },
87
+ },
88
+ neon: {
89
+ debug: {
90
+ emoji: '⚡', label: 'DEBUG',
91
+ background: 'linear-gradient(135deg, #0f3460 0%, #e94560 100%)',
92
+ color: '#00ffff', border: '1px solid #00ffff',
93
+ shadow: '0 0 10px rgba(0, 255, 255, 0.5)',
94
+ },
95
+ info: {
96
+ emoji: '🔮', label: 'INFO',
97
+ background: 'linear-gradient(135deg, #16213e 0%, #0f3460 100%)',
98
+ color: '#00ff41', border: '1px solid #00ff41',
99
+ shadow: '0 0 10px rgba(0, 255, 65, 0.5)',
100
+ },
101
+ warn: {
102
+ emoji: 'âš ī¸', label: 'WARN',
103
+ background: 'linear-gradient(135deg, #533a03 0%, #e94560 100%)',
104
+ color: '#ffff00', border: '1px solid #ffff00',
105
+ shadow: '0 0 10px rgba(255, 255, 0, 0.5)',
106
+ },
107
+ error: {
108
+ emoji: 'đŸ’Ĩ', label: 'ERROR',
109
+ background: 'linear-gradient(135deg, #5c0a0a 0%, #ff073a 100%)',
110
+ color: '#ff073a', border: '1px solid #ff073a',
111
+ shadow: '0 0 10px rgba(255, 7, 58, 0.8)',
112
+ },
113
+ success: {
114
+ emoji: '✨', label: 'SUCCESS',
115
+ background: 'linear-gradient(135deg, #0a5c0a 0%, #39ff14 100%)',
116
+ color: '#39ff14', border: '1px solid #39ff14',
117
+ shadow: '0 0 10px rgba(57, 255, 20, 0.8)',
118
+ },
119
+ critical: {
120
+ emoji: '🌟', label: 'CRITICAL',
121
+ background: 'linear-gradient(135deg, #000000 0%, #ff0080 100%)',
122
+ color: '#ff0080', border: '2px solid #ff0080',
123
+ shadow: '0 0 20px rgba(255, 0, 128, 1)',
124
+ },
125
+ },
126
+ minimal: {
127
+ debug: {
128
+ emoji: '', label: 'DEBUG',
129
+ background: '#f7fafc', color: '#4a5568',
130
+ border: '1px solid #e2e8f0', shadow: 'none',
131
+ },
132
+ info: {
133
+ emoji: '', label: 'INFO',
134
+ background: '#ebf8ff', color: '#2b6cb0',
135
+ border: '1px solid #bee3f8', shadow: 'none',
136
+ },
137
+ warn: {
138
+ emoji: '', label: 'WARN',
139
+ background: '#fffbf0', color: '#c05621',
140
+ border: '1px solid #fed7aa', shadow: 'none',
141
+ },
142
+ error: {
143
+ emoji: '', label: 'ERROR',
144
+ background: '#fef5f5', color: '#c53030',
145
+ border: '1px solid #fca5a5', shadow: 'none',
146
+ },
147
+ success: {
148
+ emoji: '', label: 'SUCCESS',
149
+ background: '#f0fff4', color: '#2f855a',
150
+ border: '1px solid #9ae6b4', shadow: 'none',
151
+ },
152
+ critical: {
153
+ emoji: '', label: 'CRITICAL',
154
+ background: '#fef5f5', color: '#e53e3e',
155
+ border: '2px solid #f56565', shadow: 'none',
156
+ },
157
+ },
158
+ // Additional theme variants can be added here
159
+ light: {
160
+ debug: {
161
+ emoji: '🔍', label: 'DEBUG',
162
+ background: 'linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%)',
163
+ color: '#1565c0', border: '1px solid #90caf9',
164
+ shadow: '0 1px 3px rgba(33, 150, 243, 0.2)',
165
+ },
166
+ info: {
167
+ emoji: 'â„šī¸', label: 'INFO',
168
+ background: 'linear-gradient(135deg, #f3e5f5 0%, #e1bee7 100%)',
169
+ color: '#7b1fa2', border: '1px solid #ce93d8',
170
+ shadow: '0 1px 3px rgba(156, 39, 176, 0.2)',
171
+ },
172
+ warn: {
173
+ emoji: 'âš ī¸', label: 'WARN',
174
+ background: 'linear-gradient(135deg, #fff8e1 0%, #ffecb3 100%)',
175
+ color: '#f57c00', border: '1px solid #ffcc02',
176
+ shadow: '0 1px 3px rgba(255, 152, 0, 0.2)',
177
+ },
178
+ error: {
179
+ emoji: '❌', label: 'ERROR',
180
+ background: 'linear-gradient(135deg, #ffebee 0%, #ffcdd2 100%)',
181
+ color: '#d32f2f', border: '1px solid #f44336',
182
+ shadow: '0 1px 3px rgba(244, 67, 54, 0.2)',
183
+ },
184
+ success: {
185
+ emoji: '✅', label: 'SUCCESS',
186
+ background: 'linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 100%)',
187
+ color: '#388e3c', border: '1px solid #4caf50',
188
+ shadow: '0 1px 3px rgba(76, 175, 80, 0.2)',
189
+ },
190
+ critical: {
191
+ emoji: '🚨', label: 'CRITICAL',
192
+ background: 'linear-gradient(135deg, #fce4ec 0%, #f8bbd9 100%)',
193
+ color: '#c2185b', border: '2px solid #e91e63',
194
+ shadow: '0 2px 6px rgba(233, 30, 99, 0.3)',
195
+ },
196
+ },
197
+ cyberpunk: {
198
+ debug: {
199
+ emoji: '🤖', label: 'DEBUG',
200
+ background: 'linear-gradient(135deg, #0d1b2a 0%, #415a77 100%)',
201
+ color: '#00d4aa', border: '1px solid #00d4aa',
202
+ shadow: '0 0 15px rgba(0, 212, 170, 0.4)',
203
+ },
204
+ info: {
205
+ emoji: '🔗', label: 'INFO',
206
+ background: 'linear-gradient(135deg, #1b263b 0%, #0d1b2a 100%)',
207
+ color: '#00b4d8', border: '1px solid #00b4d8',
208
+ shadow: '0 0 15px rgba(0, 180, 216, 0.4)',
209
+ },
210
+ warn: {
211
+ emoji: '⚡', label: 'WARN',
212
+ background: 'linear-gradient(135deg, #f72585 0%, #b5179e 100%)',
213
+ color: '#ffff3f', border: '1px solid #ffff3f',
214
+ shadow: '0 0 15px rgba(255, 255, 63, 0.4)',
215
+ },
216
+ error: {
217
+ emoji: '💀', label: 'ERROR',
218
+ background: 'linear-gradient(135deg, #7209b7 0%, #480ca8 100%)',
219
+ color: '#ff006e', border: '1px solid #ff006e',
220
+ shadow: '0 0 15px rgba(255, 0, 110, 0.6)',
221
+ },
222
+ success: {
223
+ emoji: '⚡', label: 'SUCCESS',
224
+ background: 'linear-gradient(135deg, #003566 0%, #001d3d 100%)',
225
+ color: '#00f5ff', border: '1px solid #00f5ff',
226
+ shadow: '0 0 15px rgba(0, 245, 255, 0.4)',
227
+ },
228
+ critical: {
229
+ emoji: 'đŸ’Ĩ', label: 'CRITICAL',
230
+ background: 'linear-gradient(135deg, #000000 0%, #ff0040 100%)',
231
+ color: '#ff0040', border: '2px solid #ff0040',
232
+ shadow: '0 0 25px rgba(255, 0, 64, 0.8)',
233
+ },
234
+ },
235
+ };
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @fileoverview Core type definitions for Advanced Logger
3
+ */
4
+
5
+ /**
6
+ * Supported log levels in hierarchical order (debug < info < warn < error < critical)
7
+ */
8
+ export const LOG_LEVELS = {
9
+ debug: 0,
10
+ info: 1,
11
+ warn: 2,
12
+ error: 3,
13
+ critical: 4,
14
+ } as const;
15
+
16
+ /**
17
+ * Log level type derived from LOG_LEVELS keys
18
+ */
19
+ export type LogLevel = keyof typeof LOG_LEVELS;
20
+
21
+ /**
22
+ * Verbosity level type for filtering logs
23
+ */
24
+ export type Verbosity = LogLevel | 'silent';
25
+
26
+ /**
27
+ * Theme variants for different visual styles
28
+ */
29
+ export type ThemeVariant = 'default' | 'dark' | 'light' | 'neon' | 'minimal' | 'cyberpunk';
30
+
31
+ /**
32
+ * Banner types for different visual approaches
33
+ */
34
+ export type BannerType = 'simple' | 'ascii' | 'unicode' | 'svg' | 'animated';
35
+
36
+ /**
37
+ * Export formats for log data
38
+ */
39
+ export type ExportFormat = 'json' | 'csv' | 'markdown' | 'plain' | 'html';
40
+
41
+ /**
42
+ * Configuration interface for logger instances
43
+ */
44
+ export interface LoggerConfig {
45
+ globalPrefix?: string;
46
+ verbosity: Verbosity;
47
+ enableColors: boolean;
48
+ enableTimestamps: boolean;
49
+ enableStackTrace: boolean;
50
+ theme?: ThemeVariant;
51
+ bannerType?: BannerType;
52
+ bufferSize?: number;
53
+ }
54
+
55
+ /**
56
+ * Parsed stack trace information
57
+ */
58
+ export interface StackInfo {
59
+ file: string;
60
+ line: number;
61
+ column: number;
62
+ function?: string;
63
+ }
64
+
65
+ /**
66
+ * Timer entry for performance measurement
67
+ */
68
+ export interface TimerEntry {
69
+ label: string;
70
+ startTime: number;
71
+ }
72
+
73
+ /**
74
+ * Options for styling components
75
+ */
76
+ export interface StyleOptions {
77
+ width?: number;
78
+ height?: number;
79
+ padding?: string;
80
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @fileoverview Handler and metadata type definitions for Advanced Logger
3
+ */
4
+
5
+ import type { LogLevel, StackInfo } from './core.js';
6
+
7
+ /**
8
+ * Metadata associated with each log entry
9
+ */
10
+ export interface LogMetadata {
11
+ timestamp: string;
12
+ level: LogLevel;
13
+ prefix?: string;
14
+ stackInfo?: StackInfo;
15
+ group?: string;
16
+ }
17
+
18
+ /**
19
+ * Interface for custom log handlers (extensibility)
20
+ */
21
+ export interface ILogHandler {
22
+ handle(level: LogLevel, message: string, args: any[], metadata: LogMetadata): void;
23
+ }
24
+
25
+ /**
26
+ * Stored log entry for export functionality
27
+ */
28
+ export interface LogEntry {
29
+ id: string;
30
+ timestamp: string;
31
+ level: LogLevel;
32
+ prefix?: string;
33
+ message: string;
34
+ args: any[];
35
+ location?: StackInfo;
36
+ groupInfo?: {
37
+ depth: number;
38
+ groupName?: string;
39
+ };
40
+ }
41
+
42
+ /**
43
+ * Export filter options
44
+ */
45
+ export interface ExportFilters {
46
+ levels?: LogLevel[];
47
+ since?: Date | string | number; // Date, ISO string, or hours ago
48
+ until?: Date | string | number;
49
+ prefixes?: string[];
50
+ excludePrefixes?: string[];
51
+ withStackTrace?: boolean;
52
+ errorsOnly?: boolean;
53
+ last?: number;
54
+ first?: number;
55
+ search?: string;
56
+ groupBy?: 'level' | 'prefix' | 'hour' | 'date';
57
+ }
58
+
59
+ /**
60
+ * Export options for different formats
61
+ */
62
+ export interface ExportOptions {
63
+ minimal?: boolean;
64
+ compact?: boolean;
65
+ styled?: boolean;
66
+ includeMetadata?: boolean;
67
+ groupBy?: ExportFilters['groupBy'];
68
+ }
69
+
70
+ /**
71
+ * Export result with metadata
72
+ */
73
+ export interface ExportResult {
74
+ format: string;
75
+ data: string;
76
+ metadata: {
77
+ totalLogs: number;
78
+ filteredLogs: number;
79
+ exportedAt: string;
80
+ filters?: ExportFilters;
81
+ options?: ExportOptions;
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Buffer statistics for log management
87
+ */
88
+ export interface BufferStats {
89
+ size: number;
90
+ maxSize: number;
91
+ usage: number; // percentage
92
+ oldestLog?: Date;
93
+ newestLog?: Date;
94
+ levelCounts: Record<LogLevel, number>;
95
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @fileoverview Type definitions exports for Advanced Logger
3
+ */
4
+
5
+ // Core types
6
+ export type {
7
+ LogLevel,
8
+ Verbosity,
9
+ ThemeVariant,
10
+ BannerType,
11
+ ExportFormat,
12
+ LoggerConfig,
13
+ StackInfo,
14
+ TimerEntry,
15
+ StyleOptions,
16
+ } from './core.js';
17
+
18
+ export { LOG_LEVELS } from './core.js';
19
+
20
+ // Handler types
21
+ export type {
22
+ LogMetadata,
23
+ ILogHandler,
24
+ LogEntry,
25
+ ExportFilters,
26
+ ExportOptions,
27
+ ExportResult,
28
+ BufferStats,
29
+ } from './handlers.js';
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path fill="#007ACC" d="M0 128v128h256V0H0z"></path><path fill="#FFF" d="m56.612 128.85l-.081 10.483h33.32v94.68h23.568v-94.68h33.321v-10.28c0-5.69-.122-10.444-.284-10.566c-.122-.162-20.4-.244-44.983-.203l-44.74.122l-.121 10.443Zm149.955-10.742c6.501 1.625 11.459 4.51 16.01 9.224c2.357 2.52 5.851 7.111 6.136 8.208c.08.325-11.053 7.802-17.798 11.988c-.244.162-1.22-.894-2.317-2.52c-3.291-4.795-6.745-6.867-12.028-7.233c-7.76-.528-12.759 3.535-12.718 10.321c0 1.992.284 3.17 1.097 4.795c1.707 3.536 4.876 5.649 14.832 9.956c18.326 7.883 26.168 13.084 31.045 20.48c5.445 8.249 6.664 21.415 2.966 31.208c-4.063 10.646-14.14 17.879-28.323 20.276c-4.388.772-14.79.65-19.504-.203c-10.28-1.828-20.033-6.908-26.047-13.572c-2.357-2.6-6.949-9.387-6.664-9.874c.122-.163 1.178-.813 2.356-1.504c1.138-.65 5.446-3.129 9.509-5.485l7.355-4.267l1.544 2.276c2.154 3.29 6.867 7.801 9.712 9.305c8.167 4.307 19.383 3.698 24.909-1.26c2.357-2.153 3.332-4.388 3.332-7.68c0-2.966-.366-4.266-1.91-6.501c-1.99-2.845-6.054-5.242-17.595-10.24c-13.206-5.69-18.895-9.224-24.096-14.832c-3.007-3.25-5.852-8.452-7.03-12.8c-.975-3.617-1.22-12.678-.447-16.335c2.723-12.76 12.353-21.659 26.25-24.3c4.51-.853 14.994-.528 19.424.569Z"></path></svg>
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @fileoverview Utility functions exports for Advanced Logger
3
+ */
4
+
5
+ export { parseStackTrace } from './stackTrace.js';
6
+ export {
7
+ formatTimestamp,
8
+ parseRelativeTime,
9
+ parseTimeInput,
10
+ formatDisplayTime
11
+ } from './timestamps.js';
12
+ export {
13
+ createStyledOutput,
14
+ generateLogId,
15
+ escapeHtml,
16
+ safeStringify,
17
+ type LevelStyleConfig
18
+ } from './output.js';
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @fileoverview Styled output creation utilities for Advanced Logger
3
+ */
4
+
5
+ import type { LogLevel, StackInfo } from '../types/index.js';
6
+ import { formatTimestamp } from './timestamps.js';
7
+ import { StyleBuilder } from '../styling/index.js';
8
+
9
+ /**
10
+ * Style configuration for each log level
11
+ */
12
+ export interface LevelStyleConfig {
13
+ emoji: string;
14
+ label: string;
15
+ background: string;
16
+ color: string;
17
+ border: string;
18
+ shadow: string;
19
+ }
20
+
21
+
22
+ /**
23
+ * Creates styled console output with multiple %c formatters
24
+ */
25
+ export function createStyledOutput(
26
+ level: LogLevel,
27
+ levelStyles: Record<LogLevel | 'success', LevelStyleConfig>,
28
+ prefix: string | undefined,
29
+ message: string,
30
+ stackInfo: StackInfo | null
31
+ ): [string, ...string[]] {
32
+ const levelConfig = levelStyles[level];
33
+ const timestamp = formatTimestamp();
34
+
35
+ // Base styles
36
+ const timestampStyle = new StyleBuilder()
37
+ .color('#666')
38
+ .size('11px')
39
+ .font('Monaco, Consolas, monospace')
40
+ .build();
41
+
42
+ const levelStyle = new StyleBuilder()
43
+ .bg(levelConfig.background)
44
+ .color(levelConfig.color)
45
+ .border(levelConfig.border)
46
+ .shadow(levelConfig.shadow)
47
+ .padding('2px 8px')
48
+ .rounded('4px')
49
+ .bold()
50
+ .font('Monaco, Consolas, monospace')
51
+ .size('12px')
52
+ .build();
53
+
54
+ const prefixStyle = new StyleBuilder()
55
+ .bg('#2d3748')
56
+ .color('#e2e8f0')
57
+ .padding('2px 6px')
58
+ .rounded('3px')
59
+ .bold()
60
+ .font('Monaco, Consolas, monospace')
61
+ .size('11px')
62
+ .build();
63
+
64
+ const messageStyle = new StyleBuilder()
65
+ .color('#2d3748')
66
+ .font('system-ui, -apple-system, sans-serif')
67
+ .size('14px')
68
+ .build();
69
+
70
+ const locationStyle = new StyleBuilder()
71
+ .color('#718096')
72
+ .size('11px')
73
+ .font('Monaco, Consolas, monospace')
74
+ .build();
75
+
76
+ // Build format string and styles
77
+ let format = `%c${timestamp.slice(11, 23)} %c${levelConfig.emoji} ${levelConfig.label}`;
78
+ const styles = [timestampStyle, levelStyle];
79
+
80
+ if (prefix) {
81
+ format += ` %c${prefix}`;
82
+ styles.push(prefixStyle);
83
+ }
84
+
85
+ format += ` %c${message}`;
86
+ styles.push(messageStyle);
87
+
88
+ if (stackInfo) {
89
+ format += ` %c(${stackInfo.file}:${stackInfo.line}:${stackInfo.column})`;
90
+ styles.push(locationStyle);
91
+ }
92
+
93
+ return [format, ...styles];
94
+ }
95
+
96
+ /**
97
+ * Create a unique ID for log entries
98
+ */
99
+ export function generateLogId(): string {
100
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
101
+ }
102
+
103
+ /**
104
+ * Escape HTML entities for safe HTML output
105
+ */
106
+ export function escapeHtml(text: string): string {
107
+ const div = document.createElement('div');
108
+ div.textContent = text;
109
+ return div.innerHTML;
110
+ }
111
+
112
+ /**
113
+ * Convert objects to safe string representation for logging
114
+ */
115
+ export function safeStringify(obj: any, _maxDepth = 3): string {
116
+ try {
117
+ return JSON.stringify(obj, (_key, value) => {
118
+ if (typeof value === 'function') return '[Function]';
119
+ if (value instanceof Error) return `[Error: ${value.message}]`;
120
+ if (value instanceof Date) return value.toISOString();
121
+ if (typeof value === 'undefined') return '[undefined]';
122
+ return value;
123
+ }, 2);
124
+ } catch (error) {
125
+ return String(obj);
126
+ }
127
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @fileoverview Stack trace parsing utilities for Advanced Logger
3
+ */
4
+
5
+ import type { StackInfo } from '../types/index.js';
6
+
7
+ /**
8
+ * Parses the current stack trace to extract caller information
9
+ */
10
+ export function parseStackTrace(): StackInfo | null {
11
+ try {
12
+ const stack = new Error().stack;
13
+ if (!stack) return null;
14
+
15
+ const lines = stack.split('\n').filter(line => line.trim());
16
+
17
+ // Find the first caller that's not from Logger methods
18
+ for (let i = 1; i < lines.length; i++) {
19
+ const line = lines[i];
20
+
21
+ // Skip if line contains Logger methods or parseStackTrace
22
+ if (line.includes('parseStackTrace') ||
23
+ line.includes('Logger.') ||
24
+ line.includes('.log(') ||
25
+ line.includes('createStyledOutput')) {
26
+ continue;
27
+ }
28
+
29
+ // Parse different stack trace formats
30
+ let match;
31
+
32
+ // Chrome format: "at functionName (file:line:column)" or "at file:line:column"
33
+ const chromeMatch = line.match(/at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/);
34
+ if (chromeMatch) {
35
+ match = chromeMatch;
36
+ } else {
37
+ // Firefox format: "functionName@file:line:column"
38
+ const firefoxMatch = line.match(/(.+?)@(.+?):(\d+):(\d+)$/);
39
+ if (firefoxMatch) {
40
+ match = firefoxMatch;
41
+ } else {
42
+ // Safari/other formats
43
+ const safariMatch = line.match(/(\S+)?@(.+?):(\d+):(\d+)$/);
44
+ if (safariMatch) {
45
+ match = safariMatch;
46
+ }
47
+ }
48
+ }
49
+
50
+ if (match) {
51
+ const [, functionName, file, line, column] = match;
52
+
53
+ return {
54
+ file: file?.split('/').pop()?.split('?')[0] || 'unknown',
55
+ line: parseInt(line, 10) || 0,
56
+ column: parseInt(column, 10) || 0,
57
+ function: functionName?.trim() || undefined,
58
+ };
59
+ }
60
+ }
61
+
62
+ return null;
63
+ } catch {
64
+ return null;
65
+ }
66
+ }