log
Tagged, leveled logging for every runtime - the one logger the whole monorepo shares.
logger resolves a tagged Logger via a LoggerFactory.
The factory starts as a synchronous console sink so this module never uses
top-level await (that left importers with a null namespace mid-load in
browser bundles). A memoized async chain then upgrades to consola when it
is available. LogLevel filtering runs through shouldEmit in
the consola reporter or in per-level wrappers on the console fallbacks.
Sink selection chains two factories with nullish coalescing (first match wins):
- createConsolaLoggerFactory when consola resolves and
LOG_CONSOLA_DISABLEDis not truthy. - createConsoleLoggerFactory everywhere else (also the sync bootstrap before that promise settles).
The console fallback writes formatted lines to process.stderr when it is
available (Bun inspect per argument when LOG_BUN_CONSOLE_DISABLED is
unset, otherwise node:util formatWithOptions), or delegates to global
console.* when stderr or node:util is unavailable. Browser hosts omit
the LEVEL text prefix (devtools show severity) and keep only the [name]
tag.
Env toggles: LOG_LEVEL (read per call), LOG_CONSOLA_DISABLED /
LOG_BUN_CONSOLE_DISABLED (read once during factory init).
Browser-safe: process / Bun / window / document are all reached
through globalThis and guarded, consola loads lazily, and node:util is
imported ONLY on a host that has process.stderr - never in a browser,
where the specifier is unresolvable - so the module works in any runtime.
Consola is an optional peer; the module loads fine without it.