@vielzeug/rune 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  **Key exports:** `createLogger`, `defaultLogger`, `lazy`, `consoleTransport`, `remoteTransport`, `jsonTransport`, `batchTransport`, `sampleTransport`, `redactTransport`, `pipe`, `isLevelEnabled`
13
13
 
14
- **When to use:** Structured browser/Node logging with log levels, namespaced scopes, lazy bindings, and a pluggable transport pipeline.
14
+ **When to use:** Structured browser/Node logging with log levels, namespaced scopes, lazy bindings, and pluggable transport pipelines.
15
15
 
16
16
  **Related:** [@vielzeug/courier](https://vielzeug.dev/courier/) · [@vielzeug/herald](https://vielzeug.dev/herald/) · [@vielzeug/familiar](https://vielzeug.dev/familiar/)
17
17
 
@@ -30,57 +30,34 @@ yarn add @vielzeug/rune
30
30
  ## Quick Start
31
31
 
32
32
  ```ts
33
- import { createLogger, defaultLogger, lazy } from '@vielzeug/rune';
34
- import { consoleTransport, jsonTransport, remoteTransport, sampleTransport } from '@vielzeug/rune';
33
+ import { batchTransport, consoleTransport, createLogger, lazy, remoteTransport } from '@vielzeug/rune';
35
34
 
36
- // Default singleton — uses consoleTransport() automatically
37
- defaultLogger.info({ port: 3000 }, 'server started');
38
- defaultLogger.warn('cache stale');
39
- defaultLogger.error(new Error('connection lost')); // auto-serializes Error
40
-
41
- // Namespaced child loggers
42
- const api = createLogger('api');
43
- api.info({ method: 'GET', path: '/users' }, 'request');
44
-
45
- // Pinned bindings — lazy() evaluates only when the level passes
46
- const reqLog = api.withBindings({
47
- requestId: 'abc-123',
48
- diagnostics: lazy(() => buildDiagnostics()),
49
- });
50
- reqLog.debug('processing'); // diagnostics() called only here
51
-
52
- // Structured timing — label is the message; emits { duration_ms } in context
53
- const users = await reqLog.time('db.query', () => db.query('SELECT * FROM users'));
54
-
55
- // Custom transport pipeline
56
35
  const log = createLogger({
57
- logLevel: 'info',
36
+ logLevel: 'debug',
58
37
  namespace: 'server',
59
38
  transports: [
60
39
  consoleTransport({ timestamp: true }),
61
40
  remoteTransport({
62
- handler: async (type, data) => {
63
- await fetch('/api/logs', { body: JSON.stringify(data), method: 'POST' });
64
- },
41
+ handler: (_type, data) => console.debug('remote log', data),
65
42
  level: 'error',
66
43
  }),
67
44
  ],
68
45
  });
69
46
 
70
- // Node.js: NDJSON for log aggregation (ELK, Datadog, etc.)
71
- const nodeLog = createLogger({
72
- transports: [jsonTransport({ level: 'warn' })],
47
+ const requestLog = log.withBindings({
48
+ diagnostics: lazy(() => ({ queueDepth: 0 })),
49
+ requestId: 'abc-123',
73
50
  });
74
51
 
75
- // Fan-out to multiple transports independently (errors in one don't block others)
76
- import { pipe } from '@vielzeug/rune';
77
- const fanout = pipe(consoleTransport(), remoteTransport({ handler, level: 'error' }));
52
+ requestLog.info('request started');
53
+ const users = await requestLog.time('load users', () => Promise.resolve(['user-1']));
54
+ console.log(users);
78
55
 
79
- // Sampling drop 90 % of debug entries before they reach the downstream transport
80
- const sampledLog = createLogger({
81
- logLevel: 'debug',
82
- transports: [sampleTransport({ rate: 0.1, transport: consoleTransport() })],
83
- });
56
+ const batch = batchTransport({ onFlush: (entries) => console.debug('batch', entries) });
57
+ const bufferedLog = createLogger({ transports: [batch.transport] });
58
+
59
+ bufferedLog.info('queued for delivery');
60
+ await batch.dispose();
84
61
  ```
85
62
 
86
63
  ## Documentation
@@ -89,6 +66,7 @@ const sampledLog = createLogger({
89
66
  - [Usage Guide](https://vielzeug.dev/rune/usage)
90
67
  - [API Reference](https://vielzeug.dev/rune/api)
91
68
  - [Examples](https://vielzeug.dev/rune/examples)
69
+ - [Migration Guide](https://vielzeug.dev/rune/migration)
92
70
 
93
71
  ## License
94
72
 
package/dist/_dev.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=!globalThis.__RUNE_PROD__;function t(t){e&&console.warn(`[@vielzeug/rune] ${t}`)}exports.warn=t;
1
+ function e(e){}exports.warn=e;
2
2
  //# sourceMappingURL=_dev.cjs.map
package/dist/_dev.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __RUNE_PROD__?: boolean }).__RUNE_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/rune] ${msg}`);\n}\n"],"mappings":"AAAA,IAAM,EAAQ,CAAE,WAA2C,cAG3D,SAAgB,EAAK,EAAmB,CAClC,GAAO,QAAQ,KAAK,oBAAoB,GAAK,CACnD"}
1
+ {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __RUNE_PROD__?: boolean }).__RUNE_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/rune] ${msg}`);\n}\n"],"mappings":"AAGA,SAAgB,EAAK,EAAmB,CAExC"}
package/dist/_dev.js CHANGED
@@ -1,9 +1,6 @@
1
1
  //#region src/_dev.ts
2
- var e = !globalThis.__RUNE_PROD__;
3
- function t(t) {
4
- e && console.warn(`[@vielzeug/rune] ${t}`);
5
- }
2
+ function e(e) {}
6
3
  //#endregion
7
- export { t as warn };
4
+ export { e as warn };
8
5
 
9
6
  //# sourceMappingURL=_dev.js.map
package/dist/_dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __RUNE_PROD__?: boolean }).__RUNE_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/rune] ${msg}`);\n}\n"],"mappings":";AAAA,IAAM,IAAQ,CAAE,WAA2C;AAG3D,SAAgB,EAAK,GAAmB;CACtC,AAAI,KAAO,QAAQ,KAAK,oBAAoB,GAAK;AACnD"}
1
+ {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __RUNE_PROD__?: boolean }).__RUNE_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/rune] ${msg}`);\n}\n"],"mappings":";AAGA,SAAgB,EAAK,GAAmB,CAExC"}
package/dist/console.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./types.cjs");function t(e,t,n){let r=Object.keys(e).length>0,i=n&&r?n(e):r?e:void 0;return i!==void 0&&t!==void 0?[t,i]:i===void 0?t===void 0?[]:[t]:[i]}var n={debug:{badge:`🅳`,bg:`#616161`,border:`#424242`,color:`#e0e0e0`},error:{badge:`🅴`,bg:`#d32f2f`,border:`#c62828`,color:`#fff`},fatal:{badge:`🅵`,bg:`#4a148c`,border:`#38006b`,color:`#fff`},group:{badge:`🅶`,bg:`#546e7a`,border:`#455a64`,color:`#fff`},info:{badge:`🅸`,bg:`#1976d2`,border:`#1565c0`,color:`#fff`},ns:{badge:``,bg:`#424242`,border:`#212121`,color:`#fff`},warn:{badge:`🆆`,bg:`#ffb300`,border:`#ffa000`,color:`#212121`}},r=`border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;`,i={debug:`log`,error:`error`,fatal:`error`,info:`info`,warn:`warn`};function a(e){if(!e)return n;let t={...n};for(let r of Object.keys(e)){let i=e[r];i&&(t[r]={...n[r],...i})}return t}function o(e){return[parseInt(e.slice(1,3),16),parseInt(e.slice(3,5),16),parseInt(e.slice(5,7),16)]}function s(e,t){let[n,r,i]=o(e);return`\x1b[38;2;${n};${r};${i}m${t}\x1b[0m`}function c(e){return`\x1b[90m${e}\x1b[0m`}function l(){return typeof window<`u`?!1:globalThis.process?.stdout?.isTTY===!0}function u(e,t=``){return`background: ${e.bg}; color: ${e.color}; border: 1px solid ${e.border}; border-radius: 4px; padding: 0 1px${t}`}function d(e){return e.replace(/%/g,`%%`)}function f(e,t,n,r,i){let a=e[t],o=d(a.badge),l=[i?s(a.bg,o):o];if(n){let e=d(n);l.push(i?c(`[${e}]`):`[${e}]`)}return r&&l.push(i?c(r):r),`${l.join(` | `)} |`}function p(e,t,n,i){let a=`%c${d(e[t].badge)}%c`,o=[u(e[t]),``];return n&&(a+=` %c${d(n)}%c`,o.push(u(e.ns,`; ${r}`),``)),i&&(a+=` %c${i}%c`,o.push(`color: gray`,``)),{fmt:a,parts:o}}function m(n={}){let r=n.level??`debug`,o=n.timestamp??!0,s=n.format??`raw`,c=typeof window>`u`,u=n.ansi??(c?l():!1),d=a(n.theme),m=s===`json`?e=>JSON.stringify(e):n.inspectFn;return n=>{if(!e.isLevelEnabled(r,n.level))return;let a=o?n.timestamp.toISOString().slice(11,23):``,s=t(n.data,n.message,m),l=console[i[n.level]];if(c)l(f(d,n.level,n.namespace,a,u),...s);else{let{fmt:e,parts:t}=p(d,n.level,n.namespace,a);l(e,...t,...s)}}}function h(e,t,n,i){let a=e?console.groupCollapsed:console.group;if(typeof window>`u`){let e=[i.group.badge,t];n&&e.push(`[${n}]`),a(e.join(` | `));return}let o=`${i.group.badge} %c${d(t)}%c`,s=[u(i.group,`; margin-right: 6px; padding: 1px 3px 0`),``];n&&(o+=` %c${d(n)}%c`,s.push(u(i.ns,`; ${r}; margin-right: 6px`),``)),a(o,...s)}exports.DEFAULT_THEME=n,exports.consoleTransport=m,exports.renderGroup=h,exports.resolveTheme=a;
1
+ const e=require("./types.cjs");function t(e,t,n){let r=Object.keys(e).length>0,i=n&&r?n(e):r?e:void 0;return i!==void 0&&t!==void 0?[t,i]:i===void 0?t===void 0?[]:[t]:[i]}var n={debug:{badge:`🅳`,bg:`#616161`,border:`#424242`,color:`#e0e0e0`},error:{badge:`🅴`,bg:`#d32f2f`,border:`#c62828`,color:`#fff`},fatal:{badge:`🅵`,bg:`#4a148c`,border:`#38006b`,color:`#fff`},group:{badge:`🅶`,bg:`#546e7a`,border:`#455a64`,color:`#fff`},info:{badge:`🅸`,bg:`#1976d2`,border:`#1565c0`,color:`#fff`},ns:{badge:``,bg:`#424242`,border:`#212121`,color:`#fff`},warn:{badge:`🆆`,bg:`#ffb300`,border:`#ffa000`,color:`#212121`}},r=`border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;`,i={debug:`log`,error:`error`,fatal:`error`,info:`info`,warn:`warn`};function a(e){if(!e)return n;let t={...n};for(let r of Object.keys(e)){let i=e[r];i&&(t[r]={...n[r],...i})}return t}function o(e){return[parseInt(e.slice(1,3),16),parseInt(e.slice(3,5),16),parseInt(e.slice(5,7),16)]}function s(e,t){let[n,r,i]=o(e);return`\x1b[38;2;${n};${r};${i}m${t}\x1b[0m`}function c(e){return`\x1b[90m${e}\x1b[0m`}function l(){return typeof window<`u`?!1:globalThis.process?.stdout?.isTTY===!0}function u(e,t=``){return`background: ${e.bg}; color: ${e.color}; border: 1px solid ${e.border}; border-radius: 4px; padding: 0 1px${t}`}function d(e){return e.replace(/%/g,`%%`)}function f(e,t,n,r,i){let a=e[t],o=d(a.badge),l=[i?s(a.bg,o):o];if(n){let e=d(n);l.push(i?c(`[${e}]`):`[${e}]`)}return r&&l.push(i?c(r):r),`${l.join(` | `)} |`}function p(e,t,n,i){let a=`%c${d(e[t].badge)}%c`,o=[u(e[t]),``];return n&&(a+=` %c${d(n)}%c`,o.push(u(e.ns,`; ${r}`),``)),i&&(a+=` %c${i}%c`,o.push(`color: gray`,``)),{fmt:a,parts:o}}function m(n={}){let r=n.level??`debug`,o=n.timestamp??!0,s=n.format??`raw`,c=typeof window>`u`,u=n.ansi??(c?l():!1),d=a(n.theme),m=s===`json`?e=>JSON.stringify(e):n.inspectFn;return n=>{if(!e.isLevelEnabled(r,n.level))return;let a=o?n.timestamp.toISOString().slice(11,23):``,s=t(n.data,n.message,m),l=console[i[n.level]];if(c)l(f(d,n.level,n.namespace,a,u),...s);else{let{fmt:e,parts:t}=p(d,n.level,n.namespace,a);l(e,...t,...s)}}}function h(e,t,n,i){let a=e?console.groupCollapsed:console.group;if(typeof window>`u`){let e=[i.group.badge,d(t)];n&&e.push(`[${d(n)}]`),a(e.join(` | `));return}let o=`${i.group.badge} %c${d(t)}%c`,s=[u(i.group,`; margin-right: 6px; padding: 1px 3px 0`),``];n&&(o+=` %c${d(n)}%c`,s.push(u(i.ns,`; ${r}; margin-right: 6px`),``)),a(o,...s)}exports.DEFAULT_THEME=n,exports.consoleTransport=m,exports.renderGroup=h,exports.resolveTheme=a;
2
2
  //# sourceMappingURL=console.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"console.cjs","names":[],"sources":["../src/console.ts"],"sourcesContent":["import type { Bindings, LogEntry, LogLevel, LogType, Transport } from './types';\n\nimport { isLevelEnabled } from './types';\n\n/* ─── Console theme types ─── */\n\n/**\n * Per-level style definition for the console transport.\n * All fields are optional when providing a level override — unspecified fields fall back to the default theme.\n */\nexport type ConsoleThemeEntry = {\n badge: string;\n bg: string;\n border: string;\n color: string;\n};\n\n/**\n * Partial theme overrides merged on top of the default theme.\n * Each level entry is also partial — only specify the fields you want to change.\n *\n * @example\n * consoleTransport({ theme: { error: { badge: '✖' } } })\n */\nexport type ConsoleTheme = Partial<Record<LogType | 'group' | 'ns', Partial<ConsoleThemeEntry>>>;\n\n/**\n * Fully-resolved console theme where every level and every field is populated.\n */\nexport type ResolvedTheme = Record<LogType | 'group' | 'ns', ConsoleThemeEntry>;\n\n/* ─── ConsoleTransportOptions ─── */\n\nexport type ConsoleTransportOptions = {\n /**\n * Enable ANSI 24-bit color output in Node.js.\n * Default: true when process.stdout.isTTY is true, false otherwise.\n */\n ansi?: boolean;\n /**\n * Object serialization format for Node.js output.\n * - 'json' — JSON.stringify (machine-readable, fails on circular refs)\n * - 'raw' — pass the object directly to the console method (default)\n * Default: 'raw'.\n */\n format?: 'json' | 'raw';\n /**\n * Custom object inspector function. When provided, the `data` object is\n * passed through this function before being written to the console.\n */\n inspectFn?: (value: unknown) => string;\n /** Minimum level to output. Default: 'debug'. */\n level?: LogLevel;\n /** Partial theme overrides merged on top of the default theme. */\n theme?: ConsoleTheme;\n /** Whether to include timestamp in console output. Default: true. */\n timestamp?: boolean;\n};\n\n/* ─── Payload builder ─── */\n\nfunction buildPayload(\n data: Readonly<Bindings>,\n message: string | undefined,\n inspectFn: ((v: unknown) => string) | undefined,\n): unknown[] {\n const hasData = Object.keys(data).length > 0;\n const formatted: unknown = inspectFn && hasData ? inspectFn(data) : hasData ? data : undefined;\n\n if (formatted !== undefined && message !== undefined) return [message, formatted];\n\n if (formatted !== undefined) return [formatted];\n\n if (message !== undefined) return [message];\n\n return [];\n}\n\n/* ─── Console theme ─── */\n\nexport const DEFAULT_THEME: ResolvedTheme = {\n debug: { badge: '🅳', bg: '#616161', border: '#424242', color: '#e0e0e0' },\n error: { badge: '🅴', bg: '#d32f2f', border: '#c62828', color: '#fff' },\n fatal: { badge: '🅵', bg: '#4a148c', border: '#38006b', color: '#fff' },\n group: { badge: '🅶', bg: '#546e7a', border: '#455a64', color: '#fff' },\n info: { badge: '🅸', bg: '#1976d2', border: '#1565c0', color: '#fff' },\n ns: { badge: '', bg: '#424242', border: '#212121', color: '#fff' },\n warn: { badge: '🆆', bg: '#ffb300', border: '#ffa000', color: '#212121' },\n};\n\nconst NS_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;';\n\nconst LOG_METHOD: Record<LogType, 'error' | 'info' | 'log' | 'warn'> = {\n debug: 'log',\n error: 'error',\n fatal: 'error',\n info: 'info',\n warn: 'warn',\n};\n\n/** Deep-merges per-level overrides onto the default theme. Only specified fields within each level entry are replaced. */\nexport function resolveTheme(override: ConsoleTheme | undefined): ResolvedTheme {\n if (!override) return DEFAULT_THEME;\n\n const result: ResolvedTheme = { ...DEFAULT_THEME };\n\n for (const key of Object.keys(override) as Array<LogType | 'group' | 'ns'>) {\n const entry = override[key];\n\n if (entry) result[key] = { ...DEFAULT_THEME[key], ...entry };\n }\n\n return result;\n}\n\n/* ─── ANSI helpers (Node) ─── */\n\nfunction hexToRgb(hex: string): [number, number, number] {\n return [parseInt(hex.slice(1, 3), 16), parseInt(hex.slice(3, 5), 16), parseInt(hex.slice(5, 7), 16)];\n}\n\nfunction ansiColor(hex: string, text: string): string {\n const [r, g, b] = hexToRgb(hex);\n\n return `\\x1b[38;2;${r};${g};${b}m${text}\\x1b[0m`;\n}\n\nfunction ansiMuted(text: string): string {\n return `\\x1b[90m${text}\\x1b[0m`;\n}\n\nfunction supportsAnsi(): boolean {\n if (typeof window !== 'undefined') return false;\n\n return (\n (globalThis as Record<string, unknown> & { process?: { stdout?: { isTTY?: boolean } } }).process?.stdout?.isTTY ===\n true\n );\n}\n\nfunction badgeStyle(entry: ConsoleThemeEntry, extra = ''): string {\n return `background: ${entry.bg}; color: ${entry.color}; border: 1px solid ${entry.border}; border-radius: 4px; padding: 0 1px${extra}`;\n}\n\nfunction escapeConsoleFormat(s: string): string {\n return s.replace(/%/g, '%%');\n}\n\n/**\n * Builds the Node console prefix string, passed as the first argument to `console.log()`/etc.\n * alongside the payload. `namespace` is escaped because Node's `console.*` methods run the first\n * string argument through `util.format` — an unescaped `%s`/`%d`/`%o`/etc. in a caller-controlled\n * namespace would consume and hide the actual payload arguments that follow (log forging).\n */\nfunction buildNodePrefix(\n theme: ResolvedTheme,\n type: LogType,\n namespace: string,\n timestamp: string,\n useAnsi: boolean,\n): string {\n const t = theme[type];\n const safeBadge = escapeConsoleFormat(t.badge);\n const badgeText = useAnsi ? ansiColor(t.bg, safeBadge) : safeBadge;\n const meta = [badgeText];\n\n if (namespace) {\n const safeNamespace = escapeConsoleFormat(namespace);\n\n meta.push(useAnsi ? ansiMuted(`[${safeNamespace}]`) : `[${safeNamespace}]`);\n }\n\n if (timestamp) meta.push(useAnsi ? ansiMuted(timestamp) : timestamp);\n\n return `${meta.join(' | ')} |`;\n}\n\nfunction buildBrowserPrefix(\n theme: ResolvedTheme,\n type: LogType,\n namespace: string,\n timestamp: string,\n): { fmt: string; parts: string[] } {\n let fmt = `%c${escapeConsoleFormat(theme[type].badge)}%c`;\n const parts: string[] = [badgeStyle(theme[type]), ''];\n\n if (namespace) {\n fmt += ` %c${escapeConsoleFormat(namespace)}%c`;\n parts.push(badgeStyle(theme.ns, `; ${NS_STYLE}`), '');\n }\n\n if (timestamp) {\n fmt += ` %c${timestamp}%c`;\n parts.push('color: gray', '');\n }\n\n return { fmt, parts };\n}\n\n/* ─── consoleTransport ─── */\n\n/**\n * Formats and writes log entries to the browser or Node.js console.\n * Uses CSS-styled badges in browsers and plain text in Node.\n * Accepts an optional partial `theme` to override colors and badges per level.\n *\n * @example\n * consoleTransport()\n * consoleTransport({ level: 'warn', timestamp: false })\n * consoleTransport({ theme: { error: { badge: '✖' } } })\n * consoleTransport({ inspectFn: (v) => require('util').inspect(v, { colors: true, depth: 4 }) })\n */\nexport function consoleTransport(options: ConsoleTransportOptions = {}): Transport {\n const level = options.level ?? 'debug';\n const showTimestamp = options.timestamp ?? true;\n const format = options.format ?? 'raw';\n const isNode = typeof window === 'undefined';\n const useAnsi = options.ansi ?? (isNode ? supportsAnsi() : false);\n const resolved = resolveTheme(options.theme);\n const inspectFn: ((v: unknown) => string) | undefined =\n format === 'json' ? (v) => JSON.stringify(v) : options.inspectFn;\n\n return (entry: LogEntry): void => {\n if (!isLevelEnabled(level, entry.level)) return;\n\n const timestamp = showTimestamp ? entry.timestamp.toISOString().slice(11, 23) : '';\n const payload = buildPayload(entry.data, entry.message, inspectFn);\n const method = console[LOG_METHOD[entry.level]] as (...args: unknown[]) => void;\n\n if (isNode) {\n method(buildNodePrefix(resolved, entry.level, entry.namespace, timestamp, useAnsi), ...payload);\n } else {\n const { fmt, parts } = buildBrowserPrefix(resolved, entry.level, entry.namespace, timestamp);\n\n method(fmt, ...parts, ...payload);\n }\n };\n}\n\n/* ─── Group rendering (used by logger.ts wrapGroup) ─── */\n\nexport function renderGroup(collapsed: boolean, label: string, namespace: string, theme: ResolvedTheme): void {\n const fn = collapsed ? console.groupCollapsed : console.group;\n const isNode = typeof window === 'undefined';\n\n if (isNode) {\n const meta = [theme.group.badge, label];\n\n if (namespace) meta.push(`[${namespace}]`);\n\n fn(meta.join(' | '));\n\n return;\n }\n\n let fmt = `${theme.group.badge} %c${escapeConsoleFormat(label)}%c`;\n const parts: string[] = [badgeStyle(theme.group, '; margin-right: 6px; padding: 1px 3px 0'), ''];\n\n if (namespace) {\n fmt += ` %c${escapeConsoleFormat(namespace)}%c`;\n parts.push(badgeStyle(theme.ns, `; ${NS_STYLE}; margin-right: 6px`), '');\n }\n\n fn(fmt, ...parts);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"console.cjs","names":[],"sources":["../src/console.ts"],"sourcesContent":["import type { Bindings, LogEntry, LogLevel, LogType, Transport } from './types';\n\nimport { isLevelEnabled } from './types';\n\n/* ─── Console theme types ─── */\n\n/**\n * Per-level style definition for the console transport.\n * All fields are optional when providing a level override — unspecified fields fall back to the default theme.\n */\nexport type ConsoleThemeEntry = {\n badge: string;\n bg: string;\n border: string;\n color: string;\n};\n\n/**\n * Partial theme overrides merged on top of the default theme.\n * Each level entry is also partial — only specify the fields you want to change.\n *\n * @example\n * consoleTransport({ theme: { error: { badge: '✖' } } })\n */\nexport type ConsoleTheme = Partial<Record<LogType | 'group' | 'ns', Partial<ConsoleThemeEntry>>>;\n\n/**\n * Fully-resolved console theme where every level and every field is populated.\n */\nexport type ResolvedTheme = Record<LogType | 'group' | 'ns', ConsoleThemeEntry>;\n\n/* ─── ConsoleTransportOptions ─── */\n\nexport type ConsoleTransportOptions = {\n /**\n * Enable ANSI 24-bit color output in Node.js.\n * Default: true when process.stdout.isTTY is true, false otherwise.\n */\n ansi?: boolean;\n /**\n * Object serialization format for Node.js output.\n * - 'json' — JSON.stringify (machine-readable, fails on circular refs)\n * - 'raw' — pass the object directly to the console method (default)\n * Default: 'raw'.\n */\n format?: 'json' | 'raw';\n /**\n * Custom object inspector function. When provided, the `data` object is\n * passed through this function before being written to the console.\n */\n inspectFn?: (value: unknown) => string;\n /** Minimum level to output. Default: 'debug'. */\n level?: LogLevel;\n /** Partial theme overrides merged on top of the default theme. */\n theme?: ConsoleTheme;\n /** Whether to include timestamp in console output. Default: true. */\n timestamp?: boolean;\n};\n\n/* ─── Payload builder ─── */\n\nfunction buildPayload(\n data: Readonly<Bindings>,\n message: string | undefined,\n inspectFn: ((v: unknown) => string) | undefined,\n): unknown[] {\n const hasData = Object.keys(data).length > 0;\n const formatted: unknown = inspectFn && hasData ? inspectFn(data) : hasData ? data : undefined;\n\n if (formatted !== undefined && message !== undefined) return [message, formatted];\n\n if (formatted !== undefined) return [formatted];\n\n if (message !== undefined) return [message];\n\n return [];\n}\n\n/* ─── Console theme ─── */\n\nexport const DEFAULT_THEME: ResolvedTheme = {\n debug: { badge: '🅳', bg: '#616161', border: '#424242', color: '#e0e0e0' },\n error: { badge: '🅴', bg: '#d32f2f', border: '#c62828', color: '#fff' },\n fatal: { badge: '🅵', bg: '#4a148c', border: '#38006b', color: '#fff' },\n group: { badge: '🅶', bg: '#546e7a', border: '#455a64', color: '#fff' },\n info: { badge: '🅸', bg: '#1976d2', border: '#1565c0', color: '#fff' },\n ns: { badge: '', bg: '#424242', border: '#212121', color: '#fff' },\n warn: { badge: '🆆', bg: '#ffb300', border: '#ffa000', color: '#212121' },\n};\n\nconst NS_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;';\n\nconst LOG_METHOD: Record<LogType, 'error' | 'info' | 'log' | 'warn'> = {\n debug: 'log',\n error: 'error',\n fatal: 'error',\n info: 'info',\n warn: 'warn',\n};\n\n/** Deep-merges per-level overrides onto the default theme. Only specified fields within each level entry are replaced. */\nexport function resolveTheme(override: ConsoleTheme | undefined): ResolvedTheme {\n if (!override) return DEFAULT_THEME;\n\n const result: ResolvedTheme = { ...DEFAULT_THEME };\n\n for (const key of Object.keys(override) as Array<LogType | 'group' | 'ns'>) {\n const entry = override[key];\n\n if (entry) result[key] = { ...DEFAULT_THEME[key], ...entry };\n }\n\n return result;\n}\n\n/* ─── ANSI helpers (Node) ─── */\n\nfunction hexToRgb(hex: string): [number, number, number] {\n return [parseInt(hex.slice(1, 3), 16), parseInt(hex.slice(3, 5), 16), parseInt(hex.slice(5, 7), 16)];\n}\n\nfunction ansiColor(hex: string, text: string): string {\n const [r, g, b] = hexToRgb(hex);\n\n return `\\x1b[38;2;${r};${g};${b}m${text}\\x1b[0m`;\n}\n\nfunction ansiMuted(text: string): string {\n return `\\x1b[90m${text}\\x1b[0m`;\n}\n\nfunction supportsAnsi(): boolean {\n if (typeof window !== 'undefined') return false;\n\n return (\n (globalThis as Record<string, unknown> & { process?: { stdout?: { isTTY?: boolean } } }).process?.stdout?.isTTY ===\n true\n );\n}\n\nfunction badgeStyle(entry: ConsoleThemeEntry, extra = ''): string {\n return `background: ${entry.bg}; color: ${entry.color}; border: 1px solid ${entry.border}; border-radius: 4px; padding: 0 1px${extra}`;\n}\n\nfunction escapeConsoleFormat(s: string): string {\n return s.replace(/%/g, '%%');\n}\n\n/**\n * Builds the Node console prefix string, passed as the first argument to `console.log()`/etc.\n * alongside the payload. `namespace` is escaped because Node's `console.*` methods run the first\n * string argument through `util.format` — an unescaped `%s`/`%d`/`%o`/etc. in a caller-controlled\n * namespace would consume and hide the actual payload arguments that follow (log forging).\n */\nfunction buildNodePrefix(\n theme: ResolvedTheme,\n type: LogType,\n namespace: string,\n timestamp: string,\n useAnsi: boolean,\n): string {\n const t = theme[type];\n const safeBadge = escapeConsoleFormat(t.badge);\n const badgeText = useAnsi ? ansiColor(t.bg, safeBadge) : safeBadge;\n const meta = [badgeText];\n\n if (namespace) {\n const safeNamespace = escapeConsoleFormat(namespace);\n\n meta.push(useAnsi ? ansiMuted(`[${safeNamespace}]`) : `[${safeNamespace}]`);\n }\n\n if (timestamp) meta.push(useAnsi ? ansiMuted(timestamp) : timestamp);\n\n return `${meta.join(' | ')} |`;\n}\n\nfunction buildBrowserPrefix(\n theme: ResolvedTheme,\n type: LogType,\n namespace: string,\n timestamp: string,\n): { fmt: string; parts: string[] } {\n let fmt = `%c${escapeConsoleFormat(theme[type].badge)}%c`;\n const parts: string[] = [badgeStyle(theme[type]), ''];\n\n if (namespace) {\n fmt += ` %c${escapeConsoleFormat(namespace)}%c`;\n parts.push(badgeStyle(theme.ns, `; ${NS_STYLE}`), '');\n }\n\n if (timestamp) {\n fmt += ` %c${timestamp}%c`;\n parts.push('color: gray', '');\n }\n\n return { fmt, parts };\n}\n\n/* ─── consoleTransport ─── */\n\n/**\n * Formats and writes log entries to the browser or Node.js console.\n * Uses CSS-styled badges in browsers and plain text in Node.\n * Accepts an optional partial `theme` to override colors and badges per level.\n *\n * @example\n * consoleTransport()\n * consoleTransport({ level: 'warn', timestamp: false })\n * consoleTransport({ theme: { error: { badge: '✖' } } })\n * consoleTransport({ inspectFn: (v) => require('util').inspect(v, { colors: true, depth: 4 }) })\n */\nexport function consoleTransport(options: ConsoleTransportOptions = {}): Transport {\n const level = options.level ?? 'debug';\n const showTimestamp = options.timestamp ?? true;\n const format = options.format ?? 'raw';\n const isNode = typeof window === 'undefined';\n const useAnsi = options.ansi ?? (isNode ? supportsAnsi() : false);\n const resolved = resolveTheme(options.theme);\n const inspectFn: ((v: unknown) => string) | undefined =\n format === 'json' ? (v) => JSON.stringify(v) : options.inspectFn;\n\n return (entry: LogEntry): void => {\n if (!isLevelEnabled(level, entry.level)) return;\n\n const timestamp = showTimestamp ? entry.timestamp.toISOString().slice(11, 23) : '';\n const payload = buildPayload(entry.data, entry.message, inspectFn);\n const method = console[LOG_METHOD[entry.level]] as (...args: unknown[]) => void;\n\n if (isNode) {\n method(buildNodePrefix(resolved, entry.level, entry.namespace, timestamp, useAnsi), ...payload);\n } else {\n const { fmt, parts } = buildBrowserPrefix(resolved, entry.level, entry.namespace, timestamp);\n\n method(fmt, ...parts, ...payload);\n }\n };\n}\n\n/* ─── Group rendering (used by logger.ts wrapGroup) ─── */\n\nexport function renderGroup(collapsed: boolean, label: string, namespace: string, theme: ResolvedTheme): void {\n const fn = collapsed ? console.groupCollapsed : console.group;\n const isNode = typeof window === 'undefined';\n\n if (isNode) {\n const meta = [theme.group.badge, escapeConsoleFormat(label)];\n\n if (namespace) meta.push(`[${escapeConsoleFormat(namespace)}]`);\n\n fn(meta.join(' | '));\n\n return;\n }\n\n let fmt = `${theme.group.badge} %c${escapeConsoleFormat(label)}%c`;\n const parts: string[] = [badgeStyle(theme.group, '; margin-right: 6px; padding: 1px 3px 0'), ''];\n\n if (namespace) {\n fmt += ` %c${escapeConsoleFormat(namespace)}%c`;\n parts.push(badgeStyle(theme.ns, `; ${NS_STYLE}; margin-right: 6px`), '');\n }\n\n fn(fmt, ...parts);\n}\n"],"mappings":"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"}
