caterpillar
Version:
Caterpillar is the ultimate logging system for Deno, Node.js, and Web Browsers. Log levels are implemented to the RFC standard. Log entries can be filtered and piped to various streams, including coloured output to the terminal, the browser's console, and
85 lines (84 loc) • 2.91 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Transform = void 0;
/**
* Caterpillar Transform Class.
* Provides the methods needed to provide a pipable Caterpillar Transform.
* Such that all you need to do is write your {@link Transform.format} method.
* It can pipe to anything that provides a {@link Pipeable.write} method.
* @example [Writing a Custom Transform](https://repl.it/@balupton/caterpillar-custom-transform)
*/
class Transform {
constructor() {
/** Where is this Transform piping to? */
this.pipes = [];
/** Maintain a write queue such that multiple Deno writes do not stall */
this.writer = Promise.resolve();
}
/**
* Format the received log entry representation.
* Your transformer should extend this.
*/
format(message) {
return message;
}
/** Pipe future log entries into a caterpillar transform or a stream. */
pipe(to) {
this.pipes.push(to);
return to;
}
/** Write to the child pipes. */
write(chunk) {
// format now, so that we have the correct stack
const data = this.format(chunk);
// exclude filtered entries
if (data == null)
return this.writer;
// now delegate back to the pipe
this.writer = this.writer.then(async () => {
// pipe to child transforms and streams
for (const pipe of this.pipes) {
if (pipe instanceof Transform) {
// compatibility with caterpillar transforms
await pipe.write(data);
}
else {
const str = typeof data === 'string' ? data : JSON.stringify(data);
// requires typescript dom lib to define TextEncoder global
if (typeof TextEncoder !== 'undefined') {
// compatibility with deno and later node streams
await pipe.write(new TextEncoder().encode(str));
}
else {
// compatibility with earlier node streams
await pipe.write(str);
}
}
}
});
return this.writer;
}
/** Close the child pipes. */
async close() {
await Promise.all(this.pipes.map((pipe) => {
if (pipe.close) {
return pipe.close();
}
else if (pipe.end) {
return new Promise(function (resolve) {
pipe.end(resolve);
});
}
else {
return Promise.resolve();
}
}));
}
/* Callback alias for close */
end(cb) {
const p = this.close();
if (cb)
p.finally(cb);
}
}
exports.Transform = Transform;
;