@crimsonsunset/jsg-logger 1.6.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,16 +5,185 @@ All notable changes to the JSG Logger project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [Unreleased]
8
+ ## [1.7.0] - 2025-01-XX 🎯 **Config-Driven Tree-Shaking & Enhanced Logging**
9
+
10
+ ### Added
11
+ - **Config-Driven Tree-Shaking** - DevTools panel tree-shaking now based on default config at module load time
12
+ - Tree-shaking determined by `defaultConfig.devtools.enabled` (default: `false`)
13
+ - When disabled, devtools code completely tree-shaken (zero bundle impact)
14
+ - When enabled via runtime config, loads dynamically on demand
15
+ - Static import analysis allows bundlers to eliminate unused code paths
16
+ - **Comprehensive DevTools Logging** - Added detailed logging throughout DevTools lifecycle
17
+ - Module load: logs default config tree-shaking status
18
+ - Config loading: logs when devtools enabled/disabled via user config
19
+ - DevTools activation: logs pre-load status, dynamic loading, and initialization steps
20
+ - Config merge: logs devtools status changes between defaults and user config
21
+
22
+ ### Changed
23
+ - **DevTools Import Strategy** - Simplified to relative path imports
24
+ - Removed complex Function constructor + package export path logic
25
+ - Uses simple relative path: `./devtools/dist/panel-entry.js`
26
+ - Works in production builds, requires `server.fs.allow: ['..']` for npm link dev
27
+ - **Config Loading Logging** - Enhanced visibility into config loading process
28
+ - Logs config source (file path vs inline object)
29
+ - Logs devtools status before/after config merge
30
+ - Logs initialization start with config source information
31
+
32
+ ### Fixed
33
+ - **Tree-Shaking Detection** - Bundlers can now properly analyze and eliminate devtools code when disabled
34
+ - **DevTools Pre-loading** - Non-blocking pre-load when default config enables devtools
35
+ - **Runtime Config Override** - Dynamic loading works correctly when runtime config enables devtools but default disabled
36
+
37
+ ### Technical Details
38
+ - **File**: `index.js`
39
+ - Added conditional static import based on `defaultConfig.devtools.enabled`
40
+ - Lazy initialization pattern to avoid top-level await
41
+ - Enhanced `enableDevPanel()` with comprehensive logging
42
+ - Pre-loads devtools module when default config enables it
43
+
44
+ - **File**: `config/config-manager.js`
45
+ - Added logging for config loading (file vs inline)
46
+ - Added devtools status logging before/after config merge
47
+ - Enhanced visibility into config changes
48
+
49
+ ### Migration Notes
50
+ No breaking changes. Existing code continues to work.
51
+
52
+ **For consumers:**
53
+ - DevTools code tree-shaken by default (zero bundle impact)
54
+ - Enable via runtime config: `{ devtools: { enabled: true } }`
55
+ - DevTools loads dynamically when `enableDevPanel()` called
56
+ - No special Vite config needed for production builds
57
+ - npm link users: add `server.fs.allow: ['..']` to Vite config for dev
58
+
59
+ ## [1.7.1] - 2025-11-05 🎯 **TypeScript Support & Zero-Optional-Chaining API**
60
+
61
+ ### Added
62
+ - **TypeScript Definitions** - Full TypeScript support with `index.d.ts`
63
+ - Complete type definitions for all logger interfaces
64
+ - `LoggerInstance`, `LoggerComponents`, `LoggerInstanceType` interfaces
65
+ - Proper exports configuration in `package.json` with `types` field
66
+ - **Safe Component Getters** - Component getters initialized in constructor
67
+ - `_initializeSafeComponentGetters()` ensures components accessible before initialization
68
+ - Common components (reactComponents, astroComponents, etc.) always available
69
+ - Returns no-op logger factories if logger not initialized yet
70
+
71
+ ### Changed
72
+ - **getComponent Always Available** - `getComponent` is now non-optional in TypeScript types
73
+ - Removed `?` optional marker from `getComponent` in `LoggerInstanceType`
74
+ - Always returns a logger instance (no-op if not initialized)
75
+ - Consumers can call `loggerInstance.getComponent('componentName')` without optional chaining
76
+ - **Fallback Logger Enhancement** - `createFallbackLogger()` now includes `getComponent`
77
+ - Ensures `getComponent` exists even when initialization fails
78
+ - Returns no-op logger factory for safe fallback behavior
79
+ - **Enhanced getComponent Safety** - Improved error handling and edge cases
80
+ - Returns no-op logger if instance not initialized
81
+ - Returns no-op logger if logger creation fails
82
+ - Prevents crashes when logger unavailable
83
+
84
+ ### Fixed
85
+ - **Optional Chaining Burden** - Eliminated need for `?.` optional chaining in consumer code
86
+ - Consumers can now use `loggerInstance.getComponent('componentName').debug(...)` directly
87
+ - No more `loggerInstance?.getComponent?.('componentName')?.debug(...)` chains
88
+ - TypeScript types guarantee `getComponent` always exists
89
+
90
+ ### Technical Details
91
+ - **File**: `index.d.ts` (NEW)
92
+ - Complete TypeScript definitions for the logger package
93
+ - Non-optional `getComponent` method signature
94
+ - Proper interface documentation
95
+
96
+ - **File**: `index.js`
97
+ - Added `_initializeSafeComponentGetters()` method called in constructor
98
+ - Enhanced `getComponent()` to always return logger (no-op fallback)
99
+ - Added `_createNoOpLogger()` private method for safe fallbacks
100
+ - Updated `createFallbackLogger()` to include `getComponent`
101
+ - Modified `_createAutoDiscoveryGetters()` to preserve safe getters
102
+
103
+ - **File**: `package.json`
104
+ - Added `"types": "./index.d.ts"` field
105
+ - Added `index.d.ts` to `files` array
106
+ - Updated `exports` to include proper TypeScript types export
107
+
108
+ ### Migration Notes
109
+ No breaking changes. Existing code continues to work, but optional chaining is now optional (pun intended).
110
+
111
+ **For consumers:**
112
+ - Can now use `loggerInstance.getComponent('componentName')` without `?.`
113
+ - TypeScript users get full type safety and autocomplete
114
+ - No-op logger returned if logger not initialized (safe to call)
115
+ - Recommended: Use `getInstanceSync()` for synchronous access instead of `getInstance()` when possible
116
+
117
+ ## [1.7.0] - 2025-01-XX 🎯 **Config-Driven Tree-Shaking & Enhanced Logging**
9
118
 
