significant refactor

This commit is contained in:
2025-08-30 01:42:23 -05:00
parent 7136f646a3
commit 052f53444e
106 changed files with 1994 additions and 1701 deletions

View File

@@ -1,4 +1,4 @@
type LogLevel = 'info' | 'success' | 'warn' | 'error';
type LogLevel = "info" | "success" | "warn" | "error";
interface LoggerOptions {
enabled?: boolean;
@@ -7,50 +7,38 @@ interface LoggerOptions {
colors?: boolean;
}
// Cache for performance - update once per second max
let cachedTimestamp = '';
let cachedTimestamp = "";
let lastTimestampUpdate = 0;
/**
* Get formatted timestamp with caching for performance
* Format: MM/DD HH:mm:ss
*/
function getTimestamp(): string {
const now = Date.now();
// Update cache only if more than 1 second has passed
if (now - lastTimestampUpdate > 1000) {
const date = new Date(now);
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
cachedTimestamp = `${month}/${day} ${hours}:${minutes}:${seconds}`;
lastTimestampUpdate = now;
}
return cachedTimestamp;
}
/**
* Get color and emoji for each log level
*/
function getLevelStyle(level: LogLevel): { color: string; label: string } {
const styles = {
info: { color: '#f5f5f5', label: 'INFO' },
success: { color: '#10B981', label: 'SUCCESS' },
warn: { color: '#F59E0B', label: 'WARN' },
error: { color: '#EF4444', label: 'ERROR' },
info: { color: "#f5f5f5", label: "INFO" },
success: { color: "#10B981", label: "SUCCESS" },
warn: { color: "#F59E0B", label: "WARN" },
error: { color: "#EF4444", label: "ERROR" },
};
return styles[level] || styles.info;
}
/**
* Main logger class
*/
class Logger {
private options: LoggerOptions;
private context?: string;
@@ -58,25 +46,21 @@ class Logger {
constructor(context?: string, options: LoggerOptions = {}) {
this.context = context;
this.options = {
enabled: process.env.NODE_ENV !== 'production',
enabled: process.env.NODE_ENV !== "production",
showTimestamp: true,
collapsed: true,
colors: true,
...options
...options,
};
}
/**
* Create a child logger with a specific context
*/
child(context: string, options?: LoggerOptions): Logger {
const childContext = this.context ? `${this.context} > ${context}` : context;
const childContext = this.context
? `${this.context} > ${context}`
: context;
return new Logger(childContext, { ...this.options, ...options });
}
/**
* Core logging method
*/
private log(
level: LogLevel,
label: string,
@@ -86,114 +70,92 @@ class Logger {
if (!this.options.enabled) return;
const style = getLevelStyle(level);
const timestamp = this.options.showTimestamp ? `${getTimestamp()}` : '';
const context = this.context ? `${this.context}` : '';
const timestamp = this.options.showTimestamp ? `${getTimestamp()}` : "";
const context = this.context ? `${this.context}` : "";
const groupLabel = `${timestamp}${style.label}${context}${label}`;
const group = this.options.collapsed ? console.groupCollapsed : console.group;
if (this.options.colors && typeof window !== 'undefined') {
group(
`%c${groupLabel}`,
`color: ${style.color}; font-weight: bold;`
);
const group = this.options.collapsed
? console.groupCollapsed
: console.group;
if (this.options.colors && typeof window !== "undefined") {
group(`%c${groupLabel}`, `color: ${style.color}; font-weight: bold;`);
} else {
group(groupLabel);
}
if (data !== undefined) {
console.log(data);
}
if (rest.length > 0) {
for (const item of rest) {
console.log(item);
}
}
console.groupEnd();
}
/**
* log level methods
*/
info(label: string, data?: any, ...rest: any[]): void {
this.log('info', label, data, ...rest);
this.log("info", label, data, ...rest);
}
success(label: string, data?: any, ...rest: any[]): void {
this.log('success', label, data, ...rest);
this.log("success", label, data, ...rest);
}
warn(label: string, data?: any, ...rest: any[]): void {
this.log('warn', label, data, ...rest);
this.log("warn", label, data, ...rest);
}
error(label: string, data?: any, ...rest: any[]): void {
this.log('error', label, data, ...rest);
this.log("error", label, data, ...rest);
}
simple(message: string): void {
if (!this.options.enabled) return;
const style = getLevelStyle('info');
const timestamp = this.options.showTimestamp ? `${getTimestamp()}` : '';
const context = this.context ? `${this.context}` : '';
const style = getLevelStyle("info");
const timestamp = this.options.showTimestamp ? `${getTimestamp()}` : "";
const context = this.context ? `${this.context}` : "";
const logMessage = `${timestamp}${style.label}${context}${message}`;
if (this.options.colors && typeof window !== 'undefined') {
if (this.options.colors && typeof window !== "undefined") {
console.log(`%c${logMessage}`, `color: ${style.color};`);
} else {
console.log(logMessage);
}
}
/**
* Measure performance of an operation
*/
async measure<T>(label: string, fn: () => Promise<T>): Promise<T> {
const start = performance.now();
try {
const result = await fn();
const duration = (performance.now() - start).toFixed(2);
this.success(`${label} completed`, {
duration: `${duration}ms`,
result
result,
});
return result;
} catch (error) {
const duration = (performance.now() - start).toFixed(2);
this.error(`${label} failed`, {
duration: `${duration}ms`,
error
error,
});
throw error;
}
}
/**
* Create a table log
*/
table(label: string, data: any[]): void {
if (!this.options.enabled) return;
const timestamp = this.options.showTimestamp ? `${getTimestamp()}` : '';
const context = this.context ? `${this.context}` : '';
console.group(`${timestamp}TABLE${context}${label}`);
console.table(data);
console.groupEnd();
}
}
export const logger = new Logger();
export { Logger };