package/dist/console.js CHANGED
@@ -119,8 +119,8 @@ function m(n = {}) {
119
119
  function h(e, t, n, i) {
120
120
  let a = e ? console.groupCollapsed : console.group;
121
121
  if (typeof window > "u") {
122
- let e = [i.group.badge, t];
123
- n && e.push(`[${n}]`), a(e.join(" | "));
122
+ let e = [i.group.badge, d(t)];
123
+ n && e.push(`[${d(n)}]`), a(e.join(" | "));
124
124
  return;
125
125
  }
126
126
  let o = `${i.group.badge} %c${d(t)}%c`, s = [u(i.group, "; margin-right: 6px; padding: 1px 3px 0"), ""];
@@ -1 +1 @@
1
- {"version":3,"file":"console.js","names":[],"sources":["../src/console.ts"],"sourcesContent":["import type { Bindings, LogEntry, LogLevel, LogType, Transport } from './types';\n\nimport { isLevelEnabled } from './types';\n\n/* ─── Console theme types ─── */\n\n/**\n * Per-level style definition for the console transport.\n * All fields are optional when providing a level override — unspecified fields fall back to the default theme.\n */\nexport type ConsoleThemeEntry = {\n badge: string;\n bg: string;\n border: string;\n color: string;\n};\n\n/**\n * Partial theme overrides merged on top of the default theme.\n * Each level entry is also partial — only specify the fields you want to change.\n *\n * @example\n * consoleTransport({ theme: { error: { badge: '✖' } } })\n */\nexport type ConsoleTheme = Partial<Record<LogType | 'group' | 'ns', Partial<ConsoleThemeEntry>>>;\n\n/**\n * Fully-resolved console theme where every level and every field is populated.\n */\nexport type ResolvedTheme = Record<LogType | 'group' | 'ns', ConsoleThemeEntry>;\n\n/* ─── ConsoleTransportOptions ─── */\n\nexport type ConsoleTransportOptions = {\n /**\n * Enable ANSI 24-bit color output in Node.js.\n * Default: true when process.stdout.isTTY is true, false otherwise.\n */\n ansi?: boolean;\n /**\n * Object serialization format for Node.js output.\n * - 'json' — JSON.stringify (machine-readable, fails on circular refs)\n * - 'raw' — pass the object directly to the console method (default)\n * Default: 'raw'.\n */\n format?: 'json' | 'raw';\n /**\n * Custom object inspector function. When provided, the `data` object is\n * passed through this function before being written to the console.\n */\n inspectFn?: (value: unknown) => string;\n /** Minimum level to output. Default: 'debug'. */\n level?: LogLevel;\n /** Partial theme overrides merged on top of the default theme. */\n theme?: ConsoleTheme;\n /** Whether to include timestamp in console output. Default: true. */\n timestamp?: boolean;\n};\n\n/* ─── Payload builder ─── */\n\nfunction buildPayload(\n data: Readonly<Bindings>,\n message: string | undefined,\n inspectFn: ((v: unknown) => string) | undefined,\n): unknown[] {\n const hasData = Object.keys(data).length > 0;\n const formatted: unknown = inspectFn && hasData ? inspectFn(data) : hasData ? data : undefined;\n\n if (formatted !== undefined && message !== undefined) return [message, formatted];\n\n if (formatted !== undefined) return [formatted];\n\n if (message !== undefined) return [message];\n\n return [];\n}\n\n/* ─── Console theme ─── */\n\nexport const DEFAULT_THEME: ResolvedTheme = {\n debug: { badge: '🅳', bg: '#616161', border: '#424242', color: '#e0e0e0' },\n error: { badge: '🅴', bg: '#d32f2f', border: '#c62828', color: '#fff' },\n fatal: { badge: '🅵', bg: '#4a148c', border: '#38006b', color: '#fff' },\n group: { badge: '🅶', bg: '#546e7a', border: '#455a64', color: '#fff' },\n info: { badge: '🅸', bg: '#1976d2', border: '#1565c0', color: '#fff' },\n ns: { badge: '', bg: '#424242', border: '#212121', color: '#fff' },\n warn: { badge: '🆆', bg: '#ffb300', border: '#ffa000', color: '#212121' },\n};\n\nconst NS_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;';\n\nconst LOG_METHOD: Record<LogType, 'error' | 'info' | 'log' | 'warn'> = {\n debug: 'log',\n error: 'error',\n fatal: 'error',\n info: 'info',\n warn: 'warn',\n};\n\n/** Deep-merges per-level overrides onto the default theme. Only specified fields within each level entry are replaced. */\nexport function resolveTheme(override: ConsoleTheme | undefined): ResolvedTheme {\n if (!override) return DEFAULT_THEME;\n\n const result: ResolvedTheme = { ...DEFAULT_THEME };\n\n for (const key of Object.keys(override) as Array<LogType | 'group' | 'ns'>) {\n const entry = override[key];\n\n if (entry) result[key] = { ...DEFAULT_THEME[key], ...entry };\n }\n\n return result;\n}\n\n/* ─── ANSI helpers (Node) ─── */\n\nfunction hexToRgb(hex: string): [number, number, number] {\n return [parseInt(hex.slice(1, 3), 16), parseInt(hex.slice(3, 5), 16), parseInt(hex.slice(5, 7), 16)];\n}\n\nfunction ansiColor(hex: string, text: string): string {\n const [r, g, b] = hexToRgb(hex);\n\n return `\\x1b[38;2;${r};${g};${b}m${text}\\x1b[0m`;\n}\n\nfunction ansiMuted(text: string): string {\n return `\\x1b[90m${text}\\x1b[0m`;\n}\n\nfunction supportsAnsi(): boolean {\n if (typeof window !== 'undefined') return false;\n\n return (\n (globalThis as Record<string, unknown> & { process?: { stdout?: { isTTY?: boolean } } }).process?.stdout?.isTTY ===\n true\n );\n}\n\nfunction badgeStyle(entry: ConsoleThemeEntry, extra = ''): string {\n return `background: ${entry.bg}; color: ${entry.color}; border: 1px solid ${entry.border}; border-radius: 4px; padding: 0 1px${extra}`;\n}\n\nfunction escapeConsoleFormat(s: string): string {\n return s.replace(/%/g, '%%');\n}\n\n/**\n * Builds the Node console prefix string, passed as the first argument to `console.log()`/etc.\n * alongside the payload. `namespace` is escaped because Node's `console.*` methods run the first\n * string argument through `util.format` — an unescaped `%s`/`%d`/`%o`/etc. in a caller-controlled\n * namespace would consume and hide the actual payload arguments that follow (log forging).\n */\nfunction buildNodePrefix(\n theme: ResolvedTheme,\n type: LogType,\n namespace: string,\n timestamp: string,\n useAnsi: boolean,\n): string {\n const t = theme[type];\n const safeBadge = escapeConsoleFormat(t.badge);\n const badgeText = useAnsi ? ansiColor(t.bg, safeBadge) : safeBadge;\n const meta = [badgeText];\n\n if (namespace) {\n const safeNamespace = escapeConsoleFormat(namespace);\n\n meta.push(useAnsi ? ansiMuted(`[${safeNamespace}]`) : `[${safeNamespace}]`);\n }\n\n if (timestamp) meta.push(useAnsi ? ansiMuted(timestamp) : timestamp);\n\n return `${meta.join(' | ')} |`;\n}\n\nfunction buildBrowserPrefix(\n theme: ResolvedTheme,\n type: LogType,\n namespace: string,\n timestamp: string,\n): { fmt: string; parts: string[] } {\n let fmt = `%c${escapeConsoleFormat(theme[type].badge)}%c`;\n const parts: string[] = [badgeStyle(theme[type]), ''];\n\n if (namespace) {\n fmt += ` %c${escapeConsoleFormat(namespace)}%c`;\n parts.push(badgeStyle(theme.ns, `; ${NS_STYLE}`), '');\n }\n\n if (timestamp) {\n fmt += ` %c${timestamp}%c`;\n parts.push('color: gray', '');\n }\n\n return { fmt, parts };\n}\n\n/* ─── consoleTransport ─── */\n\n/**\n * Formats and writes log entries to the browser or Node.js console.\n * Uses CSS-styled badges in browsers and plain text in Node.\n * Accepts an optional partial `theme` to override colors and badges per level.\n *\n * @example\n * consoleTransport()\n * consoleTransport({ level: 'warn', timestamp: false })\n * consoleTransport({ theme: { error: { badge: '✖' } } })\n * consoleTransport({ inspectFn: (v) => require('util').inspect(v, { colors: true, depth: 4 }) })\n */\nexport function consoleTransport(options: ConsoleTransportOptions = {}): Transport {\n const level = options.level ?? 'debug';\n const showTimestamp = options.timestamp ?? true;\n const format = options.format ?? 'raw';\n const isNode = typeof window === 'undefined';\n const useAnsi = options.ansi ?? (isNode ? supportsAnsi() : false);\n const resolved = resolveTheme(options.theme);\n const inspectFn: ((v: unknown) => string) | undefined =\n format === 'json' ? (v) => JSON.stringify(v) : options.inspectFn;\n\n return (entry: LogEntry): void => {\n if (!isLevelEnabled(level, entry.level)) return;\n\n const timestamp = showTimestamp ? entry.timestamp.toISOString().slice(11, 23) : '';\n const payload = buildPayload(entry.data, entry.message, inspectFn);\n const method = console[LOG_METHOD[entry.level]] as (...args: unknown[]) => void;\n\n if (isNode) {\n method(buildNodePrefix(resolved, entry.level, entry.namespace, timestamp, useAnsi), ...payload);\n } else {\n const { fmt, parts } = buildBrowserPrefix(resolved, entry.level, entry.namespace, timestamp);\n\n method(fmt, ...parts, ...payload);\n }\n };\n}\n\n/* ─── Group rendering (used by logger.ts wrapGroup) ─── */\n\nexport function renderGroup(collapsed: boolean, label: string, namespace: string, theme: ResolvedTheme): void {\n const fn = collapsed ? console.groupCollapsed : console.group;\n const isNode = typeof window === 'undefined';\n\n if (isNode) {\n const meta = [theme.group.badge, label];\n\n if (namespace) meta.push(`[${namespace}]`);\n\n fn(meta.join(' | '));\n\n return;\n }\n\n let fmt = `${theme.group.badge} %c${escapeConsoleFormat(label)}%c`;\n const parts: string[] = [badgeStyle(theme.group, '; margin-right: 6px; padding: 1px 3px 0'), ''];\n\n if (namespace) {\n fmt += ` %c${escapeConsoleFormat(namespace)}%c`;\n parts.push(badgeStyle(theme.ns, `; ${NS_STYLE}; margin-right: 6px`), '');\n }\n\n fn(fmt, ...parts);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"console.js","names":[],"sources":["../src/console.ts"],"sourcesContent":["import type { Bindings, LogEntry, LogLevel, LogType, Transport } from './types';\n\nimport { isLevelEnabled } from './types';\n\n/* ─── Console theme types ─── */\n\n/**\n * Per-level style definition for the console transport.\n * All fields are optional when providing a level override — unspecified fields fall back to the default theme.\n */\nexport type ConsoleThemeEntry = {\n badge: string;\n bg: string;\n border: string;\n color: string;\n};\n\n/**\n * Partial theme overrides merged on top of the default theme.\n * Each level entry is also partial — only specify the fields you want to change.\n *\n * @example\n * consoleTransport({ theme: { error: { badge: '✖' } } })\n */\nexport type ConsoleTheme = Partial<Record<LogType | 'group' | 'ns', Partial<ConsoleThemeEntry>>>;\n\n/**\n * Fully-resolved console theme where every level and every field is populated.\n */\nexport type ResolvedTheme = Record<LogType | 'group' | 'ns', ConsoleThemeEntry>;\n\n/* ─── ConsoleTransportOptions ─── */\n\nexport type ConsoleTransportOptions = {\n /**\n * Enable ANSI 24-bit color output in Node.js.\n * Default: true when process.stdout.isTTY is true, false otherwise.\n */\n ansi?: boolean;\n /**\n * Object serialization format for Node.js output.\n * - 'json' — JSON.stringify (machine-readable, fails on circular refs)\n * - 'raw' — pass the object directly to the console method (default)\n * Default: 'raw'.\n */\n format?: 'json' | 'raw';\n /**\n * Custom object inspector function. When provided, the `data` object is\n * passed through this function before being written to the console.\n */\n inspectFn?: (value: unknown) => string;\n /** Minimum level to output. Default: 'debug'. */\n level?: LogLevel;\n /** Partial theme overrides merged on top of the default theme. */\n theme?: ConsoleTheme;\n /** Whether to include timestamp in console output. Default: true. */\n timestamp?: boolean;\n};\n\n/* ─── Payload builder ─── */\n\nfunction buildPayload(\n data: Readonly<Bindings>,\n message: string | undefined,\n inspectFn: ((v: unknown) => string) | undefined,\n): unknown[] {\n const hasData = Object.keys(data).length > 0;\n const formatted: unknown = inspectFn && hasData ? inspectFn(data) : hasData ? data : undefined;\n\n if (formatted !== undefined && message !== undefined) return [message, formatted];\n\n if (formatted !== undefined) return [formatted];\n\n if (message !== undefined) return [message];\n\n return [];\n}\n\n/* ─── Console theme ─── */\n\nexport const DEFAULT_THEME: ResolvedTheme = {\n debug: { badge: '🅳', bg: '#616161', border: '#424242', color: '#e0e0e0' },\n error: { badge: '🅴', bg: '#d32f2f', border: '#c62828', color: '#fff' },\n fatal: { badge: '🅵', bg: '#4a148c', border: '#38006b', color: '#fff' },\n group: { badge: '🅶', bg: '#546e7a', border: '#455a64', color: '#fff' },\n info: { badge: '🅸', bg: '#1976d2', border: '#1565c0', color: '#fff' },\n ns: { badge: '', bg: '#424242', border: '#212121', color: '#fff' },\n warn: { badge: '🆆', bg: '#ffb300', border: '#ffa000', color: '#212121' },\n};\n\nconst NS_STYLE = 'border-radius: 8px; font: italic small-caps bold 12px; font-weight: lighter; padding: 0 4px;';\n\nconst LOG_METHOD: Record<LogType, 'error' | 'info' | 'log' | 'warn'> = {\n debug: 'log',\n error: 'error',\n fatal: 'error',\n info: 'info',\n warn: 'warn',\n};\n\n/** Deep-merges per-level overrides onto the default theme. Only specified fields within each level entry are replaced. */\nexport function resolveTheme(override: ConsoleTheme | undefined): ResolvedTheme {\n if (!override) return DEFAULT_THEME;\n\n const result: ResolvedTheme = { ...DEFAULT_THEME };\n\n for (const key of Object.keys(override) as Array<LogType | 'group' | 'ns'>) {\n const entry = override[key];\n\n if (entry) result[key] = { ...DEFAULT_THEME[key], ...entry };\n }\n\n return result;\n}\n\n/* ─── ANSI helpers (Node) ─── */\n\nfunction hexToRgb(hex: string): [number, number, number] {\n return [parseInt(hex.slice(1, 3), 16), parseInt(hex.slice(3, 5), 16), parseInt(hex.slice(5, 7), 16)];\n}\n\nfunction ansiColor(hex: string, text: string): string {\n const [r, g, b] = hexToRgb(hex);\n\n return `\\x1b[38;2;${r};${g};${b}m${text}\\x1b[0m`;\n}\n\nfunction ansiMuted(text: string): string {\n return `\\x1b[90m${text}\\x1b[0m`;\n}\n\nfunction supportsAnsi(): boolean {\n if (typeof window !== 'undefined') return false;\n\n return (\n (globalThis as Record<string, unknown> & { process?: { stdout?: { isTTY?: boolean } } }).process?.stdout?.isTTY ===\n true\n );\n}\n\nfunction badgeStyle(entry: ConsoleThemeEntry, extra = ''): string {\n return `background: ${entry.bg}; color: ${entry.color}; border: 1px solid ${entry.border}; border-radius: 4px; padding: 0 1px${extra}`;\n}\n\nfunction escapeConsoleFormat(s: string): string {\n return s.replace(/%/g, '%%');\n}\n\n/**\n * Builds the Node console prefix string, passed as the first argument to `console.log()`/etc.\n * alongside the payload. `namespace` is escaped because Node's `console.*` methods run the first\n * string argument through `util.format` — an unescaped `%s`/`%d`/`%o`/etc. in a caller-controlled\n * namespace would consume and hide the actual payload arguments that follow (log forging).\n */\nfunction buildNodePrefix(\n theme: ResolvedTheme,\n type: LogType,\n namespace: string,\n timestamp: string,\n useAnsi: boolean,\n): string {\n const t = theme[type];\n const safeBadge = escapeConsoleFormat(t.badge);\n const badgeText = useAnsi ? ansiColor(t.bg, safeBadge) : safeBadge;\n const meta = [badgeText];\n\n if (namespace) {\n const safeNamespace = escapeConsoleFormat(namespace);\n\n meta.push(useAnsi ? ansiMuted(`[${safeNamespace}]`) : `[${safeNamespace}]`);\n }\n\n if (timestamp) meta.push(useAnsi ? ansiMuted(timestamp) : timestamp);\n\n return `${meta.join(' | ')} |`;\n}\n\nfunction buildBrowserPrefix(\n theme: ResolvedTheme,\n type: LogType,\n namespace: string,\n timestamp: string,\n): { fmt: string; parts: string[] } {\n let fmt = `%c${escapeConsoleFormat(theme[type].badge)}%c`;\n const parts: string[] = [badgeStyle(theme[type]), ''];\n\n if (namespace) {\n fmt += ` %c${escapeConsoleFormat(namespace)}%c`;\n parts.push(badgeStyle(theme.ns, `; ${NS_STYLE}`), '');\n }\n\n if (timestamp) {\n fmt += ` %c${timestamp}%c`;\n parts.push('color: gray', '');\n }\n\n return { fmt, parts };\n}\n\n/* ─── consoleTransport ─── */\n\n/**\n * Formats and writes log entries to the browser or Node.js console.\n * Uses CSS-styled badges in browsers and plain text in Node.\n * Accepts an optional partial `theme` to override colors and badges per level.\n *\n * @example\n * consoleTransport()\n * consoleTransport({ level: 'warn', timestamp: false })\n * consoleTransport({ theme: { error: { badge: '✖' } } })\n * consoleTransport({ inspectFn: (v) => require('util').inspect(v, { colors: true, depth: 4 }) })\n */\nexport function consoleTransport(options: ConsoleTransportOptions = {}): Transport {\n const level = options.level ?? 'debug';\n const showTimestamp = options.timestamp ?? true;\n const format = options.format ?? 'raw';\n const isNode = typeof window === 'undefined';\n const useAnsi = options.ansi ?? (isNode ? supportsAnsi() : false);\n const resolved = resolveTheme(options.theme);\n const inspectFn: ((v: unknown) => string) | undefined =\n format === 'json' ? (v) => JSON.stringify(v) : options.inspectFn;\n\n return (entry: LogEntry): void => {\n if (!isLevelEnabled(level, entry.level)) return;\n\n const timestamp = showTimestamp ? entry.timestamp.toISOString().slice(11, 23) : '';\n const payload = buildPayload(entry.data, entry.message, inspectFn);\n const method = console[LOG_METHOD[entry.level]] as (...args: unknown[]) => void;\n\n if (isNode) {\n method(buildNodePrefix(resolved, entry.level, entry.namespace, timestamp, useAnsi), ...payload);\n } else {\n const { fmt, parts } = buildBrowserPrefix(resolved, entry.level, entry.namespace, timestamp);\n\n method(fmt, ...parts, ...payload);\n }\n };\n}\n\n/* ─── Group rendering (used by logger.ts wrapGroup) ─── */\n\nexport function renderGroup(collapsed: boolean, label: string, namespace: string, theme: ResolvedTheme): void {\n const fn = collapsed ? console.groupCollapsed : console.group;\n const isNode = typeof window === 'undefined';\n\n if (isNode) {\n const meta = [theme.group.badge, escapeConsoleFormat(label)];\n\n if (namespace) meta.push(`[${escapeConsoleFormat(namespace)}]`);\n\n fn(meta.join(' | '));\n\n return;\n }\n\n let fmt = `${theme.group.badge} %c${escapeConsoleFormat(label)}%c`;\n const parts: string[] = [badgeStyle(theme.group, '; margin-right: 6px; padding: 1px 3px 0'), ''];\n\n if (namespace) {\n fmt += ` %c${escapeConsoleFormat(namespace)}%c`;\n parts.push(badgeStyle(theme.ns, `; ${NS_STYLE}; margin-right: 6px`), '');\n }\n\n fn(fmt, ...parts);\n}\n"],"mappings":"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"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class extends e{constructor(e){super(`Transport threw an unhandled error`,{cause:e instanceof Error?e:void 0})}};exports.RuneError=e,exports.RuneTransportError=t;
1
+ var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}};exports.RuneError=e;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all rune errors. Use `instanceof RuneError` to catch any rune-originated error. */\nexport class RuneError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is RuneError {\n return err instanceof RuneError;\n }\n}\n\n/**\n * Constructed internally when a transport function throws during log entry emission.\n * Never thrown/propagated to the caller — the logger catches the underlying error, wraps it here\n * (available as `.cause`), and reports it via a dev-only warning so the failing transport cannot\n * crash the caller of `log.info()`/etc. or prevent sibling transports from receiving the entry.\n */\nexport class RuneTransportError extends RuneError {\n constructor(cause: unknown) {\n super('Transport threw an unhandled error', { cause: cause instanceof Error ? cause : undefined });\n }\n}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAkB,KAAM,CACnC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,IAAI,OAAO,KACvB,OAAO,eAAe,KAAM,IAAI,OAAO,SAAS,CAClD,CAEA,OAAO,GAAG,EAAgC,CACxC,OAAO,aAAe,CACxB,CACF,EAQa,EAAb,cAAwC,CAAU,CAChD,YAAY,EAAgB,CAC1B,MAAM,qCAAsC,CAAE,MAAO,aAAiB,MAAQ,EAAQ,IAAA,EAAU,CAAC,CACnG,CACF"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all rune errors. Use `instanceof RuneError` to catch any rune-originated error. */\nexport class RuneError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is RuneError {\n return err instanceof RuneError;\n }\n}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAkB,KAAM,CACnC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAgC,CACxC,OAAO,aAAe,CACxB,CACF"}
package/dist/errors.d.ts CHANGED
@@ -3,13 +3,4 @@ export declare class RuneError extends Error {
3
3
  constructor(message: string, opts?: ErrorOptions);
4
4
  static is(err: unknown): err is RuneError;
5
5
  }
