@vielzeug/logit 1.0.5 → 1.1.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.
package/README.md ADDED
@@ -0,0 +1,591 @@
1
+ # @vielzeug/logit
2
+
3
+ Powerful, type-safe console logging utility for TypeScript with styled output, log levels, scoped loggers, and remote logging support.
4
+
5
+ ## Features
6
+
7
+ - ✅ **Styled Console Output** - Beautiful colored logs with symbols, icons, or text
8
+ - ✅ **Log Level Filtering** - Control verbosity (debug, info, warn, error, off)
9
+ - ✅ **Scoped Loggers** - Create isolated loggers with namespaced prefixes
10
+ - ✅ **Remote Logging** - Send logs to external services (Sentry, Datadog, etc.)
11
+ - ✅ **Environment Detection** - Automatic production/development indicators
12
+ - ✅ **Timestamps** - Optional timestamp display
13
+ - ✅ **Type-Safe** - Full TypeScript support
14
+ - ✅ **Framework Agnostic** - Works in browser and Node.js
15
+ - ✅ **Zero Dependencies** - Lightweight with no external dependencies
16
+ - ✅ **Multiple Variants** - Symbol, icon, or text-based display modes
17
+
18
+ ## Installation
19
+
20
+ ::: code-group
21
+
22
+ ```sh [pnpm]
23
+ pnpm add @vielzeug/logit
24
+ ```
25
+
26
+ ```sh [npm]
27
+ npm install @vielzeug/logit
28
+ ```
29
+
30
+ ```sh [yarn]
31
+ yarn add @vielzeug/logit
32
+ ```
33
+
34
+ :::
35
+
36
+ ## Quick Start
37
+
38
+ ```typescript
39
+ import { Logit } from '@vielzeug/logit';
40
+
41
+ // Basic logging
42
+ Logit.info('Application started');
43
+ Logit.success('User authenticated');
44
+ Logit.warn('API rate limit approaching');
45
+ Logit.error('Failed to connect to database');
46
+
47
+ // With multiple arguments
48
+ Logit.debug('User data:', { id: 123, name: 'Alice' });
49
+
50
+ // Configure log level
51
+ Logit.setLogLevel('warn'); // Only warn and error messages will show
52
+
53
+ // Set namespace
54
+ Logit.setPrefix('MyApp');
55
+ Logit.info('This message has a namespace'); // [MYAPP] This message has a namespace
56
+ ```
57
+
58
+ ## Core Concepts
59
+
60
+ ### Log Levels
61
+
62
+ Control which logs are displayed based on severity:
63
+
64
+ ```typescript
65
+ // Set minimum log level
66
+ Logit.setLogLevel('warn');
67
+
68
+ Logit.debug('Not shown'); // ❌ Below threshold
69
+ Logit.info('Not shown'); // ❌ Below threshold
70
+ Logit.warn('Shown'); // ✅ At threshold
71
+ Logit.error('Shown'); // ✅ Above threshold
72
+
73
+ // Disable all logs
74
+ Logit.setLogLevel('off');
75
+
76
+ // Enable all logs
77
+ Logit.setLogLevel('debug');
78
+ ```
79
+
80
+ **Log Level Hierarchy (most to least verbose):**
81
+ ```
82
+ debug → trace → time → table → info → success → warn → error → off
83
+ ```
84
+
85
+ ### Display Variants
86
+
87
+ Choose how log messages are displayed:
88
+
89
+ ```typescript
90
+ // Symbol variant (default) - Unicode symbols
91
+ Logit.setVariant('symbol');
92
+ Logit.info('Message'); // 🅸 Message
93
+
94
+ // Icon variant - Icon characters
95
+ Logit.setVariant('icon');
96
+ Logit.info('Message'); // ℹ Message
97
+
98
+ // Text variant - Plain text labels
99
+ Logit.setVariant('text');
100
+ Logit.info('Message'); // INFO Message
101
+ ```
102
+
103
+ ### Namespaces
104
+
105
+ Add context to your logs with namespaces:
106
+
107
+ ```typescript
108
+ Logit.setPrefix('Auth');
109
+ Logit.info('Login attempt'); // [AUTH] Login attempt
110
+ Logit.error('Invalid credentials'); // [AUTH] Invalid credentials
111
+
112
+ // Clear namespace
113
+ Logit.setPrefix('');
114
+ ```
115
+
116
+ ### Scoped Loggers
117
+
118
+ Create isolated loggers without mutating global state:
119
+
120
+ ```typescript
121
+ // Global namespace
122
+ Logit.setPrefix('App');
123
+
124
+ // Create scoped loggers
125
+ const apiLogger = Logit.scope('api');
126
+ const dbLogger = Logit.scope('database');
127
+ const cacheLogger = Logit.scope('cache');
128
+
129
+ apiLogger.info('GET /users'); // [APP.API] GET /users
130
+ dbLogger.error('Connection timeout'); // [APP.DATABASE] Connection timeout
131
+ cacheLogger.debug('Cache hit'); // [APP.CACHE] Cache hit
132
+
133
+ // Global namespace unchanged
134
+ Logit.getPrefix(); // 'App'
135
+
136
+ // Nested scopes
137
+ Logit.setPrefix('App.api');
138
+ const v1Logger = Logit.scope('v1');
139
+ v1Logger.info('Request'); // [APP.API.V1] Request
140
+ ```
141
+
142
+ **Benefits:**
143
+ - No global state mutation
144
+ - Safe for concurrent operations
145
+ - Clean separation of concerns
146
+ - Easy to pass to modules/components
147
+
148
+ ## Advanced Features
149
+
150
+ ### Remote Logging
151
+
152
+ Send logs to external services for monitoring and error tracking:
153
+
154
+ ```typescript
155
+ // Configure remote handler
156
+ Logit.setRemote({
157
+ handler: (type, metadata) => {
158
+ // Send to your logging service
159
+ fetch('https://logs.example.com', {
160
+ method: 'POST',
161
+ body: JSON.stringify({
162
+ level: type,
163
+ message: metadata.args,
164
+ timestamp: metadata.timestamp,
165
+ namespace: metadata.namespace,
166
+ environment: metadata.environment,
167
+ }),
168
+ });
169
+ },
170
+ logLevel: 'warn', // Only send warn and error to remote
171
+ });
172
+
173
+ // Remote logging works independently
174
+ Logit.setLogLevel('debug'); // Console shows all logs
175
+ // But remote only receives warn/error
176
+
177
+ Logit.info('Local only'); // ✅ Console, ❌ Remote
178
+ Logit.warn('Both'); // ✅ Console, ✅ Remote
179
+ Logit.error('Both'); // ✅ Console, ✅ Remote
180
+ ```
181
+
182
+ **Metadata sent to handler:**
183
+ ```typescript
184
+ {
185
+ args: any[], // Log arguments
186
+ timestamp?: string, // ISO timestamp (if enabled)
187
+ namespace?: string, // Current namespace
188
+ environment: 'production' | 'development'
189
+ }
190
+ ```
191
+
192
+ **Integration examples:**
193
+
194
+ ```typescript
195
+ // Sentry
196
+ Logit.setRemote({
197
+ handler: (type, metadata) => {
198
+ if (type === 'error') {
199
+ Sentry.captureMessage(metadata.args.join(' '), {
200
+ level: 'error',
201
+ tags: { namespace: metadata.namespace },
202
+ });
203
+ }
204
+ },
205
+ logLevel: 'error',
206
+ });
207
+
208
+ // Datadog
209
+ Logit.setRemote({
210
+ handler: (type, metadata) => {
211
+ window.DD_LOGS?.logger.log(
212
+ type,
213
+ metadata.args.join(' '),
214
+ { namespace: metadata.namespace }
215
+ );
216
+ },
217
+ logLevel: 'info',
218
+ });
219
+
220
+ // Custom webhook
221
+ Logit.setRemote({
222
+ handler: async (type, metadata) => {
223
+ await fetch('/api/logs', {
224
+ method: 'POST',
225
+ headers: { 'Content-Type': 'application/json' },
226
+ body: JSON.stringify({ type, ...metadata }),
227
+ });
228
+ },
229
+ logLevel: 'warn',
230
+ });
231
+ ```
232
+
233
+ ### Environment Indicators
234
+
235
+ Automatically shows production/development indicators:
236
+
237
+ ```typescript
238
+ // Enable environment indicator (default)
239
+ Logit.showEnvironment(true);
240
+ Logit.info('Message'); // 🅸 🅳 Message (in development)
241
+ // 🅸 🅿 Message (in production)
242
+
243
+ // Disable environment indicator
244
+ Logit.showEnvironment(false);
245
+ Logit.info('Message'); // 🅸 Message
246
+ ```
247
+
248
+ ### Timestamps
249
+
250
+ Add timestamps to your logs:
251
+
252
+ ```typescript
253
+ // Enable timestamps (default)
254
+ Logit.showTimestamp(true);
255
+ Logit.info('Message'); // 🅸 🅳 14:23:45.123 Message
256
+
257
+ // Disable timestamps
258
+ Logit.showTimestamp(false);
259
+ Logit.info('Message'); // 🅸 🅳 Message
260
+ ```
261
+
262
+ ### Utility Methods
263
+
264
+ ```typescript
265
+ // Table display
266
+ const users = [
267
+ { id: 1, name: 'Alice', age: 30 },
268
+ { id: 2, name: 'Bob', age: 25 },
269
+ ];
270
+ Logit.table(users);
271
+ // Displays formatted table in console
272
+
273
+ // Timers
274
+ Logit.time('database-query');
275
+ await db.query('SELECT * FROM users');
276
+ Logit.timeEnd('database-query'); // database-query: 234ms
277
+
278
+ // Groups
279
+ Logit.groupCollapsed('API Request', 'GET', startTime);
280
+ Logit.info('URL:', '/api/users');
281
+ Logit.info('Status:', 200);
282
+ Logit.groupEnd();
283
+
284
+ // Assertions
285
+ Logit.assert(user !== null, 'User should exist', { userId: 123 });
286
+ ```
287
+
288
+ ## Configuration
289
+
290
+ ### Initialize with Options
291
+
292
+ ```typescript
293
+ Logit.setup({
294
+ logLevel: 'info', // Minimum log level
295
+ namespace: 'MyApp', // Global namespace
296
+ variant: 'symbol', // Display variant
297
+ timestamp: true, // Show timestamps
298
+ environment: true, // Show environment indicator
299
+ remote: { // Remote logging config
300
+ handler: remoteHandler,
301
+ logLevel: 'warn',
302
+ },
303
+ });
304
+ ```
305
+
306
+ ### Getters
307
+
308
+ ```typescript
309
+ Logit.getLevel(); // Current log level
310
+ Logit.getPrefix(); // Current namespace
311
+ Logit.getTimestamp(); // Timestamp enabled?
312
+ Logit.getEnvironment(); // Environment indicator enabled?
313
+ Logit.getVariant(); // Current variant
314
+ ```
315
+
316
+ ### Setters
317
+
318
+ ```typescript
319
+ Logit.setLogLevel('warn');
320
+ Logit.setPrefix('App');
321
+ Logit.toggleTimestamp(false);
322
+ Logit.toggleEnvironment(true);
323
+ Logit.setVariant('icon');
324
+ Logit.setRemote({ handler, logLevel: 'error' });
325
+ Logit.setRemoteLogLevel('warn');
326
+ ```
327
+
328
+ ## API Reference
329
+
330
+ ### Logging Methods
331
+
332
+ ```typescript
333
+ Logit.debug(...args: any[]): void
334
+ Logit.trace(...args: any[]): void
335
+ Logit.info(...args: any[]): void
336
+ Logit.success(...args: any[]): void
337
+ Logit.warn(...args: any[]): void
338
+ Logit.error(...args: any[]): void
339
+ ```
340
+
341
+ ### Scoped Logger
342
+
343
+ ```typescript
344
+ Logit.scope(namespace: string): ScopedLogger
345
+
346
+ // ScopedLogger has all logging methods:
347
+ {
348
+ debug: (...args: any[]) => void;
349
+ trace: (...args: any[]) => void;
350
+ info: (...args: any[]) => void;
351
+ success: (...args: any[]) => void;
352
+ warn: (...args: any[]) => void;
353
+ error: (...args: any[]) => void;
354
+ }
355
+ ```
356
+
357
+ ### Utility Methods
358
+
359
+ ```typescript
360
+ Logit.table(...args: any[]): void
361
+ Logit.time(label: string): void
362
+ Logit.timeEnd(label: string): void
363
+ Logit.groupCollapsed(text: string, label?: string, time?: number): void
364
+ Logit.groupEnd(): void
365
+ Logit.assert(valid: boolean, message: string, context: Record<string, any>): void
366
+ ```
367
+
368
+ ## Use Cases
369
+
370
+ ### Module-Specific Logging
371
+
372
+ ```typescript
373
+ // api.ts
374
+ const logger = Logit.scope('api');
375
+
376
+ export async function fetchUsers() {
377
+ logger.debug('Fetching users');
378
+ const response = await fetch('/api/users');
379
+ logger.info('Users fetched:', response.status);
380
+ return response.json();
381
+ }
382
+
383
+ // database.ts
384
+ const logger = Logit.scope('database');
385
+
386
+ export async function connect() {
387
+ logger.info('Connecting to database');
388
+ try {
389
+ await db.connect();
390
+ logger.success('Connected to database');
391
+ } catch (error) {
392
+ logger.error('Database connection failed:', error);
393
+ throw error;
394
+ }
395
+ }
396
+ ```
397
+
398
+ ### Debug vs Production
399
+
400
+ ```typescript
401
+ // During development
402
+ Logit.setLogLevel('debug');
403
+ Logit.showTimestamp(true);
404
+
405
+ // In production
406
+ if (process.env.NODE_ENV === 'production') {
407
+ Logit.setLogLevel('warn');
408
+ Logit.showTimestamp(false);
409
+ Logit.setRemote({
410
+ handler: sendToSentry,
411
+ logLevel: 'error',
412
+ });
413
+ }
414
+ ```
415
+
416
+ ### Error Tracking
417
+
418
+ ```typescript
419
+ Logit.setRemote({
420
+ handler: (type, metadata) => {
421
+ if (type === 'error') {
422
+ // Send to error tracking service
423
+ errorTracker.captureException({
424
+ message: metadata.args.join(' '),
425
+ timestamp: metadata.timestamp,
426
+ namespace: metadata.namespace,
427
+ environment: metadata.environment,
428
+ });
429
+ }
430
+ },
431
+ logLevel: 'error',
432
+ });
433
+
434
+ try {
435
+ await riskyOperation();
436
+ } catch (error) {
437
+ Logit.error('Operation failed:', error); // Logged locally + sent to tracker
438
+ }
439
+ ```
440
+
441
+ ### Performance Monitoring
442
+
443
+ ```typescript
444
+ Logit.time('page-load');
445
+
446
+ // Load application
447
+ await loadApp();
448
+
449
+ Logit.timeEnd('page-load'); // page-load: 1234ms
450
+
451
+ // With groups for detailed timing
452
+ Logit.groupCollapsed('Application Initialization');
453
+ Logit.time('load-config');
454
+ await loadConfig();
455
+ Logit.timeEnd('load-config');
456
+
457
+ Logit.time('init-modules');
458
+ await initModules();
459
+ Logit.timeEnd('init-modules');
460
+ Logit.groupEnd();
461
+ ```
462
+
463
+ ## Browser vs Node.js
464
+
465
+ ### Browser
466
+ - Styled console output with colors and symbols
467
+ - CSS-based formatting
468
+ - Environment detection via `import.meta.env` or `process.env`
469
+
470
+ ### Node.js
471
+ - Plain text output with labels
472
+ - No CSS styling
473
+ - Environment detection via `process.env.NODE_ENV`
474
+
475
+ **Example output:**
476
+
477
+ **Browser:**
478
+ ```
479
+ 🅸 🅳 14:23:45.123 User authenticated
480
+ ```
481
+
482
+ **Node.js:**
483
+ ```
484
+ INFO | 🅳 | User authenticated
485
+ ```
486
+
487
+ ## TypeScript Support
488
+
489
+ Full TypeScript support with exported types:
490
+
491
+ ```typescript
492
+ import {
493
+ Logit,
494
+ type LogitType,
495
+ type LogitLevel,
496
+ type LogitOptions,
497
+ type LogitRemoteOptions,
498
+ type ScopedLogger,
499
+ } from '@vielzeug/logit';
500
+
501
+ const options: LogitOptions = {
502
+ logLevel: 'info',
503
+ namespace: 'App',
504
+ variant: 'symbol',
505
+ };
506
+
507
+ Logit.setup(options);
508
+
509
+ const logger: ScopedLogger = Logit.scope('module');
510
+ ```
511
+
512
+ ## Best Practices
513
+
514
+ ### 1. Use Scoped Loggers for Modules
515
+
516
+ ```typescript
517
+ // ✅ Good - Each module has its own logger
518
+ const apiLogger = Logit.scope('api');
519
+ const dbLogger = Logit.scope('db');
520
+
521
+ // ❌ Avoid - Mutating global namespace
522
+ Logit.setPrefix('api');
523
+ Logit.info('Request');
524
+ Logit.setPrefix('db');
525
+ Logit.info('Query');
526
+ ```
527
+
528
+ ### 2. Set Appropriate Log Levels
529
+
530
+ ```typescript
531
+ // Development
532
+ Logit.setLogLevel('debug');
533
+
534
+ // Staging
535
+ Logit.setLogLevel('info');
536
+
537
+ // Production
538
+ Logit.setLogLevel('warn');
539
+ ```
540
+
541
+ ### 3. Use Remote Logging for Production Errors
542
+
543
+ ```typescript
544
+ if (process.env.NODE_ENV === 'production') {
545
+ Logit.setRemote({
546
+ handler: sendToErrorTracker,
547
+ logLevel: 'error',
548
+ });
549
+ }
550
+ ```
551
+
552
+ ### 4. Leverage Log Levels Appropriately
553
+
554
+ ```typescript
555
+ Logit.debug('Detailed debugging info'); // Development only
556
+ Logit.info('User logged in'); // General information
557
+ Logit.success('Payment processed'); // Success states
558
+ Logit.warn('API rate limit: 90%'); // Warnings
559
+ Logit.error('Payment failed:', error); // Errors
560
+ ```
561
+
562
+ ## Performance
563
+
564
+ - Minimal overhead when logs are filtered by level
565
+ - Lazy evaluation of timestamp and environment
566
+ - Async remote logging (Promise-based, non-blocking)
567
+ - Zero dependencies
568
+ - ~3KB gzipped
569
+
570
+ ## Browser Support
571
+
572
+ - Chrome/Edge 63+ (for styled console output)
573
+ - Firefox 58+
574
+ - Safari 13+
575
+ - Node.js 10+
576
+
577
+ ## License
578
+
579
+ MIT © [Helmuth Duarte](https://github.com/helmuthdu)
580
+
581
+ ## Links
582
+
583
+ - [GitHub Repository](https://github.com/helmuthdu/vielzeug)
584
+ - [Documentation](https://vielzeug.dev)
585
+ - [NPM Package](https://www.npmjs.com/package/@vielzeug/logit)
586
+ - [Issue Tracker](https://github.com/helmuthdu/vielzeug/issues)
587
+
588
+ ---
589
+
590
+ Part of the [Vielzeug](https://github.com/helmuthdu/vielzeug) ecosystem - A collection of type-safe utilities for modern web development.
591
+
package/dist/index.d.ts CHANGED
@@ -5,6 +5,10 @@ export declare const Logit: {
5
5
  assert: (valid: boolean, message: string, context: Record<string, any>) => void;
6
6
  debug: (...args: any[]) => void;
7
7
  error: (...args: any[]) => void;
8
+ /**
9
+ * Gets whether the environment indicator is shown.
10
+ */
11
+ getEnvironment: () => boolean;
8
12
  /**
9
13
  * Gets the current log level.
10
14
  */
@@ -17,6 +21,10 @@ export declare const Logit: {
17
21
  * Gets whether timestamps are shown.
18
22
  */
19
23
  getTimestamp: () => boolean;
24
+ /**
25
+ * Gets the current display variant.
26
+ */
27
+ getVariant: () => "text" | "symbol" | "icon";
20
28
  /**
21
29
  * Creates a collapsed group in the console.
22
30
  */
@@ -27,9 +35,22 @@ export declare const Logit: {
27
35
  groupEnd: () => void;
28
36
  info: (...args: any[]) => void;
29
37
  /**
30
- * Initializes Logit with custom options.
31
- */
32
- initialise: (options: LogitOptions) => void;
38
+ * Creates a scoped logger with a namespaced prefix.
39
+ * Does not mutate global state - returns an isolated logger instance.
40
+ *
41
+ * @param namespace - The namespace to prepend to all log messages
42
+ * @returns A scoped logger with all logging methods
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const apiLogger = Logit.scope('api');
47
+ * apiLogger.info('Request received'); // [API] Request received
48
+ *
49
+ * const dbLogger = Logit.scope('database');
50
+ * dbLogger.error('Connection failed'); // [DATABASE] Connection failed
51
+ * ```
52
+ */
53
+ scope: (namespace: string) => ScopedLogger;
33
54
  /**
34
55
  * Sets the minimum log level to display.
35
56
  */
@@ -47,17 +68,16 @@ export declare const Logit: {
47
68
  */
48
69
  setRemoteLogLevel: (level: LogitLevel) => void;
49
70
  /**
50
- * Sets the display variant (text, icon, or symbol).
71
+ * Configures Logit with custom options.
72
+ *
73
+ * Note: The remote option will be merged with existing remote config,
74
+ * not replaced entirely. To clear a remote handler, set remote.handler to undefined.
51
75
  */
52
- setVariant: (variant: "text" | "icon" | "symbol") => void;
76
+ setup: (options: LogitOptions) => void;
53
77
  /**
54
- * Shows or hides the environment indicator.
55
- */
56
- showEnvironment: (value: boolean) => void;
57
- /**
58
- * Shows or hides timestamps in logs.
78
+ * Sets the display variant (text, icon, or symbol).
59
79
  */
60
- showTimestamp: (value: boolean) => void;
80
+ setVariant: (variant: "text" | "icon" | "symbol") => void;
61
81
  success: (...args: any[]) => void;
62
82
  /**
63
83
  * Displays data in a table format.
@@ -71,6 +91,34 @@ export declare const Logit: {
71
91
  * Ends a timer with the given label.
72
92
  */
73
93
  timeEnd: (label: string) => void;
94
+ /**
95
+ * Toggles or sets the environment indicator visibility.
96
+ * When called without arguments, toggles the current state.
97
+ *
98
+ * @param value - Optional boolean to explicitly set the state
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * Logit.toggleEnvironment(); // Toggles current state
103
+ * Logit.toggleEnvironment(true); // Shows environment indicator
104
+ * Logit.toggleEnvironment(false); // Hides environment indicator
105
+ * ```
106
+ */
107
+ toggleEnvironment: (value?: boolean) => void;
108
+ /**
109
+ * Toggles or sets timestamp visibility in logs.
110
+ * When called without arguments, toggles the current state.
111
+ *
112
+ * @param value - Optional boolean to explicitly set the state
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * Logit.toggleTimestamp(); // Toggles current state
117
+ * Logit.toggleTimestamp(true); // Shows timestamps
118
+ * Logit.toggleTimestamp(false); // Hides timestamps
119
+ * ```
120
+ */
121
+ toggleTimestamp: (value?: boolean) => void;
74
122
  trace: (...args: any[]) => void;
75
123
  warn: (...args: any[]) => void;
76
124
  };
@@ -107,4 +155,16 @@ export declare type LogitTheme = {
107
155
 
108
156
  export declare type LogitType = 'debug' | 'trace' | 'time' | 'table' | 'info' | 'success' | 'warn' | 'error';
109
157
 
158
+ /**
159
+ * Scoped logger interface with namespaced logging methods.
160
+ */
161
+ export declare type ScopedLogger = {
162
+ debug: (...args: any[]) => void;
163
+ error: (...args: any[]) => void;
164
+ info: (...args: any[]) => void;
165
+ success: (...args: any[]) => void;
166
+ trace: (...args: any[]) => void;
167
+ warn: (...args: any[]) => void;
168
+ };
169
+
110
170
  export { }
package/dist/logit.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v={},E="🄿",w="🄳",L={debug:"log",success:"log"},_=()=>typeof window<"u"&&v?.NODE_ENV?!1:typeof process<"u"&&process.env?.NODE_ENV?process.env.NODE_ENV==="production":!1,x=_(),y=typeof window<"u"&&window.matchMedia?.("(prefers-color-scheme: dark)").matches,b={debug:{bg:"#616161",border:"#424242",color:"#fff",icon:"☕",symbol:"🅳"},error:{bg:"#d32f2f",border:"#c62828",color:"#fff",icon:"✘",symbol:"🅴"},group:{bg:"#546e7a",border:"#455a64",color:"#fff",icon:"⚭",symbol:"🅶"},info:{bg:"#1976d2",border:"#1565c0",color:"#fff",icon:"ℹ",symbol:"🅸"},ns:y?{bg:"#fafafa",border:"#c7c7c7",color:"#000"}:{bg:"#424242",border:"#212121",color:"#fff"},success:{bg:"#689f38",border:"#558b2f",color:"#fff",icon:"✔",symbol:"🆂"},time:{bg:"#0097a7",border:"#00838f",color:"#fff",icon:"⏲",symbol:"🆃"},trace:{bg:"#d81b60",border:"#c2185b",color:"#fff",icon:"⛢",symbol:"🆃"},warn:{bg:"#ffb300",border:"#ffa000",color:"#fff",icon:"⚠",symbol:"🆆"}},l={debug:0,trace:1,time:2,table:3,info:4,success:5,warn:6,error:7,off:8},t={environment:!0,logLevel:"debug",namespace:"",remote:{handler:void 0,logLevel:"off"},timestamp:!0,variant:"symbol"},a=e=>l[t.logLevel]<=l[e],p=()=>new Date().toISOString().slice(11,23),d=()=>x?E:w,D=(e,o)=>{t.remote.handler&&l[t.remote.logLevel]<=l[e]&&t.remote.handler(e,...o)},g=e=>L[e]||e,m="border: 1px solid",u="border-radius: 4px",h="border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter",f=(e,o="")=>{const{bg:r,color:c,border:n}=b[e],s=`color: ${r}; ${m} ${n}; ${u}`;switch(t.variant){case"symbol":return`${s}; padding: 1px 1px 0${o}`;case"icon":return`${s}; padding: 0 3px${o}`;default:return`background: ${r}; color: ${c}; ${m} ${n}; ${u}; font-weight: bold; padding: 0 3px${o}`}},$=e=>{const o=b[e],{variant:r}=t;return r==="text"||!o[r]?e.toUpperCase():o[r]};function O(e){const{namespace:o,timestamp:r,environment:c}=t;let n=`%c${$(e)}%c`;const s=[f(e),""];return o&&(n+=` %c${o}%c`,s.push(f("ns",`; ${h}`),"")),c&&(n+=` %c${d()}%c`,s.push("color: darkgray","")),r&&(n+=` %c${p()}%c`,s.push("color: gray","")),{format:n,parts:s}}const i=(e,...o)=>{if(typeof window>"u"){const s=console[g(e)];s(`${$(e)} | ${d()} |`,...o);return}if(!a(e))return;const{format:r,parts:c}=O(e),n=console[g(e)];n(r,...c,...o),D(e,o)},S=e=>{const o=Math.floor(Date.now()-e);return o?`${o}ms`:""},R={assert:(e,o,r)=>console.assert(e,o,r),debug:(...e)=>i("debug",...e),error:(...e)=>i("error",...e),getLevel:()=>t.logLevel,getPrefix:()=>t.namespace,getTimestamp:()=>t.timestamp,groupCollapsed:(e,o="GROUP",r=Date.now())=>{if(!a("success"))return;const c=S(r),n=d(),s=t.timestamp?p():"";console.groupCollapsed(`%c${o}%c${t.namespace}%c${n}%c${s}%c${c}%c${e}`,f("group","; margin-right: 6px; padding: 1px 3px 0"),f("ns",`; ${h}; margin-right: 6px`),"color: darkgray; margin-right: 6px","color: gray; font-weight: lighter; margin-right: 6px","color: gray; font-weight: lighter; margin-right: 6px","color: inherit; font-weight: lighter")},groupEnd:()=>{a("success")&&console.groupEnd()},info:(...e)=>i("info",...e),initialise:e=>{Object.assign(t,e)},setLogLevel:e=>{t.logLevel=e},setPrefix:e=>{t.namespace=e},setRemote:e=>{t.remote=e},setRemoteLogLevel:e=>{t.remote.logLevel=e},setVariant:e=>{t.variant=e},showEnvironment:e=>{t.environment=e},showTimestamp:e=>{t.timestamp=e},success:(...e)=>i("success",...e),table:(...e)=>{a("table")&&console.table(...e)},time:e=>{a("time")&&console.time(e)},timeEnd:e=>{a("time")&&console.timeEnd(e)},trace:(...e)=>i("trace",...e),warn:(...e)=>i("warn",...e)};exports.Logit=R;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h={},$="🄿",E="🄳",w={debug:"log",success:"log"},L=()=>typeof window<"u"&&h?.NODE_ENV?!1:typeof process<"u"&&process.env?.NODE_ENV?process.env.NODE_ENV==="production":!1,g=L(),_=typeof window<"u"&&window.matchMedia?.("(prefers-color-scheme: dark)").matches,u={debug:{bg:"#616161",border:"#424242",color:"#fff",icon:"☕",symbol:"🅳"},error:{bg:"#d32f2f",border:"#c62828",color:"#fff",icon:"✘",symbol:"🅴"},group:{bg:"#546e7a",border:"#455a64",color:"#fff",icon:"⚭",symbol:"🅶"},info:{bg:"#1976d2",border:"#1565c0",color:"#fff",icon:"ℹ",symbol:"🅸"},ns:_?{bg:"#fafafa",border:"#c7c7c7",color:"#000"}:{bg:"#424242",border:"#212121",color:"#fff"},success:{bg:"#689f38",border:"#558b2f",color:"#fff",icon:"✔",symbol:"🆂"},time:{bg:"#0097a7",border:"#00838f",color:"#fff",icon:"⏲",symbol:"🆃"},trace:{bg:"#d81b60",border:"#c2185b",color:"#fff",icon:"⛢",symbol:"🆃"},warn:{bg:"#ffb300",border:"#ffa000",color:"#fff",icon:"⚠",symbol:"🆆"}},m={debug:0,trace:1,time:2,table:3,info:4,success:5,warn:6,error:7,off:8},o={environment:!0,logLevel:"debug",namespace:"",remote:{handler:void 0,logLevel:"off"},timestamp:!0,variant:"symbol"},i=e=>m[o.logLevel]<=m[e],d=()=>new Date().toISOString().slice(11,23),p=()=>g?$:E,x=(e,n)=>{o.remote.handler&&m[o.remote.logLevel]<=m[e]&&Promise.resolve().then(()=>{o.remote.handler?.(e,{args:n,environment:g?"production":"development",namespace:o.namespace||void 0,timestamp:o.timestamp?d():void 0})})},f=e=>w[e]||e,y="border: 1px solid",D="border-radius: 4px",b="border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;",l=(e,n="")=>{const{bg:r,color:s,border:t}=u[e],c=`${y} ${t}; ${D}`;switch(o.variant){case"symbol":return`color: ${r}; ${c}; padding: 1px 1px 0${n}`;case"icon":return`color: ${r}; ${c}; padding: 0 3px${n}`;default:return`background: ${r}; color: ${s}; ${c}; font-weight: bold; padding: 0 3px${n}`}},v=e=>{const n=u[e],{variant:r}=o;return r==="text"||!n||!n[r]?e.toUpperCase():n[r]};function O(e){const{namespace:n,timestamp:r,environment:s}=o;let t=`%c${v(e)}%c`;const c=[l(e),""];return n&&(t+=` %c${n}%c`,c.push(l("ns",`; ${b}`),"")),s&&(t+=` %c${p()}%c`,c.push("color: darkgray","")),r&&(t+=` %c${d()}%c`,c.push("color: gray","")),{format:t,parts:c}}const a=(e,...n)=>{if(typeof window>"u"){const c=console[f(e)];c(`${v(e)} | ${p()} |`,...n);return}if(!i(e))return;const{format:r,parts:s}=O(e),t=console[f(e)];t(r,...s,...n),x(e,n)},S=e=>{const n=Math.floor(Date.now()-e);return n?`${n}ms`:""},N={assert:(e,n,r)=>console.assert(e,n,r),debug:(...e)=>a("debug",...e),error:(...e)=>a("error",...e),getEnvironment:()=>o.environment,getLevel:()=>o.logLevel,getPrefix:()=>o.namespace,getTimestamp:()=>o.timestamp,getVariant:()=>o.variant,groupCollapsed:(e,n="GROUP",r=Date.now())=>{if(!i("success"))return;const s=S(r),t=p(),c=o.timestamp?d():"";console.groupCollapsed(`%c${n}%c${o.namespace}%c${t}%c${c}%c${s}%c${e}`,l("group","; margin-right: 6px; padding: 1px 3px 0"),l("ns",`; ${b}; margin-right: 6px`),"color: darkgray; margin-right: 6px","color: gray; font-weight: lighter; margin-right: 6px","color: gray; font-weight: lighter; margin-right: 6px","color: inherit; font-weight: lighter")},groupEnd:()=>{i("success")&&console.groupEnd()},info:(...e)=>a("info",...e),scope:e=>{const n=o.namespace,r=n?`${n}.${e}`:e;return{debug:(...s)=>{const t=o.namespace;o.namespace=r,a("debug",...s),o.namespace=t},error:(...s)=>{const t=o.namespace;o.namespace=r,a("error",...s),o.namespace=t},info:(...s)=>{const t=o.namespace;o.namespace=r,a("info",...s),o.namespace=t},success:(...s)=>{const t=o.namespace;o.namespace=r,a("success",...s),o.namespace=t},trace:(...s)=>{const t=o.namespace;o.namespace=r,a("trace",...s),o.namespace=t},warn:(...s)=>{const t=o.namespace;o.namespace=r,a("warn",...s),o.namespace=t}}},setLogLevel:e=>{o.logLevel=e},setPrefix:e=>{o.namespace=e},setRemote:e=>{o.remote=e},setRemoteLogLevel:e=>{o.remote.logLevel=e},setup:e=>{e.remote&&(o.remote={...o.remote,...e.remote},delete e.remote),Object.assign(o,e)},setVariant:e=>{o.variant=e},success:(...e)=>a("success",...e),table:(...e)=>{i("table")&&console.table(...e)},time:e=>{i("time")&&console.time(e)},timeEnd:e=>{i("time")&&console.timeEnd(e)},toggleEnvironment:e=>{o.environment=e??!o.environment},toggleTimestamp:e=>{o.timestamp=e??!o.timestamp},trace:(...e)=>a("trace",...e),warn:(...e)=>a("warn",...e)};exports.Logit=N;
2
2
  //# sourceMappingURL=logit.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"logit.cjs","sources":["../src/logit.ts"],"sourcesContent":["/** biome-ignore-all lint/suspicious/noAssignInExpressions: - */\n/** biome-ignore-all lint/suspicious/noExplicitAny: - */\n\n/**\n * Environment indicator symbols.\n */\nconst ENV_PROD = '\\uD83C\\uDD3F'; // 🅿\nconst ENV_DEV = '\\uD83C\\uDD33'; // 🅳\n\n/**\n * Console method mappings for log types.\n */\nconst CONSOLE_METHOD_MAP: Record<string, keyof Console> = {\n debug: 'log',\n success: 'log',\n} as const;\n\n/**\n * Checks if the current environment is production.\n * Cached for performance - evaluated once at a module load.\n */\nconst isProduction = (): boolean => {\n // Browser environment (Vite, Webpack, etc.)\n if (typeof window !== 'undefined' && (import.meta as any)?.env?.NODE_ENV) {\n return (import.meta as any).env.NODE_ENV === 'production';\n }\n\n // Node.js environment\n // @ts-expect-error\n if (typeof process !== 'undefined' && (process as any).env?.NODE_ENV) {\n // @ts-expect-error\n return (process as any).env.NODE_ENV === 'production';\n }\n\n return false;\n};\n\n// Cache the result to avoid repeated checks\nconst IS_PROD = isProduction();\n\nexport type LogitInstance = typeof Logit;\nexport type LogitType = 'debug' | 'trace' | 'time' | 'table' | 'info' | 'success' | 'warn' | 'error';\nexport type LogitColors = Exclude<LogitType, 'table'> | 'group' | 'ns';\nexport type LogitLevel = LogitType | 'off';\nexport type LogitRemoteOptions = {\n handler?: (...args: any[]) => void;\n logLevel: LogitLevel;\n};\nexport type LogitOptions = {\n environment?: boolean;\n variant?: 'text' | 'symbol' | 'icon';\n logLevel?: LogitLevel;\n namespace?: string;\n remote?: LogitRemoteOptions;\n timestamp?: boolean;\n};\nexport type LogitTheme = { color: string; bg: string; border: string; icon?: string; symbol?: string };\n\n/**\n * Detects dark mode preference at module load time.\n * Note: This is intentionally static and won't update if the user changes their theme.\n */\nconst isDark = typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches;\n\nconst Theme: Readonly<Record<LogitColors, LogitTheme>> = {\n debug: { bg: '#616161', border: '#424242', color: '#fff', icon: '\\u2615', symbol: '\\uD83C\\uDD73' },\n error: { bg: '#d32f2f', border: '#c62828', color: '#fff', icon: '\\u2718', symbol: '\\uD83C\\uDD74' },\n group: { bg: '#546e7a', border: '#455a64', color: '#fff', icon: '\\u26AD', symbol: '\\uD83C\\uDD76' },\n info: { bg: '#1976d2', border: '#1565c0', color: '#fff', icon: '\\u2139', symbol: '\\uD83C\\uDD78' },\n ns: isDark\n ? { bg: '#fafafa', border: '#c7c7c7', color: '#000' }\n : { bg: '#424242', border: '#212121', color: '#fff' },\n success: { bg: '#689f38', border: '#558b2f', color: '#fff', icon: '\\u2714', symbol: '\\uD83C\\uDD82' },\n time: { bg: '#0097a7', border: '#00838f', color: '#fff', icon: '\\u23F2', symbol: '\\uD83C\\uDD83' },\n trace: { bg: '#d81b60', border: '#c2185b', color: '#fff', icon: '\\u26e2', symbol: '\\uD83C\\uDD83' },\n warn: { bg: '#ffb300', border: '#ffa000', color: '#fff', icon: '\\u26a0', symbol: '\\uD83C\\uDD86' },\n};\n\n// biome-ignore assist/source/useSortedKeys: -\nconst logLevel: Readonly<Record<LogitLevel, number>> = {\n debug: 0,\n trace: 1,\n time: 2,\n table: 3,\n info: 4,\n success: 5,\n warn: 6,\n error: 7,\n off: 8,\n};\n\nconst state: Required<LogitOptions> = {\n environment: true,\n logLevel: 'debug',\n namespace: '',\n remote: { handler: undefined, logLevel: 'off' },\n timestamp: true,\n variant: 'symbol',\n};\n\n/**\n * Determines if a log message should be shown based on the current log level.\n */\nconst shouldLog = (type: LogitType): boolean => logLevel[state.logLevel] <= logLevel[type];\n\n/**\n * Gets the current timestamp in ISO format (HH:MM:SS.mmm).\n */\nconst getCurrentTimestamp = (): string => new Date().toISOString().slice(11, 23);\n\n/**\n * Gets the environment indicator symbol.\n */\nconst getEnvIndicator = (): string => (IS_PROD ? ENV_PROD : ENV_DEV);\n\n/**\n * Sends log data to remote handler if configured.\n */\nconst sendRemoteLog = (type: LogitType, args: any[]): void => {\n if (state.remote.handler && logLevel[state.remote.logLevel] <= logLevel[type]) {\n state.remote.handler(type, ...args);\n }\n};\n\n/**\n * Gets the console method for a given log type.\n */\nconst getConsoleMethod = (type: LogitType): keyof Console => {\n return (CONSOLE_METHOD_MAP[type] || type) as keyof Console;\n};\n\n/**\n * CSS style constants for consistent formatting.\n */\nconst BASE_BORDER_STYLE = 'border: 1px solid';\nconst BASE_BORDER_RADIUS = 'border-radius: 4px';\nconst NAMESPACE_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter';\n\n/**\n * Generates CSS styles for log messages based on theme and variant.\n */\nconst style = (type: LogitColors, extra = ''): string => {\n const { bg, color, border } = Theme[type];\n const baseStyle = `color: ${bg}; ${BASE_BORDER_STYLE} ${border}; ${BASE_BORDER_RADIUS}`;\n\n switch (state.variant) {\n case 'symbol':\n return `${baseStyle}; padding: 1px 1px 0${extra}`;\n case 'icon':\n return `${baseStyle}; padding: 0 3px${extra}`;\n default:\n return `background: ${bg}; color: ${color}; ${BASE_BORDER_STYLE} ${border}; ${BASE_BORDER_RADIUS}; font-weight: bold; padding: 0 3px${extra}`;\n }\n};\n\n/**\n * Gets the display value for a log type based on current variant.\n */\nconst getDisplayValue = (type: LogitType): string => {\n const theme = Theme[type as LogitColors];\n const { variant } = state;\n\n // For 'text' variant or if the variant key doesn't exist, use uppercase type\n if (variant === 'text' || !theme[variant]) {\n return type.toUpperCase();\n }\n\n return theme[variant] as string;\n};\n\n/**\n * Builds the format string and style parts for browser console logging.\n */\nfunction buildBrowserLogParts(type: LogitType): { format: string; parts: string[] } {\n const { namespace, timestamp, environment } = state;\n\n let format = `%c${getDisplayValue(type)}%c`;\n const parts: string[] = [style(type as LogitColors), ''];\n\n if (namespace) {\n format += ` %c${namespace}%c`;\n parts.push(style('ns', `; ${NAMESPACE_STYLE}`), '');\n }\n\n if (environment) {\n format += ` %c${getEnvIndicator()}%c`;\n parts.push('color: darkgray', '');\n }\n\n if (timestamp) {\n format += ` %c${getCurrentTimestamp()}%c`;\n parts.push('color: gray', '');\n }\n\n return { format, parts };\n}\n\n/**\n * Logs messages to the console with styling and metadata.\n */\nconst log = (type: LogitType, ...args: any[]): void => {\n // Server-side logging (Node.js)\n if (typeof window === 'undefined') {\n const consoleMethod = console[getConsoleMethod(type)] as (...a: any[]) => void;\n consoleMethod(`${getDisplayValue(type)} | ${getEnvIndicator()} |`, ...args);\n return;\n }\n\n // Check log level\n if (!shouldLog(type)) return;\n\n // Browser-side logging with styling\n const { format, parts } = buildBrowserLogParts(type);\n const consoleMethod = console[getConsoleMethod(type)] as (...a: any[]) => void;\n\n consoleMethod(format, ...parts, ...args);\n sendRemoteLog(type, args);\n};\n\n/**\n * Formats the elapsed time for display.\n */\nconst formatElapsedTime = (startTime: number): string => {\n const elapsed = Math.floor(Date.now() - startTime);\n return elapsed ? `${elapsed}ms` : '';\n};\n\nexport const Logit = {\n /**\n * Asserts a condition and logs an error if it's false.\n */\n assert: (valid: boolean, message: string, context: Record<string, any>): void =>\n console.assert(valid, message, context),\n\n debug: (...args: any[]): void => log('debug', ...args),\n error: (...args: any[]): void => log('error', ...args),\n\n /**\n * Gets the current log level.\n */\n getLevel: (): LogitLevel => state.logLevel,\n\n /**\n * Gets the current namespace prefix.\n */\n getPrefix: (): string => state.namespace,\n\n /**\n * Gets whether timestamps are shown.\n */\n getTimestamp: (): boolean => state.timestamp,\n\n /**\n * Creates a collapsed group in the console.\n */\n groupCollapsed: (text: string, label = 'GROUP', time = Date.now()): void => {\n if (!shouldLog('success')) return;\n\n const elapsed = formatElapsedTime(time);\n const env = getEnvIndicator();\n const timestamp = state.timestamp ? getCurrentTimestamp() : '';\n\n console.groupCollapsed(\n `%c${label}%c${state.namespace}%c${env}%c${timestamp}%c${elapsed}%c${text}`,\n style('group', '; margin-right: 6px; padding: 1px 3px 0'),\n style('ns', `; ${NAMESPACE_STYLE}; margin-right: 6px`),\n 'color: darkgray; margin-right: 6px',\n 'color: gray; font-weight: lighter; margin-right: 6px',\n 'color: gray; font-weight: lighter; margin-right: 6px',\n 'color: inherit; font-weight: lighter',\n );\n },\n\n /**\n * Ends the current console group.\n */\n groupEnd: (): void => {\n if (shouldLog('success')) console.groupEnd();\n },\n\n info: (...args: any[]): void => log('info', ...args),\n\n /**\n * Initializes Logit with custom options.\n */\n initialise: (options: LogitOptions): void => {\n Object.assign(state, options);\n },\n\n /**\n * Sets the minimum log level to display.\n */\n setLogLevel: (level: LogitLevel): void => {\n state.logLevel = level;\n },\n\n /**\n * Sets the namespace prefix for all logs.\n */\n setPrefix: (namespace: string): void => {\n state.namespace = namespace;\n },\n\n /**\n * Configures remote logging options.\n */\n setRemote: (remote: LogitRemoteOptions): void => {\n state.remote = remote;\n },\n\n /**\n * Sets the log level for remote logging.\n */\n setRemoteLogLevel: (level: LogitLevel): void => {\n state.remote.logLevel = level;\n },\n\n /**\n * Sets the display variant (text, icon, or symbol).\n */\n setVariant: (variant: 'text' | 'icon' | 'symbol'): void => {\n state.variant = variant;\n },\n\n /**\n * Shows or hides the environment indicator.\n */\n showEnvironment: (value: boolean): void => {\n state.environment = value;\n },\n\n /**\n * Shows or hides timestamps in logs.\n */\n showTimestamp: (value: boolean): void => {\n state.timestamp = value;\n },\n\n success: (...args: any[]): void => log('success', ...args),\n\n /**\n * Displays data in a table format.\n */\n table: (...args: any[]): void => {\n if (shouldLog('table')) console.table(...args);\n },\n\n /**\n * Starts a timer with the given label.\n */\n time: (label: string): void => {\n if (shouldLog('time')) console.time(label);\n },\n\n /**\n * Ends a timer with the given label.\n */\n timeEnd: (label: string): void => {\n if (shouldLog('time')) console.timeEnd(label);\n },\n\n trace: (...args: any[]): void => log('trace', ...args),\n warn: (...args: any[]): void => log('warn', ...args),\n};\n"],"names":["ENV_PROD","ENV_DEV","CONSOLE_METHOD_MAP","isProduction","__vite_import_meta_env__","IS_PROD","isDark","Theme","logLevel","state","shouldLog","type","getCurrentTimestamp","getEnvIndicator","sendRemoteLog","args","getConsoleMethod","BASE_BORDER_STYLE","BASE_BORDER_RADIUS","NAMESPACE_STYLE","style","extra","bg","color","border","baseStyle","getDisplayValue","theme","variant","buildBrowserLogParts","namespace","timestamp","environment","format","parts","log","consoleMethod","formatElapsedTime","startTime","elapsed","Logit","valid","message","context","text","label","time","env","options","level","remote","value"],"mappings":"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"}
1
+ {"version":3,"file":"logit.cjs","sources":["../src/logit.ts"],"sourcesContent":["/** biome-ignore-all lint/suspicious/noAssignInExpressions: - */\n/** biome-ignore-all lint/suspicious/noExplicitAny: - */\n\n/**\n * Environment indicator symbols.\n */\nconst ENV_PROD = '\\uD83C\\uDD3F'; // 🅿\nconst ENV_DEV = '\\uD83C\\uDD33'; // 🅳\n\n/**\n * Console method mappings for log types.\n */\nconst CONSOLE_METHOD_MAP: Record<string, keyof Console> = {\n debug: 'log',\n success: 'log',\n} as const;\n\n/**\n * Checks if the current environment is production.\n * Cached for performance - evaluated once at a module load.\n *\n * Note: import.meta.env is available in Vite/Bundlers but may be undefined in some environments.\n * Using 'any' cast is necessary for cross-environment compatibility.\n */\nconst isProduction = (): boolean => {\n // Browser environment (Vite, Webpack, etc.)\n // import.meta.env may be undefined in some bundlers - safe check with optional chaining\n if (typeof window !== 'undefined' && (import.meta as any)?.env?.NODE_ENV) {\n return (import.meta as any).env.NODE_ENV === 'production';\n }\n\n // Node.js environment\n // @ts-expect-error - process.env exists in Node.js but not in browser\n if (typeof process !== 'undefined' && (process as any).env?.NODE_ENV) {\n // @ts-expect-error - process.env exists in Node.js\n return (process as any).env.NODE_ENV === 'production';\n }\n\n return false;\n};\n\n// Cache the result to avoid repeated checks\nconst IS_PROD = isProduction();\n\nexport type LogitInstance = typeof Logit;\nexport type LogitType = 'debug' | 'trace' | 'time' | 'table' | 'info' | 'success' | 'warn' | 'error';\nexport type LogitColors = Exclude<LogitType, 'table'> | 'group' | 'ns';\nexport type LogitLevel = LogitType | 'off';\nexport type LogitRemoteOptions = {\n handler?: (...args: any[]) => void;\n logLevel: LogitLevel;\n};\nexport type LogitOptions = {\n environment?: boolean;\n variant?: 'text' | 'symbol' | 'icon';\n logLevel?: LogitLevel;\n namespace?: string;\n remote?: LogitRemoteOptions;\n timestamp?: boolean;\n};\nexport type LogitTheme = { color: string; bg: string; border: string; icon?: string; symbol?: string };\n\n/**\n * Scoped logger interface with namespaced logging methods.\n */\nexport type ScopedLogger = {\n debug: (...args: any[]) => void;\n error: (...args: any[]) => void;\n info: (...args: any[]) => void;\n success: (...args: any[]) => void;\n trace: (...args: any[]) => void;\n warn: (...args: any[]) => void;\n};\n\n/**\n * Detects dark mode preference at module load time.\n * Note: This is intentionally static and won't update if the user changes their theme.\n */\nconst isDark = typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches;\n\nconst Theme: Readonly<Record<LogitColors, LogitTheme>> = {\n debug: { bg: '#616161', border: '#424242', color: '#fff', icon: '\\u2615', symbol: '\\uD83C\\uDD73' },\n error: { bg: '#d32f2f', border: '#c62828', color: '#fff', icon: '\\u2718', symbol: '\\uD83C\\uDD74' },\n group: { bg: '#546e7a', border: '#455a64', color: '#fff', icon: '\\u26AD', symbol: '\\uD83C\\uDD76' },\n info: { bg: '#1976d2', border: '#1565c0', color: '#fff', icon: '\\u2139', symbol: '\\uD83C\\uDD78' },\n ns: isDark\n ? { bg: '#fafafa', border: '#c7c7c7', color: '#000' }\n : { bg: '#424242', border: '#212121', color: '#fff' },\n success: { bg: '#689f38', border: '#558b2f', color: '#fff', icon: '\\u2714', symbol: '\\uD83C\\uDD82' },\n time: { bg: '#0097a7', border: '#00838f', color: '#fff', icon: '\\u23F2', symbol: '\\uD83C\\uDD83' },\n trace: { bg: '#d81b60', border: '#c2185b', color: '#fff', icon: '\\u26e2', symbol: '\\uD83C\\uDD83' },\n warn: { bg: '#ffb300', border: '#ffa000', color: '#fff', icon: '\\u26a0', symbol: '\\uD83C\\uDD86' },\n};\n\n// biome-ignore assist/source/useSortedKeys: -\nconst logLevel: Readonly<Record<LogitLevel, number>> = {\n debug: 0,\n trace: 1,\n time: 2,\n table: 3,\n info: 4,\n success: 5,\n warn: 6,\n error: 7,\n off: 8,\n};\n\nconst state: Required<LogitOptions> = {\n environment: true,\n logLevel: 'debug',\n namespace: '',\n remote: { handler: undefined, logLevel: 'off' },\n timestamp: true,\n variant: 'symbol',\n};\n\n/**\n * Determines if a log message should be shown based on the current log level.\n */\nconst shouldLog = (type: LogitType): boolean => logLevel[state.logLevel] <= logLevel[type];\n\n/**\n * Gets the current timestamp in ISO format (HH:MM:SS.mmm).\n */\nconst getCurrentTimestamp = (): string => new Date().toISOString().slice(11, 23);\n\n/**\n * Gets the environment indicator symbol.\n */\nconst getEnvIndicator = (): string => (IS_PROD ? ENV_PROD : ENV_DEV);\n\n/**\n * Sends log data to a remote handler if configured.\n */\nconst sendRemoteLog = (type: LogitType, args: any[]): void => {\n if (state.remote.handler && logLevel[state.remote.logLevel] <= logLevel[type]) {\n Promise.resolve().then(() => {\n state.remote.handler?.(type, {\n args,\n environment: IS_PROD ? 'production' : 'development',\n namespace: state.namespace || undefined,\n timestamp: state.timestamp ? getCurrentTimestamp() : undefined,\n });\n });\n }\n};\n\n/**\n * Gets the console method for a given log type.\n */\nconst getConsoleMethod = (type: LogitType): keyof Console => {\n return (CONSOLE_METHOD_MAP[type] || type) as keyof Console;\n};\n\n/**\n * CSS style constants for consistent formatting.\n */\nconst BASE_BORDER_STYLE = 'border: 1px solid';\nconst BASE_BORDER_RADIUS = 'border-radius: 4px';\nconst NAMESPACE_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;';\n\n/**\n * Generates CSS styles for log messages based on theme and variant.\n *\n * @param type - Log type color scheme\n * @param extra - Additional CSS to append (should include leading semicolon if needed)\n */\nconst style = (type: LogitColors, extra = ''): string => {\n const { bg, color, border } = Theme[type];\n const baseStyle = `${BASE_BORDER_STYLE} ${border}; ${BASE_BORDER_RADIUS}`;\n\n switch (state.variant) {\n case 'symbol':\n // Symbol variant: colored text on a transparent background\n return `color: ${bg}; ${baseStyle}; padding: 1px 1px 0${extra}`;\n case 'icon':\n // Icon variant: colored text on a transparent background\n return `color: ${bg}; ${baseStyle}; padding: 0 3px${extra}`;\n default:\n // Text variant: white text on a colored background\n return `background: ${bg}; color: ${color}; ${baseStyle}; font-weight: bold; padding: 0 3px${extra}`;\n }\n};\n\n/**\n * Gets the display value for a log type based on the current variant.\n */\nconst getDisplayValue = (type: LogitType): string => {\n const theme = Theme[type as LogitColors];\n const { variant } = state;\n\n // For 'text' variant or if the variant property doesn't exist in theme, use uppercase type\n if (variant === 'text' || !theme || !theme[variant]) {\n return type.toUpperCase();\n }\n\n return theme[variant] as string;\n};\n\n/**\n * Builds the format string and style parts for browser console logging.\n */\nfunction buildBrowserLogParts(type: LogitType): { format: string; parts: string[] } {\n const { namespace, timestamp, environment } = state;\n\n let format = `%c${getDisplayValue(type)}%c`;\n const parts: string[] = [style(type as LogitColors), ''];\n\n if (namespace) {\n format += ` %c${namespace}%c`;\n parts.push(style('ns', `; ${NAMESPACE_STYLE}`), '');\n }\n\n if (environment) {\n format += ` %c${getEnvIndicator()}%c`;\n parts.push('color: darkgray', '');\n }\n\n if (timestamp) {\n format += ` %c${getCurrentTimestamp()}%c`;\n parts.push('color: gray', '');\n }\n\n return { format, parts };\n}\n\n/**\n * Logs messages to the console with styling and metadata.\n */\nconst log = (type: LogitType, ...args: any[]): void => {\n // Server-side logging (Node.js)\n if (typeof window === 'undefined') {\n const consoleMethod = console[getConsoleMethod(type)] as (...a: any[]) => void;\n consoleMethod(`${getDisplayValue(type)} | ${getEnvIndicator()} |`, ...args);\n return;\n }\n\n // Check the log level\n if (!shouldLog(type)) return;\n\n // Browser-side logging with styling\n const { format, parts } = buildBrowserLogParts(type);\n const consoleMethod = console[getConsoleMethod(type)] as (...a: any[]) => void;\n\n consoleMethod(format, ...parts, ...args);\n sendRemoteLog(type, args);\n};\n\n/**\n * Formats the elapsed time for display.\n */\nconst formatElapsedTime = (startTime: number): string => {\n const elapsed = Math.floor(Date.now() - startTime);\n return elapsed ? `${elapsed}ms` : '';\n};\n\nexport const Logit = {\n /**\n * Asserts a condition and logs an error if it's false.\n */\n assert: (valid: boolean, message: string, context: Record<string, any>): void =>\n console.assert(valid, message, context),\n\n debug: (...args: any[]): void => log('debug', ...args),\n error: (...args: any[]): void => log('error', ...args),\n\n /**\n * Gets whether the environment indicator is shown.\n */\n getEnvironment: (): boolean => state.environment,\n\n /**\n * Gets the current log level.\n */\n getLevel: (): LogitLevel => state.logLevel,\n\n /**\n * Gets the current namespace prefix.\n */\n getPrefix: (): string => state.namespace,\n\n /**\n * Gets whether timestamps are shown.\n */\n getTimestamp: (): boolean => state.timestamp,\n\n /**\n * Gets the current display variant.\n */\n getVariant: (): 'text' | 'symbol' | 'icon' => state.variant,\n\n /**\n * Creates a collapsed group in the console.\n */\n groupCollapsed: (text: string, label = 'GROUP', time = Date.now()): void => {\n if (!shouldLog('success')) return;\n\n const elapsed = formatElapsedTime(time);\n const env = getEnvIndicator();\n const timestamp = state.timestamp ? getCurrentTimestamp() : '';\n\n console.groupCollapsed(\n `%c${label}%c${state.namespace}%c${env}%c${timestamp}%c${elapsed}%c${text}`,\n style('group', '; margin-right: 6px; padding: 1px 3px 0'),\n style('ns', `; ${NAMESPACE_STYLE}; margin-right: 6px`),\n 'color: darkgray; margin-right: 6px',\n 'color: gray; font-weight: lighter; margin-right: 6px',\n 'color: gray; font-weight: lighter; margin-right: 6px',\n 'color: inherit; font-weight: lighter',\n );\n },\n\n /**\n * Ends the current console group.\n */\n groupEnd: (): void => {\n if (shouldLog('success')) console.groupEnd();\n },\n\n info: (...args: any[]): void => log('info', ...args),\n\n /**\n * Creates a scoped logger with a namespaced prefix.\n * Does not mutate global state - returns an isolated logger instance.\n *\n * @param namespace - The namespace to prepend to all log messages\n * @returns A scoped logger with all logging methods\n *\n * @example\n * ```ts\n * const apiLogger = Logit.scope('api');\n * apiLogger.info('Request received'); // [API] Request received\n *\n * const dbLogger = Logit.scope('database');\n * dbLogger.error('Connection failed'); // [DATABASE] Connection failed\n * ```\n */\n scope: (namespace: string): ScopedLogger => {\n const originalNamespace = state.namespace;\n const scopedNamespace = originalNamespace ? `${originalNamespace}.${namespace}` : namespace;\n\n return {\n debug: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('debug', ...args);\n state.namespace = prev;\n },\n error: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('error', ...args);\n state.namespace = prev;\n },\n info: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('info', ...args);\n state.namespace = prev;\n },\n success: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('success', ...args);\n state.namespace = prev;\n },\n trace: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('trace', ...args);\n state.namespace = prev;\n },\n warn: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('warn', ...args);\n state.namespace = prev;\n },\n };\n },\n\n /**\n * Sets the minimum log level to display.\n */\n setLogLevel: (level: LogitLevel): void => {\n state.logLevel = level;\n },\n\n /**\n * Sets the namespace prefix for all logs.\n */\n setPrefix: (namespace: string): void => {\n state.namespace = namespace;\n },\n\n /**\n * Configures remote logging options.\n */\n setRemote: (remote: LogitRemoteOptions): void => {\n state.remote = remote;\n },\n\n /**\n * Sets the log level for remote logging.\n */\n setRemoteLogLevel: (level: LogitLevel): void => {\n state.remote.logLevel = level;\n },\n\n /**\n * Configures Logit with custom options.\n *\n * Note: The remote option will be merged with existing remote config,\n * not replaced entirely. To clear a remote handler, set remote.handler to undefined.\n */\n setup: (options: LogitOptions): void => {\n if (options.remote) {\n state.remote = { ...state.remote, ...options.remote };\n delete (options as any).remote; // Remove to avoid Object.assign overwrite\n }\n Object.assign(state, options);\n },\n\n /**\n * Sets the display variant (text, icon, or symbol).\n */\n setVariant: (variant: 'text' | 'icon' | 'symbol'): void => {\n state.variant = variant;\n },\n\n success: (...args: any[]): void => log('success', ...args),\n\n /**\n * Displays data in a table format.\n */\n table: (...args: any[]): void => {\n if (shouldLog('table')) console.table(...args);\n },\n\n /**\n * Starts a timer with the given label.\n */\n time: (label: string): void => {\n if (shouldLog('time')) console.time(label);\n },\n\n /**\n * Ends a timer with the given label.\n */\n timeEnd: (label: string): void => {\n if (shouldLog('time')) console.timeEnd(label);\n },\n\n /**\n * Toggles or sets the environment indicator visibility.\n * When called without arguments, toggles the current state.\n *\n * @param value - Optional boolean to explicitly set the state\n *\n * @example\n * ```ts\n * Logit.toggleEnvironment(); // Toggles current state\n * Logit.toggleEnvironment(true); // Shows environment indicator\n * Logit.toggleEnvironment(false); // Hides environment indicator\n * ```\n */\n toggleEnvironment: (value?: boolean): void => {\n state.environment = value ?? !state.environment;\n },\n\n /**\n * Toggles or sets timestamp visibility in logs.\n * When called without arguments, toggles the current state.\n *\n * @param value - Optional boolean to explicitly set the state\n *\n * @example\n * ```ts\n * Logit.toggleTimestamp(); // Toggles current state\n * Logit.toggleTimestamp(true); // Shows timestamps\n * Logit.toggleTimestamp(false); // Hides timestamps\n * ```\n */\n toggleTimestamp: (value?: boolean): void => {\n state.timestamp = value ?? !state.timestamp;\n },\n\n trace: (...args: any[]): void => log('trace', ...args),\n warn: (...args: any[]): void => log('warn', ...args),\n};\n"],"names":["ENV_PROD","ENV_DEV","CONSOLE_METHOD_MAP","isProduction","__vite_import_meta_env__","IS_PROD","isDark","Theme","logLevel","state","shouldLog","type","getCurrentTimestamp","getEnvIndicator","sendRemoteLog","args","getConsoleMethod","BASE_BORDER_STYLE","BASE_BORDER_RADIUS","NAMESPACE_STYLE","style","extra","bg","color","border","baseStyle","getDisplayValue","theme","variant","buildBrowserLogParts","namespace","timestamp","environment","format","parts","log","consoleMethod","formatElapsedTime","startTime","elapsed","Logit","valid","message","context","text","label","time","env","originalNamespace","scopedNamespace","prev","level","remote","options","value"],"mappings":"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"}
package/dist/logit.js CHANGED
@@ -1,18 +1,18 @@
1
- const $ = {};
2
- const v = {
1
+ const h = {};
2
+ const E = {
3
3
  debug: "log",
4
4
  success: "log"
5
- }, w = () => typeof window < "u" && $?.NODE_ENV ? !1 : typeof process < "u" && process.env?.NODE_ENV ? process.env.NODE_ENV === "production" : !1, _ = w(), L = typeof window < "u" && window.matchMedia?.("(prefers-color-scheme: dark)").matches, b = {
5
+ }, $ = () => typeof window < "u" && h?.NODE_ENV ? !1 : typeof process < "u" && process.env?.NODE_ENV ? process.env.NODE_ENV === "production" : !1, g = $(), w = typeof window < "u" && window.matchMedia?.("(prefers-color-scheme: dark)").matches, u = {
6
6
  debug: { bg: "#616161", border: "#424242", color: "#fff", icon: "☕", symbol: "🅳" },
7
7
  error: { bg: "#d32f2f", border: "#c62828", color: "#fff", icon: "✘", symbol: "🅴" },
8
8
  group: { bg: "#546e7a", border: "#455a64", color: "#fff", icon: "⚭", symbol: "🅶" },
9
9
  info: { bg: "#1976d2", border: "#1565c0", color: "#fff", icon: "ℹ", symbol: "🅸" },
10
- ns: L ? { bg: "#fafafa", border: "#c7c7c7", color: "#000" } : { bg: "#424242", border: "#212121", color: "#fff" },
10
+ ns: w ? { bg: "#fafafa", border: "#c7c7c7", color: "#000" } : { bg: "#424242", border: "#212121", color: "#fff" },
11
11
  success: { bg: "#689f38", border: "#558b2f", color: "#fff", icon: "✔", symbol: "🆂" },
12
12
  time: { bg: "#0097a7", border: "#00838f", color: "#fff", icon: "⏲", symbol: "🆃" },
13
13
  trace: { bg: "#d81b60", border: "#c2185b", color: "#fff", icon: "⛢", symbol: "🆃" },
14
14
  warn: { bg: "#ffb300", border: "#ffa000", color: "#fff", icon: "⚠", symbol: "🆆" }
15
- }, l = {
15
+ }, m = {
16
16
  debug: 0,
17
17
  trace: 1,
18
18
  time: 2,
@@ -22,76 +22,91 @@ const v = {
22
22
  warn: 6,
23
23
  error: 7,
24
24
  off: 8
25
- }, r = {
25
+ }, o = {
26
26
  environment: !0,
27
27
  logLevel: "debug",
28
28
  namespace: "",
29
29
  remote: { handler: void 0, logLevel: "off" },
30
30
  timestamp: !0,
31
31
  variant: "symbol"
32
- }, a = (e) => l[r.logLevel] <= l[e], u = () => (/* @__PURE__ */ new Date()).toISOString().slice(11, 23), d = () => _ ? "🄿" : "🄳", x = (e, o) => {
33
- r.remote.handler && l[r.remote.logLevel] <= l[e] && r.remote.handler(e, ...o);
34
- }, g = (e) => v[e] || e, m = "border: 1px solid", p = "border-radius: 4px", h = "border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter", f = (e, o = "") => {
35
- const { bg: t, color: c, border: n } = b[e], s = `color: ${t}; ${m} ${n}; ${p}`;
36
- switch (r.variant) {
32
+ }, i = (e) => m[o.logLevel] <= m[e], p = () => (/* @__PURE__ */ new Date()).toISOString().slice(11, 23), d = () => g ? "🄿" : "🄳", _ = (e, n) => {
33
+ o.remote.handler && m[o.remote.logLevel] <= m[e] && Promise.resolve().then(() => {
34
+ o.remote.handler?.(e, {
35
+ args: n,
36
+ environment: g ? "production" : "development",
37
+ namespace: o.namespace || void 0,
38
+ timestamp: o.timestamp ? p() : void 0
39
+ });
40
+ });
41
+ }, f = (e) => E[e] || e, L = "border: 1px solid", x = "border-radius: 4px", b = "border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;", l = (e, n = "") => {
42
+ const { bg: r, color: s, border: t } = u[e], c = `${L} ${t}; ${x}`;
43
+ switch (o.variant) {
37
44
  case "symbol":
38
- return `${s}; padding: 1px 1px 0${o}`;
45
+ return `color: ${r}; ${c}; padding: 1px 1px 0${n}`;
39
46
  case "icon":
40
- return `${s}; padding: 0 3px${o}`;
47
+ return `color: ${r}; ${c}; padding: 0 3px${n}`;
41
48
  default:
42
- return `background: ${t}; color: ${c}; ${m} ${n}; ${p}; font-weight: bold; padding: 0 3px${o}`;
49
+ return `background: ${r}; color: ${s}; ${c}; font-weight: bold; padding: 0 3px${n}`;
43
50
  }
44
- }, E = (e) => {
45
- const o = b[e], { variant: t } = r;
46
- return t === "text" || !o[t] ? e.toUpperCase() : o[t];
51
+ }, v = (e) => {
52
+ const n = u[e], { variant: r } = o;
53
+ return r === "text" || !n || !n[r] ? e.toUpperCase() : n[r];
47
54
  };
48
55
  function D(e) {
49
- const { namespace: o, timestamp: t, environment: c } = r;
50
- let n = `%c${E(e)}%c`;
51
- const s = [f(e), ""];
52
- return o && (n += ` %c${o}%c`, s.push(f("ns", `; ${h}`), "")), c && (n += ` %c${d()}%c`, s.push("color: darkgray", "")), t && (n += ` %c${u()}%c`, s.push("color: gray", "")), { format: n, parts: s };
56
+ const { namespace: n, timestamp: r, environment: s } = o;
57
+ let t = `%c${v(e)}%c`;
58
+ const c = [l(e), ""];
59
+ return n && (t += ` %c${n}%c`, c.push(l("ns", `; ${b}`), "")), s && (t += ` %c${d()}%c`, c.push("color: darkgray", "")), r && (t += ` %c${p()}%c`, c.push("color: gray", "")), { format: t, parts: c };
53
60
  }
54
- const i = (e, ...o) => {
61
+ const a = (e, ...n) => {
55
62
  if (typeof window > "u") {
56
- const s = console[g(e)];
57
- s(`${E(e)} | ${d()} |`, ...o);
63
+ const c = console[f(e)];
64
+ c(`${v(e)} | ${d()} |`, ...n);
58
65
  return;
59
66
  }
60
- if (!a(e)) return;
61
- const { format: t, parts: c } = D(e), n = console[g(e)];
62
- n(t, ...c, ...o), x(e, o);
63
- }, O = (e) => {
64
- const o = Math.floor(Date.now() - e);
65
- return o ? `${o}ms` : "";
66
- }, y = {
67
+ if (!i(e)) return;
68
+ const { format: r, parts: s } = D(e), t = console[f(e)];
69
+ t(r, ...s, ...n), _(e, n);
70
+ }, N = (e) => {
71
+ const n = Math.floor(Date.now() - e);
72
+ return n ? `${n}ms` : "";
73
+ }, O = {
67
74
  /**
68
75
  * Asserts a condition and logs an error if it's false.
69
76
  */
70
- assert: (e, o, t) => console.assert(e, o, t),
71
- debug: (...e) => i("debug", ...e),
72
- error: (...e) => i("error", ...e),
77
+ assert: (e, n, r) => console.assert(e, n, r),
78
+ debug: (...e) => a("debug", ...e),
79
+ error: (...e) => a("error", ...e),
80
+ /**
81
+ * Gets whether the environment indicator is shown.
82
+ */
83
+ getEnvironment: () => o.environment,
73
84
  /**
74
85
  * Gets the current log level.
75
86
  */
76
- getLevel: () => r.logLevel,
87
+ getLevel: () => o.logLevel,
77
88
  /**
78
89
  * Gets the current namespace prefix.
79
90
  */
80
- getPrefix: () => r.namespace,
91
+ getPrefix: () => o.namespace,
81
92
  /**
82
93
  * Gets whether timestamps are shown.
83
94
  */
84
- getTimestamp: () => r.timestamp,
95
+ getTimestamp: () => o.timestamp,
96
+ /**
97
+ * Gets the current display variant.
98
+ */
99
+ getVariant: () => o.variant,
85
100
  /**
86
101
  * Creates a collapsed group in the console.
87
102
  */
88
- groupCollapsed: (e, o = "GROUP", t = Date.now()) => {
89
- if (!a("success")) return;
90
- const c = O(t), n = d(), s = r.timestamp ? u() : "";
103
+ groupCollapsed: (e, n = "GROUP", r = Date.now()) => {
104
+ if (!i("success")) return;
105
+ const s = N(r), t = d(), c = o.timestamp ? p() : "";
91
106
  console.groupCollapsed(
92
- `%c${o}%c${r.namespace}%c${n}%c${s}%c${c}%c${e}`,
93
- f("group", "; margin-right: 6px; padding: 1px 3px 0"),
94
- f("ns", `; ${h}; margin-right: 6px`),
107
+ `%c${n}%c${o.namespace}%c${t}%c${c}%c${s}%c${e}`,
108
+ l("group", "; margin-right: 6px; padding: 1px 3px 0"),
109
+ l("ns", `; ${b}; margin-right: 6px`),
95
110
  "color: darkgray; margin-right: 6px",
96
111
  "color: gray; font-weight: lighter; margin-right: 6px",
97
112
  "color: gray; font-weight: lighter; margin-right: 6px",
@@ -102,80 +117,148 @@ const i = (e, ...o) => {
102
117
  * Ends the current console group.
103
118
  */
104
119
  groupEnd: () => {
105
- a("success") && console.groupEnd();
120
+ i("success") && console.groupEnd();
106
121
  },
107
- info: (...e) => i("info", ...e),
122
+ info: (...e) => a("info", ...e),
108
123
  /**
109
- * Initializes Logit with custom options.
124
+ * Creates a scoped logger with a namespaced prefix.
125
+ * Does not mutate global state - returns an isolated logger instance.
126
+ *
127
+ * @param namespace - The namespace to prepend to all log messages
128
+ * @returns A scoped logger with all logging methods
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * const apiLogger = Logit.scope('api');
133
+ * apiLogger.info('Request received'); // [API] Request received
134
+ *
135
+ * const dbLogger = Logit.scope('database');
136
+ * dbLogger.error('Connection failed'); // [DATABASE] Connection failed
137
+ * ```
110
138
  */
111
- initialise: (e) => {
112
- Object.assign(r, e);
139
+ scope: (e) => {
140
+ const n = o.namespace, r = n ? `${n}.${e}` : e;
141
+ return {
142
+ debug: (...s) => {
143
+ const t = o.namespace;
144
+ o.namespace = r, a("debug", ...s), o.namespace = t;
145
+ },
146
+ error: (...s) => {
147
+ const t = o.namespace;
148
+ o.namespace = r, a("error", ...s), o.namespace = t;
149
+ },
150
+ info: (...s) => {
151
+ const t = o.namespace;
152
+ o.namespace = r, a("info", ...s), o.namespace = t;
153
+ },
154
+ success: (...s) => {
155
+ const t = o.namespace;
156
+ o.namespace = r, a("success", ...s), o.namespace = t;
157
+ },
158
+ trace: (...s) => {
159
+ const t = o.namespace;
160
+ o.namespace = r, a("trace", ...s), o.namespace = t;
161
+ },
162
+ warn: (...s) => {
163
+ const t = o.namespace;
164
+ o.namespace = r, a("warn", ...s), o.namespace = t;
165
+ }
166
+ };
113
167
  },
114
168
  /**
115
169
  * Sets the minimum log level to display.
116
170
  */
117
171
  setLogLevel: (e) => {
118
- r.logLevel = e;
172
+ o.logLevel = e;
119
173
  },
120
174
  /**
121
175
  * Sets the namespace prefix for all logs.
122
176
  */
123
177
  setPrefix: (e) => {
124
- r.namespace = e;
178
+ o.namespace = e;
125
179
  },
126
180
  /**
127
181
  * Configures remote logging options.
128
182
  */
129
183
  setRemote: (e) => {
130
- r.remote = e;
184
+ o.remote = e;
131
185
  },
132
186
  /**
133
187
  * Sets the log level for remote logging.
134
188
  */
135
189
  setRemoteLogLevel: (e) => {
136
- r.remote.logLevel = e;
137
- },
138
- /**
139
- * Sets the display variant (text, icon, or symbol).
140
- */
141
- setVariant: (e) => {
142
- r.variant = e;
190
+ o.remote.logLevel = e;
143
191
  },
144
192
  /**
145
- * Shows or hides the environment indicator.
193
+ * Configures Logit with custom options.
194
+ *
195
+ * Note: The remote option will be merged with existing remote config,
196
+ * not replaced entirely. To clear a remote handler, set remote.handler to undefined.
146
197
  */
147
- showEnvironment: (e) => {
148
- r.environment = e;
198
+ setup: (e) => {
199
+ e.remote && (o.remote = { ...o.remote, ...e.remote }, delete e.remote), Object.assign(o, e);
149
200
  },
150
201
  /**
151
- * Shows or hides timestamps in logs.
202
+ * Sets the display variant (text, icon, or symbol).
152
203
  */
153
- showTimestamp: (e) => {
154
- r.timestamp = e;
204
+ setVariant: (e) => {
205
+ o.variant = e;
155
206
  },
156
- success: (...e) => i("success", ...e),
207
+ success: (...e) => a("success", ...e),
157
208
  /**
158
209
  * Displays data in a table format.
159
210
  */
160
211
  table: (...e) => {
161
- a("table") && console.table(...e);
212
+ i("table") && console.table(...e);
162
213
  },
163
214
  /**
164
215
  * Starts a timer with the given label.
165
216
  */
166
217
  time: (e) => {
167
- a("time") && console.time(e);
218
+ i("time") && console.time(e);
168
219
  },
169
220
  /**
170
221
  * Ends a timer with the given label.
171
222
  */
172
223
  timeEnd: (e) => {
173
- a("time") && console.timeEnd(e);
224
+ i("time") && console.timeEnd(e);
225
+ },
226
+ /**
227
+ * Toggles or sets the environment indicator visibility.
228
+ * When called without arguments, toggles the current state.
229
+ *
230
+ * @param value - Optional boolean to explicitly set the state
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * Logit.toggleEnvironment(); // Toggles current state
235
+ * Logit.toggleEnvironment(true); // Shows environment indicator
236
+ * Logit.toggleEnvironment(false); // Hides environment indicator
237
+ * ```
238
+ */
239
+ toggleEnvironment: (e) => {
240
+ o.environment = e ?? !o.environment;
241
+ },
242
+ /**
243
+ * Toggles or sets timestamp visibility in logs.
244
+ * When called without arguments, toggles the current state.
245
+ *
246
+ * @param value - Optional boolean to explicitly set the state
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * Logit.toggleTimestamp(); // Toggles current state
251
+ * Logit.toggleTimestamp(true); // Shows timestamps
252
+ * Logit.toggleTimestamp(false); // Hides timestamps
253
+ * ```
254
+ */
255
+ toggleTimestamp: (e) => {
256
+ o.timestamp = e ?? !o.timestamp;
174
257
  },
175
- trace: (...e) => i("trace", ...e),
176
- warn: (...e) => i("warn", ...e)
258
+ trace: (...e) => a("trace", ...e),
259
+ warn: (...e) => a("warn", ...e)
177
260
  };
178
261
  export {
179
- y as Logit
262
+ O as Logit
180
263
  };
181
264
  //# sourceMappingURL=logit.js.map
package/dist/logit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"logit.js","sources":["../src/logit.ts"],"sourcesContent":["/** biome-ignore-all lint/suspicious/noAssignInExpressions: - */\n/** biome-ignore-all lint/suspicious/noExplicitAny: - */\n\n/**\n * Environment indicator symbols.\n */\nconst ENV_PROD = '\\uD83C\\uDD3F'; // 🅿\nconst ENV_DEV = '\\uD83C\\uDD33'; // 🅳\n\n/**\n * Console method mappings for log types.\n */\nconst CONSOLE_METHOD_MAP: Record<string, keyof Console> = {\n debug: 'log',\n success: 'log',\n} as const;\n\n/**\n * Checks if the current environment is production.\n * Cached for performance - evaluated once at a module load.\n */\nconst isProduction = (): boolean => {\n // Browser environment (Vite, Webpack, etc.)\n if (typeof window !== 'undefined' && (import.meta as any)?.env?.NODE_ENV) {\n return (import.meta as any).env.NODE_ENV === 'production';\n }\n\n // Node.js environment\n // @ts-expect-error\n if (typeof process !== 'undefined' && (process as any).env?.NODE_ENV) {\n // @ts-expect-error\n return (process as any).env.NODE_ENV === 'production';\n }\n\n return false;\n};\n\n// Cache the result to avoid repeated checks\nconst IS_PROD = isProduction();\n\nexport type LogitInstance = typeof Logit;\nexport type LogitType = 'debug' | 'trace' | 'time' | 'table' | 'info' | 'success' | 'warn' | 'error';\nexport type LogitColors = Exclude<LogitType, 'table'> | 'group' | 'ns';\nexport type LogitLevel = LogitType | 'off';\nexport type LogitRemoteOptions = {\n handler?: (...args: any[]) => void;\n logLevel: LogitLevel;\n};\nexport type LogitOptions = {\n environment?: boolean;\n variant?: 'text' | 'symbol' | 'icon';\n logLevel?: LogitLevel;\n namespace?: string;\n remote?: LogitRemoteOptions;\n timestamp?: boolean;\n};\nexport type LogitTheme = { color: string; bg: string; border: string; icon?: string; symbol?: string };\n\n/**\n * Detects dark mode preference at module load time.\n * Note: This is intentionally static and won't update if the user changes their theme.\n */\nconst isDark = typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches;\n\nconst Theme: Readonly<Record<LogitColors, LogitTheme>> = {\n debug: { bg: '#616161', border: '#424242', color: '#fff', icon: '\\u2615', symbol: '\\uD83C\\uDD73' },\n error: { bg: '#d32f2f', border: '#c62828', color: '#fff', icon: '\\u2718', symbol: '\\uD83C\\uDD74' },\n group: { bg: '#546e7a', border: '#455a64', color: '#fff', icon: '\\u26AD', symbol: '\\uD83C\\uDD76' },\n info: { bg: '#1976d2', border: '#1565c0', color: '#fff', icon: '\\u2139', symbol: '\\uD83C\\uDD78' },\n ns: isDark\n ? { bg: '#fafafa', border: '#c7c7c7', color: '#000' }\n : { bg: '#424242', border: '#212121', color: '#fff' },\n success: { bg: '#689f38', border: '#558b2f', color: '#fff', icon: '\\u2714', symbol: '\\uD83C\\uDD82' },\n time: { bg: '#0097a7', border: '#00838f', color: '#fff', icon: '\\u23F2', symbol: '\\uD83C\\uDD83' },\n trace: { bg: '#d81b60', border: '#c2185b', color: '#fff', icon: '\\u26e2', symbol: '\\uD83C\\uDD83' },\n warn: { bg: '#ffb300', border: '#ffa000', color: '#fff', icon: '\\u26a0', symbol: '\\uD83C\\uDD86' },\n};\n\n// biome-ignore assist/source/useSortedKeys: -\nconst logLevel: Readonly<Record<LogitLevel, number>> = {\n debug: 0,\n trace: 1,\n time: 2,\n table: 3,\n info: 4,\n success: 5,\n warn: 6,\n error: 7,\n off: 8,\n};\n\nconst state: Required<LogitOptions> = {\n environment: true,\n logLevel: 'debug',\n namespace: '',\n remote: { handler: undefined, logLevel: 'off' },\n timestamp: true,\n variant: 'symbol',\n};\n\n/**\n * Determines if a log message should be shown based on the current log level.\n */\nconst shouldLog = (type: LogitType): boolean => logLevel[state.logLevel] <= logLevel[type];\n\n/**\n * Gets the current timestamp in ISO format (HH:MM:SS.mmm).\n */\nconst getCurrentTimestamp = (): string => new Date().toISOString().slice(11, 23);\n\n/**\n * Gets the environment indicator symbol.\n */\nconst getEnvIndicator = (): string => (IS_PROD ? ENV_PROD : ENV_DEV);\n\n/**\n * Sends log data to remote handler if configured.\n */\nconst sendRemoteLog = (type: LogitType, args: any[]): void => {\n if (state.remote.handler && logLevel[state.remote.logLevel] <= logLevel[type]) {\n state.remote.handler(type, ...args);\n }\n};\n\n/**\n * Gets the console method for a given log type.\n */\nconst getConsoleMethod = (type: LogitType): keyof Console => {\n return (CONSOLE_METHOD_MAP[type] || type) as keyof Console;\n};\n\n/**\n * CSS style constants for consistent formatting.\n */\nconst BASE_BORDER_STYLE = 'border: 1px solid';\nconst BASE_BORDER_RADIUS = 'border-radius: 4px';\nconst NAMESPACE_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter';\n\n/**\n * Generates CSS styles for log messages based on theme and variant.\n */\nconst style = (type: LogitColors, extra = ''): string => {\n const { bg, color, border } = Theme[type];\n const baseStyle = `color: ${bg}; ${BASE_BORDER_STYLE} ${border}; ${BASE_BORDER_RADIUS}`;\n\n switch (state.variant) {\n case 'symbol':\n return `${baseStyle}; padding: 1px 1px 0${extra}`;\n case 'icon':\n return `${baseStyle}; padding: 0 3px${extra}`;\n default:\n return `background: ${bg}; color: ${color}; ${BASE_BORDER_STYLE} ${border}; ${BASE_BORDER_RADIUS}; font-weight: bold; padding: 0 3px${extra}`;\n }\n};\n\n/**\n * Gets the display value for a log type based on current variant.\n */\nconst getDisplayValue = (type: LogitType): string => {\n const theme = Theme[type as LogitColors];\n const { variant } = state;\n\n // For 'text' variant or if the variant key doesn't exist, use uppercase type\n if (variant === 'text' || !theme[variant]) {\n return type.toUpperCase();\n }\n\n return theme[variant] as string;\n};\n\n/**\n * Builds the format string and style parts for browser console logging.\n */\nfunction buildBrowserLogParts(type: LogitType): { format: string; parts: string[] } {\n const { namespace, timestamp, environment } = state;\n\n let format = `%c${getDisplayValue(type)}%c`;\n const parts: string[] = [style(type as LogitColors), ''];\n\n if (namespace) {\n format += ` %c${namespace}%c`;\n parts.push(style('ns', `; ${NAMESPACE_STYLE}`), '');\n }\n\n if (environment) {\n format += ` %c${getEnvIndicator()}%c`;\n parts.push('color: darkgray', '');\n }\n\n if (timestamp) {\n format += ` %c${getCurrentTimestamp()}%c`;\n parts.push('color: gray', '');\n }\n\n return { format, parts };\n}\n\n/**\n * Logs messages to the console with styling and metadata.\n */\nconst log = (type: LogitType, ...args: any[]): void => {\n // Server-side logging (Node.js)\n if (typeof window === 'undefined') {\n const consoleMethod = console[getConsoleMethod(type)] as (...a: any[]) => void;\n consoleMethod(`${getDisplayValue(type)} | ${getEnvIndicator()} |`, ...args);\n return;\n }\n\n // Check log level\n if (!shouldLog(type)) return;\n\n // Browser-side logging with styling\n const { format, parts } = buildBrowserLogParts(type);\n const consoleMethod = console[getConsoleMethod(type)] as (...a: any[]) => void;\n\n consoleMethod(format, ...parts, ...args);\n sendRemoteLog(type, args);\n};\n\n/**\n * Formats the elapsed time for display.\n */\nconst formatElapsedTime = (startTime: number): string => {\n const elapsed = Math.floor(Date.now() - startTime);\n return elapsed ? `${elapsed}ms` : '';\n};\n\nexport const Logit = {\n /**\n * Asserts a condition and logs an error if it's false.\n */\n assert: (valid: boolean, message: string, context: Record<string, any>): void =>\n console.assert(valid, message, context),\n\n debug: (...args: any[]): void => log('debug', ...args),\n error: (...args: any[]): void => log('error', ...args),\n\n /**\n * Gets the current log level.\n */\n getLevel: (): LogitLevel => state.logLevel,\n\n /**\n * Gets the current namespace prefix.\n */\n getPrefix: (): string => state.namespace,\n\n /**\n * Gets whether timestamps are shown.\n */\n getTimestamp: (): boolean => state.timestamp,\n\n /**\n * Creates a collapsed group in the console.\n */\n groupCollapsed: (text: string, label = 'GROUP', time = Date.now()): void => {\n if (!shouldLog('success')) return;\n\n const elapsed = formatElapsedTime(time);\n const env = getEnvIndicator();\n const timestamp = state.timestamp ? getCurrentTimestamp() : '';\n\n console.groupCollapsed(\n `%c${label}%c${state.namespace}%c${env}%c${timestamp}%c${elapsed}%c${text}`,\n style('group', '; margin-right: 6px; padding: 1px 3px 0'),\n style('ns', `; ${NAMESPACE_STYLE}; margin-right: 6px`),\n 'color: darkgray; margin-right: 6px',\n 'color: gray; font-weight: lighter; margin-right: 6px',\n 'color: gray; font-weight: lighter; margin-right: 6px',\n 'color: inherit; font-weight: lighter',\n );\n },\n\n /**\n * Ends the current console group.\n */\n groupEnd: (): void => {\n if (shouldLog('success')) console.groupEnd();\n },\n\n info: (...args: any[]): void => log('info', ...args),\n\n /**\n * Initializes Logit with custom options.\n */\n initialise: (options: LogitOptions): void => {\n Object.assign(state, options);\n },\n\n /**\n * Sets the minimum log level to display.\n */\n setLogLevel: (level: LogitLevel): void => {\n state.logLevel = level;\n },\n\n /**\n * Sets the namespace prefix for all logs.\n */\n setPrefix: (namespace: string): void => {\n state.namespace = namespace;\n },\n\n /**\n * Configures remote logging options.\n */\n setRemote: (remote: LogitRemoteOptions): void => {\n state.remote = remote;\n },\n\n /**\n * Sets the log level for remote logging.\n */\n setRemoteLogLevel: (level: LogitLevel): void => {\n state.remote.logLevel = level;\n },\n\n /**\n * Sets the display variant (text, icon, or symbol).\n */\n setVariant: (variant: 'text' | 'icon' | 'symbol'): void => {\n state.variant = variant;\n },\n\n /**\n * Shows or hides the environment indicator.\n */\n showEnvironment: (value: boolean): void => {\n state.environment = value;\n },\n\n /**\n * Shows or hides timestamps in logs.\n */\n showTimestamp: (value: boolean): void => {\n state.timestamp = value;\n },\n\n success: (...args: any[]): void => log('success', ...args),\n\n /**\n * Displays data in a table format.\n */\n table: (...args: any[]): void => {\n if (shouldLog('table')) console.table(...args);\n },\n\n /**\n * Starts a timer with the given label.\n */\n time: (label: string): void => {\n if (shouldLog('time')) console.time(label);\n },\n\n /**\n * Ends a timer with the given label.\n */\n timeEnd: (label: string): void => {\n if (shouldLog('time')) console.timeEnd(label);\n },\n\n trace: (...args: any[]): void => log('trace', ...args),\n warn: (...args: any[]): void => log('warn', ...args),\n};\n"],"names":["CONSOLE_METHOD_MAP","isProduction","__vite_import_meta_env__","IS_PROD","isDark","Theme","logLevel","state","shouldLog","type","getCurrentTimestamp","getEnvIndicator","sendRemoteLog","args","getConsoleMethod","BASE_BORDER_STYLE","BASE_BORDER_RADIUS","NAMESPACE_STYLE","style","extra","bg","color","border","baseStyle","getDisplayValue","theme","variant","buildBrowserLogParts","namespace","timestamp","environment","format","parts","log","consoleMethod","formatElapsedTime","startTime","elapsed","Logit","valid","message","context","text","label","time","env","options","level","remote","value"],"mappings":";AAYA,MAAMA,IAAoD;AAAA,EACxD,OAAO;AAAA,EACP,SAAS;AACX,GAMMC,IAAe,MAEf,OAAO,SAAW,OAAgBC,GAA0B,WACtD,KAKN,OAAO,UAAY,OAAgB,QAAgB,KAAK,WAElD,QAAgB,IAAI,aAAa,eAGpC,IAIHC,IAAUF,EAAA,GAwBVG,IAAS,OAAO,SAAW,OAAe,OAAO,aAAa,8BAA8B,EAAE,SAE9FC,IAAmD;AAAA,EACvD,OAAO,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,QAAQ,MAAM,KAAU,QAAQ,KAAA;AAAA,EAClF,OAAO,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,QAAQ,MAAM,KAAU,QAAQ,KAAA;AAAA,EAClF,OAAO,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,QAAQ,MAAM,KAAU,QAAQ,KAAA;AAAA,EAClF,MAAM,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,QAAQ,MAAM,KAAU,QAAQ,KAAA;AAAA,EACjF,IAAID,IACA,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,OAAA,IAC3C,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,OAAA;AAAA,EAC/C,SAAS,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,QAAQ,MAAM,KAAU,QAAQ,KAAA;AAAA,EACpF,MAAM,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,QAAQ,MAAM,KAAU,QAAQ,KAAA;AAAA,EACjF,OAAO,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,QAAQ,MAAM,KAAU,QAAQ,KAAA;AAAA,EAClF,MAAM,EAAE,IAAI,WAAW,QAAQ,WAAW,OAAO,QAAQ,MAAM,KAAU,QAAQ,KAAA;AACnF,GAGME,IAAiD;AAAA,EACrD,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AACP,GAEMC,IAAgC;AAAA,EACpC,aAAa;AAAA,EACb,UAAU;AAAA,EACV,WAAW;AAAA,EACX,QAAQ,EAAE,SAAS,QAAW,UAAU,MAAA;AAAA,EACxC,WAAW;AAAA,EACX,SAAS;AACX,GAKMC,IAAY,CAACC,MAA6BH,EAASC,EAAM,QAAQ,KAAKD,EAASG,CAAI,GAKnFC,IAAsB,OAAc,oBAAI,KAAA,GAAO,YAAA,EAAc,MAAM,IAAI,EAAE,GAKzEC,IAAkB,MAAeR,IAAU,OAAW,MAKtDS,IAAgB,CAACH,GAAiBI,MAAsB;AAC5D,EAAIN,EAAM,OAAO,WAAWD,EAASC,EAAM,OAAO,QAAQ,KAAKD,EAASG,CAAI,KAC1EF,EAAM,OAAO,QAAQE,GAAM,GAAGI,CAAI;AAEtC,GAKMC,IAAmB,CAACL,MAChBT,EAAmBS,CAAI,KAAKA,GAMhCM,IAAoB,qBACpBC,IAAqB,sBACrBC,IAAkB,+EAKlBC,IAAQ,CAACT,GAAmBU,IAAQ,OAAe;AACvD,QAAM,EAAE,IAAAC,GAAI,OAAAC,GAAO,QAAAC,EAAA,IAAWjB,EAAMI,CAAI,GAClCc,IAAY,UAAUH,CAAE,KAAKL,CAAiB,IAAIO,CAAM,KAAKN,CAAkB;AAErF,UAAQT,EAAM,SAAA;AAAA,IACZ,KAAK;AACH,aAAO,GAAGgB,CAAS,uBAAuBJ,CAAK;AAAA,IACjD,KAAK;AACH,aAAO,GAAGI,CAAS,mBAAmBJ,CAAK;AAAA,IAC7C;AACE,aAAO,eAAeC,CAAE,YAAYC,CAAK,KAAKN,CAAiB,IAAIO,CAAM,KAAKN,CAAkB,sCAAsCG,CAAK;AAAA,EAAA;AAEjJ,GAKMK,IAAkB,CAACf,MAA4B;AACnD,QAAMgB,IAAQpB,EAAMI,CAAmB,GACjC,EAAE,SAAAiB,MAAYnB;AAGpB,SAAImB,MAAY,UAAU,CAACD,EAAMC,CAAO,IAC/BjB,EAAK,YAAA,IAGPgB,EAAMC,CAAO;AACtB;AAKA,SAASC,EAAqBlB,GAAsD;AAClF,QAAM,EAAE,WAAAmB,GAAW,WAAAC,GAAW,aAAAC,EAAA,IAAgBvB;AAE9C,MAAIwB,IAAS,KAAKP,EAAgBf,CAAI,CAAC;AACvC,QAAMuB,IAAkB,CAACd,EAAMT,CAAmB,GAAG,EAAE;AAEvD,SAAImB,MACFG,KAAU,MAAMH,CAAS,MACzBI,EAAM,KAAKd,EAAM,MAAM,KAAKD,CAAe,EAAE,GAAG,EAAE,IAGhDa,MACFC,KAAU,MAAMpB,GAAiB,MACjCqB,EAAM,KAAK,mBAAmB,EAAE,IAG9BH,MACFE,KAAU,MAAMrB,GAAqB,MACrCsB,EAAM,KAAK,eAAe,EAAE,IAGvB,EAAE,QAAAD,GAAQ,OAAAC,EAAA;AACnB;AAKA,MAAMC,IAAM,CAACxB,MAAoBI,MAAsB;AAErD,MAAI,OAAO,SAAW,KAAa;AACjC,UAAMqB,IAAgB,QAAQpB,EAAiBL,CAAI,CAAC;AACpDyB,IAAAA,EAAc,GAAGV,EAAgBf,CAAI,CAAC,MAAME,GAAiB,MAAM,GAAGE,CAAI;AAC1E;AAAA,EACF;AAGA,MAAI,CAACL,EAAUC,CAAI,EAAG;AAGtB,QAAM,EAAE,QAAAsB,GAAQ,OAAAC,MAAUL,EAAqBlB,CAAI,GAC7CyB,IAAgB,QAAQpB,EAAiBL,CAAI,CAAC;AAEpD,EAAAyB,EAAcH,GAAQ,GAAGC,GAAO,GAAGnB,CAAI,GACvCD,EAAcH,GAAMI,CAAI;AAC1B,GAKMsB,IAAoB,CAACC,MAA8B;AACvD,QAAMC,IAAU,KAAK,MAAM,KAAK,IAAA,IAAQD,CAAS;AACjD,SAAOC,IAAU,GAAGA,CAAO,OAAO;AACpC,GAEaC,IAAQ;AAAA;AAAA;AAAA;AAAA,EAInB,QAAQ,CAACC,GAAgBC,GAAiBC,MACxC,QAAQ,OAAOF,GAAOC,GAASC,CAAO;AAAA,EAExC,OAAO,IAAI5B,MAAsBoB,EAAI,SAAS,GAAGpB,CAAI;AAAA,EACrD,OAAO,IAAIA,MAAsBoB,EAAI,SAAS,GAAGpB,CAAI;AAAA;AAAA;AAAA;AAAA,EAKrD,UAAU,MAAkBN,EAAM;AAAA;AAAA;AAAA;AAAA,EAKlC,WAAW,MAAcA,EAAM;AAAA;AAAA;AAAA;AAAA,EAK/B,cAAc,MAAeA,EAAM;AAAA;AAAA;AAAA;AAAA,EAKnC,gBAAgB,CAACmC,GAAcC,IAAQ,SAASC,IAAO,KAAK,UAAgB;AAC1E,QAAI,CAACpC,EAAU,SAAS,EAAG;AAE3B,UAAM6B,IAAUF,EAAkBS,CAAI,GAChCC,IAAMlC,EAAA,GACNkB,IAAYtB,EAAM,YAAYG,EAAA,IAAwB;AAE5D,YAAQ;AAAA,MACN,KAAKiC,CAAK,KAAKpC,EAAM,SAAS,KAAKsC,CAAG,KAAKhB,CAAS,KAAKQ,CAAO,KAAKK,CAAI;AAAA,MACzExB,EAAM,SAAS,yCAAyC;AAAA,MACxDA,EAAM,MAAM,KAAKD,CAAe,qBAAqB;AAAA,MACrD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,MAAY;AACpB,IAAIT,EAAU,SAAS,KAAG,QAAQ,SAAA;AAAA,EACpC;AAAA,EAEA,MAAM,IAAIK,MAAsBoB,EAAI,QAAQ,GAAGpB,CAAI;AAAA;AAAA;AAAA;AAAA,EAKnD,YAAY,CAACiC,MAAgC;AAC3C,WAAO,OAAOvC,GAAOuC,CAAO;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,CAACC,MAA4B;AACxC,IAAAxC,EAAM,WAAWwC;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,CAACnB,MAA4B;AACtC,IAAArB,EAAM,YAAYqB;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,CAACoB,MAAqC;AAC/C,IAAAzC,EAAM,SAASyC;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,CAACD,MAA4B;AAC9C,IAAAxC,EAAM,OAAO,WAAWwC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,CAACrB,MAA8C;AACzD,IAAAnB,EAAM,UAAUmB;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,CAACuB,MAAyB;AACzC,IAAA1C,EAAM,cAAc0C;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,CAACA,MAAyB;AACvC,IAAA1C,EAAM,YAAY0C;AAAA,EACpB;AAAA,EAEA,SAAS,IAAIpC,MAAsBoB,EAAI,WAAW,GAAGpB,CAAI;AAAA;AAAA;AAAA;AAAA,EAKzD,OAAO,IAAIA,MAAsB;AAC/B,IAAIL,EAAU,OAAO,KAAG,QAAQ,MAAM,GAAGK,CAAI;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,CAAC8B,MAAwB;AAC7B,IAAInC,EAAU,MAAM,KAAG,QAAQ,KAAKmC,CAAK;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,CAACA,MAAwB;AAChC,IAAInC,EAAU,MAAM,KAAG,QAAQ,QAAQmC,CAAK;AAAA,EAC9C;AAAA,EAEA,OAAO,IAAI9B,MAAsBoB,EAAI,SAAS,GAAGpB,CAAI;AAAA,EACrD,MAAM,IAAIA,MAAsBoB,EAAI,QAAQ,GAAGpB,CAAI;AACrD;"}
1
+ {"version":3,"file":"logit.js","sources":["../src/logit.ts"],"sourcesContent":["/** biome-ignore-all lint/suspicious/noAssignInExpressions: - */\n/** biome-ignore-all lint/suspicious/noExplicitAny: - */\n\n/**\n * Environment indicator symbols.\n */\nconst ENV_PROD = '\\uD83C\\uDD3F'; // 🅿\nconst ENV_DEV = '\\uD83C\\uDD33'; // 🅳\n\n/**\n * Console method mappings for log types.\n */\nconst CONSOLE_METHOD_MAP: Record<string, keyof Console> = {\n debug: 'log',\n success: 'log',\n} as const;\n\n/**\n * Checks if the current environment is production.\n * Cached for performance - evaluated once at a module load.\n *\n * Note: import.meta.env is available in Vite/Bundlers but may be undefined in some environments.\n * Using 'any' cast is necessary for cross-environment compatibility.\n */\nconst isProduction = (): boolean => {\n // Browser environment (Vite, Webpack, etc.)\n // import.meta.env may be undefined in some bundlers - safe check with optional chaining\n if (typeof window !== 'undefined' && (import.meta as any)?.env?.NODE_ENV) {\n return (import.meta as any).env.NODE_ENV === 'production';\n }\n\n // Node.js environment\n // @ts-expect-error - process.env exists in Node.js but not in browser\n if (typeof process !== 'undefined' && (process as any).env?.NODE_ENV) {\n // @ts-expect-error - process.env exists in Node.js\n return (process as any).env.NODE_ENV === 'production';\n }\n\n return false;\n};\n\n// Cache the result to avoid repeated checks\nconst IS_PROD = isProduction();\n\nexport type LogitInstance = typeof Logit;\nexport type LogitType = 'debug' | 'trace' | 'time' | 'table' | 'info' | 'success' | 'warn' | 'error';\nexport type LogitColors = Exclude<LogitType, 'table'> | 'group' | 'ns';\nexport type LogitLevel = LogitType | 'off';\nexport type LogitRemoteOptions = {\n handler?: (...args: any[]) => void;\n logLevel: LogitLevel;\n};\nexport type LogitOptions = {\n environment?: boolean;\n variant?: 'text' | 'symbol' | 'icon';\n logLevel?: LogitLevel;\n namespace?: string;\n remote?: LogitRemoteOptions;\n timestamp?: boolean;\n};\nexport type LogitTheme = { color: string; bg: string; border: string; icon?: string; symbol?: string };\n\n/**\n * Scoped logger interface with namespaced logging methods.\n */\nexport type ScopedLogger = {\n debug: (...args: any[]) => void;\n error: (...args: any[]) => void;\n info: (...args: any[]) => void;\n success: (...args: any[]) => void;\n trace: (...args: any[]) => void;\n warn: (...args: any[]) => void;\n};\n\n/**\n * Detects dark mode preference at module load time.\n * Note: This is intentionally static and won't update if the user changes their theme.\n */\nconst isDark = typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches;\n\nconst Theme: Readonly<Record<LogitColors, LogitTheme>> = {\n debug: { bg: '#616161', border: '#424242', color: '#fff', icon: '\\u2615', symbol: '\\uD83C\\uDD73' },\n error: { bg: '#d32f2f', border: '#c62828', color: '#fff', icon: '\\u2718', symbol: '\\uD83C\\uDD74' },\n group: { bg: '#546e7a', border: '#455a64', color: '#fff', icon: '\\u26AD', symbol: '\\uD83C\\uDD76' },\n info: { bg: '#1976d2', border: '#1565c0', color: '#fff', icon: '\\u2139', symbol: '\\uD83C\\uDD78' },\n ns: isDark\n ? { bg: '#fafafa', border: '#c7c7c7', color: '#000' }\n : { bg: '#424242', border: '#212121', color: '#fff' },\n success: { bg: '#689f38', border: '#558b2f', color: '#fff', icon: '\\u2714', symbol: '\\uD83C\\uDD82' },\n time: { bg: '#0097a7', border: '#00838f', color: '#fff', icon: '\\u23F2', symbol: '\\uD83C\\uDD83' },\n trace: { bg: '#d81b60', border: '#c2185b', color: '#fff', icon: '\\u26e2', symbol: '\\uD83C\\uDD83' },\n warn: { bg: '#ffb300', border: '#ffa000', color: '#fff', icon: '\\u26a0', symbol: '\\uD83C\\uDD86' },\n};\n\n// biome-ignore assist/source/useSortedKeys: -\nconst logLevel: Readonly<Record<LogitLevel, number>> = {\n debug: 0,\n trace: 1,\n time: 2,\n table: 3,\n info: 4,\n success: 5,\n warn: 6,\n error: 7,\n off: 8,\n};\n\nconst state: Required<LogitOptions> = {\n environment: true,\n logLevel: 'debug',\n namespace: '',\n remote: { handler: undefined, logLevel: 'off' },\n timestamp: true,\n variant: 'symbol',\n};\n\n/**\n * Determines if a log message should be shown based on the current log level.\n */\nconst shouldLog = (type: LogitType): boolean => logLevel[state.logLevel] <= logLevel[type];\n\n/**\n * Gets the current timestamp in ISO format (HH:MM:SS.mmm).\n */\nconst getCurrentTimestamp = (): string => new Date().toISOString().slice(11, 23);\n\n/**\n * Gets the environment indicator symbol.\n */\nconst getEnvIndicator = (): string => (IS_PROD ? ENV_PROD : ENV_DEV);\n\n/**\n * Sends log data to a remote handler if configured.\n */\nconst sendRemoteLog = (type: LogitType, args: any[]): void => {\n if (state.remote.handler && logLevel[state.remote.logLevel] <= logLevel[type]) {\n Promise.resolve().then(() => {\n state.remote.handler?.(type, {\n args,\n environment: IS_PROD ? 'production' : 'development',\n namespace: state.namespace || undefined,\n timestamp: state.timestamp ? getCurrentTimestamp() : undefined,\n });\n });\n }\n};\n\n/**\n * Gets the console method for a given log type.\n */\nconst getConsoleMethod = (type: LogitType): keyof Console => {\n return (CONSOLE_METHOD_MAP[type] || type) as keyof Console;\n};\n\n/**\n * CSS style constants for consistent formatting.\n */\nconst BASE_BORDER_STYLE = 'border: 1px solid';\nconst BASE_BORDER_RADIUS = 'border-radius: 4px';\nconst NAMESPACE_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;';\n\n/**\n * Generates CSS styles for log messages based on theme and variant.\n *\n * @param type - Log type color scheme\n * @param extra - Additional CSS to append (should include leading semicolon if needed)\n */\nconst style = (type: LogitColors, extra = ''): string => {\n const { bg, color, border } = Theme[type];\n const baseStyle = `${BASE_BORDER_STYLE} ${border}; ${BASE_BORDER_RADIUS}`;\n\n switch (state.variant) {\n case 'symbol':\n // Symbol variant: colored text on a transparent background\n return `color: ${bg}; ${baseStyle}; padding: 1px 1px 0${extra}`;\n case 'icon':\n // Icon variant: colored text on a transparent background\n return `color: ${bg}; ${baseStyle}; padding: 0 3px${extra}`;\n default:\n // Text variant: white text on a colored background\n return `background: ${bg}; color: ${color}; ${baseStyle}; font-weight: bold; padding: 0 3px${extra}`;\n }\n};\n\n/**\n * Gets the display value for a log type based on the current variant.\n */\nconst getDisplayValue = (type: LogitType): string => {\n const theme = Theme[type as LogitColors];\n const { variant } = state;\n\n // For 'text' variant or if the variant property doesn't exist in theme, use uppercase type\n if (variant === 'text' || !theme || !theme[variant]) {\n return type.toUpperCase();\n }\n\n return theme[variant] as string;\n};\n\n/**\n * Builds the format string and style parts for browser console logging.\n */\nfunction buildBrowserLogParts(type: LogitType): { format: string; parts: string[] } {\n const { namespace, timestamp, environment } = state;\n\n let format = `%c${getDisplayValue(type)}%c`;\n const parts: string[] = [style(type as LogitColors), ''];\n\n if (namespace) {\n format += ` %c${namespace}%c`;\n parts.push(style('ns', `; ${NAMESPACE_STYLE}`), '');\n }\n\n if (environment) {\n format += ` %c${getEnvIndicator()}%c`;\n parts.push('color: darkgray', '');\n }\n\n if (timestamp) {\n format += ` %c${getCurrentTimestamp()}%c`;\n parts.push('color: gray', '');\n }\n\n return { format, parts };\n}\n\n/**\n * Logs messages to the console with styling and metadata.\n */\nconst log = (type: LogitType, ...args: any[]): void => {\n // Server-side logging (Node.js)\n if (typeof window === 'undefined') {\n const consoleMethod = console[getConsoleMethod(type)] as (...a: any[]) => void;\n consoleMethod(`${getDisplayValue(type)} | ${getEnvIndicator()} |`, ...args);\n return;\n }\n\n // Check the log level\n if (!shouldLog(type)) return;\n\n // Browser-side logging with styling\n const { format, parts } = buildBrowserLogParts(type);\n const consoleMethod = console[getConsoleMethod(type)] as (...a: any[]) => void;\n\n consoleMethod(format, ...parts, ...args);\n sendRemoteLog(type, args);\n};\n\n/**\n * Formats the elapsed time for display.\n */\nconst formatElapsedTime = (startTime: number): string => {\n const elapsed = Math.floor(Date.now() - startTime);\n return elapsed ? `${elapsed}ms` : '';\n};\n\nexport const Logit = {\n /**\n * Asserts a condition and logs an error if it's false.\n */\n assert: (valid: boolean, message: string, context: Record<string, any>): void =>\n console.assert(valid, message, context),\n\n debug: (...args: any[]): void => log('debug', ...args),\n error: (...args: any[]): void => log('error', ...args),\n\n /**\n * Gets whether the environment indicator is shown.\n */\n getEnvironment: (): boolean => state.environment,\n\n /**\n * Gets the current log level.\n */\n getLevel: (): LogitLevel => state.logLevel,\n\n /**\n * Gets the current namespace prefix.\n */\n getPrefix: (): string => state.namespace,\n\n /**\n * Gets whether timestamps are shown.\n */\n getTimestamp: (): boolean => state.timestamp,\n\n /**\n * Gets the current display variant.\n */\n getVariant: (): 'text' | 'symbol' | 'icon' => state.variant,\n\n /**\n * Creates a collapsed group in the console.\n */\n groupCollapsed: (text: string, label = 'GROUP', time = Date.now()): void => {\n if (!shouldLog('success')) return;\n\n const elapsed = formatElapsedTime(time);\n const env = getEnvIndicator();\n const timestamp = state.timestamp ? getCurrentTimestamp() : '';\n\n console.groupCollapsed(\n `%c${label}%c${state.namespace}%c${env}%c${timestamp}%c${elapsed}%c${text}`,\n style('group', '; margin-right: 6px; padding: 1px 3px 0'),\n style('ns', `; ${NAMESPACE_STYLE}; margin-right: 6px`),\n 'color: darkgray; margin-right: 6px',\n 'color: gray; font-weight: lighter; margin-right: 6px',\n 'color: gray; font-weight: lighter; margin-right: 6px',\n 'color: inherit; font-weight: lighter',\n );\n },\n\n /**\n * Ends the current console group.\n */\n groupEnd: (): void => {\n if (shouldLog('success')) console.groupEnd();\n },\n\n info: (...args: any[]): void => log('info', ...args),\n\n /**\n * Creates a scoped logger with a namespaced prefix.\n * Does not mutate global state - returns an isolated logger instance.\n *\n * @param namespace - The namespace to prepend to all log messages\n * @returns A scoped logger with all logging methods\n *\n * @example\n * ```ts\n * const apiLogger = Logit.scope('api');\n * apiLogger.info('Request received'); // [API] Request received\n *\n * const dbLogger = Logit.scope('database');\n * dbLogger.error('Connection failed'); // [DATABASE] Connection failed\n * ```\n */\n scope: (namespace: string): ScopedLogger => {\n const originalNamespace = state.namespace;\n const scopedNamespace = originalNamespace ? `${originalNamespace}.${namespace}` : namespace;\n\n return {\n debug: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('debug', ...args);\n state.namespace = prev;\n },\n error: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('error', ...args);\n state.namespace = prev;\n },\n info: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('info', ...args);\n state.namespace = prev;\n },\n success: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('success', ...args);\n state.namespace = prev;\n },\n trace: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('trace', ...args);\n state.namespace = prev;\n },\n warn: (...args: any[]) => {\n const prev = state.namespace;\n state.namespace = scopedNamespace;\n log('warn', ...args);\n state.namespace = prev;\n },\n };\n },\n\n /**\n * Sets the minimum log level to display.\n */\n setLogLevel: (level: LogitLevel): void => {\n state.logLevel = level;\n },\n\n /**\n * Sets the namespace prefix for all logs.\n */\n setPrefix: (namespace: string): void => {\n state.namespace = namespace;\n },\n\n /**\n * Configures remote logging options.\n */\n setRemote: (remote: LogitRemoteOptions): void => {\n state.remote = remote;\n },\n\n /**\n * Sets the log level for remote logging.\n */\n setRemoteLogLevel: (level: LogitLevel): void => {\n state.remote.logLevel = level;\n },\n\n /**\n * Configures Logit with custom options.\n *\n * Note: The remote option will be merged with existing remote config,\n * not replaced entirely. To clear a remote handler, set remote.handler to undefined.\n */\n setup: (options: LogitOptions): void => {\n if (options.remote) {\n state.remote = { ...state.remote, ...options.remote };\n delete (options as any).remote; // Remove to avoid Object.assign overwrite\n }\n Object.assign(state, options);\n },\n\n /**\n * Sets the display variant (text, icon, or symbol).\n */\n setVariant: (variant: 'text' | 'icon' | 'symbol'): void => {\n state.variant = variant;\n },\n\n success: (...args: any[]): void => log('success', ...args),\n\n /**\n * Displays data in a table format.\n */\n table: (...args: any[]): void => {\n if (shouldLog('table')) console.table(...args);\n },\n\n /**\n * Starts a timer with the given label.\n */\n time: (label: string): void => {\n if (shouldLog('time')) console.time(label);\n },\n\n /**\n * Ends a timer with the given label.\n */\n timeEnd: (label: string): void => {\n if (shouldLog('time')) console.timeEnd(label);\n },\n\n /**\n * Toggles or sets the environment indicator visibility.\n * When called without arguments, toggles the current state.\n *\n * @param value - Optional boolean to explicitly set the state\n *\n * @example\n * ```ts\n * Logit.toggleEnvironment(); // Toggles current state\n * Logit.toggleEnvironment(true); // Shows environment indicator\n * Logit.toggleEnvironment(false); // Hides environment indicator\n * ```\n */\n toggleEnvironment: (value?: boolean): void => {\n state.environment = value ?? !state.environment;\n },\n\n /**\n * Toggles or sets timestamp visibility in logs.\n * When called without arguments, toggles the current state.\n *\n * @param value - Optional boolean to explicitly set the state\n *\n * @example\n * ```ts\n * Logit.toggleTimestamp(); // Toggles current state\n * Logit.toggleTimestamp(true); // Shows timestamps\n * Logit.toggleTimestamp(false); // Hides timestamps\n * ```\n */\n toggleTimestamp: (value?: boolean): void => {\n state.timestamp = value ?? !state.timestamp;\n },\n\n trace: (...args: any[]): void => log('trace', ...args),\n warn: (...args: any[]): void => log('warn', ...args),\n};\n"],"names":["CONSOLE_METHOD_MAP","isProduction","__vite_import_meta_env__","IS_PROD","isDark","Theme","logLevel","state","shouldLog","type","getCurrentTimestamp","getEnvIndicator","sendRemoteLog","args","getConsoleMethod","BASE_BORDER_STYLE","BASE_BORDER_RADIUS","NAMESPACE_STYLE","style","extra","bg","color","border","baseStyle","getDisplayValue","theme","variant","buildBrowserLogParts","namespace","timestamp","environment","format","parts","log","consoleMethod","formatElapsedTime","startTime","elapsed","Logit","valid","message","context","text","label","time","env","originalNamespace","scopedNamespace","prev","level","remote","options","value"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vielzeug/logit",
3
- "version": "1.0.5",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"