@heojeongbo/log-palette 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,301 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/config.ts
3
+ const _config = {
4
+ innerWidth: 8,
5
+ timestamp: true
6
+ };
7
+ /**
8
+ * Read the current global configuration.
9
+ * Returns a snapshot — mutating the returned object has no effect.
10
+ */
11
+ function getConfig() {
12
+ return { ..._config };
13
+ }
14
+ /**
15
+ * Update one or more global format settings.
16
+ * Changes apply immediately to all subsequent log calls across all loggers.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // Wider prefix column (good when you have long domain names)
21
+ * configure({ innerWidth: 12 })
22
+ *
23
+ * // Strip timestamps (cleaner in environments that add their own)
24
+ * configure({ timestamp: false })
25
+ * ```
26
+ */
27
+ function configure(options) {
28
+ if (options.innerWidth !== void 0) {
29
+ if (options.innerWidth < 1) throw new RangeError("innerWidth must be >= 1");
30
+ _config.innerWidth = options.innerWidth;
31
+ }
32
+ if (options.timestamp !== void 0) _config.timestamp = options.timestamp;
33
+ }
34
+ //#endregion
35
+ //#region src/color.ts
36
+ function djb2(str) {
37
+ let hash = 5381;
38
+ for (let i = 0; i < str.length; i++) {
39
+ hash = (hash << 5) + hash ^ str.charCodeAt(i);
40
+ hash = hash >>> 0;
41
+ }
42
+ return hash;
43
+ }
44
+ function domainToColor(domain) {
45
+ return `hsl(${djb2(domain) % 360}, 75%, 60%)`;
46
+ }
47
+ //#endregion
48
+ //#region src/formatter.ts
49
+ function formatTimestamp(date) {
50
+ return `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}:${String(date.getSeconds()).padStart(2, "0")}.${String(date.getMilliseconds()).padStart(3, "0")}`;
51
+ }
52
+ function formatPrefix(domain) {
53
+ const { innerWidth } = getConfig();
54
+ if (domain.length < innerWidth) return `[${".".repeat(innerWidth - domain.length)}${domain}]`;
55
+ if (domain.length === innerWidth) return `[${domain}]`;
56
+ return `[${domain.slice(0, innerWidth - 1)}\u2026]`;
57
+ }
58
+ function prefixStyle(color) {
59
+ return `color: ${color}; font-weight: bold;`;
60
+ }
61
+ //#endregion
62
+ //#region src/logger.ts
63
+ const LEVEL_RANK = {
64
+ debug: 0,
65
+ log: 1,
66
+ info: 2,
67
+ warn: 3,
68
+ error: 4
69
+ };
70
+ /**
71
+ * A logger instance tied to a specific domain.
72
+ * Outputs colored prefix badges to the browser console.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * const log = new LogPalette('auth', { color: '#7c3aed', level: 'info' })
77
+ * log.info('User signed in', { userId: 42 })
78
+ * // → [....auth] 05:35:41.039 User signed in { userId: 42 }
79
+ * ```
80
+ */
81
+ var LogPalette = class {
82
+ /**
83
+ * @param domain Service/feature name shown in the prefix badge (e.g. 'auth', 'api').
84
+ * @param options Optional configuration for color, level filtering, and enabled state.
85
+ */
86
+ constructor(domain, options = {}) {
87
+ this.domain = domain;
88
+ this.color = options.color ?? domainToColor(domain);
89
+ this._minLevel = LEVEL_RANK[options.level ?? "debug"];
90
+ this._enabled = options.enabled ?? true;
91
+ }
92
+ /**
93
+ * Dynamically change the minimum log level for this logger.
94
+ * Useful for adjusting verbosity at runtime without recreating the logger.
95
+ */
96
+ setLevel(level) {
97
+ this._minLevel = LEVEL_RANK[level];
98
+ }
99
+ /**
100
+ * Enable or disable this logger at runtime.
101
+ * When disabled, all log calls are silently dropped.
102
+ */
103
+ setEnabled(enabled) {
104
+ this._enabled = enabled;
105
+ }
106
+ _log(level, args) {
107
+ if (!this._enabled) return;
108
+ if (LEVEL_RANK[level] < this._minLevel) return;
109
+ const prefix = formatPrefix(this.domain);
110
+ const style = prefixStyle(this.color);
111
+ const { timestamp } = getConfig();
112
+ const time = timestamp ? ` ${formatTimestamp(/* @__PURE__ */ new Date())}` : "";
113
+ console[level](`%c${prefix}%c${time}`, style, "", ...args);
114
+ }
115
+ /** @inheritdoc */
116
+ log(...args) {
117
+ this._log("log", args);
118
+ }
119
+ /** @inheritdoc */
120
+ info(...args) {
121
+ this._log("info", args);
122
+ }
123
+ /** @inheritdoc */
124
+ warn(...args) {
125
+ this._log("warn", args);
126
+ }
127
+ /** @inheritdoc */
128
+ error(...args) {
129
+ this._log("error", args);
130
+ }
131
+ /** @inheritdoc */
132
+ debug(...args) {
133
+ this._log("debug", args);
134
+ }
135
+ /**
136
+ * Open a DevTools console group with the domain prefix applied to the label.
137
+ * Always call `groupEnd()` to close it.
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * apiLog.group('Fetch /users')
142
+ * apiLog.info('response', data)
143
+ * apiLog.groupEnd()
144
+ * ```
145
+ */
146
+ group(label) {
147
+ if (!this._enabled) return;
148
+ const prefix = formatPrefix(this.domain);
149
+ const style = prefixStyle(this.color);
150
+ console.group(`%c${prefix}%c ${label}`, style, "");
151
+ }
152
+ /**
153
+ * Open a collapsed DevTools console group with the domain prefix applied to the label.
154
+ * Always call `groupEnd()` to close it.
155
+ */
156
+ groupCollapsed(label) {
157
+ if (!this._enabled) return;
158
+ const prefix = formatPrefix(this.domain);
159
+ const style = prefixStyle(this.color);
160
+ console.groupCollapsed(`%c${prefix}%c ${label}`, style, "");
161
+ }
162
+ /** Close the most recently opened group. */
163
+ groupEnd() {
164
+ console.groupEnd();
165
+ }
166
+ /**
167
+ * Start a named performance timer, namespaced to this domain.
168
+ * Use `timeEnd(label)` to stop it and log the elapsed time.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * authLog.time('login')
173
+ * await performLogin()
174
+ * authLog.timeEnd('login')
175
+ * // DevTools: [....auth] login: 42.1ms
176
+ * ```
177
+ */
178
+ time(label) {
179
+ if (!this._enabled) return;
180
+ console.time(`${formatPrefix(this.domain)} ${label}`);
181
+ }
182
+ /**
183
+ * Stop the named timer started with `time(label)` and log the elapsed duration.
184
+ * @param label Must match the label passed to `time()`.
185
+ */
186
+ timeEnd(label) {
187
+ if (!this._enabled) return;
188
+ console.timeEnd(`${formatPrefix(this.domain)} ${label}`);
189
+ }
190
+ };
191
+ /**
192
+ * Create a new logger for the given domain.
193
+ * Each call creates a fresh instance; use `getLogger()` for singleton behavior.
194
+ *
195
+ * @param domain Service/feature name (e.g. 'auth', 'api', 'payments').
196
+ * @param options Optional color, level, and enabled settings.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * const log = createLogger('auth')
201
+ * log.info('App started')
202
+ *
203
+ * const payLog = createLogger('payments', { color: '#16a34a', level: 'warn' })
204
+ * ```
205
+ */
206
+ function createLogger(domain, options) {
207
+ return new LogPalette(domain, options);
208
+ }
209
+ //#endregion
210
+ //#region src/registry.ts
211
+ const _registry = /* @__PURE__ */ new Map();
212
+ /**
213
+ * Get or create a logger for the given domain.
214
+ * Unlike `createLogger()`, this returns the same instance every time it is
215
+ * called with the same domain — making it safe to call from multiple modules.
216
+ *
217
+ * Options are only applied on first call for a domain; subsequent calls with
218
+ * the same domain return the existing instance regardless of options.
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * // In module A
223
+ * const log = getLogger('api')
224
+ *
225
+ * // In module B — same instance
226
+ * const log = getLogger('api')
227
+ * ```
228
+ */
229
+ function getLogger(domain, options) {
230
+ let logger = _registry.get(domain);
231
+ if (!logger) {
232
+ logger = new LogPalette(domain, options);
233
+ _registry.set(domain, logger);
234
+ }
235
+ return logger;
236
+ }
237
+ /**
238
+ * Return a read-only snapshot of all registered loggers, keyed by domain.
239
+ * Useful for debugging or building DevTools integrations.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * const loggers = getAllLoggers()
244
+ * console.log([...loggers.keys()]) // ['api', 'auth', 'payments']
245
+ * ```
246
+ */
247
+ function getAllLoggers() {
248
+ return _registry;
249
+ }
250
+ /**
251
+ * Set the minimum log level for every registered logger at once.
252
+ * Loggers created after this call are not affected — they use their own
253
+ * options or the default ('debug').
254
+ *
255
+ * Call this early in your app entry point to control verbosity globally:
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * // Only show warnings and errors in production
260
+ * if (import.meta.env.PROD) setGlobalLevel('warn')
261
+ * ```
262
+ */
263
+ function setGlobalLevel(level) {
264
+ for (const logger of _registry.values()) logger.setLevel(level);
265
+ }
266
+ /**
267
+ * Enable all registered loggers.
268
+ *
269
+ * @example
270
+ * ```ts
271
+ * enableAll()
272
+ * ```
273
+ */
274
+ function enableAll() {
275
+ for (const logger of _registry.values()) logger.setEnabled(true);
276
+ }
277
+ /**
278
+ * Disable all registered loggers. All log calls will be silently dropped
279
+ * until `enableAll()` or individual `setEnabled(true)` is called.
280
+ *
281
+ * @example
282
+ * ```ts
283
+ * // Silence everything in production builds
284
+ * if (import.meta.env.PROD) disableAll()
285
+ * ```
286
+ */
287
+ function disableAll() {
288
+ for (const logger of _registry.values()) logger.setEnabled(false);
289
+ }
290
+ //#endregion
291
+ exports.LogPalette = LogPalette;
292
+ exports.configure = configure;
293
+ exports.createLogger = createLogger;
294
+ exports.disableAll = disableAll;
295
+ exports.enableAll = enableAll;
296
+ exports.getAllLoggers = getAllLoggers;
297
+ exports.getConfig = getConfig;
298
+ exports.getLogger = getLogger;
299
+ exports.setGlobalLevel = setGlobalLevel;
300
+
301
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/config.ts","../src/color.ts","../src/formatter.ts","../src/logger.ts","../src/registry.ts"],"sourcesContent":["/**\n * Global format configuration for log-palette.\n * Change these settings once to affect all loggers.\n */\nexport interface GlobalConfig {\n /**\n * Number of inner characters inside the prefix brackets.\n * Total prefix width = innerWidth + 2 (for the `[` and `]`).\n *\n * - Short domains are left-padded with dots to fill this width.\n * - Domains longer than this are truncated with `…`.\n *\n * @default 8 → prefix is always `[XXXXXXXX]` (10 chars total)\n */\n innerWidth: number\n\n /**\n * Whether to include a timestamp in each log line.\n * @default true\n */\n timestamp: boolean\n}\n\nconst _config: GlobalConfig = {\n innerWidth: 8,\n timestamp: true,\n}\n\n/**\n * Read the current global configuration.\n * Returns a snapshot — mutating the returned object has no effect.\n */\nexport function getConfig(): Readonly<GlobalConfig> {\n return { ..._config }\n}\n\n/**\n * Update one or more global format settings.\n * Changes apply immediately to all subsequent log calls across all loggers.\n *\n * @example\n * ```ts\n * // Wider prefix column (good when you have long domain names)\n * configure({ innerWidth: 12 })\n *\n * // Strip timestamps (cleaner in environments that add their own)\n * configure({ timestamp: false })\n * ```\n */\nexport function configure(options: Partial<GlobalConfig>): void {\n if (options.innerWidth !== undefined) {\n if (options.innerWidth < 1) throw new RangeError('innerWidth must be >= 1')\n _config.innerWidth = options.innerWidth\n }\n if (options.timestamp !== undefined) {\n _config.timestamp = options.timestamp\n }\n}\n","function djb2(str: string): number {\n let hash = 5381\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i)\n hash = hash >>> 0\n }\n return hash\n}\n\nexport function domainToColor(domain: string): string {\n const hue = djb2(domain) % 360\n return `hsl(${hue}, 75%, 60%)`\n}\n","import { getConfig } from './config.js'\n\nexport function formatTimestamp(date: Date): string {\n const h = String(date.getHours()).padStart(2, '0')\n const m = String(date.getMinutes()).padStart(2, '0')\n const s = String(date.getSeconds()).padStart(2, '0')\n const ms = String(date.getMilliseconds()).padStart(3, '0')\n return `${h}:${m}:${s}.${ms}`\n}\n\nexport function formatPrefix(domain: string): string {\n const { innerWidth } = getConfig()\n if (domain.length < innerWidth) {\n const dots = '.'.repeat(innerWidth - domain.length)\n return `[${dots}${domain}]`\n }\n if (domain.length === innerWidth) {\n return `[${domain}]`\n }\n // Truncate long domains: keep (innerWidth - 1) chars + ellipsis\n return `[${domain.slice(0, innerWidth - 1)}\\u2026]`\n}\n\nexport function prefixStyle(color: string): string {\n return `color: ${color}; font-weight: bold;`\n}\n","import { domainToColor } from './color.js'\nimport { getConfig } from './config.js'\nimport { formatPrefix, formatTimestamp, prefixStyle } from './formatter.js'\nimport type { Logger, LoggerOptions, LogLevel } from './types.js'\n\nconst LEVEL_RANK: Record<LogLevel, number> = {\n debug: 0,\n log: 1,\n info: 2,\n warn: 3,\n error: 4,\n}\n\n/**\n * A logger instance tied to a specific domain.\n * Outputs colored prefix badges to the browser console.\n *\n * @example\n * ```ts\n * const log = new LogPalette('auth', { color: '#7c3aed', level: 'info' })\n * log.info('User signed in', { userId: 42 })\n * // → [....auth] 05:35:41.039 User signed in { userId: 42 }\n * ```\n */\nexport class LogPalette implements Logger {\n readonly domain: string\n readonly color: string\n private _minLevel: number\n private _enabled: boolean\n\n /**\n * @param domain Service/feature name shown in the prefix badge (e.g. 'auth', 'api').\n * @param options Optional configuration for color, level filtering, and enabled state.\n */\n constructor(domain: string, options: LoggerOptions = {}) {\n this.domain = domain\n this.color = options.color ?? domainToColor(domain)\n this._minLevel = LEVEL_RANK[options.level ?? 'debug']\n this._enabled = options.enabled ?? true\n }\n\n /**\n * Dynamically change the minimum log level for this logger.\n * Useful for adjusting verbosity at runtime without recreating the logger.\n */\n setLevel(level: LogLevel): void {\n this._minLevel = LEVEL_RANK[level]\n }\n\n /**\n * Enable or disable this logger at runtime.\n * When disabled, all log calls are silently dropped.\n */\n setEnabled(enabled: boolean): void {\n this._enabled = enabled\n }\n\n private _log(level: LogLevel, args: unknown[]): void {\n if (!this._enabled) return\n if (LEVEL_RANK[level] < this._minLevel) return\n\n const prefix = formatPrefix(this.domain)\n const style = prefixStyle(this.color)\n const { timestamp } = getConfig()\n const time = timestamp ? ` ${formatTimestamp(new Date())}` : ''\n\n console[level](`%c${prefix}%c${time}`, style, '', ...args)\n }\n\n /** @inheritdoc */\n log(...args: unknown[]): void {\n this._log('log', args)\n }\n /** @inheritdoc */\n info(...args: unknown[]): void {\n this._log('info', args)\n }\n /** @inheritdoc */\n warn(...args: unknown[]): void {\n this._log('warn', args)\n }\n /** @inheritdoc */\n error(...args: unknown[]): void {\n this._log('error', args)\n }\n /** @inheritdoc */\n debug(...args: unknown[]): void {\n this._log('debug', args)\n }\n\n /**\n * Open a DevTools console group with the domain prefix applied to the label.\n * Always call `groupEnd()` to close it.\n *\n * @example\n * ```ts\n * apiLog.group('Fetch /users')\n * apiLog.info('response', data)\n * apiLog.groupEnd()\n * ```\n */\n group(label: string): void {\n if (!this._enabled) return\n const prefix = formatPrefix(this.domain)\n const style = prefixStyle(this.color)\n console.group(`%c${prefix}%c ${label}`, style, '')\n }\n\n /**\n * Open a collapsed DevTools console group with the domain prefix applied to the label.\n * Always call `groupEnd()` to close it.\n */\n groupCollapsed(label: string): void {\n if (!this._enabled) return\n const prefix = formatPrefix(this.domain)\n const style = prefixStyle(this.color)\n console.groupCollapsed(`%c${prefix}%c ${label}`, style, '')\n }\n\n /** Close the most recently opened group. */\n groupEnd(): void {\n console.groupEnd()\n }\n\n /**\n * Start a named performance timer, namespaced to this domain.\n * Use `timeEnd(label)` to stop it and log the elapsed time.\n *\n * @example\n * ```ts\n * authLog.time('login')\n * await performLogin()\n * authLog.timeEnd('login')\n * // DevTools: [....auth] login: 42.1ms\n * ```\n */\n time(label: string): void {\n if (!this._enabled) return\n console.time(`${formatPrefix(this.domain)} ${label}`)\n }\n\n /**\n * Stop the named timer started with `time(label)` and log the elapsed duration.\n * @param label Must match the label passed to `time()`.\n */\n timeEnd(label: string): void {\n if (!this._enabled) return\n console.timeEnd(`${formatPrefix(this.domain)} ${label}`)\n }\n}\n\n/**\n * Create a new logger for the given domain.\n * Each call creates a fresh instance; use `getLogger()` for singleton behavior.\n *\n * @param domain Service/feature name (e.g. 'auth', 'api', 'payments').\n * @param options Optional color, level, and enabled settings.\n *\n * @example\n * ```ts\n * const log = createLogger('auth')\n * log.info('App started')\n *\n * const payLog = createLogger('payments', { color: '#16a34a', level: 'warn' })\n * ```\n */\nexport function createLogger(domain: string, options?: LoggerOptions): Logger {\n return new LogPalette(domain, options)\n}\n","import { LogPalette } from './logger.js'\nimport type { Logger, LoggerOptions, LogLevel } from './types.js'\n\nconst _registry = new Map<string, LogPalette>()\n\n/**\n * Get or create a logger for the given domain.\n * Unlike `createLogger()`, this returns the same instance every time it is\n * called with the same domain — making it safe to call from multiple modules.\n *\n * Options are only applied on first call for a domain; subsequent calls with\n * the same domain return the existing instance regardless of options.\n *\n * @example\n * ```ts\n * // In module A\n * const log = getLogger('api')\n *\n * // In module B — same instance\n * const log = getLogger('api')\n * ```\n */\nexport function getLogger(domain: string, options?: LoggerOptions): Logger {\n let logger = _registry.get(domain)\n if (!logger) {\n logger = new LogPalette(domain, options)\n _registry.set(domain, logger)\n }\n return logger\n}\n\n/**\n * Return a read-only snapshot of all registered loggers, keyed by domain.\n * Useful for debugging or building DevTools integrations.\n *\n * @example\n * ```ts\n * const loggers = getAllLoggers()\n * console.log([...loggers.keys()]) // ['api', 'auth', 'payments']\n * ```\n */\nexport function getAllLoggers(): ReadonlyMap<string, Logger> {\n return _registry\n}\n\n/**\n * Set the minimum log level for every registered logger at once.\n * Loggers created after this call are not affected — they use their own\n * options or the default ('debug').\n *\n * Call this early in your app entry point to control verbosity globally:\n *\n * @example\n * ```ts\n * // Only show warnings and errors in production\n * if (import.meta.env.PROD) setGlobalLevel('warn')\n * ```\n */\nexport function setGlobalLevel(level: LogLevel): void {\n for (const logger of _registry.values()) {\n logger.setLevel(level)\n }\n}\n\n/**\n * Enable all registered loggers.\n *\n * @example\n * ```ts\n * enableAll()\n * ```\n */\nexport function enableAll(): void {\n for (const logger of _registry.values()) {\n logger.setEnabled(true)\n }\n}\n\n/**\n * Disable all registered loggers. All log calls will be silently dropped\n * until `enableAll()` or individual `setEnabled(true)` is called.\n *\n * @example\n * ```ts\n * // Silence everything in production builds\n * if (import.meta.env.PROD) disableAll()\n * ```\n */\nexport function disableAll(): void {\n for (const logger of _registry.values()) {\n logger.setEnabled(false)\n }\n}\n"],"mappings":"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"}
package/dist/index.mjs ADDED
@@ -0,0 +1,292 @@
1
+ //#region src/config.ts
2
+ const _config = {
3
+ innerWidth: 8,
4
+ timestamp: true
5
+ };
6
+ /**
7
+ * Read the current global configuration.
8
+ * Returns a snapshot — mutating the returned object has no effect.
9
+ */
10
+ function getConfig() {
11
+ return { ..._config };
12
+ }
13
+ /**
14
+ * Update one or more global format settings.
15
+ * Changes apply immediately to all subsequent log calls across all loggers.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * // Wider prefix column (good when you have long domain names)
20
+ * configure({ innerWidth: 12 })
21
+ *
22
+ * // Strip timestamps (cleaner in environments that add their own)
23
+ * configure({ timestamp: false })
24
+ * ```
25
+ */
26
+ function configure(options) {
27
+ if (options.innerWidth !== void 0) {
28
+ if (options.innerWidth < 1) throw new RangeError("innerWidth must be >= 1");
29
+ _config.innerWidth = options.innerWidth;
30
+ }
31
+ if (options.timestamp !== void 0) _config.timestamp = options.timestamp;
32
+ }
33
+ //#endregion
34
+ //#region src/color.ts
35
+ function djb2(str) {
36
+ let hash = 5381;
37
+ for (let i = 0; i < str.length; i++) {
38
+ hash = (hash << 5) + hash ^ str.charCodeAt(i);
39
+ hash = hash >>> 0;
40
+ }
41
+ return hash;
42
+ }
43
+ function domainToColor(domain) {
44
+ return `hsl(${djb2(domain) % 360}, 75%, 60%)`;
45
+ }
46
+ //#endregion
47
+ //#region src/formatter.ts
48
+ function formatTimestamp(date) {
49
+ return `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}:${String(date.getSeconds()).padStart(2, "0")}.${String(date.getMilliseconds()).padStart(3, "0")}`;
50
+ }
51
+ function formatPrefix(domain) {
52
+ const { innerWidth } = getConfig();
53
+ if (domain.length < innerWidth) return `[${".".repeat(innerWidth - domain.length)}${domain}]`;
54
+ if (domain.length === innerWidth) return `[${domain}]`;
55
+ return `[${domain.slice(0, innerWidth - 1)}\u2026]`;
56
+ }
57
+ function prefixStyle(color) {
58
+ return `color: ${color}; font-weight: bold;`;
59
+ }
60
+ //#endregion
61
+ //#region src/logger.ts
62
+ const LEVEL_RANK = {
63
+ debug: 0,
64
+ log: 1,
65
+ info: 2,
66
+ warn: 3,
67
+ error: 4
68
+ };
69
+ /**
70
+ * A logger instance tied to a specific domain.
71
+ * Outputs colored prefix badges to the browser console.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * const log = new LogPalette('auth', { color: '#7c3aed', level: 'info' })
76
+ * log.info('User signed in', { userId: 42 })
77
+ * // → [....auth] 05:35:41.039 User signed in { userId: 42 }
78
+ * ```
79
+ */
80
+ var LogPalette = class {
81
+ /**
82
+ * @param domain Service/feature name shown in the prefix badge (e.g. 'auth', 'api').
83
+ * @param options Optional configuration for color, level filtering, and enabled state.
84
+ */
85
+ constructor(domain, options = {}) {
86
+ this.domain = domain;
87
+ this.color = options.color ?? domainToColor(domain);
88
+ this._minLevel = LEVEL_RANK[options.level ?? "debug"];
89
+ this._enabled = options.enabled ?? true;
90
+ }
91
+ /**
92
+ * Dynamically change the minimum log level for this logger.
93
+ * Useful for adjusting verbosity at runtime without recreating the logger.
94
+ */
95
+ setLevel(level) {
96
+ this._minLevel = LEVEL_RANK[level];
97
+ }
98
+ /**
99
+ * Enable or disable this logger at runtime.
100
+ * When disabled, all log calls are silently dropped.
101
+ */
102
+ setEnabled(enabled) {
103
+ this._enabled = enabled;
104
+ }
105
+ _log(level, args) {
106
+ if (!this._enabled) return;
107
+ if (LEVEL_RANK[level] < this._minLevel) return;
108
+ const prefix = formatPrefix(this.domain);
109
+ const style = prefixStyle(this.color);
110
+ const { timestamp } = getConfig();
111
+ const time = timestamp ? ` ${formatTimestamp(/* @__PURE__ */ new Date())}` : "";
112
+ console[level](`%c${prefix}%c${time}`, style, "", ...args);
113
+ }
114
+ /** @inheritdoc */
115
+ log(...args) {
116
+ this._log("log", args);
117
+ }
118
+ /** @inheritdoc */
119
+ info(...args) {
120
+ this._log("info", args);
121
+ }
122
+ /** @inheritdoc */
123
+ warn(...args) {
124
+ this._log("warn", args);
125
+ }
126
+ /** @inheritdoc */
127
+ error(...args) {
128
+ this._log("error", args);
129
+ }
130
+ /** @inheritdoc */
131
+ debug(...args) {
132
+ this._log("debug", args);
133
+ }
134
+ /**
135
+ * Open a DevTools console group with the domain prefix applied to the label.
136
+ * Always call `groupEnd()` to close it.
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * apiLog.group('Fetch /users')
141
+ * apiLog.info('response', data)
142
+ * apiLog.groupEnd()
143
+ * ```
144
+ */
145
+ group(label) {
146
+ if (!this._enabled) return;
147
+ const prefix = formatPrefix(this.domain);
148
+ const style = prefixStyle(this.color);
149
+ console.group(`%c${prefix}%c ${label}`, style, "");
150
+ }
151
+ /**
152
+ * Open a collapsed DevTools console group with the domain prefix applied to the label.
153
+ * Always call `groupEnd()` to close it.
154
+ */
155
+ groupCollapsed(label) {
156
+ if (!this._enabled) return;
157
+ const prefix = formatPrefix(this.domain);
158
+ const style = prefixStyle(this.color);
159
+ console.groupCollapsed(`%c${prefix}%c ${label}`, style, "");
160
+ }
161
+ /** Close the most recently opened group. */
162
+ groupEnd() {
163
+ console.groupEnd();
164
+ }
165
+ /**
166
+ * Start a named performance timer, namespaced to this domain.
167
+ * Use `timeEnd(label)` to stop it and log the elapsed time.
168
+ *
169
+ * @example
170
+ * ```ts
171
+ * authLog.time('login')
172
+ * await performLogin()
173
+ * authLog.timeEnd('login')
174
+ * // DevTools: [....auth] login: 42.1ms
175
+ * ```
176
+ */
177
+ time(label) {
178
+ if (!this._enabled) return;
179
+ console.time(`${formatPrefix(this.domain)} ${label}`);
180
+ }
181
+ /**
182
+ * Stop the named timer started with `time(label)` and log the elapsed duration.
183
+ * @param label Must match the label passed to `time()`.
184
+ */
185
+ timeEnd(label) {
186
+ if (!this._enabled) return;
187
+ console.timeEnd(`${formatPrefix(this.domain)} ${label}`);
188
+ }
189
+ };
190
+ /**
191
+ * Create a new logger for the given domain.
192
+ * Each call creates a fresh instance; use `getLogger()` for singleton behavior.
193
+ *
194
+ * @param domain Service/feature name (e.g. 'auth', 'api', 'payments').
195
+ * @param options Optional color, level, and enabled settings.
196
+ *
197
+ * @example
198
+ * ```ts
199
+ * const log = createLogger('auth')
200
+ * log.info('App started')
201
+ *
202
+ * const payLog = createLogger('payments', { color: '#16a34a', level: 'warn' })
203
+ * ```
204
+ */
205
+ function createLogger(domain, options) {
206
+ return new LogPalette(domain, options);
207
+ }
208
+ //#endregion
209
+ //#region src/registry.ts
210
+ const _registry = /* @__PURE__ */ new Map();
211
+ /**
212
+ * Get or create a logger for the given domain.
213
+ * Unlike `createLogger()`, this returns the same instance every time it is
214
+ * called with the same domain — making it safe to call from multiple modules.
215
+ *
216
+ * Options are only applied on first call for a domain; subsequent calls with
217
+ * the same domain return the existing instance regardless of options.
218
+ *
219
+ * @example
220
+ * ```ts
221
+ * // In module A
222
+ * const log = getLogger('api')
223
+ *
224
+ * // In module B — same instance
225
+ * const log = getLogger('api')
226
+ * ```
227
+ */
228
+ function getLogger(domain, options) {
229
+ let logger = _registry.get(domain);
230
+ if (!logger) {
231
+ logger = new LogPalette(domain, options);
232
+ _registry.set(domain, logger);
233
+ }
234
+ return logger;
235
+ }
236
+ /**
237
+ * Return a read-only snapshot of all registered loggers, keyed by domain.
238
+ * Useful for debugging or building DevTools integrations.
239
+ *
240
+ * @example
241
+ * ```ts
242
+ * const loggers = getAllLoggers()
243
+ * console.log([...loggers.keys()]) // ['api', 'auth', 'payments']
244
+ * ```
245
+ */
246
+ function getAllLoggers() {
247
+ return _registry;
248
+ }
249
+ /**
250
+ * Set the minimum log level for every registered logger at once.
251
+ * Loggers created after this call are not affected — they use their own
252
+ * options or the default ('debug').
253
+ *
254
+ * Call this early in your app entry point to control verbosity globally:
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * // Only show warnings and errors in production
259
+ * if (import.meta.env.PROD) setGlobalLevel('warn')
260
+ * ```
261
+ */
262
+ function setGlobalLevel(level) {
263
+ for (const logger of _registry.values()) logger.setLevel(level);
264
+ }
265
+ /**
266
+ * Enable all registered loggers.
267
+ *
268
+ * @example
269
+ * ```ts
270
+ * enableAll()
271
+ * ```
272
+ */
273
+ function enableAll() {
274
+ for (const logger of _registry.values()) logger.setEnabled(true);
275
+ }
276
+ /**
277
+ * Disable all registered loggers. All log calls will be silently dropped
278
+ * until `enableAll()` or individual `setEnabled(true)` is called.
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * // Silence everything in production builds
283
+ * if (import.meta.env.PROD) disableAll()
284
+ * ```
285
+ */
286
+ function disableAll() {
287
+ for (const logger of _registry.values()) logger.setEnabled(false);
288
+ }
289
+ //#endregion
290
+ export { LogPalette, configure, createLogger, disableAll, enableAll, getAllLoggers, getConfig, getLogger, setGlobalLevel };
291
+
292
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/config.ts","../src/color.ts","../src/formatter.ts","../src/logger.ts","../src/registry.ts"],"sourcesContent":["/**\n * Global format configuration for log-palette.\n * Change these settings once to affect all loggers.\n */\nexport interface GlobalConfig {\n /**\n * Number of inner characters inside the prefix brackets.\n * Total prefix width = innerWidth + 2 (for the `[` and `]`).\n *\n * - Short domains are left-padded with dots to fill this width.\n * - Domains longer than this are truncated with `…`.\n *\n * @default 8 → prefix is always `[XXXXXXXX]` (10 chars total)\n */\n innerWidth: number\n\n /**\n * Whether to include a timestamp in each log line.\n * @default true\n */\n timestamp: boolean\n}\n\nconst _config: GlobalConfig = {\n innerWidth: 8,\n timestamp: true,\n}\n\n/**\n * Read the current global configuration.\n * Returns a snapshot — mutating the returned object has no effect.\n */\nexport function getConfig(): Readonly<GlobalConfig> {\n return { ..._config }\n}\n\n/**\n * Update one or more global format settings.\n * Changes apply immediately to all subsequent log calls across all loggers.\n *\n * @example\n * ```ts\n * // Wider prefix column (good when you have long domain names)\n * configure({ innerWidth: 12 })\n *\n * // Strip timestamps (cleaner in environments that add their own)\n * configure({ timestamp: false })\n * ```\n */\nexport function configure(options: Partial<GlobalConfig>): void {\n if (options.innerWidth !== undefined) {\n if (options.innerWidth < 1) throw new RangeError('innerWidth must be >= 1')\n _config.innerWidth = options.innerWidth\n }\n if (options.timestamp !== undefined) {\n _config.timestamp = options.timestamp\n }\n}\n","function djb2(str: string): number {\n let hash = 5381\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i)\n hash = hash >>> 0\n }\n return hash\n}\n\nexport function domainToColor(domain: string): string {\n const hue = djb2(domain) % 360\n return `hsl(${hue}, 75%, 60%)`\n}\n","import { getConfig } from './config.js'\n\nexport function formatTimestamp(date: Date): string {\n const h = String(date.getHours()).padStart(2, '0')\n const m = String(date.getMinutes()).padStart(2, '0')\n const s = String(date.getSeconds()).padStart(2, '0')\n const ms = String(date.getMilliseconds()).padStart(3, '0')\n return `${h}:${m}:${s}.${ms}`\n}\n\nexport function formatPrefix(domain: string): string {\n const { innerWidth } = getConfig()\n if (domain.length < innerWidth) {\n const dots = '.'.repeat(innerWidth - domain.length)\n return `[${dots}${domain}]`\n }\n if (domain.length === innerWidth) {\n return `[${domain}]`\n }\n // Truncate long domains: keep (innerWidth - 1) chars + ellipsis\n return `[${domain.slice(0, innerWidth - 1)}\\u2026]`\n}\n\nexport function prefixStyle(color: string): string {\n return `color: ${color}; font-weight: bold;`\n}\n","import { domainToColor } from './color.js'\nimport { getConfig } from './config.js'\nimport { formatPrefix, formatTimestamp, prefixStyle } from './formatter.js'\nimport type { Logger, LoggerOptions, LogLevel } from './types.js'\n\nconst LEVEL_RANK: Record<LogLevel, number> = {\n debug: 0,\n log: 1,\n info: 2,\n warn: 3,\n error: 4,\n}\n\n/**\n * A logger instance tied to a specific domain.\n * Outputs colored prefix badges to the browser console.\n *\n * @example\n * ```ts\n * const log = new LogPalette('auth', { color: '#7c3aed', level: 'info' })\n * log.info('User signed in', { userId: 42 })\n * // → [....auth] 05:35:41.039 User signed in { userId: 42 }\n * ```\n */\nexport class LogPalette implements Logger {\n readonly domain: string\n readonly color: string\n private _minLevel: number\n private _enabled: boolean\n\n /**\n * @param domain Service/feature name shown in the prefix badge (e.g. 'auth', 'api').\n * @param options Optional configuration for color, level filtering, and enabled state.\n */\n constructor(domain: string, options: LoggerOptions = {}) {\n this.domain = domain\n this.color = options.color ?? domainToColor(domain)\n this._minLevel = LEVEL_RANK[options.level ?? 'debug']\n this._enabled = options.enabled ?? true\n }\n\n /**\n * Dynamically change the minimum log level for this logger.\n * Useful for adjusting verbosity at runtime without recreating the logger.\n */\n setLevel(level: LogLevel): void {\n this._minLevel = LEVEL_RANK[level]\n }\n\n /**\n * Enable or disable this logger at runtime.\n * When disabled, all log calls are silently dropped.\n */\n setEnabled(enabled: boolean): void {\n this._enabled = enabled\n }\n\n private _log(level: LogLevel, args: unknown[]): void {\n if (!this._enabled) return\n if (LEVEL_RANK[level] < this._minLevel) return\n\n const prefix = formatPrefix(this.domain)\n const style = prefixStyle(this.color)\n const { timestamp } = getConfig()\n const time = timestamp ? ` ${formatTimestamp(new Date())}` : ''\n\n console[level](`%c${prefix}%c${time}`, style, '', ...args)\n }\n\n /** @inheritdoc */\n log(...args: unknown[]): void {\n this._log('log', args)\n }\n /** @inheritdoc */\n info(...args: unknown[]): void {\n this._log('info', args)\n }\n /** @inheritdoc */\n warn(...args: unknown[]): void {\n this._log('warn', args)\n }\n /** @inheritdoc */\n error(...args: unknown[]): void {\n this._log('error', args)\n }\n /** @inheritdoc */\n debug(...args: unknown[]): void {\n this._log('debug', args)\n }\n\n /**\n * Open a DevTools console group with the domain prefix applied to the label.\n * Always call `groupEnd()` to close it.\n *\n * @example\n * ```ts\n * apiLog.group('Fetch /users')\n * apiLog.info('response', data)\n * apiLog.groupEnd()\n * ```\n */\n group(label: string): void {\n if (!this._enabled) return\n const prefix = formatPrefix(this.domain)\n const style = prefixStyle(this.color)\n console.group(`%c${prefix}%c ${label}`, style, '')\n }\n\n /**\n * Open a collapsed DevTools console group with the domain prefix applied to the label.\n * Always call `groupEnd()` to close it.\n */\n groupCollapsed(label: string): void {\n if (!this._enabled) return\n const prefix = formatPrefix(this.domain)\n const style = prefixStyle(this.color)\n console.groupCollapsed(`%c${prefix}%c ${label}`, style, '')\n }\n\n /** Close the most recently opened group. */\n groupEnd(): void {\n console.groupEnd()\n }\n\n /**\n * Start a named performance timer, namespaced to this domain.\n * Use `timeEnd(label)` to stop it and log the elapsed time.\n *\n * @example\n * ```ts\n * authLog.time('login')\n * await performLogin()\n * authLog.timeEnd('login')\n * // DevTools: [....auth] login: 42.1ms\n * ```\n */\n time(label: string): void {\n if (!this._enabled) return\n console.time(`${formatPrefix(this.domain)} ${label}`)\n }\n\n /**\n * Stop the named timer started with `time(label)` and log the elapsed duration.\n * @param label Must match the label passed to `time()`.\n */\n timeEnd(label: string): void {\n if (!this._enabled) return\n console.timeEnd(`${formatPrefix(this.domain)} ${label}`)\n }\n}\n\n/**\n * Create a new logger for the given domain.\n * Each call creates a fresh instance; use `getLogger()` for singleton behavior.\n *\n * @param domain Service/feature name (e.g. 'auth', 'api', 'payments').\n * @param options Optional color, level, and enabled settings.\n *\n * @example\n * ```ts\n * const log = createLogger('auth')\n * log.info('App started')\n *\n * const payLog = createLogger('payments', { color: '#16a34a', level: 'warn' })\n * ```\n */\nexport function createLogger(domain: string, options?: LoggerOptions): Logger {\n return new LogPalette(domain, options)\n}\n","import { LogPalette } from './logger.js'\nimport type { Logger, LoggerOptions, LogLevel } from './types.js'\n\nconst _registry = new Map<string, LogPalette>()\n\n/**\n * Get or create a logger for the given domain.\n * Unlike `createLogger()`, this returns the same instance every time it is\n * called with the same domain — making it safe to call from multiple modules.\n *\n * Options are only applied on first call for a domain; subsequent calls with\n * the same domain return the existing instance regardless of options.\n *\n * @example\n * ```ts\n * // In module A\n * const log = getLogger('api')\n *\n * // In module B — same instance\n * const log = getLogger('api')\n * ```\n */\nexport function getLogger(domain: string, options?: LoggerOptions): Logger {\n let logger = _registry.get(domain)\n if (!logger) {\n logger = new LogPalette(domain, options)\n _registry.set(domain, logger)\n }\n return logger\n}\n\n/**\n * Return a read-only snapshot of all registered loggers, keyed by domain.\n * Useful for debugging or building DevTools integrations.\n *\n * @example\n * ```ts\n * const loggers = getAllLoggers()\n * console.log([...loggers.keys()]) // ['api', 'auth', 'payments']\n * ```\n */\nexport function getAllLoggers(): ReadonlyMap<string, Logger> {\n return _registry\n}\n\n/**\n * Set the minimum log level for every registered logger at once.\n * Loggers created after this call are not affected — they use their own\n * options or the default ('debug').\n *\n * Call this early in your app entry point to control verbosity globally:\n *\n * @example\n * ```ts\n * // Only show warnings and errors in production\n * if (import.meta.env.PROD) setGlobalLevel('warn')\n * ```\n */\nexport function setGlobalLevel(level: LogLevel): void {\n for (const logger of _registry.values()) {\n logger.setLevel(level)\n }\n}\n\n/**\n * Enable all registered loggers.\n *\n * @example\n * ```ts\n * enableAll()\n * ```\n */\nexport function enableAll(): void {\n for (const logger of _registry.values()) {\n logger.setEnabled(true)\n }\n}\n\n/**\n * Disable all registered loggers. All log calls will be silently dropped\n * until `enableAll()` or individual `setEnabled(true)` is called.\n *\n * @example\n * ```ts\n * // Silence everything in production builds\n * if (import.meta.env.PROD) disableAll()\n * ```\n */\nexport function disableAll(): void {\n for (const logger of _registry.values()) {\n logger.setEnabled(false)\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function domainToColor(domain: string): string;