@lowdefy/logger 0.0.0-experimental-20260309111833 → 4.6.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.
@@ -34,9 +34,10 @@ function getTime() {
34
34
  const pad = (n)=>String(n).padStart(2, '0');
35
35
  return `${pad(t.getHours())}:${pad(t.getMinutes())}:${pad(t.getSeconds())}`;
36
36
  }
37
- // Standard pino levels + spin/succeed at info level
37
+ // Standard pino levels + spin/succeed/fail for spinner control
38
38
  const logLevelValues = {
39
39
  error: 50,
40
+ fail: 50,
40
41
  warn: 40,
41
42
  succeed: 30,
42
43
  spin: 30,
@@ -61,26 +62,27 @@ function createOraPrint({ logLevel }) {
61
62
  prefixText: ()=>colors.gray(getTime()),
62
63
  color: 'blue'
63
64
  });
64
- return filterLevels({
65
- error: (text, { color } = {})=>spinner.fail(colorize(text, color, 'error')),
66
- warn: (text, { color } = {})=>spinner.warn(colorize(text, color, 'warn')),
67
- info: (text, { color } = {})=>spinner.stopAndPersist({
68
- symbol: '∙',
69
- text: colorize(text, color, 'info')
70
- }),
71
- debug: (text, { color } = {})=>{
72
- if (spinner.isSpinning) {
73
- spinner.stopAndPersist({
74
- symbol: '∙'
75
- });
76
- }
65
+ // Write a log line. If spinner is active, output above it without stopping it.
66
+ function writeLine(symbol, text) {
67
+ if (spinner.isSpinning) {
68
+ spinner.clear();
69
+ process.stderr.write(`${colors.gray(getTime())} ${symbol} ${text}\n`);
70
+ spinner.render();
71
+ } else {
77
72
  spinner.stopAndPersist({
78
- symbol: colors.gray('+'),
79
- text: colorize(text, color, 'debug')
73
+ symbol,
74
+ text
80
75
  });
81
- },
76
+ }
77
+ }
78
+ return filterLevels({
79
+ error: (text, { color } = {})=>writeLine('✖', colorize(text, color, 'error')),
80
+ warn: (text, { color } = {})=>writeLine('⚠', colorize(text, color, 'warn')),
81
+ info: (text, { color } = {})=>writeLine('∙', colorize(text, color, 'info')),
82
+ debug: (text, { color } = {})=>writeLine(colors.gray('+'), colorize(text, color, 'debug')),
82
83
  spin: (text)=>spinner.start(text),
83
- succeed: (text, { color } = {})=>spinner.succeed(color ? colorize(text, color, 'info') : colors.green(text))
84
+ succeed: (text, { color } = {})=>spinner.succeed(color ? colorize(text, color, 'info') : colors.green(text)),
85
+ fail: (text, { color } = {})=>spinner.fail(colorize(text, color ?? 'red', 'error'))
84
86
  }, logLevel);
85
87
  }
86
88
  function createBasicPrint({ logLevel = 'info' }) {
@@ -90,7 +92,8 @@ function createBasicPrint({ logLevel = 'info' }) {
90
92
  info: (text)=>console.log(text),
91
93
  debug: (text)=>console.debug(text),
92
94
  spin: (text)=>console.log(text),
93
- succeed: (text)=>console.log(text)
95
+ succeed: (text)=>console.log(text),
96
+ fail: (text)=>console.error(text)
94
97
  }, logLevel);
95
98
  }
96
99
  // Memoise print so that error handler can get the same spinner object
@@ -144,16 +147,22 @@ function createCliLogger({ logLevel } = {}) {
144
147
  }
145
148
  // 2. Pino two-arg form: (mergeObj, messageString)
146
149
  if (typeof second === 'string') {
147
- if (first?.spin) {
150
+ if (first?.spin === 'start') {
148
151
  print.spin(second);
149
152
  return;
150
153
  }
151
- if (first?.succeed) {
154
+ if (first?.spin === 'succeed') {
152
155
  print.succeed(second, {
153
156
  color: first?.color
154
157
  });
155
158
  return;
156
159
  }
160
+ if (first?.spin === 'fail') {
161
+ print.fail(second, {
162
+ color: first?.color
163
+ });
164
+ return;
165
+ }
157
166
  if (first?.source) {
158
167
  print.info(first.source, {
159
168
  color: 'blue'
@@ -42,7 +42,7 @@ function createStdOutLineHandler({ context }) {
42
42
  const msg = typeof parsed.msg === 'string' && parsed.msg !== '' ? parsed.msg : null;
43
43
  // Strip pino metadata — level/time/name are already handled by the CLI logger
44
44
  // Also strip CLI control fields — they are passed via the mergeObj, not displayed as data
45
- const { level, time, name, pid, hostname, msg: _msg, source, color, spin, succeed, ...data } = parsed;
45
+ const { level, time, name, pid, hostname, msg: _msg, source, color, spin, ...data } = parsed;
46
46
  const dataEntries = Object.entries(data);
47
47
  if (msg == null && dataEntries.length === 0) {
48
48
  logger[levelName](line);
@@ -59,15 +59,13 @@ function createStdOutLineHandler({ context }) {
59
59
  logger[levelName]({
60
60
  source,
61
61
  color,
62
- spin,
63
- succeed
62
+ spin
64
63
  }, msg);
65
64
  } else if (dataLines.length > 0) {
66
65
  logger[levelName]({
67
66
  source,
68
67
  color,
69
- spin,
70
- succeed
68
+ spin
71
69
  }, dataLines.shift());
72
70
  }
73
71
  for (const dataLine of dataLines){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/logger",
3
- "version": "0.0.0-experimental-20260309111833",
3
+ "version": "4.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Lowdefy logging utilities for node, cli, and browser",
6
6
  "homepage": "https://lowdefy.com",
@@ -37,8 +37,8 @@
37
37
  "dist/*"
38
38
  ],
39
39
  "dependencies": {
40
- "@lowdefy/errors": "0.0.0-experimental-20260309111833",
41
- "@lowdefy/helpers": "0.0.0-experimental-20260309111833",
40
+ "@lowdefy/errors": "4.6.0",
41
+ "@lowdefy/helpers": "4.6.0",
42
42
  "ora": "7.0.1",
43
43
  "pino": "8.16.2"
44
44
  },