@vanilla-bean/log 7.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 justfatlard
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,311 @@
1
+ # Log
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
+
5
+ Zero-dependency console logging with tags, verbosity control, and unlimited custom log levels.
6
+
7
+ ## Why Log
8
+
9
+ Log follows Unix philosophy: do logging well, let the system handle output routing. Writes to stdout as plain text; containers, process supervisors, and log tails handle the rest.
10
+
11
+ - Zero runtime dependencies
12
+ - Custom methods (`log.success()`, `log.database()`) alongside native console methods, no configuration needed
13
+ - Tagged loggers, verbosity filtering, color, and global registry in ~1KB, easy to read, easy to fork
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @vanilla-bean/log
19
+ # or
20
+ bun add @vanilla-bean/log
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ Create tagged loggers that share instances and support unlimited custom methods:
26
+
27
+ ```javascript
28
+ import Log from '@vanilla-bean/log';
29
+
30
+ // Create tagged logger instances
31
+ const api = new Log({ tag: 'api', verbosity: 2, color: true });
32
+ const db = new Log({ tag: 'database', verbosity: 1 });
33
+
34
+ // Use all console methods
35
+ api.info('Server started');
36
+ api.warn('High memory usage');
37
+ api.error('Connection failed');
38
+
39
+ // Custom methods work automatically
40
+ api.success('Request completed');
41
+ db.query('SELECT * FROM users');
42
+
43
+ // Verbosity-gated calls: log(n)('msg') shows when logger verbosity > n
44
+ api(1)('Debug info'); // shows when verbosity > 1 (visible here, verbosity is 2)
45
+ api(3)('Trace data'); // shows when verbosity > 3 (hidden here, verbosity is 2)
46
+
47
+ // log('msg') is shorthand for log(0)('msg') — shows when verbosity > 0
48
+ api('Request received');
49
+ ```
50
+
51
+ ## Core Features
52
+
53
+ ### Tagged Logger Registry
54
+
55
+ Identical tags return the same logger instance, preventing duplicates and enabling cross-module coordination:
56
+
57
+ ```javascript
58
+ // Module A
59
+ const log = new Log({ tag: 'app', verbosity: 1 });
60
+
61
+ // Module B - gets same logger instance
62
+ const log = new Log({ tag: 'app' }); // Inherits verbosity: 1
63
+
64
+ // Access any logger globally
65
+ import { loggers } from '@vanilla-bean/log';
66
+ loggers.app.options.verbosity = 3; // Updates everywhere
67
+ ```
68
+
69
+ > **Note:** Calling `new Log()` without a tag uses the shared `__default` singleton. Two unrelated modules both doing `new Log()` will share the same logger instance and options. Always pass a tag when you want an independent logger.
70
+
71
+ ### Verbosity Control
72
+
73
+ The primary form is `log(n)('msg')`: logs when the logger's verbosity is greater than `n`, silent otherwise. Calling `log('msg')` directly is shorthand for `log(0)('msg')`: shows when verbosity is greater than 0.
74
+
75
+ ```javascript
76
+ const log = new Log({ verbosity: 3 });
77
+
78
+ log(1)('High priority'); // shows when verbosity > 1
79
+ log(2)('Debug info'); // shows when verbosity > 2
80
+ log(5)('Trace data'); // shows when verbosity > 5 (hidden here)
81
+
82
+ log('Shorthand'); // shorthand for log(0)('Shorthand') — shows when verbosity > 0
83
+
84
+ // Works the same on any method
85
+ log.warn(1)('Important warning');
86
+ log.error(0)('Critical error');
87
+ ```
88
+
89
+ > **Gotcha:** A lone number is always treated as a verbosity level, never as a message. `log(42)` returns a curried function; it does not log the number 42. To log a bare number, pass a second argument: `log(42, '')`.
90
+
91
+ ### Unlimited Log Methods
92
+
93
+ Create unlimited custom log methods alongside native console methods:
94
+
95
+ ```javascript
96
+ const log = new Log({ tag: 'app' });
97
+
98
+ // Native console methods
99
+ log.info('Information');
100
+ log.warn('Warning');
101
+ log.error('Error');
102
+ log.debug('Debug data');
103
+
104
+ // Custom methods work automatically
105
+ log.success('Operation completed');
106
+ log.database('Query executed');
107
+ log.network('Request sent');
108
+ log.cache('Cache hit');
109
+ log.security('Auth failed');
110
+ ```
111
+
112
+ ### Color Output
113
+
114
+ Add color support for enhanced terminal readability:
115
+
116
+ ```javascript
117
+ const log = new Log({ color: true });
118
+
119
+ log.info('Blue text'); // Built-in blue
120
+ log.warn('Yellow text'); // Built-in yellow
121
+ log.error('Red text'); // Built-in red
122
+
123
+ // Custom colors per tag or method
124
+ const colorLog = new Log({
125
+ color: true,
126
+ colorMap: {
127
+ success: '\x1b[32m', // Green
128
+ critical: '\x1b[91m', // Bright red
129
+ },
130
+ });
131
+ ```
132
+
133
+ ## Configuration Options
134
+
135
+ ```javascript
136
+ const log = new Log({
137
+ tag: 'myapp', // Logger identifier (omit to share the global __default singleton)
138
+ verbosity: 0, // Default: 0 (silent). log(n)() shows when n < verbosity; log('msg') shows when verbosity > 0
139
+ color: false, // Disable color output
140
+ silentTag: false, // Hide [tag] prefix
141
+ methodTag: false, // Show [method] label for native methods (info/warn/error); custom methods always show their label
142
+ colorMap: {}, // Custom ANSI color codes
143
+ });
144
+ ```
145
+
146
+ ## Advanced Usage
147
+
148
+ ### Dynamic Configuration
149
+
150
+ ```javascript
151
+ const log = new Log({ tag: 'api', verbosity: 1 });
152
+
153
+ log(2)('This is hidden');
154
+
155
+ // Increase verbosity at runtime
156
+ log.options.verbosity = 3;
157
+
158
+ log(2)('Now visible');
159
+ ```
160
+
161
+ ### Tag Management
162
+
163
+ ```javascript
164
+ const log = new Log({ tag: 'init' });
165
+ log('Starting up');
166
+
167
+ // Switch to different tag
168
+ log.setTag('runtime');
169
+ log('Now running');
170
+ ```
171
+
172
+ ### Global Configuration
173
+
174
+ Set process-wide defaults before creating loggers, or map custom methods to console methods:
175
+
176
+ ```javascript
177
+ import Log, { setDefaults, setMethodMap } from '@vanilla-bean/log';
178
+
179
+ setDefaults({ verbosity: 2, color: true });
180
+ setMethodMap({ critical: 'error', trace: 'debug' });
181
+
182
+ const log = new Log({ tag: 'app' }); // inherits verbosity: 2, color: true
183
+ log.critical('Fatal error'); // routes to console.error
184
+ ```
185
+
186
+ ### Cross-Module Coordination
187
+
188
+ ```javascript
189
+ // logger.js
190
+ import Log from '@vanilla-bean/log';
191
+ export const appLog = new Log({ tag: 'app', verbosity: 1 });
192
+
193
+ // module1.js
194
+ import { appLog } from './logger.js';
195
+ appLog.info('Module 1 loaded');
196
+
197
+ // module2.js
198
+ import { loggers } from '@vanilla-bean/log';
199
+ loggers.app.warn('Module 2 warning'); // Same logger instance
200
+ ```
201
+
202
+ ## Production Deployment
203
+
204
+ ### Log Aggregation
205
+
206
+ Log writes human-readable text to stdout. For log aggregation pipelines that expect JSON (ELK, Fluentd, Datadog), you'll need a JSON logger. Log is the right tool when a human is reading the output — development, debugging, process supervision, or simple production tails.
207
+
208
+ For plain-text pipelines, disable colors and keep tags for pattern matching:
209
+
210
+ ```javascript
211
+ const log = new Log({
212
+ tag: 'api',
213
+ silentTag: false, // keep [api] prefix for grep/awk
214
+ color: false, // no ANSI codes in log files
215
+ });
216
+
217
+ log.info('user_login', { userId: 123, ip: '1.2.3.4' });
218
+ // Output: [api] user_login { userId: 123, ip: '1.2.3.4' }
219
+ ```
220
+
221
+ ### Environment Configuration
222
+
223
+ ```javascript
224
+ const log = new Log({
225
+ tag: process.env.SERVICE_NAME || 'app',
226
+ verbosity: process.env.LOG_LEVEL || 1,
227
+ color: process.env.NODE_ENV === 'development',
228
+ });
229
+ ```
230
+
231
+ ## Comparison
232
+
233
+ | Feature | Log | Winston | Pino | Debug |
234
+ | ----------------- | --------------------- | ---------------------- | ---------------- | ----------- |
235
+ | Bundle Size | ~1KB | ~2MB | ~1MB | ~8KB |
236
+ | Dependencies | 0 | Many | Some | 1 |
237
+ | Log Levels | Unlimited | 6 + custom | 6 standard | 1 |
238
+ | Verbosity Control | ✓ Core | ✓ | ✓ | Environment |
239
+ | Tags/Namespaces | ✓ Singleton | ✓ | ✓ | ✓ |
240
+ | Transports | stdout only | 20+ built-in | Plugin ecosystem | stdout only |
241
+ | Container-Native | ✓ | Configuration required | ✓ | ✓ |
242
+
243
+ ## API Reference
244
+
245
+ ### Constructor
246
+
247
+ ```typescript
248
+ new Log(options?: {
249
+ tag?: string; // Default: '__default'
250
+ verbosity?: number; // Default: 0
251
+ color?: boolean; // Default: false
252
+ silentTag?: boolean; // Default: false
253
+ methodTag?: boolean; // Default: false — shows [method] for native methods; custom methods always show it
254
+ colorMap?: object; // Custom colors
255
+ })
256
+ ```
257
+
258
+ ### Logger Methods
259
+
260
+ ```typescript
261
+ // Primary form: verbosity-gated, curried
262
+ log(verbosity: number): (message: any, ...args: any[]) => void;
263
+ log.methodName(verbosity: number): (message: any, ...args: any[]) => void;
264
+
265
+ // Shorthand: equivalent to log(0)('msg') — shows when verbosity > 0
266
+ log(message: any, ...args: any[]): void;
267
+ log.methodName(message: any, ...args: any[]): void;
268
+ ```
269
+
270
+ ### Instance Methods
271
+
272
+ ```typescript
273
+ log.setTag(newTag: string): void;
274
+ log.options: object; // Mutable configuration
275
+ ```
276
+
277
+ ### Global Configuration
278
+
279
+ ```typescript
280
+ setDefaults(options: Partial<LogOptions>): void;
281
+ setMethodMap(map: Record<string, string>): void;
282
+ ```
283
+
284
+ ### Exports
285
+
286
+ ```typescript
287
+ import Log, { loggers, defaults, methodMap, setDefaults, setMethodMap } from '@vanilla-bean/log';
288
+ ```
289
+
290
+ ## Contributing
291
+
292
+ Contributions welcome! Submit Pull Requests for improvements. Open issues first for major changes.
293
+
294
+ ### Development Setup
295
+
296
+ ```bash
297
+ # Clone and setup
298
+ git clone https://github.com/fatlard1993/log.git
299
+ cd log
300
+ bun install
301
+
302
+ # Development workflow
303
+ bun test # Run tests
304
+ bun run demo # Run examples
305
+ bun run lint # Check code style
306
+ bun test --watch # Watch mode
307
+ ```
308
+
309
+ ## License
310
+
311
+ MIT License - see the [LICENSE](LICENSE) file for details.
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { default } from './src/log';
2
+ export * from './src/log';
package/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { default } from './src/log';
2
+ export * from './src/log';
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@vanilla-bean/log",
3
+ "version": "7.0.0",
4
+ "exports": {
5
+ ".": "./index.js"
6
+ },
7
+ "types": "./index.d.ts",
8
+ "files": [
9
+ "/src/**/*",
10
+ "!/src/**/*.test.js",
11
+ "index.js",
12
+ "index.d.ts"
13
+ ],
14
+ "description": "A console log wrapper with tags, colors, and verbosity",
15
+ "author": "justfatlard",
16
+ "license": "MIT",
17
+ "scripts": {
18
+ "demo": "bun ./demo/index.js",
19
+ "lint": "bun --bun eslint",
20
+ "lint:fix": "bun --bun eslint --fix",
21
+ "format": "bun run lint:fix && bun --bun prettier --write . | grep -q unchanged",
22
+ "test": "bun test",
23
+ "test:watch": "bun test --watch",
24
+ "version": "npm version"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/fatlard1993/log.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/fatlard1993/log/issues"
32
+ },
33
+ "homepage": "https://github.com/fatlard1993/log#readme",
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "dependencies": {},
38
+ "devDependencies": {
39
+ "@eslint/compat": "^1.4.1",
40
+ "@eslint/js": "^9.39.4",
41
+ "bun-types": "^1.3.14",
42
+ "eslint": "^9.39.4",
43
+ "eslint-plugin-compat": "^7.0.2",
44
+ "eslint-plugin-import": "^2.32.0",
45
+ "eslint-plugin-jsdoc": "^63.0.2",
46
+ "eslint-plugin-spellcheck": "0.0.20",
47
+ "eslint-plugin-unicorn": "^64.0.0",
48
+ "eslint-plugin-write-good-comments": "^0.2.0",
49
+ "globals": "^16.5.0",
50
+ "prettier": "^3.8.3"
51
+ }
52
+ }
package/src/log.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ export interface LogOptions {
2
+ /** Unique identifier for this logger */
3
+ tag?: string;
4
+ /** log(n) calls show when n < verbosity; direct calls show when verbosity > 0 */
5
+ verbosity?: number;
6
+ /** Enable ANSI color output */
7
+ color?: boolean;
8
+ /** Suppress [tag] prefix in output */
9
+ silentTag?: boolean;
10
+ /** Show [method] label for native console methods; custom methods always show their label */
11
+ methodTag?: boolean;
12
+ /** Custom ANSI color code mappings keyed by tag or method name */
13
+ colorMap?: Record<string, string>;
14
+ }
15
+
16
+ export type ResolvedLogOptions = Required<LogOptions>;
17
+
18
+ /**
19
+ * Callable directly or with a verbosity number for curried calls:
20
+ * log.info('message') → immediate log
21
+ * log.info(2)('message') → logs only when logger verbosity > 2
22
+ */
23
+ export interface LogMethod {
24
+ (verbosity: number): (...args: any[]) => void;
25
+ (...args: any[]): void;
26
+ }
27
+
28
+ /** Logger instance returned by `new Log()` */
29
+ export interface Logger extends LogMethod {
30
+ options: ResolvedLogOptions;
31
+ setTag(newTag: string): void;
32
+ info: LogMethod;
33
+ warn: LogMethod;
34
+ error: LogMethod;
35
+ debug: LogMethod;
36
+ /** Any custom method name works via Proxy */
37
+ [method: string]: any;
38
+ }
39
+
40
+ interface LogConstructor {
41
+ new(options?: LogOptions): Logger;
42
+ }
43
+
44
+ declare const Log: LogConstructor;
45
+ export default Log;
46
+
47
+ /** Global default options applied to all new logger instances */
48
+ export declare const defaults: ResolvedLogOptions;
49
+ /** Global map of custom method names to console method names */
50
+ export declare const methodMap: Record<string, string>;
51
+ /** Registry of all tagged logger instances */
52
+ export declare const loggers: Record<string, Logger>;
53
+
54
+ /** Merges options into the global defaults applied to all new logger instances */
55
+ export declare function setDefaults(options: Partial<ResolvedLogOptions>): void;
56
+ /** Merges entries into the global method map used by all loggers */
57
+ export declare function setMethodMap(map: Record<string, string>): void;
package/src/log.js ADDED
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Stores all logger instances indexed by tag name.
3
+ * @type {Record<string, Function>}
4
+ */
5
+ export const loggers = {};
6
+
7
+ /**
8
+ * Default configuration options for all logger instances.
9
+ * @type {object}
10
+ * @property {number} verbosity - Verbosity threshold; log(n) shows when n < verbosity, direct calls show when verbosity > 0
11
+ * @property {boolean} color - Enable ANSI color output
12
+ * @property {boolean} silentTag - Suppress tag labels in output
13
+ * @property {boolean} methodTag - Show [method] label for native console methods; custom methods always show their label
14
+ * @property {string} tag - Default tag identifier
15
+ * @property {Record<string, string>} colorMap - Custom ANSI color code mappings
16
+ */
17
+ export const defaults = {
18
+ verbosity: 0,
19
+ color: false,
20
+ silentTag: false,
21
+ methodTag: false,
22
+ tag: '__default',
23
+ colorMap: {},
24
+ };
25
+
26
+ /**
27
+ * Maps custom method names to console methods.
28
+ * @type {Record<string, string>}
29
+ */
30
+ export const methodMap = {};
31
+
32
+ /**
33
+ * Default ANSI color codes for console output.
34
+ * @type {Record<string, string>}
35
+ */
36
+ const DEFAULT_COLOR_MAP = {
37
+ __reset: '\u001B[0m',
38
+ info: '\u001B[34m',
39
+ warn: '\u001B[33m',
40
+ error: '\u001B[31m',
41
+ };
42
+
43
+ /**
44
+ * Creates flexible logging utility with tagging, verbosity levels, and color output.
45
+ * Implements singleton pattern where instances with identical tags share the same logger.
46
+ */
47
+ class Log {
48
+ /**
49
+ * Creates new Log instance or returns existing instance for duplicate tags.
50
+ * @param {object} [options] - Configuration options
51
+ * @param {string} [options.tag] - Unique identifier for this logger
52
+ * @param {number} [options.verbosity] - Verbosity threshold to display messages
53
+ * @param {boolean} [options.color] - Enable ANSI color output
54
+ * @param {boolean} [options.silentTag] - Suppress tag labels from output
55
+ * @param {boolean} [options.methodTag] - Show [method] label for native console methods; custom methods always show their label
56
+ * @param {Record<string, string>} [options.colorMap] - Custom ANSI color code mappings
57
+ * @returns {Function} Proxy-wrapped logger function with dynamic method access
58
+ */
59
+ constructor(options = {}) {
60
+ this.options = { ...defaults, ...options };
61
+
62
+ const { tag } = this.options;
63
+
64
+ if (loggers[tag]) {
65
+ loggers[tag].options = { ...loggers[tag].options, ...options };
66
+
67
+ return loggers[tag];
68
+ }
69
+
70
+ this._explicit = options;
71
+
72
+ /**
73
+ * Proxy that intercepts property access to dynamically create logger methods.
74
+ * Enables calling log.info(), log.warn(), etc. without pre-defining methods.
75
+ */
76
+ const defaultLogger = new Proxy(this.makeLogger('log'), {
77
+ get: (target, key) => {
78
+ if (typeof key !== 'string') return Reflect.get(target, key);
79
+ return Reflect.get(target, key) ?? this[key] ?? this.makeLogger(key);
80
+ },
81
+ });
82
+
83
+ defaultLogger.options = this.options;
84
+
85
+ loggers[tag] = defaultLogger;
86
+
87
+ return defaultLogger;
88
+ }
89
+
90
+ /**
91
+ * Creates logger function for specified console method.
92
+ * @param {string} method - Console method name (log, info, warn, error, etc.)
93
+ * @returns {Function} Logger function supporting direct calls and verbosity-specific curried calls
94
+ */
95
+ makeLogger(method) {
96
+ const { tag } = this.options;
97
+
98
+ return (...args) => {
99
+ const {
100
+ colorMap,
101
+ silentTag,
102
+ methodTag,
103
+ verbosity,
104
+ color: useColor,
105
+ } = loggers[tag]?.options || this.options;
106
+
107
+ const isVerbosityCall = args.length === 1 && typeof args[0] === 'number';
108
+ const thisVerbosity = isVerbosityCall ? args.shift() : 0;
109
+ if (!isVerbosityCall && args.length === 0) return;
110
+ const willShow = !!console && thisVerbosity < verbosity;
111
+ const isNativeConsoleMethod = !!console && typeof console[method] === 'function';
112
+ const resolvedMethod = isNativeConsoleMethod ? method : (methodMap[method] || 'log');
113
+
114
+ let colorReset;
115
+
116
+ if (willShow) {
117
+ const colors = { ...DEFAULT_COLOR_MAP, ...colorMap };
118
+ const color = colors[tag] || colors[method] || colors[methodMap[method]];
119
+
120
+ if (!silentTag) {
121
+ let tagText = '';
122
+
123
+ if (tag !== '__default') tagText += `[${tag}]`;
124
+ if (methodTag || !isNativeConsoleMethod) tagText += `[${method}]`;
125
+
126
+ if (tagText) args.unshift(tagText);
127
+ }
128
+
129
+ if (useColor && color) {
130
+ args.unshift(color);
131
+ colorReset = colors.__reset;
132
+ if (!isVerbosityCall) args.push(colorReset);
133
+ } else if (method === 'error') {
134
+ args.unshift('[ERROR]');
135
+ }
136
+ }
137
+
138
+ if (isVerbosityCall) {
139
+ if (!willShow || !console) return () => {};
140
+ return colorReset
141
+ ? (...messageArgs) => console[resolvedMethod](...args, ...messageArgs, colorReset)
142
+ : (...messageArgs) => console[resolvedMethod](...args, ...messageArgs);
143
+ }
144
+
145
+ if (willShow) console[resolvedMethod](...args);
146
+ };
147
+ }
148
+
149
+ /**
150
+ * Updates logger tag and relocates instance in global registry.
151
+ * When newTag already exists, options are merged: constructor-time options take priority over the
152
+ * existing logger's options. Runtime mutations to this.options after construction are not tracked
153
+ * and may be overwritten by the existing logger's values during the merge.
154
+ * @param {string} newTag - New tag identifier
155
+ */
156
+ setTag(newTag) {
157
+ const { tag } = this.options;
158
+
159
+ if (newTag === tag) return;
160
+
161
+ if (loggers[newTag]) {
162
+ Object.assign(this.options, loggers[newTag].options, this._explicit);
163
+ }
164
+
165
+ loggers[newTag] = loggers[tag];
166
+ this.options.tag = newTag;
167
+
168
+ const { colorMap } = this.options;
169
+ if (colorMap[tag]) {
170
+ colorMap[newTag] = colorMap[tag];
171
+ }
172
+
173
+ delete loggers[tag];
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Merges options into the global defaults applied to all new logger instances.
179
+ * @param {Partial<typeof defaults>} options - Default settings to apply
180
+ */
181
+ export function setDefaults(options) {
182
+ Object.assign(defaults, options);
183
+ }
184
+
185
+ /**
186
+ * Merges entries into the global method map used by all loggers.
187
+ * @param {Record<string, string>} map - Custom method names mapped to console methods
188
+ */
189
+ export function setMethodMap(map) {
190
+ Object.assign(methodMap, map);
191
+ }
192
+
193
+ export default Log;