/** * Frontend logger with configurable level (window.__DT_LOG_LEVEL). * Only messages at or above the configured level are forwarded to console. * Prefix [DutyTeller][level] for DevTools filtering. */ const LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 }; /** * Resolve current log level from window.__DT_LOG_LEVEL. Default: info. * @returns {string} One of "debug", "info", "warn", "error" */ function getLogLevel() { const raw = (typeof window !== "undefined" && window.__DT_LOG_LEVEL) || "info"; const level = String(raw).toLowerCase(); return LEVEL_ORDER.hasOwnProperty(level) ? level : "info"; } /** * Return true if message at level should be emitted (level >= configured). * @param {string} messageLevel - "debug" | "info" | "warn" | "error" * @returns {boolean} */ function shouldLog(messageLevel) { const configured = getLogLevel(); const configuredNum = LEVEL_ORDER[configured] ?? 1; const messageNum = LEVEL_ORDER[messageLevel] ?? 1; return messageNum >= configuredNum; } const PREFIX = "[DutyTeller]"; function logAt(level, args) { if (!shouldLog(level)) return; const consoleMethod = level === "debug" ? console.debug : level === "info" ? console.info : level === "warn" ? console.warn : console.error; const prefix = `${PREFIX}[${level}]`; if (args.length === 0) { consoleMethod(prefix); } else if (args.length === 1) { consoleMethod(prefix, args[0]); } else { consoleMethod(prefix, ...args); } } /** * Logger object with debug, info, warn, error (signature like console). * Example: logger.info("Loaded", { count: 5 }); */ export const logger = { debug(msg, ...args) { logAt("debug", [msg, ...args]); }, info(msg, ...args) { logAt("info", [msg, ...args]); }, warn(msg, ...args) { logAt("warn", [msg, ...args]); }, error(msg, ...args) { logAt("error", [msg, ...args]); }, };