Addresses the lack of options we currently have for surfacing issues in
our application via debugging tools. Prioritizes performance and
usability (visually) over clarity in some places that could have been
object mapped.
A logger with three separate audiences:
* `internal`: Logs for developers maintaining Theatre.js
* `dev`: Logs for developers using Theatre.js
* `public`: Logs for everyone
This logger supports:
* multiple logging levels (error, warn, debug, trace),
* multiple audience levels (internal, dev, public),
* multiple categories (general, todo, troubleshooting)
* named and keyed loggers (e.g.
`rootLogger.named("Project", project.id)`)
* console styling with deterministic coloring
* console devtool maintains accurate sourcemap link to logging origin
(e.g. `coreExports.ts:71` as opposed to `logger.ts:45` or whatever)
* swappable logger
* customizable filtering
* Accepts lazy `args`: `args: () => object` via
`logger.lazy.<level>("message", () => <expensive computation>)` (e.g.
`logger.lazy.debugDev("Loaded project state", () => ({ save: bigProject.exportToSaveable() }))`)