10
119
  ### Added
11
- - None
120
+ - **Config-Driven Tree-Shaking** - DevTools panel tree-shaking now based on default config at module load time
121
+ - Tree-shaking determined by `defaultConfig.devtools.enabled` (default: `false`)
122
+ - When disabled, devtools code completely tree-shaken (zero bundle impact)
123
+ - When enabled via runtime config, loads dynamically on demand
124
+ - Static import analysis allows bundlers to eliminate unused code paths
125
+ - **Comprehensive DevTools Logging** - Added detailed logging throughout DevTools lifecycle
126
+ - Module load: logs default config tree-shaking status
127
+ - Config loading: logs when devtools enabled/disabled via user config
128
+ - DevTools activation: logs pre-load status, dynamic loading, and initialization steps
129
+ - Config merge: logs devtools status changes between defaults and user config
12
130
 
13
- ### Changed
14
- - None
131
+ ### Changed
132
+ - **DevTools Import Strategy** - Simplified to relative path imports
133
+ - Removed complex Function constructor + package export path logic
134
+ - Uses simple relative path: `./devtools/dist/panel-entry.js`
135
+ - Works in production builds, requires `server.fs.allow: ['..']` for npm link dev
136
+ - **Config Loading Logging** - Enhanced visibility into config loading process
137
+ - Logs config source (file path vs inline object)
138
+ - Logs devtools status before/after config merge
139
+ - Logs initialization start with config source information
15
140
 
16
141
  ### Fixed
