Files
crowd-funder-for-time-pwa/src/utils/logger.ts
Matthew Raymer c55a486a25 Remove debug logging from generateAndRegisterEthrUser test utility
Clean up verbose console.log statements that were cluttering test output.
The function now performs the same operations without debug noise,
making test runs cleaner and more focused on actual test results.
2025-07-05 08:11:14 +00:00

208 lines
6.1 KiB
TypeScript

/**
* Enhanced logger with self-contained database logging
*
* Eliminates circular dependency with databaseUtil by using direct database access.
* Provides comprehensive logging with console and database output.
*
* @author Matthew Raymer
* @version 2.0.0
* @since 2025-01-25
*/
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
export function safeStringify(obj: unknown) {
const seen = new WeakSet();
return JSON.stringify(obj, (_key, value) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return "[Circular]";
}
seen.add(value);
}
if (typeof value === "function") {
return `[Function: ${value.name || "anonymous"}]`;
}
return value;
});
}
// Determine if we should suppress verbose logging (for Electron)
const isElectron = process.env.VITE_PLATFORM === "electron";
const isProduction = process.env.NODE_ENV === "production";
// Track initialization state to prevent circular dependencies
let isInitializing = true;
// Mark initialization as complete after a delay to allow all services to start
setTimeout(() => {
isInitializing = false;
}, 2000); // 2 second delay to allow all services to initialize
// Function to check if we should skip database logging during initialization
function shouldSkipDatabaseLogging(message: string): boolean {
// Skip during initialization phase
if (isInitializing) {
return true;
}
// Skip specific initialization-related messages even after initialization
const initializationMessages = [
"[PlatformServiceFactory]",
"[SQLWorker]",
"[WebPlatformService]",
"[CapacitorPlatformService]",
"[CapacitorMigration]",
"[DB-Integrity]",
"[Migration]",
"[IndexedDBMigrationService]",
"Creating singleton instance",
"Worker loaded",
"Worker initialized",
"Platform service",
];
return initializationMessages.some((pattern) => message.includes(pattern));
}
// Self-contained database logging function
async function logToDatabase(
message: string,
level: string = "info",
): Promise<void> {
// Prevent infinite logging loops
if (isInitializing || shouldSkipDatabaseLogging(message)) {
return;
}
try {
const platform = PlatformServiceFactory.getInstance();
const todayKey = new Date().toDateString();
await platform.dbExec("INSERT INTO logs (date, message) VALUES (?, ?)", [
todayKey,
`[${level.toUpperCase()}] ${message}`,
]);
} catch (error) {
// Fallback to console if database logging fails
// eslint-disable-next-line no-console
console.error(`[Logger] Database logging failed: ${error}`);
}
}
// Enhanced logger with self-contained database methods
export const logger = {
debug: (message: string, ...args: unknown[]) => {
// Debug logs are very verbose - only show in development mode for web
if (!isProduction && !isElectron) {
// eslint-disable-next-line no-console
console.debug(message, ...args);
}
// Don't log debug messages to database to reduce noise
},
log: (message: string, ...args: unknown[]) => {
// Regular logs - show in development or for capacitor, but quiet for Electron
if (
(!isProduction && !isElectron) ||
process.env.VITE_PLATFORM === "capacitor"
) {
// eslint-disable-next-line no-console
console.log(message, ...args);
}
// Database logging
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDatabase(message + argsString, "info");
},
info: (message: string, ...args: unknown[]) => {
if (
process.env.NODE_ENV !== "production" ||
process.env.VITE_PLATFORM === "capacitor" ||
process.env.VITE_PLATFORM === "electron"
) {
// eslint-disable-next-line no-console
console.info(message, ...args);
}
// Database logging
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDatabase(message + argsString, "info");
},
warn: (message: string, ...args: unknown[]) => {
// Always show warnings, but for Electron, suppress routine database warnings
if (!isElectron || !message.includes("[CapacitorPlatformService]")) {
// eslint-disable-next-line no-console
console.warn(message, ...args);
}
// Database logging
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDatabase(message + argsString, "warn");
},
error: (message: string, ...args: unknown[]) => {
// Errors will always be logged to console
// eslint-disable-next-line no-console
console.error(message, ...args);
// Database logging
const messageString = safeStringify(message);
const argsString = args.length > 0 ? safeStringify(args) : "";
logToDatabase(messageString + argsString, "error");
},
// New database-focused methods (self-contained)
toDb: async (message: string, level?: string): Promise<void> => {
await logToDatabase(message, level || "info");
},
toConsoleAndDb: async (message: string, isError = false): Promise<void> => {
// Console output
if (isError) {
// eslint-disable-next-line no-console
console.error(message);
} else {
// eslint-disable-next-line no-console
console.log(message);
}
// Database output
await logToDatabase(message, isError ? "error" : "info");
},
// Component context methods
withContext: (componentName?: string) => ({
log: (message: string, level?: string) =>
logToDatabase(`[${componentName}] ${message}`, level),
error: (message: string) =>
logToDatabase(`[${componentName}] ${message}`, "error"),
}),
};
// Function to manually mark initialization as complete
export function markInitializationComplete(): void {
isInitializing = false;
}
// Function to check initialization status
export function isInitializationPhase(): boolean {
return isInitializing;
}
// Add CommonJS export for Electron
if (typeof module !== "undefined" && module.exports) {
module.exports = {
logger,
markInitializationComplete,
isInitializationPhase,
};
}
// Add default export for ESM
export default { logger, markInitializationComplete, isInitializationPhase };