@vielzeug/logit 1.1.2 → 2.1.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/logit.js CHANGED
@@ -1,273 +1,196 @@
1
- const E = {};
2
- const $ = {
3
- debug: "log",
4
- success: "log"
5
- }, l = {
6
- debug: 0,
7
- trace: 1,
8
- time: 2,
9
- table: 3,
10
- info: 4,
11
- success: 5,
12
- warn: 6,
13
- error: 7,
14
- off: 8
15
- }, w = typeof window < "u" && window.matchMedia?.("(prefers-color-scheme: dark)").matches, p = {
16
- debug: { bg: "#616161", border: "#424242", color: "#fff", icon: "☕", symbol: "🅳" },
17
- error: { bg: "#d32f2f", border: "#c62828", color: "#fff", icon: "✘", symbol: "🅴" },
18
- group: { bg: "#546e7a", border: "#455a64", color: "#fff", icon: "⚭", symbol: "🅶" },
19
- info: { bg: "#1976d2", border: "#1565c0", color: "#fff", icon: "ℹ", symbol: "🅸" },
20
- ns: w ? { bg: "#fafafa", border: "#c7c7c7", color: "#000" } : { bg: "#424242", border: "#212121", color: "#fff" },
21
- success: { bg: "#689f38", border: "#558b2f", color: "#fff", icon: "✔", symbol: "🆂" },
22
- time: { bg: "#0097a7", border: "#00838f", color: "#fff", icon: "", symbol: "🆃" },
23
- trace: { bg: "#d81b60", border: "#c2185b", color: "#fff", icon: "⛢", symbol: "🆃" },
24
- warn: { bg: "#ffb300", border: "#ffa000", color: "#fff", icon: "⚠", symbol: "🆆" }
25
- }, b = "border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;";
26
- function L() {
27
- return typeof window < "u" && E?.NODE_ENV === "production" ? !0 : typeof process < "u" && process.env?.NODE_ENV === "production";
28
- }
29
- const v = L(), o = {
30
- environment: !0,
31
- logLevel: "debug",
32
- namespace: "",
33
- remote: { handler: void 0, logLevel: "off" },
34
- timestamp: !0,
35
- variant: "symbol"
1
+ //#region src/logit.ts
2
+ var e = {
3
+ debug: 0,
4
+ error: 5,
5
+ info: 2,
6
+ off: 6,
7
+ success: 3,
8
+ trace: 1,
9
+ warn: 4
10
+ }, t = {
11
+ debug: {
12
+ bg: "#616161",
13
+ border: "#424242",
14
+ color: "#fff",
15
+ icon: "",
16
+ symbol: "🅳"
17
+ },
18
+ error: {
19
+ bg: "#d32f2f",
20
+ border: "#c62828",
21
+ color: "#fff",
22
+ icon: "",
23
+ symbol: "🅴"
24
+ },
25
+ group: {
26
+ bg: "#546e7a",
27
+ border: "#455a64",
28
+ color: "#fff",
29
+ icon: "⚭",
30
+ symbol: "🅶"
31
+ },
32
+ info: {
33
+ bg: "#1976d2",
34
+ border: "#1565c0",
35
+ color: "#fff",
36
+ icon: "ℹ",
37
+ symbol: "🅸"
38
+ },
39
+ ns: typeof window < "u" && window.matchMedia?.("(prefers-color-scheme: dark)").matches ? {
40
+ bg: "#fafafa",
41
+ border: "#c7c7c7",
42
+ color: "#000"
43
+ } : {
44
+ bg: "#424242",
45
+ border: "#212121",
46
+ color: "#fff"
47
+ },
48
+ success: {
49
+ bg: "#689f38",
50
+ border: "#558b2f",
51
+ color: "#fff",
52
+ icon: "✔",
53
+ symbol: "🆂"
54
+ },
55
+ trace: {
56
+ bg: "#d81b60",
57
+ border: "#c2185b",
58
+ color: "#fff",
59
+ icon: "⛢",
60
+ symbol: "🆃"
61
+ },
62
+ warn: {
63
+ bg: "#ffb300",
64
+ border: "#ffa000",
65
+ color: "#fff",
66
+ icon: "⚠",
67
+ symbol: "🆆"
68
+ }
69
+ }, n = "border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;", r = typeof window > "u", i = r ? process.env.NODE_ENV === "production" : !1, a = i ? "🅿" : "🅳", o = {
70
+ debug: "log",
71
+ error: "error",
72
+ info: "info",
73
+ success: "log",
74
+ trace: "trace",
75
+ warn: "warn"
36
76
  };
37
- function a(e) {
38
- return l[o.logLevel] <= l[e];
39
- }
40
- function g() {
41
- return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
42
- }
43
- function d() {
44
- return v ? "🅿" : "🅳";
45
- }
46
- function _(e, t) {
47
- const { handler: r, logLevel: n } = o.remote;
48
- r && l[n] <= l[e] && Promise.resolve().then(() => {
49
- r(e, {
50
- args: t,
51
- environment: v ? "production" : "development",
52
- namespace: o.namespace || void 0,
53
- timestamp: o.timestamp ? g() : void 0
54
- });
55
- });
56
- }
57
- function u(e) {
58
- return $[e] || e;
59
- }
60
- function f(e, t = "") {
61
- const { bg: r, color: n, border: s } = p[e], c = `border: 1px solid ${s}; border-radius: 4px`;
62
- switch (o.variant) {
63
- case "symbol":
64
- case "icon":
65
- return `color: ${r}; ${c}; padding: 0 3px${t}`;
66
- default:
67
- return `background: ${r}; color: ${n}; ${c}; font-weight: bold; padding: 0 3px${t}`;
68
- }
77
+ function s(c = {}) {
78
+ let l = typeof c == "string" ? { namespace: c } : c, u = {
79
+ environment: !0,
80
+ logLevel: "debug",
81
+ namespace: "",
82
+ timestamp: !0,
83
+ variant: "symbol",
84
+ ...l,
85
+ remote: {
86
+ logLevel: "debug",
87
+ ...l.remote
88
+ }
89
+ }, d = (t) => e[u.logLevel] <= e[t], f = () => (/* @__PURE__ */ new Date()).toISOString().slice(11, 23), p = (e) => {
90
+ let n = t[e];
91
+ return u.variant === "text" || !n[u.variant] ? e.toUpperCase() : n[u.variant];
92
+ }, m = (e, n = "") => {
93
+ let { bg: r, border: i, color: a } = t[e], o = `border: 1px solid ${i}; border-radius: 4px`;
94
+ switch (u.variant) {
95
+ case "icon": return `color: ${r}; ${o}; padding: 0 3px${n}`;
96
+ case "symbol": return `color: ${r}; ${o}; padding: 0 1px${n}`;
97
+ default: return `background: ${r}; color: ${a}; ${o}; font-weight: bold; padding: 0 3px${n}`;
98
+ }
99
+ }, h = (e, t, n, r) => {
100
+ let i = [p(e)];
101
+ u.environment && i.push(a), t && i.push(`[${t}]`), n && i.push(n);
102
+ let s = console[o[e]];
103
+ s(`${i.join(" | ")} |`, ...r);
104
+ }, g = (e, t, r, i) => {
105
+ let s = `%c${p(e)}%c`, c = [m(e), ""];
106
+ t && (s += ` %c${t}%c`, c.push(m("ns", `; ${n}`), "")), u.environment && (s += ` %c${a}%c`, c.push("color: darkgray", "")), r && (s += ` %c${r}%c`, c.push("color: gray", ""));
107
+ let l = console[o[e]];
108
+ l(s, ...c, ...i);
109
+ }, _ = (t, n) => {
110
+ if (!d(t)) return;
111
+ let a = u.namespace, o = u.timestamp ? f() : "";
112
+ r ? h(t, a, o, n) : g(t, a, o, n);
113
+ let { handler: s, logLevel: c } = u.remote;
114
+ if (s && e[c] <= e[t]) {
115
+ let e = {
116
+ args: n,
117
+ env: i ? "production" : "development",
118
+ namespace: a || void 0,
119
+ timestamp: u.timestamp ? (/* @__PURE__ */ new Date()).toISOString() : void 0
120
+ };
121
+ Promise.resolve().then(() => s(t, e)).catch(() => {});
122
+ }
123
+ }, v = (e) => u.namespace ? `[${u.namespace}] ${e}` : e, y = (e = {}) => {
124
+ let { remote: t, ...n } = e;
125
+ return s({
126
+ ...u,
127
+ ...n,
128
+ remote: {
129
+ ...u.remote,
130
+ ...t
131
+ }
132
+ });
133
+ }, b = (e, t, n, r) => {
134
+ let i = e ? console.groupCollapsed : console.group, o = [p("group")];
135
+ u.environment && o.push(a), o.push(t), n && o.push(`[${n}]`), r && o.push(r), i(o.join(" | "));
136
+ }, x = (e, t, r, i) => {
137
+ let o = e ? console.groupCollapsed : console.group, s = `%c${t}%c`, c = [m("group", "; margin-right: 6px; padding: 1px 3px 0"), ""];
138
+ r && (s += ` %c${r}%c`, c.push(m("ns", `; ${n}; margin-right: 6px`), "")), u.environment && (s += ` %c${a}%c`, c.push("color: darkgray; margin-right: 6px", "")), i && (s += ` %c${i}%c`, c.push("color: gray; font-weight: lighter; margin-right: 6px", "")), o(s, ...c);
139
+ }, S = (e, t) => {
140
+ let n = u.namespace, i = u.timestamp ? f() : "";
141
+ r ? b(e, t, n, i) : x(e, t, n, i);
142
+ }, C = {
143
+ assert: (e, ...t) => {
144
+ d("error") && console.assert(e, ...t);
145
+ },
146
+ child: y,
147
+ get config() {
148
+ return {
149
+ ...u,
150
+ remote: { ...u.remote }
151
+ };
152
+ },
153
+ debug: (...e) => _("debug", e),
154
+ enabled: (e) => d(e),
155
+ error: (...e) => _("error", e),
156
+ group: (e, t, n = !1) => {
157
+ if (!d("debug")) return t();
158
+ S(n, e);
159
+ try {
160
+ let e = t();
161
+ return e instanceof Promise ? e.finally(() => console.groupEnd()) : (console.groupEnd(), e);
162
+ } catch (e) {
163
+ throw console.groupEnd(), e;
164
+ }
165
+ },
166
+ info: (...e) => _("info", e),
167
+ scope: (e) => y({ namespace: u.namespace ? `${u.namespace}.${e}` : e }),
168
+ setConfig: (e) => {
169
+ let { remote: t, ...n } = e;
170
+ return t !== void 0 && Object.assign(u.remote, t), Object.assign(u, n), C;
171
+ },
172
+ success: (...e) => _("success", e),
173
+ table: (e, t) => {
174
+ d("debug") && console.table(e, t);
175
+ },
176
+ time: (e, t) => {
177
+ if (!d("debug")) return t();
178
+ let n = v(e);
179
+ console.time(n);
180
+ try {
181
+ let e = t();
182
+ return e instanceof Promise ? e.finally(() => console.timeEnd(n)) : (console.timeEnd(n), e);
183
+ } catch (e) {
184
+ throw console.timeEnd(n), e;
185
+ }
186
+ },
187
+ trace: (...e) => _("trace", e),
188
+ warn: (...e) => _("warn", e)
189
+ };
190
+ return C;
69
191
  }
70
- function h(e) {
71
- if (e === "table")
72
- return e.toUpperCase();
73
- const t = p[e], { variant: r } = o;
74
- return r === "text" || !t[r] ? e.toUpperCase() : t[r];
75
- }
76
- function x(e) {
77
- const { namespace: t, timestamp: r, environment: n } = o;
78
- let s = `%c${h(e)}%c`;
79
- const c = [f(e), ""];
80
- return t && (s += ` %c${t}%c`, c.push(f("ns", `; ${b}`), "")), n && (s += ` %c${d()}%c`, c.push("color: darkgray", "")), r && (s += ` %c${g()}%c`, c.push("color: gray", "")), { format: s, parts: c };
81
- }
82
- function i(e, ...t) {
83
- if (typeof window > "u") {
84
- const c = console[u(e)];
85
- c(`${h(e)} | ${d()} |`, ...t);
86
- return;
87
- }
88
- if (!a(e)) return;
89
- const { format: r, parts: n } = x(e), s = console[u(e)];
90
- s(r, ...n, ...t), _(e, t);
91
- }
92
- function O(e) {
93
- const t = o.namespace, r = t ? `${t}.${e}` : e, n = (s) => (...c) => {
94
- const m = o.namespace;
95
- o.namespace = r, i(s, ...c), o.namespace = m;
96
- };
97
- return {
98
- debug: n("debug"),
99
- error: n("error"),
100
- info: n("info"),
101
- success: n("success"),
102
- trace: n("trace"),
103
- warn: n("warn")
104
- };
105
- }
106
- const D = {
107
- /**
108
- * Asserts a condition and logs if false.
109
- */
110
- assert: (e, t, r) => {
111
- console.assert(e, t, r);
112
- },
113
- /**
114
- * Logs a debug message.
115
- */
116
- debug: (...e) => i("debug", ...e),
117
- /**
118
- * Logs an error message.
119
- */
120
- error: (...e) => i("error", ...e),
121
- /**
122
- * Gets environment indicator visibility.
123
- */
124
- getEnvironment: () => o.environment,
125
- /**
126
- * Gets the current log level.
127
- */
128
- getLevel: () => o.logLevel,
129
- /**
130
- * Gets the current namespace.
131
- */
132
- getPrefix: () => o.namespace,
133
- /**
134
- * Gets timestamp visibility.
135
- */
136
- getTimestamp: () => o.timestamp,
137
- /**
138
- * Gets the current variant.
139
- */
140
- getVariant: () => o.variant,
141
- /**
142
- * Creates a collapsed console group.
143
- */
144
- groupCollapsed: (e, t = "GROUP", r = Date.now()) => {
145
- if (!a("success")) return;
146
- const n = Date.now() - r, s = n ? `${n}ms` : "", c = d(), m = o.timestamp ? g() : "";
147
- console.groupCollapsed(
148
- `%c${t}%c${o.namespace}%c${c}%c${m}%c${s}%c${e}`,
149
- f("group", "; margin-right: 6px; padding: 1px 3px 0"),
150
- f("ns", `; ${b}; margin-right: 6px`),
151
- "color: darkgray; margin-right: 6px",
152
- "color: gray; font-weight: lighter; margin-right: 6px",
153
- "color: gray; font-weight: lighter; margin-right: 6px",
154
- "color: inherit; font-weight: lighter"
155
- );
156
- },
157
- /**
158
- * Ends the current console group.
159
- */
160
- groupEnd: () => {
161
- a("success") && console.groupEnd();
162
- },
163
- /**
164
- * Logs an info message.
165
- */
166
- info: (...e) => i("info", ...e),
167
- /**
168
- * Creates a scoped logger with a namespace.
169
- *
170
- * @example
171
- * ```ts
172
- * const apiLogger = Logit.scope('api');
173
- * apiLogger.info('Request received'); // [api] Request received
174
- * ```
175
- */
176
- scope: (e) => O(e),
177
- /**
178
- * Sets the minimum log level.
179
- */
180
- setLogLevel: (e) => {
181
- o.logLevel = e;
182
- },
183
- /**
184
- * Sets the global namespace prefix.
185
- */
186
- setPrefix: (e) => {
187
- o.namespace = e;
188
- },
189
- /**
190
- * Sets the remote logging options.
191
- */
192
- setRemote: (e) => {
193
- o.remote = { ...o.remote, ...e };
194
- },
195
- /**
196
- * Sets the remote log level.
197
- */
198
- setRemoteLogLevel: (e) => {
199
- o.remote.logLevel = e;
200
- },
201
- /**
202
- * Configures Logit with options.
203
- *
204
- * @example
205
- * ```ts
206
- * Logit.setup({
207
- * logLevel: 'info',
208
- * variant: 'text',
209
- * timestamp: false
210
- * });
211
- * ```
212
- */
213
- setup: (e) => {
214
- if (e.remote) {
215
- o.remote = { ...o.remote, ...e.remote };
216
- const { remote: t, ...r } = e;
217
- Object.assign(o, r);
218
- } else
219
- Object.assign(o, e);
220
- },
221
- /**
222
- * Sets the display variant.
223
- */
224
- setVariant: (e) => {
225
- o.variant = e;
226
- },
227
- /**
228
- * Logs a success message.
229
- */
230
- success: (...e) => i("success", ...e),
231
- /**
232
- * Displays data in a table format.
233
- */
234
- table: (...e) => {
235
- a("table") && console.table(...e);
236
- },
237
- /**
238
- * Starts a timer.
239
- */
240
- time: (e) => {
241
- a("time") && console.time(e);
242
- },
243
- /**
244
- * Ends a timer.
245
- */
246
- timeEnd: (e) => {
247
- a("time") && console.timeEnd(e);
248
- },
249
- /**
250
- * Toggles or sets environment indicator visibility.
251
- */
252
- toggleEnvironment: (e) => {
253
- o.environment = e ?? !o.environment;
254
- },
255
- /**
256
- * Toggles or sets timestamp visibility.
257
- */
258
- toggleTimestamp: (e) => {
259
- o.timestamp = e ?? !o.timestamp;
260
- },
261
- /**
262
- * Logs a trace message.
263
- */
264
- trace: (...e) => i("trace", ...e),
265
- /**
266
- * Logs a warning message.
267
- */
268
- warn: (...e) => i("warn", ...e)
269
- };
270
- export {
271
- D as Logit
272
- };
273
- //# sourceMappingURL=logit.js.map
192
+ var c = s();
193
+ //#endregion
194
+ export { c as Logit, s as createLogger };
195
+
196
+ //# 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/noExplicitAny: - */\n\n/* -------------------- Core Types -------------------- */\n\nexport type LogLevel = 'debug' | 'trace' | 'time' | 'table' | 'info' | 'success' | 'warn' | 'error' | 'off';\nexport type LogType = Exclude<LogLevel, 'off'>;\nexport type ColorType = Exclude<LogType, 'table'> | 'group' | 'ns';\nexport type Variant = 'text' | 'symbol' | 'icon';\n\nexport type RemoteOptions = {\n handler?: (type: LogType, data: RemoteLogData) => void;\n logLevel?: LogLevel;\n};\n\nexport type RemoteLogData = {\n args: unknown[];\n environment: 'production' | 'development';\n namespace?: string;\n timestamp?: string;\n};\n\nexport type LogitOptions = {\n environment?: boolean;\n variant?: Variant;\n logLevel?: LogLevel;\n namespace?: string;\n remote?: RemoteOptions;\n timestamp?: boolean;\n};\n\nexport type ScopedLogger = {\n debug: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n success: (...args: unknown[]) => void;\n trace: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n};\n\n/* -------------------- Constants -------------------- */\n\nconst ENV_PROD = '🅿';\nconst ENV_DEV = '🅳';\n\nconst CONSOLE_METHOD_MAP: Partial<Record<LogType, keyof Console>> = {\n debug: 'log',\n success: 'log',\n};\n\n// biome-ignore assist/source/useSortedKeys: -\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, 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\n/* -------------------- Theme & Styles -------------------- */\n\ntype Theme = {\n color: string;\n bg: string;\n border: string;\n icon?: string;\n symbol?: string;\n};\n\nconst isDarkMode = typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches;\n\nconst THEME: Record<ColorType, Theme> = {\n debug: { bg: '#616161', border: '#424242', color: '#fff', icon: '☕', symbol: '🅳' },\n error: { bg: '#d32f2f', border: '#c62828', color: '#fff', icon: '✘', symbol: '🅴' },\n group: { bg: '#546e7a', border: '#455a64', color: '#fff', icon: '⚭', symbol: '🅶' },\n info: { bg: '#1976d2', border: '#1565c0', color: '#fff', icon: 'ℹ', symbol: '🅸' },\n ns: isDarkMode\n ? { bg: '#fafafa', border: '#c7c7c7', color: '#000' }\n : { bg: '#424242', border: '#212121', color: '#fff' },\n success: { bg: '#689f38', border: '#558b2f', color: '#fff', icon: '✔', symbol: '🆂' },\n time: { bg: '#0097a7', border: '#00838f', color: '#fff', icon: '⏲', symbol: '🆃' },\n trace: { bg: '#d81b60', border: '#c2185b', color: '#fff', icon: '⛢', symbol: '🆃' },\n warn: { bg: '#ffb300', border: '#ffa000', color: '#fff', icon: '⚠', symbol: '🆆' },\n};\n\nconst NAMESPACE_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;';\n\n/* -------------------- Environment Detection -------------------- */\n\n/**\n * Detects if running in a production environment.\n * Checks both browser (import.meta.env) and Node.js (process.env).\n */\nfunction isProduction(): boolean {\n // Browser environment (Vite, Webpack, etc.)\n if (typeof window !== 'undefined' && (import.meta as any)?.env?.NODE_ENV === 'production') {\n return true;\n }\n\n // @ts-expect-error - process.env exists in Node.js but not in a browser\n return typeof process !== 'undefined' && (process as any).env?.NODE_ENV === 'production';\n}\n\nconst IS_PROD = isProduction();\n\n/* -------------------- State -------------------- */\n\nconst state: Required<LogitOptions> & { remote: Required<RemoteOptions> } = {\n environment: true,\n logLevel: 'debug',\n namespace: '',\n remote: { handler: undefined as any, logLevel: 'off' },\n timestamp: true,\n variant: 'symbol',\n};\n\n/* -------------------- Helper Functions -------------------- */\n\n/**\n * Checks if a log should be displayed based on the current log level.\n */\nfunction shouldLog(type: LogType): boolean {\n return LOG_LEVEL_PRIORITY[state.logLevel] <= LOG_LEVEL_PRIORITY[type];\n}\n\n/**\n * Gets the current timestamp in HH:MM:SS.mmm format.\n */\nfunction getTimestamp(): string {\n return new Date().toISOString().slice(11, 23);\n}\n\n/**\n * Gets environment indicator emoji.\n */\nfunction getEnvIndicator(): string {\n return IS_PROD ? ENV_PROD : ENV_DEV;\n}\n\n/**\n * Sends log to remote handler if configured.\n */\nfunction sendRemote(type: LogType, args: unknown[]): void {\n const { handler, logLevel } = state.remote;\n\n if (handler && LOG_LEVEL_PRIORITY[logLevel] <= LOG_LEVEL_PRIORITY[type]) {\n // Use microtask to make async without setTimeout overhead\n Promise.resolve().then(() => {\n handler(type, {\n args,\n environment: IS_PROD ? 'production' : 'development',\n namespace: state.namespace || undefined,\n timestamp: state.timestamp ? getTimestamp() : undefined,\n });\n });\n }\n}\n\n/**\n * Gets the console method for a log type.\n */\nfunction getConsoleMethod(type: LogType): keyof Console {\n return (CONSOLE_METHOD_MAP[type] || type) as keyof Console;\n}\n\n/**\n * Generates CSS style for a log type.\n */\nfunction getStyle(type: ColorType, extra = ''): string {\n const { bg, color, border } = THEME[type];\n const baseStyle = `border: 1px solid ${border}; border-radius: 4px`;\n\n switch (state.variant) {\n case 'symbol':\n case 'icon':\n return `color: ${bg}; ${baseStyle}; padding: 0 3px${extra}`;\n default:\n return `background: ${bg}; color: ${color}; ${baseStyle}; font-weight: bold; padding: 0 3px${extra}`;\n }\n}\n\n/**\n * Gets display value for a log type based on variant.\n */\nfunction getDisplayValue(type: LogType): string {\n // Table doesn't have a theme, return uppercase\n if (type === 'table') {\n return type.toUpperCase();\n }\n\n const theme = THEME[type as ColorType];\n const { variant } = state;\n\n if (variant === 'text' || !theme[variant]) {\n return type.toUpperCase();\n }\n\n return theme[variant]!;\n}\n\n/**\n * Builds browser console format string and style parts.\n */\nfunction buildLogParts(type: LogType): { format: string; parts: string[] } {\n const { namespace, timestamp, environment } = state;\n\n let format = `%c${getDisplayValue(type)}%c`;\n // Table doesn't have styling, but this is only called for types that do\n const parts: string[] = [getStyle(type as ColorType), ''];\n\n if (namespace) {\n format += ` %c${namespace}%c`;\n parts.push(getStyle('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${getTimestamp()}%c`;\n parts.push('color: gray', '');\n }\n\n return { format, parts };\n}\n\n/**\n * Core logging function.\n */\nfunction log(type: LogType, ...args: unknown[]): void {\n // Node.js logging (simplified)\n if (typeof window === 'undefined') {\n const method = console[getConsoleMethod(type)] as (...a: unknown[]) => void;\n method(`${getDisplayValue(type)} | ${getEnvIndicator()} |`, ...args);\n return;\n }\n\n // Check the log level\n if (!shouldLog(type)) return;\n\n // Browser logging with styles\n const { format, parts } = buildLogParts(type);\n const method = console[getConsoleMethod(type)] as (...a: unknown[]) => void;\n\n method(format, ...parts, ...args);\n sendRemote(type, args);\n}\n\n/**\n * Creates a scoped logger without mutating global state.\n */\nfunction createScopedLogger(scopeName: string): ScopedLogger {\n const originalNamespace = state.namespace;\n const fullNamespace = originalNamespace ? `${originalNamespace}.${scopeName}` : scopeName;\n\n const createMethod = (type: LogType) => {\n return (...args: unknown[]) => {\n const prev = state.namespace;\n state.namespace = fullNamespace;\n log(type, ...args);\n state.namespace = prev;\n };\n };\n\n return {\n debug: createMethod('debug'),\n error: createMethod('error'),\n info: createMethod('info'),\n success: createMethod('success'),\n trace: createMethod('trace'),\n warn: createMethod('warn'),\n };\n}\n\n/* -------------------- Public API -------------------- */\n\nexport const Logit = {\n /**\n * Asserts a condition and logs if false.\n */\n assert: (condition: boolean, message: string, context?: Record<string, unknown>): void => {\n console.assert(condition, message, context);\n },\n /**\n * Logs a debug message.\n */\n debug: (...args: unknown[]): void => log('debug', ...args),\n\n /**\n * Logs an error message.\n */\n error: (...args: unknown[]): void => log('error', ...args),\n\n /**\n * Gets environment indicator visibility.\n */\n getEnvironment: (): boolean => state.environment,\n\n /**\n * Gets the current log level.\n */\n getLevel: (): LogLevel => state.logLevel,\n\n /**\n * Gets the current namespace.\n */\n getPrefix: (): string => state.namespace,\n\n /**\n * Gets timestamp visibility.\n */\n getTimestamp: (): boolean => state.timestamp,\n\n /**\n * Gets the current variant.\n */\n getVariant: (): Variant => state.variant,\n\n /**\n * Creates a collapsed console group.\n */\n groupCollapsed: (text: string, label = 'GROUP', startTime = Date.now()): void => {\n if (!shouldLog('success')) return;\n\n const elapsed = Date.now() - startTime;\n const elapsedStr = elapsed ? `${elapsed}ms` : '';\n const env = getEnvIndicator();\n const timestamp = state.timestamp ? getTimestamp() : '';\n\n console.groupCollapsed(\n `%c${label}%c${state.namespace}%c${env}%c${timestamp}%c${elapsedStr}%c${text}`,\n getStyle('group', '; margin-right: 6px; padding: 1px 3px 0'),\n getStyle('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 /**\n * Logs an info message.\n */\n info: (...args: unknown[]): void => log('info', ...args),\n\n /**\n * Creates a scoped logger with a namespace.\n *\n * @example\n * ```ts\n * const apiLogger = Logit.scope('api');\n * apiLogger.info('Request received'); // [api] Request received\n * ```\n */\n scope: (namespace: string): ScopedLogger => createScopedLogger(namespace),\n\n /**\n * Sets the minimum log level.\n */\n setLogLevel: (level: LogLevel): void => {\n state.logLevel = level;\n },\n\n /**\n * Sets the global namespace prefix.\n */\n setPrefix: (namespace: string): void => {\n state.namespace = namespace;\n },\n\n /**\n * Sets the remote logging options.\n */\n setRemote: (remote: RemoteOptions): void => {\n state.remote = { ...state.remote, ...remote };\n },\n\n /**\n * Sets the remote log level.\n */\n setRemoteLogLevel: (level: LogLevel): void => {\n state.remote.logLevel = level;\n },\n\n /**\n * Configures Logit with options.\n *\n * @example\n * ```ts\n * Logit.setup({\n * logLevel: 'info',\n * variant: 'text',\n * timestamp: false\n * });\n * ```\n */\n setup: (options: LogitOptions): void => {\n if (options.remote) {\n state.remote = { ...state.remote, ...options.remote };\n const { remote, ...rest } = options;\n Object.assign(state, rest);\n } else {\n Object.assign(state, options);\n }\n },\n\n /**\n * Sets the display variant.\n */\n setVariant: (variant: Variant): void => {\n state.variant = variant;\n },\n\n /**\n * Logs a success message.\n */\n success: (...args: unknown[]): void => log('success', ...args),\n\n /**\n * Displays data in a table format.\n */\n table: (...args: unknown[]): void => {\n if (shouldLog('table')) console.table(...args);\n },\n\n /**\n * Starts a timer.\n */\n time: (label: string): void => {\n if (shouldLog('time')) console.time(label);\n },\n\n /**\n * Ends a timer.\n */\n timeEnd: (label: string): void => {\n if (shouldLog('time')) console.timeEnd(label);\n },\n\n /**\n * Toggles or sets environment indicator visibility.\n */\n toggleEnvironment: (value?: boolean): void => {\n state.environment = value ?? !state.environment;\n },\n\n /**\n * Toggles or sets timestamp visibility.\n */\n toggleTimestamp: (value?: boolean): void => {\n state.timestamp = value ?? !state.timestamp;\n },\n\n /**\n * Logs a trace message.\n */\n trace: (...args: unknown[]): void => log('trace', ...args),\n\n /**\n * Logs a warning message.\n */\n warn: (...args: unknown[]): void => log('warn', ...args),\n};\n"],"names":["CONSOLE_METHOD_MAP","LOG_LEVEL_PRIORITY","isDarkMode","THEME","NAMESPACE_STYLE","isProduction","__vite_import_meta_env__","IS_PROD","state","shouldLog","type","getTimestamp","getEnvIndicator","sendRemote","args","handler","logLevel","getConsoleMethod","getStyle","extra","bg","color","border","baseStyle","getDisplayValue","theme","variant","buildLogParts","namespace","timestamp","environment","format","parts","log","method","createScopedLogger","scopeName","originalNamespace","fullNamespace","createMethod","prev","Logit","condition","message","context","text","label","startTime","elapsed","elapsedStr","env","level","remote","options","rest","value"],"mappings":"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"}
1
+ {"version":3,"file":"logit.js","names":[],"sources":["../src/logit.ts"],"sourcesContent":["/* -------------------- Types -------------------- */\n\nexport type LogType = 'debug' | 'trace' | 'info' | 'success' | 'warn' | 'error';\nexport type LogLevel = LogType | 'off';\nexport type Variant = 'text' | 'symbol' | 'icon';\n\nexport type RemoteHandler = (type: LogType, data: RemoteLogData) => void;\n\nexport type RemoteOptions = { handler?: RemoteHandler; logLevel?: LogLevel };\n\nexport type RemoteLogData = {\n args: unknown[];\n env: 'production' | 'development';\n namespace?: string;\n timestamp?: string;\n};\n\nexport type LogitOptions = {\n environment?: boolean;\n logLevel?: LogLevel;\n namespace?: string;\n remote?: RemoteOptions;\n timestamp?: boolean;\n variant?: Variant;\n};\n\n/** The shape of a fully resolved logger config (all fields present). */\ntype ResolvedRemote = { handler?: RemoteHandler; logLevel: LogLevel };\nexport type LogitConfig = Omit<Required<LogitOptions>, 'remote'> & { remote: ResolvedRemote };\n\nexport type Logger = {\n assert: (condition: boolean, ...args: unknown[]) => void;\n child: (overrides?: LogitOptions) => Logger;\n readonly config: Readonly<LogitConfig>;\n debug: (...args: unknown[]) => void;\n enabled: (type: LogLevel) => boolean;\n error: (...args: unknown[]) => void;\n group: <T>(label: string, fn: () => T, collapsed?: boolean) => T;\n info: (...args: unknown[]) => void;\n scope: (name: string) => Logger;\n setConfig: (opts: LogitOptions) => Logger;\n success: (...args: unknown[]) => void;\n table: (data: unknown, properties?: string[]) => void;\n time: <T>(label: string, fn: () => T) => T;\n trace: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n};\n\n/* -------------------- Priority -------------------- */\n\nconst PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n error: 5,\n info: 2,\n off: 6,\n success: 3,\n trace: 1,\n warn: 4,\n};\n\n/* -------------------- Theme -------------------- */\n\ntype Theme = { bg: string; border: string; color: string; icon?: string; symbol?: string };\n\nconst isDarkMode = typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches;\n\nconst THEME: Record<LogType | 'group' | 'ns', Theme> = {\n debug: { bg: '#616161', border: '#424242', color: '#fff', icon: '☕', symbol: '🅳' },\n error: { bg: '#d32f2f', border: '#c62828', color: '#fff', icon: '✘', symbol: '🅴' },\n group: { bg: '#546e7a', border: '#455a64', color: '#fff', icon: '⚭', symbol: '🅶' },\n info: { bg: '#1976d2', border: '#1565c0', color: '#fff', icon: 'ℹ', symbol: '🅸' },\n ns: isDarkMode\n ? { bg: '#fafafa', border: '#c7c7c7', color: '#000' }\n : { bg: '#424242', border: '#212121', color: '#fff' },\n success: { bg: '#689f38', border: '#558b2f', color: '#fff', icon: '✔', symbol: '🆂' },\n trace: { bg: '#d81b60', border: '#c2185b', color: '#fff', icon: '⛢', symbol: '🆃' },\n warn: { bg: '#ffb300', border: '#ffa000', color: '#fff', icon: '⚠', symbol: '🆆' },\n};\n\nconst NS_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;';\n\n/* -------------------- createLogger -------------------- */\n\nconst IS_NODE = typeof window === 'undefined';\nconst IS_PROD = IS_NODE\n ? // @ts-expect-error - process is Node-only\n (process as any).env?.NODE_ENV === 'production'\n : (import.meta as any)?.env?.NODE_ENV === 'production';\n\nconst ENV_BADGE = IS_PROD ? '🅿' : '🅳';\n\nconst LOG_METHOD: Record<LogType, 'log' | 'info' | 'warn' | 'error' | 'trace'> = {\n debug: 'log',\n error: 'error',\n info: 'info',\n success: 'log',\n trace: 'trace',\n warn: 'warn',\n};\n\n/**\n * Creates an independent logger instance with its own isolated configuration.\n *\n * @example\n * ```ts\n * const log = createLogger({ logLevel: 'info', namespace: 'App' });\n * log.info('Hello');\n *\n * const apiLog = log.scope('api');\n * apiLog.warn('slow request');\n * ```\n */\nexport function createLogger(initial: LogitOptions | string = {}): Logger {\n const opts: LogitOptions = typeof initial === 'string' ? { namespace: initial } : initial;\n const cfg: LogitConfig = {\n environment: true,\n logLevel: 'debug',\n namespace: '',\n timestamp: true,\n variant: 'symbol',\n ...opts,\n remote: { logLevel: 'debug', ...opts.remote }, // 'debug' default means a handler just works; set 'off' explicitly to disable\n };\n\n /* ---- helpers ---- */\n\n const passes = (type: LogLevel): boolean => PRIORITY[cfg.logLevel] <= PRIORITY[type];\n\n const ts = (): string => new Date().toISOString().slice(11, 23);\n\n const badge = (type: LogType | 'group'): string => {\n const theme = THEME[type];\n\n if (cfg.variant === 'text' || !theme[cfg.variant]) return type.toUpperCase();\n\n return theme[cfg.variant]!;\n };\n\n const style = (type: LogType | 'group' | 'ns', extra = ''): string => {\n const { bg, border, color } = THEME[type];\n const base = `border: 1px solid ${border}; border-radius: 4px`;\n\n switch (cfg.variant) {\n case 'icon':\n return `color: ${bg}; ${base}; padding: 0 3px${extra}`;\n case 'symbol':\n return `color: ${bg}; ${base}; padding: 0 1px${extra}`;\n default:\n return `background: ${bg}; color: ${color}; ${base}; font-weight: bold; padding: 0 3px${extra}`;\n }\n };\n\n const emitNode = (type: LogType, ns: string, stamp: string, args: unknown[]): void => {\n const meta = [badge(type)];\n\n if (cfg.environment) meta.push(ENV_BADGE);\n\n if (ns) meta.push(`[${ns}]`);\n\n if (stamp) meta.push(stamp);\n\n const method = console[LOG_METHOD[type]] as (...a: unknown[]) => void;\n\n method(`${meta.join(' | ')} |`, ...args);\n };\n\n const emitBrowser = (type: LogType, ns: string, stamp: string, args: unknown[]): void => {\n let fmt = `%c${badge(type)}%c`;\n const parts: string[] = [style(type), ''];\n\n if (ns) {\n fmt += ` %c${ns}%c`;\n parts.push(style('ns', `; ${NS_STYLE}`), '');\n }\n\n if (cfg.environment) {\n fmt += ` %c${ENV_BADGE}%c`;\n parts.push('color: darkgray', '');\n }\n\n if (stamp) {\n fmt += ` %c${stamp}%c`;\n parts.push('color: gray', '');\n }\n\n const method = console[LOG_METHOD[type]] as (...a: unknown[]) => void;\n\n method(fmt, ...parts, ...args);\n };\n\n const emit = (type: LogType, args: unknown[]): void => {\n if (!passes(type)) return;\n\n const ns = cfg.namespace;\n const stamp = cfg.timestamp ? ts() : '';\n\n if (IS_NODE) emitNode(type, ns, stamp, args);\n else emitBrowser(type, ns, stamp, args);\n\n /* remote dispatch — snapshot data now, dispatch in microtask to avoid blocking caller */\n const { handler, logLevel } = cfg.remote;\n\n if (handler && PRIORITY[logLevel] <= PRIORITY[type]) {\n const data: RemoteLogData = {\n args,\n env: IS_PROD ? 'production' : 'development',\n namespace: ns || undefined,\n timestamp: cfg.timestamp ? new Date().toISOString() : undefined,\n };\n\n Promise.resolve()\n .then(() => handler(type, data))\n .catch(() => {});\n }\n };\n\n const timeLabel = (label: string): string => (cfg.namespace ? `[${cfg.namespace}] ${label}` : label);\n\n /* ---- child factory ---- */\n const makeChild = (overrides: LogitOptions = {}): Logger => {\n const { remote: overrideRemote, ...overrideRest } = overrides;\n\n return createLogger({ ...cfg, ...overrideRest, remote: { ...cfg.remote, ...overrideRemote } });\n };\n\n /* ---- group renderer ---- */\n\n const renderGroupNode = (collapsed: boolean, label: string, ns: string, stamp: string): void => {\n const fn = collapsed ? console.groupCollapsed : console.group;\n const meta = [badge('group')];\n\n if (cfg.environment) meta.push(ENV_BADGE);\n\n meta.push(label);\n\n if (ns) meta.push(`[${ns}]`);\n\n if (stamp) meta.push(stamp);\n\n fn(meta.join(' | '));\n };\n\n const renderGroupBrowser = (collapsed: boolean, label: string, ns: string, stamp: string): void => {\n const fn = collapsed ? console.groupCollapsed : console.group;\n let fmt = `%c${label}%c`;\n const parts: string[] = [style('group', '; margin-right: 6px; padding: 1px 3px 0'), ''];\n\n if (ns) {\n fmt += ` %c${ns}%c`;\n parts.push(style('ns', `; ${NS_STYLE}; margin-right: 6px`), '');\n }\n\n if (cfg.environment) {\n fmt += ` %c${ENV_BADGE}%c`;\n parts.push('color: darkgray; margin-right: 6px', '');\n }\n\n if (stamp) {\n fmt += ` %c${stamp}%c`;\n parts.push('color: gray; font-weight: lighter; margin-right: 6px', '');\n }\n\n fn(fmt, ...parts);\n };\n\n const renderGroup = (collapsed: boolean, label: string): void => {\n const ns = cfg.namespace;\n const stamp = cfg.timestamp ? ts() : '';\n\n if (IS_NODE) renderGroupNode(collapsed, label, ns, stamp);\n else renderGroupBrowser(collapsed, label, ns, stamp);\n };\n\n /* ---- public API ---- */\n\n const logger: Logger = {\n assert: (condition: boolean, ...args: unknown[]): void => {\n if (passes('error')) console.assert(condition, ...args);\n },\n\n child: makeChild,\n\n get config(): Readonly<LogitConfig> {\n return { ...cfg, remote: { ...cfg.remote } };\n },\n\n debug: (...a) => emit('debug', a),\n\n enabled: (type: LogLevel): boolean => passes(type),\n error: (...a) => emit('error', a),\n\n group: <T>(label: string, fn: () => T, collapsed = false): T => {\n if (!passes('debug')) return fn();\n\n renderGroup(collapsed, label);\n\n try {\n const result = fn();\n\n if (result instanceof Promise) {\n return result.finally(() => console.groupEnd()) as T;\n }\n\n console.groupEnd();\n\n return result;\n } catch (e) {\n console.groupEnd();\n throw e;\n }\n },\n\n info: (...a) => emit('info', a),\n\n scope: (name: string): Logger => makeChild({ namespace: cfg.namespace ? `${cfg.namespace}.${name}` : name }),\n\n setConfig: (opts: LogitOptions): Logger => {\n const { remote, ...rest } = opts;\n\n if (remote !== undefined) Object.assign(cfg.remote, remote);\n\n Object.assign(cfg, rest);\n\n return logger;\n },\n success: (...a) => emit('success', a),\n\n table: (data: unknown, properties?: string[]): void => {\n if (passes('debug')) console.table(data, properties);\n },\n\n time: <T>(label: string, fn: () => T): T => {\n if (!passes('debug')) return fn();\n\n const tl = timeLabel(label);\n\n console.time(tl);\n\n try {\n const result = fn();\n\n if (result instanceof Promise) {\n return result.finally(() => console.timeEnd(tl)) as T;\n }\n\n console.timeEnd(tl);\n\n return result;\n } catch (e) {\n console.timeEnd(tl);\n throw e;\n }\n },\n\n trace: (...a) => emit('trace', a),\n warn: (...a) => emit('warn', a),\n };\n\n return logger;\n}\n\n/* -------------------- Default instance -------------------- */\n\n/**\n * Shared default logger instance. For isolated configurations use `createLogger()`.\n *\n * @example\n * ```ts\n * import { Logit } from '@vielzeug/logit';\n * Logit.info('Hello');\n * ```\n */\nexport const Logit = createLogger();\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vielzeug/logit",
3
- "version": "1.1.2",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -10,15 +10,18 @@
10
10
  "types": "dist/index.d.ts",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
14
+ "types": "./dist/index.d.ts",
13
15
  "import": "./dist/index.js",
14
16
  "require": "./dist/index.cjs"
15
17
  }
16
18
  },
17
19
  "scripts": {
18
- "build": "tsc && vite build",
19
- "fix": "biome check --write --unsafe src",
20
- "lint": "biome check src",
21
- "prepublishOnly": "npm run build",
20
+ "build": "vite build && pnpm run build:types",
21
+ "build:types": "tsc -p tsconfig.declarations.json",
22
+ "fix": "eslint --fix src",
23
+ "lint": "eslint src",
24
+ "prepublishOnly": "pnpm run build",
22
25
  "preview": "vite preview",
23
26
  "test": "vitest"
24
27
  },
@@ -27,9 +30,9 @@
27
30
  "registry": "https://registry.npmjs.org/"
28
31
  },
29
32
  "devDependencies": {
30
- "typescript": "~5.9.3",
31
- "vite": "^7.3.1",
32
- "vite-plugin-dts": "^4.5.4",
33
- "vitest": "^4.0.18"
33
+ "@types/node": "^25.5.0",
34
+ "typescript": "~6.0.2",
35
+ "vite": "^8.0.3",
36
+ "vitest": "^4.1.2"
34
37
  }
35
38
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}