@loggerjs/pretty 0.5.6 → 0.7.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/README.md CHANGED
@@ -1,12 +1,12 @@
1
+ <p align="center">
2
+ <a href="https://jskits.github.io/loggerjs/"><img src="https://raw.githubusercontent.com/jskits/loggerjs/main/docs/public/logo.png" alt="LoggerJS logo" width="64" height="64" /></a>
3
+ </p>
4
+
1
5
  # @loggerjs/pretty
2
6
 
3
7
  Pretty display transports and formatters for LoggerJS.
4
8
 
5
- This package is for local developer experience: browser DevTools, Node
6
- terminals, and custom debug sinks. Production delivery should still prefer
7
- structured transports such as `stdoutTransport()`, `fileTransport()`,
8
- `browserHttpTransport()`, OTLP, Loki, Datadog, or another machine-readable
9
- destination.
9
+ This package is for local developer experience: browser DevTools, Node terminals, and custom debug sinks. Production delivery should still prefer structured transports such as `stdoutTransport()`, `fileTransport()`, `browserHttpTransport()`, OTLP, Loki, Datadog, or another machine-readable destination.
10
10
 
11
11
  ## Browser / Console
12
12
 
@@ -25,8 +25,7 @@ const logger = createLogger({
25
25
  });
26
26
  ```
27
27
 
28
- `prettyConsoleTransport()` writes through the unpatched console registry, so it
29
- can run beside `captureConsoleIntegration()` without feedback loops.
28
+ `prettyConsoleTransport()` writes through the unpatched console registry, so it can run beside `captureConsoleIntegration()` without feedback loops.
30
29
 
31
30
  ## Node Terminal
32
31
 
@@ -45,10 +44,7 @@ const logger = createLogger({
45
44
  });
46
45
  ```
47
46
 
48
- `prettyStdoutTransport()` and `prettyStderrTransport()` use ANSI colors when the
49
- target stream is a TTY. They honor `NO_COLOR` and `FORCE_COLOR`, and their
50
- `flush()` waits for `drain` when the stream reports backpressure. Use these for
51
- local development; keep `stdoutTransport()` for production NDJSON.
47
+ `prettyStdoutTransport()` and `prettyStderrTransport()` use ANSI colors when the target stream is a TTY. They honor `NO_COLOR` and `FORCE_COLOR`, and their `flush()` waits for `drain` when the stream reports backpressure. Use these for local development; keep `stdoutTransport()` for production NDJSON.
52
48
 
53
49
  ## Formatter
54
50
 
@@ -59,5 +55,4 @@ const rendered = formatPrettyEvent(event, { mode: "expanded", colors: "never" })
59
55
  console.log(rendered.text);