6
- /**
7
- * Constructed internally when a transport function throws during log entry emission.
8
- * Never thrown/propagated to the caller — the logger catches the underlying error, wraps it here
9
- * (available as `.cause`), and reports it via a dev-only warning so the failing transport cannot
10
- * crash the caller of `log.info()`/etc. or prevent sibling transports from receiving the entry.
11
- */
12
- export declare class RuneTransportError extends RuneError {
13
- constructor(cause: unknown);
14
- }
15
6
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;IAMhD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,SAAS;CAG1C;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;gBACnC,KAAK,EAAE,OAAO;CAG3B"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;IAMhD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,SAAS;CAG1C"}
package/dist/errors.js CHANGED
@@ -6,12 +6,8 @@ var e = class e extends Error {
6
6
  static is(t) {
7
7
  return t instanceof e;
8
8
  }
9
- }, t = class extends e {
10
- constructor(e) {
11
- super("Transport threw an unhandled error", { cause: e instanceof Error ? e : void 0 });
12
- }
13
9
  };
14
10
  //#endregion
15
- export { e as RuneError, t as RuneTransportError };
11
+ export { e as RuneError };
16
12
 
17
13
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all rune errors. Use `instanceof RuneError` to catch any rune-originated error. */\nexport class RuneError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is RuneError {\n return err instanceof RuneError;\n }\n}\n\n/**\n * Constructed internally when a transport function throws during log entry emission.\n * Never thrown/propagated to the caller — the logger catches the underlying error, wraps it here\n * (available as `.cause`), and reports it via a dev-only warning so the failing transport cannot\n * crash the caller of `log.info()`/etc. or prevent sibling transports from receiving the entry.\n */\nexport class RuneTransportError extends RuneError {\n constructor(cause: unknown) {\n super('Transport threw an unhandled error', { cause: cause instanceof Error ? cause : undefined });\n }\n}\n"],"mappings":";AACA,IAAa,IAAb,MAAa,UAAkB,MAAM;CACnC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,IAAI,OAAO,MACvB,OAAO,eAAe,MAAM,IAAI,OAAO,SAAS;CAClD;CAEA,OAAO,GAAG,GAAgC;EACxC,OAAO,aAAe;CACxB;AACF,GAQa,IAAb,cAAwC,EAAU;CAChD,YAAY,GAAgB;EAC1B,MAAM,sCAAsC,EAAE,OAAO,aAAiB,QAAQ,IAAQ,KAAA,EAAU,CAAC;CACnG;AACF"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all rune errors. Use `instanceof RuneError` to catch any rune-originated error. */\nexport class RuneError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is RuneError {\n return err instanceof RuneError;\n }\n}\n"],"mappings":";AACA,IAAa,IAAb,MAAa,UAAkB,MAAM;CACnC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;CAEA,OAAO,GAAG,GAAgC;EACxC,OAAO,aAAe;CACxB;AACF"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./types.cjs"),n=require("./lazy.cjs"),r=require("./console.cjs"),i=require("./logger.cjs"),a=require("./transports.cjs");exports.DEFAULT_THEME=r.DEFAULT_THEME,exports.PRIORITY=t.PRIORITY,exports.RuneError=e.RuneError,exports.RuneTransportError=e.RuneTransportError,exports.batchTransport=a.batchTransport,exports.consoleTransport=r.consoleTransport,exports.createLogger=i.createLogger,exports.defaultLogger=i.defaultLogger,exports.isLevelEnabled=t.isLevelEnabled,exports.jsonTransport=a.jsonTransport,exports.lazy=n.lazy,exports.pipe=a.pipe,exports.redactTransport=a.redactTransport,exports.remoteTransport=a.remoteTransport,exports.resolveTheme=r.resolveTheme,exports.sampleTransport=a.sampleTransport;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./types.cjs"),n=require("./lazy.cjs"),r=require("./console.cjs"),i=require("./logger.cjs"),a=require("./transports.cjs");exports.DEFAULT_THEME=r.DEFAULT_THEME,exports.PRIORITY=t.PRIORITY,exports.RuneError=e.RuneError,exports.batchTransport=a.batchTransport,exports.consoleTransport=r.consoleTransport,exports.createLogger=i.createLogger,exports.defaultLogger=i.defaultLogger,exports.isLevelEnabled=t.isLevelEnabled,exports.jsonTransport=a.jsonTransport,exports.lazy=n.lazy,exports.pipe=a.pipe,exports.redactTransport=a.redactTransport,exports.remoteTransport=a.remoteTransport,exports.resolveTheme=r.resolveTheme,exports.sampleTransport=a.sampleTransport;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type { BatchHandle, BatchTransportOptions, Bindings, JsonTransportOptions, LogEntry, LogLevel, LogMethod, LogMiddleware, Logger, LogType, PipeOptions, RedactTransportOptions, RemoteLogData, RemoteTransportOptions, RuneOptions, SampleTransportOptions, Transport, } from './types';
2
- export { RuneError, RuneTransportError } from './errors';
2
+ export { RuneError } from './errors';
3
3
  export { isLevelEnabled, PRIORITY } from './types';
