{"version":3,"file":"logger.cjs","names":[],"sources":["../../src/logger/logger.ts"],"sourcesContent":["export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogEntry {\n    level: LogLevel;\n    message: string;\n    context?: Record<string, unknown>;\n    timestamp: number;\n}\n\nexport interface LoggerSink {\n    (entry: LogEntry): void;\n}\n\nexport interface Logger {\n    debug: (message: string, context?: Record<string, unknown>) => void;\n    info: (message: string, context?: Record<string, unknown>) => void;\n    warn: (message: string, context?: Record<string, unknown>) => void;\n    error: (message: string, context?: Record<string, unknown>) => void;\n    /** Build a child logger that prefixes the namespace to each message. */\n    child: (namespace: string) => Logger;\n}\n\nexport interface CreateLoggerOptions {\n    /** Lowest level recorded. Default: `\"info\"`. */\n    level?: LogLevel;\n    /** Output adapters. Default: a `console.*` sink. */\n    sinks?: LoggerSink[];\n    /** Initial namespace (prepended to every message). */\n    namespace?: string;\n}\n\nconst LEVELS: LogLevel[] = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction shouldLog(threshold: LogLevel, level: LogLevel): boolean {\n    return LEVELS.indexOf(level) >= LEVELS.indexOf(threshold);\n}\n\n/** Default sink that writes to the browser console. */\nexport const consoleSink: LoggerSink = ({ level, message, context }) => {\n    const method = level === \"debug\" ? \"log\" : level;\n    if (context) {\n        console[method](message, context);\n    } else {\n        console[method](message);\n    }\n};\n\n/**\n * Create a structured leveled logger. Plug arbitrary sinks (Sentry, Datadog,\n * remote ingestion) by implementing the `LoggerSink` interface.\n *\n * @tempest-limits empty-catch — a sink that throws must not take the app with it,\n * and it must not stop the sinks after it in the list either. Logging is the thing\n * you reach for when something is already going wrong; a transport failure that\n * propagates would turn a diagnostic into the outage. Nothing here can report the\n * failure without recursing into the logger that just failed.\n */\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n    const threshold = options.level ?? \"info\";\n    const sinks = options.sinks ?? [consoleSink];\n    const namespace = options.namespace ?? \"\";\n\n    function emit(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n        if (!shouldLog(threshold, level)) return;\n        const entry: LogEntry = {\n            level,\n            message: namespace ? `[${namespace}] ${message}` : message,\n            context,\n            timestamp: Date.now(),\n        };\n        for (const sink of sinks) {\n            try {\n                sink(entry);\n            } catch {\n                /* empty */\n            }\n        }\n    }\n\n    return {\n        debug: (message, context) => emit(\"debug\", message, context),\n        info: (message, context) => emit(\"info\", message, context),\n        warn: (message, context) => emit(\"warn\", message, context),\n        error: (message, context) => emit(\"error\", message, context),\n        child: (childNamespace: string) =>\n            createLogger({\n                level: threshold,\n                sinks,\n                namespace: namespace ? `${namespace}:${childNamespace}` : childNamespace,\n            }),\n    };\n}\n"],"mappings":"AA+BA,IAAM,EAAqB,CAAC,QAAS,OAAQ,OAAQ,OAAO,EAE5D,SAAS,EAAU,EAAqB,EAA0B,CAC9D,OAAO,EAAO,QAAQ,CAAK,GAAK,EAAO,QAAQ,CAAS,CAC5D,CAGA,IAAa,GAA2B,CAAE,QAAO,UAAS,aAAc,CACpE,IAAM,EAAS,IAAU,QAAU,MAAQ,EACvC,EACA,QAAQ,EAAO,CAAC,EAAS,CAAO,EAEhC,QAAQ,EAAO,CAAC,CAAO,CAE/B,EAYA,SAAgB,EAAa,EAA+B,CAAC,EAAW,CACpE,IAAM,EAAY,EAAQ,OAAS,OAC7B,EAAQ,EAAQ,OAAS,CAAC,CAAW,EACrC,EAAY,EAAQ,WAAa,GAEvC,SAAS,EAAK,EAAiB,EAAiB,EAAyC,CACrF,GAAI,CAAC,EAAU,EAAW,CAAK,EAAG,OAClC,IAAM,EAAkB,CACpB,QACA,QAAS,EAAY,IAAI,EAAU,IAAI,IAAY,EACnD,UACA,UAAW,KAAK,IAAI,CACxB,EACA,IAAK,IAAM,KAAQ,EACf,GAAI,CACA,EAAK,CAAK,CACd,MAAQ,CAER,CAER,CAEA,MAAO,CACH,OAAQ,EAAS,IAAY,EAAK,QAAS,EAAS,CAAO,EAC3D,MAAO,EAAS,IAAY,EAAK,OAAQ,EAAS,CAAO,EACzD,MAAO,EAAS,IAAY,EAAK,OAAQ,EAAS,CAAO,EACzD,OAAQ,EAAS,IAAY,EAAK,QAAS,EAAS,CAAO,EAC3D,MAAQ,GACJ,EAAa,CACT,MAAO,EACP,QACA,UAAW,EAAY,GAAG,EAAU,GAAG,IAAmB,CAC9D,CAAC,CACT,CACJ"}