60
56
  ```
61
57
 
62
- The formatter returns plain text, ANSI text, browser console arguments, and raw
63
- detail values so custom transports can preserve inspectable objects.
58
+ The formatter returns plain text, ANSI text, browser console arguments, and raw detail values so custom transports can preserve inspectable objects.
@@ -1 +1 @@
1
- {"version":3,"file":"console-transport.d.ts","sourceRoot":"","sources":["../src/console-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,QAAQ,EAEb,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAqB,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,6BAA8B,SAAQ,sBAAsB;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;CACvC;AAmDD,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,6BAAkC,GAAG,SAAS,CAqC7F"}
1
+ {"version":3,"file":"console-transport.d.ts","sourceRoot":"","sources":["../src/console-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAEb,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAqB,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,6BAA8B,SAAQ,sBAAsB;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;CACvC;AAmDD,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,6BAAkC,GAAG,SAAS,CAqC7F"}
package/dist/index.cjs CHANGED
@@ -1,354 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- let _loggerjs_core = require("@loggerjs/core");
3
- //#region src/formatter.ts
4
- const ansiReset = "\x1B[0m";
5
- const ansiStyles = {
6
- trace: "\x1B[90m",
7
- debug: "\x1B[36m",
8
- info: "\x1B[34m",
9
- warn: "\x1B[33m",
10
- error: "\x1B[31m",
11
- fatal: "\x1B[35m"
12
- };
13
- const cssStyles = {
14
- trace: "color:#6b7280;font-weight:600",
15
- debug: "color:#0891b2;font-weight:600",
16
- info: "color:#2563eb;font-weight:600",
17
- warn: "color:#b45309;font-weight:700",
18
- error: "color:#dc2626;font-weight:700",
19
- fatal: "color:#7e22ce;font-weight:800"
20
- };
21
- const labels = {
22
- trace: "TRACE",
23
- debug: "DEBUG",
24
- info: "INFO ",
25
- warn: "WARN ",
26
- error: "ERROR",
27
- fatal: "FATAL"
28
- };
29
- function levelStyle(levelName, overrides) {
30
- const override = overrides?.[levelName];
31
- return {
32
- label: override?.label ?? labels[levelName],
33
- ansi: override?.ansi ?? ansiStyles[levelName],
34
- css: override?.css ?? cssStyles[levelName]
35
- };
36
- }
37
- function formatTime(event, format) {
38
- if (typeof format === "function") return format(event);
39
- if (format === "none") return void 0;
40
- const date = new Date(event.time);
41
- if (format === "iso") return date.toISOString();
42
- if (format === "local") return date.toLocaleString();
43
- return date.toISOString().slice(11, 23);
44
- }
45
- function scalar(value) {
46
- if (value === null) return "null";
47
- if (value === void 0) return "undefined";
48
- if (typeof value === "string") return value;
49
- if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
50
- return (0, _loggerjs_core.safeJsonStringify)(value, {
51
- maxDepth: 2,
52
- maxArrayLength: 20,
53
- maxObjectKeys: 20
54
- });
55
- }
56
- function truncate(value, maxLength) {
57
- if (value.length <= maxLength) return value;
58
- if (maxLength <= 1) return value.slice(0, maxLength);
59
- return `${value.slice(0, Math.max(0, maxLength - 3))}...`;
60
- }
61
- function tagText(tags, maxInlineLength) {
62
- if (!tags) return void 0;
63
- const entries = Object.entries(tags);
64
- if (entries.length === 0) return void 0;
65
- return entries.map(([key, value]) => `${key}=${truncate(scalar(value), maxInlineLength)}`).join(" ");
66
- }
67
- function detailText(value, options) {
68
- return (0, _loggerjs_core.safeJsonStringify)(value, {
69
- maxDepth: options.maxObjectDepth ?? 4,
70
- maxArrayLength: 50,
71
- maxObjectKeys: options.maxObjectKeys ?? 80,
72
- stable: true
73
- });
74
- }
75
- function collectDetails(event, options) {
76
- const details = [];
77
- const push = (key, value) => {
78
- if (value === void 0) return;
79
- details.push({
80
- key,
81
- value,
82
- text: detailText(value, options)
83
- });
84
- };
85
- if (options.includeData ?? true) push("data", event.data);
86
- if (options.includeError ?? true) push("error", event.error);
87
- if (options.includeContext ?? false) push("context", event.context);
88
- if (options.includeTrace ?? false) push("trace", event.trace);
89
- if (options.includeSource ?? false) push("source", event.source);
90
- if (options.includeId ?? false) push("id", event.id);
91
- return details;
92
- }
93
- function baseSegments(event, options) {
94
- const maxInlineLength = options.maxInlineLength ?? 160;
95
- const style = levelStyle(event.levelName, options.levelStyles);
96
- const segments = [];
97
- const time = formatTime(event, options.time ?? "time");
98
- if (time) segments.push(`[${time}]`);
99
- segments.push(style.label);
100
- if (options.includeLogger ?? true) segments.push(event.logger);
101
- if ((options.includeType ?? true) && event.type) segments.push(`<${event.type}>`);
102
- if (options.includeTags ?? true) {
103
- const tags = tagText(event.tags, maxInlineLength);
104
- if (tags) segments.push(`[${tags}]`);
105
- }
106
- return segments;
107
- }
108
- function plainBaseLine(event, options) {
109
- return `${baseSegments(event, options).join(" ")} ${event.message}`;
110
- }
111
- function compactText(baseLine, details, maxInlineLength) {
112
- if (details.length === 0) return baseLine;
113
- return `${baseLine} ${details.map((detail) => `${detail.key}=${truncate(detail.text, maxInlineLength)}`).join(" ")}`;
114
- }
115
- function expandedText(baseLine, details) {
116
- if (details.length === 0) return baseLine;
117
- return [baseLine, ...details.map((detail) => ` ${detail.key}: ${detail.text}`)].join("\n");
118
- }
119
- function withAnsi(event, text, options) {
120
- if (options.colors !== "always") return text;
121
- const style = levelStyle(event.levelName, options.levelStyles);
122
- const label = style.label;
123
- return text.replace(label, `${style.ansi}${label}${ansiReset}`);
124
- }
125
- function browserArgs(event, options, details) {
126
- const style = levelStyle(event.levelName, options.levelStyles);
127
- const segments = baseSegments(event, options);
128
- const levelIndex = segments.indexOf(style.label);
129
- const beforeLevel = segments.slice(0, levelIndex).join(" ");
130
- const afterLevel = segments.slice(levelIndex + 1).join(" ");
131
- const before = beforeLevel ? `${beforeLevel} ` : "";
132
- const after = afterLevel ? ` ${afterLevel}` : "";
133
- return [
134
- `%c${before}%c${style.label}%c${after} ${event.message}`,
135
- "color:#6b7280",
136
- style.css,
137
- "",
138
- ...details.map((detail) => detail.value)
139
- ];
140
- }
141
- function formatPrettyEvent(event, options = {}) {
142
- const maxInlineLength = options.maxInlineLength ?? 160;
143
- const details = collectDetails(event, options);
144
- const baseLine = plainBaseLine(event, options);
145
- const text = (options.mode ?? "compact") === "expanded" ? expandedText(baseLine, details) : compactText(baseLine, details, maxInlineLength);
146
- return {
147
- text,
148
- ansiText: withAnsi(event, text, options),
149
- browserArgs: browserArgs(event, options, details),
150
- details
151
- };
152
- }
153
- //#endregion
154
- //#region src/console-transport.ts
155
- function methodForEvent(event) {
156
- if (event.levelName === "trace") return "trace";
157
- if (event.levelName === "debug") return "debug";
158
- if (event.levelName === "warn") return "warn";
159
- if (event.levelName === "error" || event.levelName === "fatal") return "error";
160
- return "info";
161
- }
162
- function defaultFilter(event) {
163
- const integration = event.source?.integration;
164
- return integration !== "capture-console" && integration !== "integration:capture-console";
165
- }
166
- function browserStyleSupport() {
167
- return typeof window !== "undefined" && typeof document !== "undefined";
168
- }
169
- function shouldUseBrowserStyles(value) {
170
- if (value === void 0 || value === "auto") return browserStyleSupport();
171
- return value;
172
- }
173
- function writerFor(method, target) {
174
- if (target) return (target[method] ?? target.log ?? target.info ?? (() => {})).bind(target);
175
- const registry = (0, _loggerjs_core.registerUnpatchedDefaults)();
176
- const fallback = typeof console === "undefined" ? {} : console;
177
- const writer = registry.console[method] ?? fallback[method] ?? registry.console.log ?? fallback.log ?? (() => {});
178
- return typeof console === "undefined" ? writer : writer.bind(console);
179
- }
180
- function prettyConsoleTransport(options = {}) {
181
- const filter = options.filter ?? defaultFilter;
182
- const useBrowserStyles = shouldUseBrowserStyles(options.browserStyles);
183
- const writeEvent = (event) => {
184
- if (!filter(event)) return;
185
- const rendered = formatPrettyEvent(event, options);
186
- const writer = writerFor(methodForEvent(event), options.console);
187
- const args = useBrowserStyles ? rendered.browserArgs : [options.colors === "always" ? rendered.ansiText : rendered.text, ...rendered.details.map((detail) => detail.value)];
188
- if (options.includeEvent) args.push(event);
189
- writer(...args);
190
- };
191
- const writeRecord = (record, context) => {
192
- writeEvent(context.toEvent(record));
193
- };
194
- return {
195
- name: options.name ?? "pretty-console",
196
- write(record, context) {
197
- writeRecord(record, context);
198
- },
199
- writeBatch(records, context) {
200
- for (const record of records) writeRecord(record, context);
201
- },
202
- log(event) {
203
- writeEvent(event);
204
- },
205
- logBatch(events) {
206
- for (const event of events) writeEvent(event);
207
- }
208
- };
209
- }
210
- //#endregion
211
- //#region src/stream-transport.ts
212
- function normalizeError(error) {
213
- return error instanceof Error ? error : new Error(String(error));
214
- }
215
- function currentProcess() {
216
- return globalThis.process;
217
- }
218
- function processFor(options) {
219
- return options.process ?? currentProcess();
220
- }
221
- function shouldUseAnsi(stream, options) {
222
- if (options.colors === "always") return true;
223
- if (options.colors === "never") return false;
224
- const env = processFor(options)?.env;
225
- if (env?.NO_COLOR !== void 0) return false;
226
- if (env?.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") return true;
227
- return stream.isTTY === true;
228
- }
229
- function streamFromProcess(options, key) {
230
- const stream = processFor(options)?.[key];
231
- if (!stream) throw new Error(`pretty ${key} transport requires a writable stream or process.${key}`);
232
- return stream;
233
- }
234
- function prettyStreamTransport(options = {}) {
235
- const stream = options.stream ?? streamFromProcess(options, "stdout");
236
- const useAnsi = shouldUseAnsi(stream, options);
237
- const newline = options.newline ?? "\n";
238
- const waiters = [];
239
- let pendingDrains = 0;
240
- let lastError;
241
- let lastContext;
242
- let closed = false;
243
- const settleWaitersIfIdle = () => {
244
- if (pendingDrains > 0 || waiters.length === 0) return;
245
- const error = lastError;
246
- lastError = void 0;
247
- for (const waiter of waiters.splice(0)) if (error) waiter.reject(error);
248
- else waiter.resolve();
249
- };
250
- const recordError = (error, operation) => {
251
- lastError = normalizeError(error);
252
- lastContext?.reportInternalError(lastError, {
253
- phase: "transport",
254
- transport: options.name ?? "pretty-stream",
255
- operation
256
- });
257
- settleWaitersIfIdle();
258
- };
259
- const onError = (error) => recordError(error, "stream-error");
260
- stream.on?.("error", onError);
261
- const waitForDrain = () => {
262
- if (!stream.once) return;
263
- pendingDrains += 1;
264
- stream.once("drain", () => {
265
- pendingDrains -= 1;
266
- settleWaitersIfIdle();
267
- });
268
- };
269
- const writePayload = (payload, context) => {
270
- if (closed) return;
271
- lastContext = context;
272
- try {
273
- if (stream.write(payload) === false) waitForDrain();
274
- } catch (error) {
275
- recordError(error, "write");
276
- }
277
- };
278
- const writeEvent = (event, context) => {
279
- if (options.minLevel !== void 0 && event.level < (0, _loggerjs_core.toLevelValue)(options.minLevel)) return;
280
- const rendered = formatPrettyEvent(event, {
281
- ...options,
282
- colors: useAnsi ? "always" : "never"
283
- });
284
- writePayload(`${useAnsi ? rendered.ansiText : rendered.text}${newline}`, context);
285
- };
286
- const transport = {
287
- name: options.name ?? "pretty-stream",
288
- minLevel: options.minLevel,
289
- write(record, context) {
290
- writeEvent(context.toEvent(record), context);
291
- },
292
- writeBatch(records, context) {
293
- for (const record of records) writeEvent(context.toEvent(record), context);
294
- },
295
- log(event, context) {
296
- writeEvent(event, context);
297
- },
298
- logBatch(events, context) {
299
- for (const event of events) writeEvent(event, context);
300
- },
301
- flush() {
302
- if (pendingDrains === 0) {
303
- const error = lastError;
304
- lastError = void 0;
305
- if (error) return Promise.reject(error);
306
- return Promise.resolve();
307
- }
308
- return new Promise((resolve, reject) => {
309
- waiters.push({
310
- resolve,
311
- reject
312
- });
313
- });
314
- },
315
- flushSync() {},
316
- close() {
317
- return Promise.resolve(transport.flush?.()).then(() => new Promise((resolve, reject) => {
318
- closed = true;
319
- stream.off?.("error", onError);
320
- if (!options.endOnClose || !stream.end) {
321
- resolve();
322
- return;
323
- }
324
- stream.end((error) => {
325
- if (error) reject(error);
326
- else resolve();
327
- });
328
- }));
329
- }
330
- };
331
- return transport;
332
- }
333
- function prettyStdoutTransport(options = {}) {
334
- return prettyStreamTransport({
335
- ...options,
336
- name: options.name ?? "pretty-stdout",
337
- stream: options.stream ?? streamFromProcess(options, "stdout")
338
- });
339
- }
340
- function prettyStderrTransport(options = {}) {
341
- return prettyStreamTransport({
342
- ...options,
343
- name: options.name ?? "pretty-stderr",
344
- stream: options.stream ?? streamFromProcess(options, "stderr")
345
- });
346
- }
347
- //#endregion
348
- exports.formatPrettyEvent = formatPrettyEvent;
349
- exports.prettyConsoleTransport = prettyConsoleTransport;
350
- exports.prettyStderrTransport = prettyStderrTransport;
351
- exports.prettyStdoutTransport = prettyStdoutTransport;
352
- exports.prettyStreamTransport = prettyStreamTransport;
353
-
354
- //# sourceMappingURL=index.cjs.map
2
+ const require_formatter = require("./formatter.cjs");
3
+ const require_transport_console = require("./transport-console.cjs");
4
+ const require_transport_stream = require("./transport-stream.cjs");
5
+ exports.formatPrettyEvent = require_formatter.formatPrettyEvent;
6
+ exports.prettyConsoleTransport = require_transport_console.prettyConsoleTransport;
7
+ exports.prettyStderrTransport = require_transport_stream.prettyStderrTransport;
8
+ exports.prettyStdoutTransport = require_transport_stream.prettyStdoutTransport;
9
+ exports.prettyStreamTransport = require_transport_stream.prettyStreamTransport;