17
- - None
142
+ - **Tree-Shaking Detection** - Bundlers can now properly analyze and eliminate devtools code when disabled
143
+ - **DevTools Pre-loading** - Non-blocking pre-load when default config enables devtools
144
+ - **Runtime Config Override** - Dynamic loading works correctly when runtime config enables devtools but default disabled
145
+
146
+ ### Technical Details
147
+ - **File**: `index.js`
148
+ - Added conditional static import based on `defaultConfig.devtools.enabled`
149
+ - Lazy initialization pattern to avoid top-level await
150
+ - Enhanced `enableDevPanel()` with comprehensive logging
151
+ - Pre-loads devtools module when default config enables it
152
+
153
+ - **File**: `config/config-manager.js`
154
+ - Added logging for config loading (file vs inline)
155
+ - Added devtools status logging before/after config merge
156
+ - Enhanced visibility into config changes
157
+
158
+ ### Migration Notes
159
+ No breaking changes. Existing code continues to work.
160
+
161
+ **For consumers:**
162
+ - DevTools code tree-shaken by default (zero bundle impact)
163
+ - Enable via runtime config: `{ devtools: { enabled: true } }`
164
+ - DevTools loads dynamically when `enableDevPanel()` called
165
+ - No special Vite config needed for production builds
166
+ - npm link users: add `server.fs.allow: ['..']` to Vite config for dev
167
+
168
+ ## [Unreleased]
169
+
170
+ ## [1.5.2] - 2025-10-25 🐛 **PATCH: CLI Formatter Custom Component Display**
171
+
172
+ ### Technical Changes
173
+ - `formatters/cli-formatter.js` - Use `configManager.getComponentConfig()` instead of static `COMPONENT_SCHEME`
174
+ - `formatters/browser-formatter.js` - Remove redundant name transformation
175
+ - `tests/custom-components.test.js` - Added Test 6 for formatter output validation
176
+
177
+ ## [1.5.1] - 2025-10-25 🔧 **PATCH: Component Initialization Optimization**
178
+
179
+ ### Fixed
180
+ - **Component initialization pollution** - `getAvailableComponents()` no longer initializes all 13 default COMPONENT_SCHEME components when user defines custom components (3 defined → 3 initialized instead of 16)
181
+ - **Component name formatting** - Changed from PascalCase (`MyComponent`) to uppercase with separators (`MY-COMPONENT`)
182
+
183
+ ### Technical Changes
184
+ - `config/config-manager.js` - Return only user components when defined, fallback to COMPONENT_SCHEME if empty; components replaced instead of merged; enhanced `_formatComponentName()`
185
+ - `index.js` - Clean reinitialization: reset config, clear loggers, normalize inline config
186
+ - `tests/custom-components.test.js` - New comprehensive test suite (5 tests)
18
187
 
19
188
  ## [1.5.0] - 2025-10-25 🎯 **CRITICAL FIX: CLI Tool Support**
20
189
 
package/README.md CHANGED
@@ -4,16 +4,19 @@
4
4
 
5
5
  A sophisticated, fully generic logging system that automatically detects its environment (browser, CLI, server) and provides optimal logging experience for any JavaScript project, with powerful file-level overrides and granular control.
6
6
 
