isoscribe
Version:
An isomorphic logging utility for any JavaScript runtime, providing structured, styled, and extensible logs.
85 lines (84 loc) • 2.62 kB
JavaScript
const ANSI_COLORS = {
black: "\x1b[30m",
red: "\x1b[31m",
green: "\x1b[32m",
yellow: "\x1b[33m",
blue: "\x1b[34m",
magenta: "\x1b[35m",
cyan: "\x1b[36m",
white: "\x1b[37m",
gray: "\x1b[90m",
redBright: "\x1b[91m",
greenBright: "\x1b[92m",
yellowBright: "\x1b[93m",
blueBright: "\x1b[94m",
magentaBright: "\x1b[95m",
cyanBright: "\x1b[96m",
whiteBright: "\x1b[97m",
};
const ANSI_STYLES = {
bold: "\x1b[1m",
underline: "\x1b[4m",
bg: "\x1b[7m",
};
const RESET = "\x1b[0m";
class Colorizer {
_color;
_styles = [];
constructor(parent, color, style) {
if (parent) {
this._color = parent._color;
this._styles = [...parent._styles]; // Preserve styles
}
if (color)
this._color = ANSI_COLORS[color];
if (style)
this._styles.push(ANSI_STYLES[style]);
this.createColorMethods();
this.createStyleMethods();
}
createColorMethods() {
Object.keys(ANSI_COLORS).forEach((color) => {
this[color] = () => {
this._color = ANSI_COLORS[color];
return this;
};
});
}
createStyleMethods() {
Object.keys(ANSI_STYLES).forEach((style) => {
this[style] = () => {
this._styles.push(ANSI_STYLES[style]);
return this;
};
});
}
format(text) {
return `${this._styles.join("")}${this._color ?? ""}${text}${RESET}`;
}
callable = (text) => this.format(text);
}
const createColorizerProxy = (parent, color, style) => {
// 🔥 This function actually gets called when you invoke `c("text")`
function applyColorizer(text) {
return new Colorizer(parent, color, style)["callable"](text);
}
return new Proxy(applyColorizer, {
// 🔹 Handle property access (e.g., `c.red`, `c.underline`)
get(_, prop) {
if (prop in ANSI_COLORS) {
return createColorizerProxy(new Colorizer(parent, prop));
}
if (prop in ANSI_STYLES) {
return createColorizerProxy(new Colorizer(parent, undefined, prop));
}
return undefined;
},
// 🔹 Handle function calls (e.g., `c("Hello")`)
apply(target, _, args) {
return target(args[0]); // Calls `applyColorizer(text)`, which formats the string
},
});
};
// ✅ `c` is now a function-proxy hybrid that supports both method chaining and function calls
export const c = createColorizerProxy();