4
4
  export type { LazyBinding } from './lazy';
5
5
  export { lazy } from './lazy';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,WAAW,EACX,qBAAqB,EACrB,QAAQ,EACR,oBAAoB,EACpB,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,aAAa,EACb,MAAM,EACN,OAAO,EACP,WAAW,EACX,sBAAsB,EACtB,aAAa,EACb,sBAAsB,EACtB,WAAW,EACX,sBAAsB,EACtB,SAAS,GACV,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,WAAW,EACX,qBAAqB,EACrB,QAAQ,EACR,oBAAoB,EACpB,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,aAAa,EACb,MAAM,EACN,OAAO,EACP,WAAW,EACX,sBAAsB,EACtB,aAAa,EACb,sBAAsB,EACtB,WAAW,EACX,sBAAsB,EACtB,SAAS,GACV,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { RuneError as e, RuneTransportError as t } from "./errors.js";
2
- import { PRIORITY as n, isLevelEnabled as r } from "./types.js";
3
- import { lazy as i } from "./lazy.js";
4
- import { DEFAULT_THEME as a, consoleTransport as o, resolveTheme as s } from "./console.js";
5
- import { createLogger as c, defaultLogger as l } from "./logger.js";
6
- import { batchTransport as u, jsonTransport as d, pipe as f, redactTransport as p, remoteTransport as m, sampleTransport as h } from "./transports.js";
7
- export { a as DEFAULT_THEME, n as PRIORITY, e as RuneError, t as RuneTransportError, u as batchTransport, o as consoleTransport, c as createLogger, l as defaultLogger, r as isLevelEnabled, d as jsonTransport, i as lazy, f as pipe, p as redactTransport, m as remoteTransport, s as resolveTheme, h as sampleTransport };
1
+ import { RuneError as e } from "./errors.js";
2
+ import { PRIORITY as t, isLevelEnabled as n } from "./types.js";
3
+ import { lazy as r } from "./lazy.js";
4
+ import { DEFAULT_THEME as i, consoleTransport as a, resolveTheme as o } from "./console.js";
5
+ import { createLogger as s, defaultLogger as c } from "./logger.js";
6
+ import { batchTransport as l, jsonTransport as u, pipe as d, redactTransport as f, remoteTransport as p, sampleTransport as m } from "./transports.js";
7
+ export { i as DEFAULT_THEME, t as PRIORITY, e as RuneError, l as batchTransport, a as consoleTransport, s as createLogger, c as defaultLogger, n as isLevelEnabled, u as jsonTransport, r as lazy, d as pipe, f as redactTransport, p as remoteTransport, o as resolveTheme, m as sampleTransport };
package/dist/logger.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs"),t=require("./types.cjs"),n=require("./_prototype.cjs"),r=require("./lazy.cjs"),i=require("./_dev.cjs"),a=require("./console.cjs");function o(e){return{message:e.message,name:e.name,stack:e.stack}}function s(e){let t={};for(let[r,i]of Object.entries(e))n.isUnsafeObjectKey(r)||(t[r]=i instanceof Error?o(i):i);return t}function c(e,t,n){if(typeof e==`string`)return{context:void 0,message:e};if(e instanceof Error){let r=typeof t==`object`&&t?t:{};return{context:{err:o(e),...r},message:n===void 0?t!==void 0&&typeof t!=`object`?String(t):void 0:String(n)}}return typeof e==`object`&&e?{context:e,message:t===void 0?void 0:String(t)}:{context:void 0,message:e===void 0?void 0:String(e)}}function l(e,t){return e?t?`${e}.${t}`:e:t}function u(n={},d){let f=typeof n==`string`?{namespace:n,...d}:n,p=f.logLevel??`debug`,m=f.middleware??[],h=f.namespace??``,g=f.transports??[a.consoleTransport()],_={...f.bindings??{}},v=new AbortController,y=!1,b=e=>t.isLevelEnabled(p,e),x=()=>h?` (namespace: "${h}")`:``,S=t=>{let n=t;if(m.length>0){let e=t;for(let t of m)try{let n=t(e);if(n==null)return;e=n}catch(e){i.warn(`middleware threw and dropped this entry${x()}: ${String(e)}`);return}n=e}for(let t of g)try{t(n)}catch(t){i.warn(`${new e.RuneTransportError(t).message}${x()}: ${String(t)}`)}},C=(e,t,n,i)=>{if(y||!b(e))return;let{context:a,message:o}=c(t,n,i),l=s(r.resolveBindings(_)),u=a?{...l,...s(r.resolveBindings(a))}:l;S({data:u,level:e,message:o,namespace:h,timestamp:new Date})},w=(e,t,n=`debug`)=>{let r=performance.now(),i=t=>{let i={duration_ms:Math.round((performance.now()-r)*100)/100};t!==void 0&&(i.err=o(t instanceof Error?t:Error(String(t)))),C(n,i,e)};try{let e=t();return e instanceof Promise?e.then(e=>(i(),e),e=>(i(e),Promise.reject(e))):(i(),e)}catch(e){throw i(e),e}},T=(e,t,n,r)=>{if(y||p===`off`||r!==void 0&&!b(r))return n();a.renderGroup(e,t,h,a.DEFAULT_THEME);try{let e=n();return e instanceof Promise?e.finally(()=>console.groupEnd()):(console.groupEnd(),e)}catch(e){throw console.groupEnd(),e}},E=(e={})=>u({bindings:{..._,...e.bindings??{}},logLevel:e.logLevel??p,middleware:e.middleware??m,namespace:e.namespace===void 0?h:l(h,e.namespace),transports:e.transports??g}),D={get bindings(){return{..._}},child:E,debug:(e,t,n)=>C(`debug`,e,t,n),get disposalSignal(){return v.signal},dispose:()=>{y||(y=!0,v.abort())},get disposed(){return y},enabled:e=>t.isLevelEnabled(p,e),error:(e,t,n)=>C(`error`,e,t,n),fatal:(e,t,n)=>C(`fatal`,e,t,n),group:(e,t,n)=>T(!1,e,t,n),groupCollapsed:(e,t,n)=>T(!0,e,t,n),info:(e,t,n)=>C(`info`,e,t,n),get logLevel(){return p},get middleware(){return[...m]},get namespace(){return h},[Symbol.dispose](){D.dispose()},time:w,get transports(){return[...g]},use:e=>E({middleware:[...m,e]}),warn:(e,t,n)=>C(`warn`,e,t,n),withBindings:e=>E({bindings:e})};return D}var d=u();exports.createLogger=u,exports.defaultLogger=d;
1
+ const e=require("./types.cjs"),t=require("./_prototype.cjs"),n=require("./lazy.cjs");require("./_dev.cjs");const r=require("./console.cjs");function i(e){return{message:e.message,name:e.name,stack:e.stack}}function a(e){let n={};for(let[r,a]of Object.entries(e))t.isUnsafeObjectKey(r)||(n[r]=a instanceof Error?i(a):a);return n}function o(e,t,n){if(typeof e==`string`)return{context:void 0,message:e};if(e instanceof Error){let r=typeof t==`object`&&t?t:{};return{context:{err:i(e),...r},message:n===void 0?t!==void 0&&typeof t!=`object`?String(t):void 0:String(n)}}return typeof e==`object`&&e?{context:e,message:t===void 0?void 0:String(t)}:{context:void 0,message:e===void 0?void 0:String(e)}}function s(e,t){return e?t?`${e}.${t}`:e:t}function c(t={},l){let u=typeof t==`string`?{namespace:t,...l}:t,d=u.logLevel??`debug`,f=u.middleware??[],p=u.namespace??``,m=u.transports??[r.consoleTransport()],h={...u.bindings??{}},g=new AbortController,_=!1,v=t=>e.isLevelEnabled(d,t),y=()=>p?` (namespace: "${p}")`:``,b=e=>{let t=e;if(f.length>0){let n=e;for(let e of f)try{let t=e(n);if(t==null)return;n=t}catch(e){`${y()}${String(e)}`;return}t=n}for(let e of m)try{e(t)}catch(e){`${y()}${String(e)}`}},x=(e,t,r,i)=>{if(_||!v(e))return;let{context:s,message:c}=o(t,r,i),l=a(n.resolveBindings(h)),u=s?{...l,...a(n.resolveBindings(s))}:l;b({data:u,level:e,message:c,namespace:p,timestamp:new Date})},S=(e,t,n=`debug`)=>{let r=performance.now(),a=t=>{let a={duration_ms:Math.round((performance.now()-r)*100)/100};t!==void 0&&(a.err=i(t instanceof Error?t:Error(String(t)))),x(n,a,e)};try{let e=t();return e instanceof Promise?e.then(e=>(a(),e),e=>(a(e),Promise.reject(e))):(a(),e)}catch(e){throw a(e),e}},C=(e,t,n,i)=>{if(_||d===`off`||i!==void 0&&!v(i))return n();r.renderGroup(e,t,p,r.DEFAULT_THEME);try{let e=n();return e instanceof Promise?e.finally(()=>console.groupEnd()):(console.groupEnd(),e)}catch(e){throw console.groupEnd(),e}},w=(e={})=>c({bindings:{...h,...e.bindings??{}},logLevel:e.logLevel??d,middleware:e.middleware??f,namespace:e.namespace===void 0?p:s(p,e.namespace),transports:e.transports??m}),T={get bindings(){return{...h}},child:w,debug:(e,t,n)=>x(`debug`,e,t,n),get disposalSignal(){return g.signal},dispose:()=>{_||(_=!0,g.abort())},get disposed(){return _},enabled:t=>e.isLevelEnabled(d,t),error:(e,t,n)=>x(`error`,e,t,n),fatal:(e,t,n)=>x(`fatal`,e,t,n),group:(e,t,n)=>C(!1,e,t,n),groupCollapsed:(e,t,n)=>C(!0,e,t,n),info:(e,t,n)=>x(`info`,e,t,n),get logLevel(){return d},get middleware(){return[...f]},get namespace(){return p},[Symbol.dispose](){T.dispose()},time:S,get transports(){return[...m]},use:e=>w({middleware:[...f,e]}),warn:(e,t,n)=>x(`warn`,e,t,n),withBindings:e=>w({bindings:e})};return T}var l=c();exports.createLogger=c,exports.defaultLogger=l;
2
2
  //# sourceMappingURL=logger.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.cjs","names":[],"sources":["../src/logger.ts"],"sourcesContent":["import type { Bindings, LogEntry, Logger, LogLevel, LogMiddleware, LogType, RuneOptions, Transport } from './types';\n\nimport { warn } from './_dev';\nimport { isUnsafeObjectKey } from './_prototype';\nimport { DEFAULT_THEME, consoleTransport, renderGroup } from './console';\nimport { RuneTransportError } from './errors';\nimport { resolveBindings } from './lazy';\nimport { isLevelEnabled } from './types';\n\n/* --- Arg parsing (simplified) --- */\n\nfunction serializeError(err: Error): { message: string; name: string; stack?: string } {\n return { message: err.message, name: err.name, stack: err.stack };\n}\n\nfunction serializeErrors(ctx: Bindings): Bindings {\n const out: Bindings = {};\n\n for (const [k, v] of Object.entries(ctx)) {\n // Guard against a `__proto__`/`constructor`/`prototype` field name hijacking out's own\n // prototype via the bracket-assignment accessor — see _prototype.ts.\n if (isUnsafeObjectKey(k)) continue;\n\n out[k] = v instanceof Error ? serializeError(v) : v;\n }\n\n return out;\n}\n\ntype ParsedArgs = { context: Bindings | undefined; message: string | undefined };\n\nfunction parseArgs(msgOrCtx: unknown, second: unknown, third?: unknown): ParsedArgs {\n if (typeof msgOrCtx === 'string') {\n return { context: undefined, message: msgOrCtx };\n }\n\n if (msgOrCtx instanceof Error) {\n const ctx: Bindings = second !== null && typeof second === 'object' ? (second as Bindings) : {};\n\n return {\n context: { err: serializeError(msgOrCtx), ...ctx },\n message:\n third !== undefined\n ? String(third)\n : second !== undefined && typeof second !== 'object'\n ? String(second)\n : undefined,\n };\n }\n\n if (typeof msgOrCtx === 'object' && msgOrCtx !== null) {\n return {\n context: msgOrCtx as Bindings,\n message: second !== undefined ? String(second) : undefined,\n };\n }\n\n return { context: undefined, message: msgOrCtx !== undefined ? String(msgOrCtx) : undefined };\n}\n\n/* --- Namespace joining --- */\n\n/**\n * Joins parent and child namespaces with '.' as separator.\n * Examples:\n * joinNamespace('api', 'auth') → 'api.auth'\n * joinNamespace('', 'api') → 'api'\n * joinNamespace('api', '') → 'api'\n */\nfunction joinNamespace(parent: string, child: string): string {\n if (!parent) return child;\n\n if (!child) return parent;\n\n return `${parent}.${child}`;\n}\n\n/* --- createLogger --- */\n\n/**\n * Creates an isolated logger instance.\n *\n * Accepts two call signatures:\n * - `createLogger()` / `createLogger(options)` — configure via `RuneOptions`\n * - `createLogger('namespace', options?)` — namespace shorthand + optional options\n *\n * Each instance has its own immutable config (logLevel, transports, middleware).\n * To change the log level at runtime, create a new logger or child.\n */\nexport function createLogger(namespace: string, options?: Omit<RuneOptions, 'namespace'>): Logger;\nexport function createLogger(options?: RuneOptions): Logger;\nexport function createLogger(initial: RuneOptions | string = {}, extra?: Omit<RuneOptions, 'namespace'>): Logger {\n const initialOpts: RuneOptions = typeof initial === 'string' ? { namespace: initial, ...extra } : initial;\n\n const logLevel: LogLevel = initialOpts.logLevel ?? 'debug';\n const middleware: LogMiddleware[] = initialOpts.middleware ?? [];\n const namespace: string = initialOpts.namespace ?? '';\n const transports = initialOpts.transports ?? [consoleTransport()];\n const ownBindings: Bindings = { ...(initialOpts.bindings ?? {}) };\n\n const disposeController = new AbortController();\n let isDisposed = false;\n\n const passes = (type: LogType): boolean => isLevelEnabled(logLevel, type);\n const namespaceSuffix = (): string => (namespace ? ` (namespace: \"${namespace}\")` : '');\n\n const dispatch = (entry: LogEntry): void => {\n let current: LogEntry = entry;\n\n if (middleware.length > 0) {\n let c: LogEntry = entry;\n\n for (const mw of middleware) {\n try {\n const next = mw(c);\n\n if (next == null) return;\n\n c = next;\n } catch (err) {\n warn(`middleware threw and dropped this entry${namespaceSuffix()}: ${String(err)}`);\n\n return;\n }\n }\n\n current = c;\n }\n\n for (const t of transports) {\n try {\n t(current);\n } catch (err) {\n const transportErr = new RuneTransportError(err);\n\n warn(`${transportErr.message}${namespaceSuffix()}: ${String(err)}`);\n }\n }\n };\n\n const emit = (type: LogType, msgOrCtx: unknown, second?: unknown, third?: unknown): void => {\n if (isDisposed) return;\n\n if (!passes(type)) return;\n\n const { context, message } = parseArgs(msgOrCtx, second, third);\n // serializeErrors() always allocates a fresh object, so `data` is never an alias of `ownBindings`.\n const resolvedBindings = serializeErrors(resolveBindings(ownBindings));\n\n const data: Bindings = context\n ? { ...resolvedBindings, ...serializeErrors(resolveBindings(context)) }\n : resolvedBindings;\n\n dispatch({\n data,\n level: type,\n message,\n namespace,\n timestamp: new Date(),\n });\n };\n\n const timeImpl = <T>(label: string, fn: () => T, level: LogType = 'debug'): T => {\n const start = performance.now();\n\n const done = (thrownErr?: unknown): void => {\n const duration_ms = Math.round((performance.now() - start) * 100) / 100;\n const ctx: Bindings = { duration_ms };\n\n if (thrownErr !== undefined)\n ctx['err'] = serializeError(thrownErr instanceof Error ? thrownErr : new Error(String(thrownErr)));\n\n emit(level, ctx, label);\n };\n\n try {\n const result = fn();\n\n if (result instanceof Promise) {\n return result.then(\n (v) => {\n done();\n\n return v;\n },\n (err: unknown) => {\n done(err);\n\n return Promise.reject(err) as never;\n },\n ) as T;\n }\n\n done();\n\n return result;\n } catch (err) {\n done(err);\n throw err;\n }\n };\n\n const wrapGroup = <T>(collapsed: boolean, label: string, fn: () => T, level?: LogType): T => {\n if (isDisposed || logLevel === 'off') return fn();\n\n if (level !== undefined && !passes(level)) {\n return fn();\n }\n\n renderGroup(collapsed, label, namespace, DEFAULT_THEME);\n\n try {\n const result = fn();\n\n if (result instanceof Promise) return result.finally(() => console.groupEnd()) as T;\n\n console.groupEnd();\n\n return result;\n } catch (err) {\n console.groupEnd();\n throw err;\n }\n };\n\n const childLogger = (overrides: RuneOptions = {}): Logger =>\n createLogger({\n bindings: { ...ownBindings, ...(overrides.bindings ?? {}) },\n logLevel: overrides.logLevel ?? logLevel,\n middleware: overrides.middleware ?? middleware,\n namespace: overrides.namespace !== undefined ? joinNamespace(namespace, overrides.namespace) : namespace,\n transports: overrides.transports ?? transports,\n });\n\n const logger: Logger = {\n get bindings(): Readonly<Bindings> {\n return { ...ownBindings };\n },\n\n child: childLogger,\n\n debug: (m: unknown, s?: unknown, t?: unknown) => emit('debug', m, s, t),\n\n get disposalSignal(): AbortSignal {\n return disposeController.signal;\n },\n\n dispose: (): void => {\n if (isDisposed) return;\n\n isDisposed = true;\n disposeController.abort();\n },\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n enabled: (type: LogLevel): boolean => isLevelEnabled(logLevel, type),\n\n error: (m: unknown, s?: unknown, t?: unknown) => emit('error', m, s, t),\n\n fatal: (m: unknown, s?: unknown, t?: unknown) => emit('fatal', m, s, t),\n\n group: (label, fn, level) => wrapGroup(false, label, fn, level),\n\n groupCollapsed: (label, fn, level) => wrapGroup(true, label, fn, level),\n\n info: (m: unknown, s?: unknown, t?: unknown) => emit('info', m, s, t),\n\n get logLevel(): LogLevel {\n return logLevel;\n },\n\n get middleware(): readonly LogMiddleware[] {\n return [...middleware];\n },\n\n get namespace(): string {\n return namespace;\n },\n\n [Symbol.dispose](): void {\n logger.dispose();\n },\n\n time: timeImpl,\n\n get transports(): readonly Transport[] {\n return [...transports];\n },\n\n use: (mw: LogMiddleware): Logger => childLogger({ middleware: [...middleware, mw] }),\n\n warn: (m: unknown, s?: unknown, t?: unknown) => emit('warn', m, s, t),\n\n withBindings: (bindings: Bindings): Logger => childLogger({ bindings }),\n };\n\n return logger;\n}\n\nexport const defaultLogger = createLogger();\n"],"mappings":"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"}