7
+ > 🎮 **[Try the Interactive DevTools Playground →](https://logger.joesangiorgio.com/)**
8
+ > Test all features in your browser with live examples and real-time controls!
9
+
7
10
  ## ✨ Features
8
11
 
9
- - 🎯 **100% Generic** - *New in v1.2.0!* Zero hardcoded assumptions, works with any project type
12
+ - 🎯 **100% Generic** - Zero hardcoded assumptions, works with any project type
10
13
  - 🚀 **Zero-Boilerplate Integration** - Eliminates 200+ lines of project setup code
11
14
  - 🔧 **Auto-Discovery Components** - Both camelCase and kebab-case component access
12
15
  - ⚡ **Built-in Performance Logging** - Static utilities with auto-getInstance
13
16
  - 🛡️ **Non-Destructive Error Handling** - Missing components log but don't break apps
14
- - 🎨 **Custom Component Names** - *New in v1.5.0!* Use ANY component name, auto-generated styling
15
- - 🔧 **Force Environment Override** - *New in v1.5.0!* Override auto-detection for CLI tools
16
- - 🧠 **Enhanced Environment Detection** - *New in v1.5.0!* Robust CLI detection with fallbacks
17
+ - 🎨 **Custom Component Names** - Use ANY component name, auto-generated styling
18
+ - 🔧 **Force Environment Override** - Override auto-detection for CLI tools
19
+ - 🧠 **Enhanced Environment Detection** - Robust CLI detection with fallbacks
17
20
  - 🎨 **Beautiful Visual Output** - Emoji, colors, and structured context display
18
21
  - 📱 **Multi-Environment** - Browser console, terminal, and production JSON
19
22
  - 🏪 **Log Store** - In-memory storage for debugging and popup interfaces
@@ -27,14 +30,12 @@ A sophisticated, fully generic logging system that automatically detects its env
27
30
 
28
31
  ## 🚀 Quick Start
29
32
 
30
- ### **v1.5.0: Custom Components & Force Environment - Perfect for CLI Tools!**
31
-
32
- > **✨ New in v1.5.0:** Use ANY component name (not just pre-defined ones) and force CLI mode for terminal applications!
33
+ ### **Custom Components & Force Environment for CLI Tools**
33
34
 
34
35
  ```javascript
35
36
  import JSGLogger from '@crimsonsunset/jsg-logger';
36
37
 
37
- // ✨ NEW: Force environment for CLI tools (fixes terminal detection)
38
+ // Force environment for CLI tools (fixes terminal detection)
38
39
  const logger = JSGLogger.getInstanceSync({
39
40
  forceEnvironment: 'cli', // Forces pretty terminal output
40
41
  globalLevel: 'info',
@@ -46,7 +47,7 @@ const logger = JSGLogger.getInstanceSync({
46
47
  }
47
48
  });
48
49
 
49
- // ✨ NEW: Custom components work immediately
50
+ // Custom components work immediately
50
51
  const sysLog = logger.getComponent('system');
51
52
  sysLog.info('✓ macOS version compatible', { version: '14.2', build: '23C64' });
52
53
  // Output: Pretty formatted terminal output with colors AND context data!
@@ -59,12 +60,10 @@ installLog.info('✓ Applications installed', { installed: 25, duration: '5m' })
59
60
  // 21:32:11.8 📦 [INSTALLER] ✓ Applications installed
60
61
  // ├─ installed: 25
61
62
  // └─ duration: 5m
62
- // No more JSON blobs in terminal! 🎉
63
+ // No more JSON blobs in terminal!
63
64
  ```
64
65
 
65
- ### **v1.2.0: Fully Generic Design - Works with Any Project!**
66
-
67
- > **⚠️ Breaking Change:** v1.2.0 requires defining components in your logger-config.json. The logger is now 100% generic with no hardcoded assumptions.
66
+ ### **Standard Usage**
68
67
 
69
68
  ```javascript
70
69
  import JSGLogger from '@crimsonsunset/jsg-logger';
@@ -84,12 +83,12 @@ const startTime = performance.now();
84
83
  // ... do work ...
85
84
  JSGLogger.logPerformance('Page Generation', startTime, 'api');
86
85
 
87
- // ✨ NEW: Custom components auto-created on demand
86
+ // Custom components auto-created on demand
88
87
  const dynamicLogger = logger.getComponent('new-feature');
89
88
  dynamicLogger.info('Auto-created component!'); // Works immediately
90
89
  ```
91
90
 
92
- ### **Traditional Usage (Still Supported)**
91
+ ### **Alternative Usage**
93
92
 
94
93
  ```javascript
95
94
  import logger from '@crimsonsunset/jsg-logger';
@@ -119,7 +118,7 @@ This allows surgical debugging - you can turn on trace logging for just one prob
119
118
 
120
119
  ## ⚙️ **Advanced Configuration**
121
120
 
122
- ### **Force Environment Override** ✨ *New in v1.5.0*
121
+ ### **Force Environment Override**
123
122
 
124
123
  Perfect for CLI tools that get mis-detected as "server" mode:
125
124
 
@@ -153,7 +152,7 @@ Or in `logger-config.json`:
153
152
  - Testing different output formats
154
153
  - Production deployments with specific requirements
155
154
 
156
- ### **Custom Component Names** ✨ *New in v1.5.0*
155
+ ### **Custom Component Names**
157
156
 
158
157
  Use ANY component name - no need to pre-define in COMPONENT_SCHEME:
159
158
 
@@ -229,6 +228,9 @@ log4.info('This works!'); // Uses auto-generated styling
229
228
  "jsonPayload": false
230
229
  }
231
230
  }
231
+ },
232
+ "devtools": {
233
+ "enabled": false
232
234
  }
233
235
  }
234
236
  ```
@@ -351,7 +353,7 @@ logger.controls.addFileOverride('src/popup.js', {
351
353
 
352
354
  ### **Context Data**
353
355
 
354
- ✨ **New in v1.5.0:** Context data now displays in CLI/terminal mode with tree formatting!
356
+ Context data displays in CLI/terminal mode with tree formatting:
355
357
 
356
358
  ```javascript
357
359
  logger.api.error('Request failed', {
@@ -414,12 +416,10 @@ logger.controls.getTimestampMode() // Get current mode
414
416
  logger.controls.getTimestampModes() // List available modes
415
417
  ```
416
418
 
417
- ### **System Controls**
419
+ ### **DevTools Panel Controls**
418
420
  ```javascript
419
- logger.controls.refresh() // Refresh all loggers
420
- logger.controls.reset() // Reset to defaults
421
- logger.controls.getConfigSummary() // Get config summary
422
- logger.controls.getStats() // Get logging stats
421
+ logger.controls.enableDevPanel() // Enable DevTools panel (requires devtools.enabled: true)
422
+ logger.controls.disableDevPanel() // Disable DevTools panel
423
423
  ```
424
424
 
425
425
  ## 📊 **Log Store & Statistics**
@@ -509,26 +509,15 @@ The logger automatically detects its environment and uses optimal implementation
509
509
  - **CLI**: Uses pino-colada for beautiful terminal output
510
510
  - **Server**: Uses structured JSON for production logging
511
511
 
512
- ### **Enhanced CLI Detection** ✨ *Improved in v1.5.0*
512
+ ### **Enhanced CLI Detection**
513
513
 
514
- The CLI detection now checks multiple signals:
514
+ The CLI detection checks multiple signals:
515
515
  1. **TTY Check**: `process.stdout.isTTY` or `process.stderr.isTTY`
516
516
  2. **Terminal Environment**: `process.env.TERM` or `process.env.COLORTERM`
517
517
  3. **Non-CI Context**: Not running in CI/GitHub Actions
518
518
 
519
519
  This fixes detection issues in various terminal contexts where `isTTY` may be undefined.
520
520
 
521
- ### **Force Environment Override** ✨ *New in v1.5.0*
522
-
523
- If auto-detection fails, you can force the environment:
524
-
525
- ```javascript
526
- const logger = JSGLogger.getInstanceSync({
527
- forceEnvironment: 'cli', // Override auto-detection
528
- // ... rest of config
529
- });
530
- ```
531
-
532
521
  **Why Browser is Different:**
533
522
  Our testing revealed that Pino's browser detection was interfering with custom formatters, especially in Chrome extensions. By creating a custom direct browser logger that bypasses Pino entirely, we achieved:
534
523
  - Perfect emoji and color display
@@ -567,6 +556,64 @@ logger.controls.addFileOverride('src/popup.js', { // Debug popup
567
556
  });
568
557
  ```
569
558
 
559
+ ## 🎛️ **DevTools Panel (Optional)**
560
+
561
+ JSG Logger includes an optional DevTools panel for visual debugging. The panel is **disabled by default** to keep bundle size minimal.
562
+
563
+ ### **How Tree-Shaking Works**
564
+
565
+ Tree-shaking is based on the **default config** (`devtools.enabled: false` by default). This means:
566
+
567
+ - **Default behavior**: DevTools code is completely tree-shaken out, resulting in zero bundle impact
568
+ - **Consumer config override**: If you enable devtools in your runtime config (`{ devtools: { enabled: true } }`), it loads dynamically when needed
569
+ - **Best of both worlds**: Zero bundle by default, but runtime flexibility when needed
570
+
571
+ ### **Enabling DevTools**
572
+
573
+ 1. **Enable in config:**
574
+ ```json
575
+ {
576
+ "devtools": {
577
+ "enabled": true
578
+ }
579
+ }
580
+ ```
581
+
582
+ Or enable at runtime:
583
+ ```javascript
584
+ const logger = JSGLogger.getInstance({
585
+ devtools: { enabled: true }
586
+ });
587
+ ```
588
+
589
+ 2. **Enable the panel:**
590
+ ```javascript
591
+ // Enable DevTools panel (only works if devtools.enabled: true in config)
592
+ await logger.controls.enableDevPanel();
593
+ ```
594
+
595
+ ### **DevTools Features**
596
+
597
+ - 🎛️ Visual component filter controls
598
+ - 📊 Real-time log statistics
599
+ - 🔧 Runtime level adjustment
600
+ - ⚙️ Display option toggles
601
+ - 📈 Component-level monitoring
602
+
603
+ **Bundle Size:**
604
+ - When `devtools.enabled: false` (default): Zero bundle impact (tree-shaken)
605
+ - When enabled: ~81KB gzipped (includes Preact + Evergreen UI, self-contained)
606
+
607
+ **Note for npm link users:** When developing with `npm link`, ensure your Vite config includes:
608
+ ```typescript
609
+ server: {
610
+ fs: {
611
+ allow: ['..']
612
+ }
613
+ }
614
+ ```
615
+ This allows Vite to serve files from the symlinked package directory.
616
+
570
617
  ## 🔧 **Browser Developer Tools**
571
618
 
572
619
  In browser environments, runtime controls are available globally:
@@ -577,6 +624,7 @@ JSG_Logger.enableDebugMode();
577
624
  JSG_Logger.setDisplayOption('level', true);
578
625
  JSG_Logger.addFileOverride('src/popup.js', { level: 'trace' });
579
626
  JSG_Logger.getStats();
627
+ JSG_Logger.enableDevPanel(); // Enable DevTools panel (requires devtools.enabled: true)
580
628
  ```
581
629
 
582
630
  ## ⚠️ **Disclaimer**
@@ -25,18 +25,35 @@ export class ConfigManager {
25
25
 
26
26
  if (typeof configSource === 'string') {
27
27
  // Load from file path - handle all path formats
28
+ console.log(`[JSG-LOGGER] Loading config from file: ${configSource}`);
28
29
  externalConfig = await this._loadConfigFromPath(configSource);
29
30
  } else if (typeof configSource === 'object') {
30
31
  // Direct config object
32
+ console.log('[JSG-LOGGER] Loading inline config object:', Object.keys(configSource));
31
33
  externalConfig = configSource;
32
34
  }
33
35
 
34
36
  // Normalize external config to match expected structure
35
37
  const normalizedConfig = this._normalizeConfigStructure(externalConfig);
36
38
 
39
+ // Log devtools status before merge
40
+ const devtoolsBefore = this.config.devtools?.enabled ?? false;
41
+ const devtoolsAfter = normalizedConfig.devtools?.enabled ?? devtoolsBefore;
42
+
37
43
  // Merge configurations - project configs override defaults
38
44
  this.config = this.mergeConfigs(this.config, normalizedConfig);
39
45
 
46
+ // Log devtools activation status
47
+ const finalDevtoolsEnabled = this.config.devtools?.enabled ?? false;
48
+ if (finalDevtoolsEnabled !== devtoolsBefore) {
49
+ console.log(`[JSG-LOGGER] DevTools ${finalDevtoolsEnabled ? 'ENABLED' : 'DISABLED'} via user config (was ${devtoolsBefore ? 'enabled' : 'disabled'} in defaults)`);
50
+ if (finalDevtoolsEnabled) {
51
+ console.log('[JSG-LOGGER] DevTools will be available when enableDevPanel() is called');
52
+ }
53
+ } else {
54
+ console.log(`[JSG-LOGGER] DevTools status: ${finalDevtoolsEnabled ? 'ENABLED' : 'DISABLED'} (using default config)`);
55
+ }
56
+
40
57
  return this.config;
41
58
  } catch (error) {
42
59
  console.error('ConfigManager: Error loading configuration:', error);
@@ -133,7 +150,7 @@ export class ConfigManager {
133
150
 
134
151
  try {
135
152
  // Try dynamic import first (works with ES modules)
136
- const module = await import(path, { assert: { type: 'json' } });
153
+ const module = await import(/* @vite-ignore */ path, { assert: { type: 'json' } });
137
154
  return module.default || module;
138
155
  } catch (error) {
139
156
  try {
@@ -156,7 +173,7 @@ export class ConfigManager {
156
173
  async _loadConfigBrowserImport(path) {
157
174
  try {
158
175
  // Some bundlers can handle dynamic imports of JSON files
159
- const module = await import(path);
176
+ const module = await import(/* @vite-ignore */ path);
160
177
  return module.default || module;
161
178
  } catch (error) {
162
179
  return null;
@@ -292,10 +309,16 @@ export class ConfigManager {
292
309
  * @private
293
310
  */
294
311
  _formatComponentName(componentName) {
312
+ // If already uppercase, return as-is
313
+ if (componentName === componentName.toUpperCase()) {
314
+ return componentName;
315
+ }
316
+
317
+ // Convert to uppercase and preserve separators for readability
295
318
  return componentName
296
- .split('-')
297
- .map(word => word.charAt(0).toUpperCase() + word.slice(1))
298
- .join('');
319
+ .replace(/([a-z])([A-Z])/g, '$1-$2') // camelCase → kebab-case
320
+ .replace(/_/g, '-') // snake_case → kebab-case
321
+ .toUpperCase();
299
322
  }
300
323
 
301
324
  /**
@@ -315,7 +338,11 @@ export class ConfigManager {
315
338
 
316
339
  for (const key in override) {
317
340
  if (override.hasOwnProperty(key)) {
318
- if (typeof override[key] === 'object' && !Array.isArray(override[key])) {
341
+ // Special case: 'components' should be replaced, not merged
342
+ // This allows users to define their own components without getting defaults
343
+ if (key === 'components' && typeof override[key] === 'object') {
344
+ merged[key] = override[key];
345
+ } else if (typeof override[key] === 'object' && !Array.isArray(override[key])) {
319
346
  merged[key] = this.mergeConfigs(merged[key] || {}, override[key]);
320
347
  } else {
321
348
  merged[key] = override[key];
@@ -419,7 +446,7 @@ export class ConfigManager {
419
446
  baseComponent = {
420
447
  emoji: '📦',
421
448
  color: '#999999',
422
- name: componentName.toUpperCase().replace(/-/g, '-'),
449
+ name: this._formatComponentName(componentName),
423
450
  level: this.config.globalLevel || 'info'
424
451
  };
425
452
  }
@@ -539,10 +566,14 @@ export class ConfigManager {
539
566
  */
540
567
  getAvailableComponents() {
541
568
  const configComponents = Object.keys(this.config.components || {});
542
- const schemeComponents = Object.keys(COMPONENT_SCHEME);
543
-
544
- // Combine and deduplicate
545
- return [...new Set([...configComponents, ...schemeComponents])];
569
+
570
+ // If user has defined components, only return those
571
+ if (configComponents.length > 0) {
572
+ return configComponents;
573
+ }
574
+
575
+ // Fallback to COMPONENT_SCHEME if no components configured (backward compatibility)
576
+ return Object.keys(COMPONENT_SCHEME);
546
577
  }
547
578
 
548
579
  /**
@@ -33,5 +33,8 @@
33
33
  }
34
34
  },
35
35
  "fileOverrides": {
36
+ },
37
+ "devtools": {
38
+ "enabled": false
36
39
  }
37
40
  }