@plugjs/plug
Version:
PlugJS Build System ===================
137 lines • 6.1 kB
JavaScript
import { formatWithOptions } from 'node:util';
import { fail } from "../asserts.js";
import { $blu, $grn, $gry, $red, $t, $ylw } from "./colors.js";
import { DEBUG, INFO, NOTICE, TRACE, WARN } from "./levels.js";
import { logOptions } from "./options.js";
import { zapSpinner } from "./spinner.js";
/* ========================================================================== */
/* Initial values, and subscribe to changes */
let _output = logOptions.output;
let _indentSize = logOptions.indentSize;
let _taskLength = logOptions.taskLength;
let _lineLength = logOptions.lineLength;
let _inspectOptions = { ...logOptions.inspectOptions };
logOptions.on('changed', (options) => {
_output = options.output;
_indentSize = options.indentSize;
_taskLength = options.taskLength;
_lineLength = options.lineLength;
_inspectOptions = { ...options.inspectOptions }; // proxy
_defaultEmitter =
options.format === 'fancy' ? emitFancy :
options.format === 'plain' ? emitPlain :
fail(`Invalid log format "${logOptions.format}"`);
});
/* ========================================================================== */
/** Emit in full colors with spinner support and whatnot! */
export const emitFancy = (options, args) => {
const { taskName, level, prefix = '', indent = 0 } = options;
const logPrefix = ''.padStart(indent * _indentSize) + prefix;
/* Prefixes, to prepend at the beginning of each line */
const prefixes = [];
/* Task name or blank padding */
prefixes.push(''.padStart(_taskLength - taskName.length, ' ')); // padding
prefixes.push(`${$t(taskName, false)}`); // task name
/* Level indicator (our little colorful squares) */
if (level <= TRACE) {
prefixes.push(` ${$gry('\u25a1')} `); // trace: gray open
}
else if (level <= DEBUG) {
prefixes.push(` ${$gry('\u25a0')} `); // debug: gray
}
else if (level <= INFO) {
prefixes.push(` ${$grn('\u25a0')} `); // info: green
}
else if (level <= NOTICE) {
prefixes.push(` ${$blu('\u25a0')} `); // notice: blue
}
else if (level <= WARN) {
prefixes.push(` ${$ylw('\u25a0')} `); // warning: yellow
}
else {
prefixes.push(` ${$red('\u25a0')} `); // error: red
}
/* The prefix (task name and level) */
prefixes.push(logPrefix);
const linePrefix = prefixes.join('');
/* Now for the normal logging of all our parameters */
const breakLength = _lineLength - _taskLength - logPrefix.length - 3; // 3 chas: space square space
const message = formatWithOptions({ ..._inspectOptions, breakLength }, ...args);
/* Write each individual line out */
for (const line of message.split('\n')) {
_output.write(`${zapSpinner}${linePrefix}${line}\n`);
}
};
/* ========================================================================== */
/** Emit in plain text (maybe with some colors?) */
export const emitPlain = (options, args) => {
const { taskName, level, prefix = '', indent = 0 } = options;
const logPrefix = ''.padStart(indent * _indentSize) + prefix;
const prefixes = [];
const pad = ''.padStart(_taskLength - taskName.length, ' ');
prefixes.push(`${pad}${$t(taskName, false)}`);
if (level <= TRACE) {
prefixes.push(` ${$gry('\u2502')} ${$gry(' trace')} ${$gry('\u2502')} `);
}
else if (level <= DEBUG) {
prefixes.push(` ${$gry('\u2502')} ${$gry(' debug')} ${$gry('\u2502')} `);
}
else if (level <= INFO) {
prefixes.push(` ${$gry('\u2502')} ${$grn(' info')} ${$gry('\u2502')} `);
}
else if (level <= NOTICE) {
prefixes.push(` ${$gry('\u2502')} ${$blu('notice')} ${$gry('\u2502')} `);
}
else if (level <= WARN) {
prefixes.push(` ${$gry('\u2502')} ${$ylw(' warn')} ${$gry('\u2502')} `);
}
else {
prefixes.push(` ${$gry('\u2502')} ${$red(' error')} ${$gry('\u2502')} `);
}
/* The prefix (task name and level) */
prefixes.push(logPrefix);
const linePrefix = prefixes.join('');
/* Now for the normal logging of all our parameters */
const breakLength = _lineLength - _taskLength - logPrefix.length - 12; // 12 chars of the level above
const message = formatWithOptions({ ..._inspectOptions, breakLength }, ...args);
/* Write each individual line out */
for (const line of message.split('\n')) {
_output.write(`${linePrefix}${line}\n`);
}
};
/** Emit to the parent process of a forked child, or to the default emitter */
export const emitForked = (options, args) => {
if (process.connected && process.send) {
const { taskName, level, prefix = '', indent = 0 } = options;
const linePrefix = ''.padStart(indent * _indentSize) + prefix;
/* Now for the normal logging of all our parameters */
const breakLength = _lineLength - _taskLength - linePrefix.length - 20;
const message = formatWithOptions({ ..._inspectOptions, breakLength }, ...args);
/* Format each individual line */
const lines = message.split('\n').map((line) => `${linePrefix}${line}`);
/* Send the message to the parent process */
process.send({ logLevel: level, taskName, lines });
}
else {
_defaultEmitter(options, args);
}
};
/* ========================================================================== */
/** The _default_ emitter (from `format`) */
let _defaultEmitter = logOptions.format === 'fancy' ? emitFancy :
logOptions.format === 'plain' ? emitPlain :
fail(`Invalid log format "${logOptions.format}"`);
/** The _actual_ emitter (either default or configured) */
let _emitter = _defaultEmitter;
/** Our `emit` wrapper function to export */
const wrapper = function emit(options, args) {
_defaultEmitter(options, args);
};
/** A _configurable_ {@link LogEmitter} where log should be emitted to */
export const emit = Object.defineProperty(wrapper, 'emitter', {
get: () => _emitter,
set: (emitter) => {
_emitter = emitter || _defaultEmitter;
},
});
//# sourceMappingURL=emit.js.map