1
+ {"version":3,"file":"logger.cjs","names":[],"sources":["../src/logger.ts"],"sourcesContent":["import type { Bindings, LogEntry, Logger, LogLevel, LogMiddleware, LogType, RuneOptions, Transport } from './types';\n\nimport { warn } from './_dev';\nimport { isUnsafeObjectKey } from './_prototype';\nimport { DEFAULT_THEME, consoleTransport, renderGroup } from './console';\nimport { resolveBindings } from './lazy';\nimport { isLevelEnabled } from './types';\n\n/* --- Arg parsing (simplified) --- */\n\nfunction serializeError(err: Error): { message: string; name: string; stack?: string } {\n return { message: err.message, name: err.name, stack: err.stack };\n}\n\nfunction serializeErrors(ctx: Bindings): Bindings {\n const out: Bindings = {};\n\n for (const [k, v] of Object.entries(ctx)) {\n // Guard against a `__proto__`/`constructor`/`prototype` field name hijacking out's own\n // prototype via the bracket-assignment accessor — see _prototype.ts.\n if (isUnsafeObjectKey(k)) continue;\n\n out[k] = v instanceof Error ? serializeError(v) : v;\n }\n\n return out;\n}\n\ntype ParsedArgs = { context: Bindings | undefined; message: string | undefined };\n\nfunction parseArgs(msgOrCtx: unknown, second: unknown, third?: unknown): ParsedArgs {\n if (typeof msgOrCtx === 'string') {\n return { context: undefined, message: msgOrCtx };\n }\n\n if (msgOrCtx instanceof Error) {\n const ctx: Bindings = second !== null && typeof second === 'object' ? (second as Bindings) : {};\n\n return {\n context: { err: serializeError(msgOrCtx), ...ctx },\n message:\n third !== undefined\n ? String(third)\n : second !== undefined && typeof second !== 'object'\n ? String(second)\n : undefined,\n };\n }\n\n if (typeof msgOrCtx === 'object' && msgOrCtx !== null) {\n return {\n context: msgOrCtx as Bindings,\n message: second !== undefined ? String(second) : undefined,\n };\n }\n\n return { context: undefined, message: msgOrCtx !== undefined ? String(msgOrCtx) : undefined };\n}\n\n/* --- Namespace joining --- */\n\n/**\n * Joins parent and child namespaces with '.' as separator.\n * Examples:\n * joinNamespace('api', 'auth') → 'api.auth'\n * joinNamespace('', 'api') → 'api'\n * joinNamespace('api', '') → 'api'\n */\nfunction joinNamespace(parent: string, child: string): string {\n if (!parent) return child;\n\n if (!child) return parent;\n\n return `${parent}.${child}`;\n}\n\n/* --- createLogger --- */\n\n/**\n * Creates an isolated logger instance.\n *\n * Accepts two call signatures:\n * - `createLogger()` / `createLogger(options)` — configure via `RuneOptions`\n * - `createLogger('namespace', options?)` — namespace shorthand + optional options\n *\n * Each instance has its own immutable config (logLevel, transports, middleware).\n * To change the log level at runtime, create a new logger or child.\n */\nexport function createLogger(namespace: string, options?: Omit<RuneOptions, 'namespace'>): Logger;\nexport function createLogger(options?: RuneOptions): Logger;\nexport function createLogger(initial: RuneOptions | string = {}, extra?: Omit<RuneOptions, 'namespace'>): Logger {\n const initialOpts: RuneOptions = typeof initial === 'string' ? { namespace: initial, ...extra } : initial;\n\n const logLevel: LogLevel = initialOpts.logLevel ?? 'debug';\n const middleware: LogMiddleware[] = initialOpts.middleware ?? [];\n const namespace: string = initialOpts.namespace ?? '';\n const transports = initialOpts.transports ?? [consoleTransport()];\n const ownBindings: Bindings = { ...(initialOpts.bindings ?? {}) };\n\n const disposeController = new AbortController();\n let isDisposed = false;\n\n const passes = (type: LogType): boolean => isLevelEnabled(logLevel, type);\n const namespaceSuffix = (): string => (namespace ? ` (namespace: \"${namespace}\")` : '');\n\n const dispatch = (entry: LogEntry): void => {\n let current: LogEntry = entry;\n\n if (middleware.length > 0) {\n let c: LogEntry = entry;\n\n for (const mw of middleware) {\n try {\n const next = mw(c);\n\n if (next == null) return;\n\n c = next;\n } catch (err) {\n warn(`middleware threw and dropped this entry${namespaceSuffix()}: ${String(err)}`);\n\n return;\n }\n }\n\n current = c;\n }\n\n for (const t of transports) {\n try {\n t(current);\n } catch (err) {\n warn(`Transport threw an unhandled error${namespaceSuffix()}: ${String(err)}`);\n }\n }\n };\n\n const emit = (type: LogType, msgOrCtx: unknown, second?: unknown, third?: unknown): void => {\n if (isDisposed) return;\n\n if (!passes(type)) return;\n\n const { context, message } = parseArgs(msgOrCtx, second, third);\n // serializeErrors() always allocates a fresh object, so `data` is never an alias of `ownBindings`.\n const resolvedBindings = serializeErrors(resolveBindings(ownBindings));\n\n const data: Bindings = context\n ? { ...resolvedBindings, ...serializeErrors(resolveBindings(context)) }\n : resolvedBindings;\n\n dispatch({\n data,\n level: type,\n message,\n namespace,\n timestamp: new Date(),\n });\n };\n\n const timeImpl = <T>(label: string, fn: () => T, level: LogType = 'debug'): T => {\n const start = performance.now();\n\n const done = (thrownErr?: unknown): void => {\n const duration_ms = Math.round((performance.now() - start) * 100) / 100;\n const ctx: Bindings = { duration_ms };\n\n if (thrownErr !== undefined)\n ctx['err'] = serializeError(thrownErr instanceof Error ? thrownErr : new Error(String(thrownErr)));\n\n emit(level, ctx, label);\n };\n\n try {\n const result = fn();\n\n if (result instanceof Promise) {\n return result.then(\n (v) => {\n done();\n\n return v;\n },\n (err: unknown) => {\n done(err);\n\n return Promise.reject(err) as never;\n },\n ) as T;\n }\n\n done();\n\n return result;\n } catch (err) {\n done(err);\n throw err;\n }\n };\n\n const wrapGroup = <T>(collapsed: boolean, label: string, fn: () => T, level?: LogType): T => {\n if (isDisposed || logLevel === 'off') return fn();\n\n if (level !== undefined && !passes(level)) {\n return fn();\n }\n\n renderGroup(collapsed, label, namespace, DEFAULT_THEME);\n\n try {\n const result = fn();\n\n if (result instanceof Promise) return result.finally(() => console.groupEnd()) as T;\n\n console.groupEnd();\n\n return result;\n } catch (err) {\n console.groupEnd();\n throw err;\n }\n };\n\n const childLogger = (overrides: RuneOptions = {}): Logger =>\n createLogger({\n bindings: { ...ownBindings, ...(overrides.bindings ?? {}) },\n logLevel: overrides.logLevel ?? logLevel,\n middleware: overrides.middleware ?? middleware,\n namespace: overrides.namespace !== undefined ? joinNamespace(namespace, overrides.namespace) : namespace,\n transports: overrides.transports ?? transports,\n });\n\n const logger: Logger = {\n get bindings(): Readonly<Bindings> {\n return { ...ownBindings };\n },\n\n child: childLogger,\n\n debug: (m: unknown, s?: unknown, t?: unknown) => emit('debug', m, s, t),\n\n get disposalSignal(): AbortSignal {\n return disposeController.signal;\n },\n\n dispose: (): void => {\n if (isDisposed) return;\n\n isDisposed = true;\n disposeController.abort();\n },\n\n get disposed(): boolean {\n return isDisposed;\n },\n\n enabled: (type: LogLevel): boolean => isLevelEnabled(logLevel, type),\n\n error: (m: unknown, s?: unknown, t?: unknown) => emit('error', m, s, t),\n\n fatal: (m: unknown, s?: unknown, t?: unknown) => emit('fatal', m, s, t),\n\n group: (label, fn, level) => wrapGroup(false, label, fn, level),\n\n groupCollapsed: (label, fn, level) => wrapGroup(true, label, fn, level),\n\n info: (m: unknown, s?: unknown, t?: unknown) => emit('info', m, s, t),\n\n get logLevel(): LogLevel {\n return logLevel;\n },\n\n get middleware(): readonly LogMiddleware[] {\n return [...middleware];\n },\n\n get namespace(): string {\n return namespace;\n },\n\n [Symbol.dispose](): void {\n logger.dispose();\n },\n\n time: timeImpl,\n\n get transports(): readonly Transport[] {\n return [...transports];\n },\n\n use: (mw: LogMiddleware): Logger => childLogger({ middleware: [...middleware, mw] }),\n\n warn: (m: unknown, s?: unknown, t?: unknown) => emit('warn', m, s, t),\n\n withBindings: (bindings: Bindings): Logger => childLogger({ bindings }),\n };\n\n return logger;\n}\n\nexport const defaultLogger = createLogger();\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,MAAM,EAAoC,WAAW,EAAa,MAAM,SAAS,CAAC;AA+EpH;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,MAAM,CAAC;AAClG,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;AAoN5D,eAAO,MAAM,aAAa,QAAiB,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,MAAM,EAAoC,WAAW,EAAa,MAAM,SAAS,CAAC;AA8EpH;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,MAAM,CAAC;AAClG,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;AAkN5D,eAAO,MAAM,aAAa,QAAiB,CAAC"}