@mmutils/logger 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +1038 -2
- package/dist/cjs/index.cjs +72 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/levels.cjs +82 -0
- package/dist/cjs/levels.cjs.map +1 -0
- package/dist/cjs/logger.cjs +576 -0
- package/dist/cjs/logger.cjs.map +1 -0
- package/dist/cjs/outputs.cjs +24 -0
- package/dist/cjs/outputs.cjs.map +1 -0
- package/dist/cjs/plugins/columns.cjs +782 -0
- package/dist/cjs/plugins/columns.cjs.map +1 -0
- package/dist/cjs/plugins/graph.cjs +578 -0
- package/dist/cjs/plugins/graph.cjs.map +1 -0
- package/dist/cjs/plugins/json.cjs +644 -0
- package/dist/cjs/plugins/json.cjs.map +1 -0
- package/dist/cjs/plugins/message.cjs +108 -0
- package/dist/cjs/plugins/message.cjs.map +1 -0
- package/dist/cjs/plugins/shared.cjs +194 -0
- package/dist/cjs/plugins/shared.cjs.map +1 -0
- package/dist/cjs/time.cjs +234 -0
- package/dist/cjs/time.cjs.map +1 -0
- package/dist/cjs/utils/text.cjs +646 -0
- package/dist/cjs/utils/text.cjs.map +1 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/levels.js +72 -0
- package/dist/esm/levels.js.map +1 -0
- package/dist/esm/logger.js +572 -0
- package/dist/esm/logger.js.map +1 -0
- package/dist/esm/outputs.js +21 -0
- package/dist/esm/outputs.js.map +1 -0
- package/dist/esm/plugins/columns.js +778 -0
- package/dist/esm/plugins/columns.js.map +1 -0
- package/dist/esm/plugins/graph.js +572 -0
- package/dist/esm/plugins/graph.js.map +1 -0
- package/dist/esm/plugins/json.js +641 -0
- package/dist/esm/plugins/json.js.map +1 -0
- package/dist/esm/plugins/message.js +105 -0
- package/dist/esm/plugins/message.js.map +1 -0
- package/dist/esm/plugins/shared.js +187 -0
- package/dist/esm/plugins/shared.js.map +1 -0
- package/dist/esm/time.js +231 -0
- package/dist/esm/time.js.map +1 -0
- package/dist/esm/utils/text.js +621 -0
- package/dist/esm/utils/text.js.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/levels.d.ts +50 -0
- package/dist/types/logger.d.ts +245 -0
- package/dist/types/outputs.d.ts +12 -0
- package/dist/types/plugins/columns.d.ts +151 -0
- package/dist/types/plugins/graph.d.ts +243 -0
- package/dist/types/plugins/json.d.ts +169 -0
- package/dist/types/plugins/message.d.ts +181 -0
- package/dist/types/plugins/shared.d.ts +74 -0
- package/dist/types/time.d.ts +48 -0
- package/dist/types/types.d.ts +176 -0
- package/dist/types/utils/text.d.ts +231 -0
- package/package.json +85 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sources":["../../../src/utils/text.ts"],"sourcesContent":["/**\n * Centers `text` by padding it left and right. Text longer than `length` is\n * returned unchanged.\n */\nexport const padTextMiddle = (\n text: string,\n length: number,\n padString = ' '\n): string =>\n text\n .padStart(text.length + Math.floor((length - text.length) / 2), padString)\n .padEnd(length, padString);\n\n/**\n * Justifies two strings to the left and right of a column. If the column is\n * too narrow, each text is placed on its own line.\n */\nexport const justifyLeftRight = (\n leftText: string,\n rightText: string,\n columnWidth: number\n): string =>\n columnWidth < leftText.length + rightText.length ?\n `${leftText}\\n${rightText}`\n : `${leftText.padEnd(columnWidth - rightText.length)}${rightText}`;\n\n/**\n * Rules for the control characters of logged text. C0 controls (except `\\t`\n * and `\\n`), DEL and C1 controls are always shown as `\\xHH`, like\n * `util.inspect`: ESC and C1 start terminal escape sequences (cursor moves,\n * screen clears, window titles, hyperlinks, clipboard writes), `\\r` and `\\b`\n * overwrite printed text.\n */\nexport interface SanitizeRules {\n /**\n * SGR sequences (`\\x1B[...m`: colors, bold, etc.): `'keep'` them and end\n * the text with a reset, so they can't leak into the following output, or\n * `'escape'` them. Default: `'keep'`.\n */\n readonly colors?: 'keep' | 'escape';\n /**\n * Newlines: `'keep'` them, `'indent'` the continuation lines, so logged text\n * can't start a line that looks like a log header, or `'escape'` them as\n * `\\x0A`. Default: `'indent'`.\n */\n readonly newlines?: 'keep' | 'indent' | 'escape';\n}\n\n/**\n * Sanitization of logged text:\n * - `'safe'`: colors kept, continuation lines indented, other control\n * characters escaped;\n * - `'strict'`: all control characters, colors and newlines escaped;\n * - `'none'`: text is written as is, at no cost. Only for trusted text;\n * - `SanitizeRules`: custom rules, missing ones as in `'safe'`.\n */\nexport type Sanitize = 'none' | 'safe' | 'strict' | SanitizeRules;\n\n/**\n * Sanitizing functions built by `createSanitizer`. Clean text is returned as\n * is, without allocation.\n */\nexport interface Sanitizer {\n /** Free text, e.g. messages: newlines follow the rules. */\n readonly text: (text: string) => string;\n /**\n * Single line text, e.g. object keys, stack frames, graph labels: newlines\n * are always escaped.\n */\n readonly label: (text: string) => string;\n}\n\n/* eslint-disable no-control-regex -- matching control characters is the point */\n/**\n * SGR (color and text style) sequence.\n */\nconst SGR = /\\x1B\\[[0-9;:]*m/g;\n/* eslint-enable no-control-regex */\n\nconst SGR_RESET = '\\x1b[0m';\nconst INDENT = ' ';\n\n/**\n * Source of a character class with the control characters to replace.\n *\n * @param newlines Include `\\n`.\n * @param esc Include ESC.\n */\nconst controlClass = (newlines: boolean, esc: boolean): string =>\n `[\\\\x00-\\\\x08${newlines ? '\\\\x0A' : ''}\\\\x0B-${esc ? '\\\\x1F' : '\\\\x1A\\\\x1C-\\\\x1F'}\\\\x7F-\\\\x9F]`;\n\n/**\n * Replaces every `\\n`. Faster than `replaceAll`, which matters for multi-line\n * messages.\n */\nconst replaceNewlines = (text: string, newline: string): string => {\n let index = text.indexOf('\\n');\n if (index === -1) return text;\n let result = '';\n let start = 0;\n while (index !== -1) {\n result += `${text.slice(start, index)}${newline}`;\n start = index + 1;\n index = text.indexOf('\\n', start);\n }\n return `${result}${text.slice(start)}`;\n};\n\nconst toHexEscape = (char: string): string =>\n `\\\\x${char.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0')}`;\n\n/**\n * Builds the regular expressions once and returns the escape function. Clean\n * text costs one regex scan. Text with only kept colors and newlines is\n * handled natively; the replacer runs only for other control characters.\n */\nconst createEscape = (\n keepColors: boolean,\n newlines: 'keep' | 'indent' | 'escape'\n): ((text: string) => string) => {\n const matchNewlines = newlines !== 'keep';\n const control = controlClass(matchNewlines, true);\n const test = new RegExp(control);\n // control characters the native fast path can't handle\n const unsafe = new RegExp(\n keepColors ?\n `${controlClass(false, false)}|\\\\x1B(?!\\\\[[0-9;:]*m)`\n : controlClass(false, true)\n );\n const newline = newlines === 'indent' ? `\\n${INDENT}` : '\\\\x0A';\n const replaceControl = (char: string): string =>\n char === '\\n' ? newline : toHexEscape(char);\n\n if (!keepColors) {\n const controls = new RegExp(control, 'g');\n return (text) => {\n if (!test.test(text)) return text;\n // only newlines\n if (!unsafe.test(text)) return replaceNewlines(text, newline);\n return text.replace(controls, replaceControl);\n };\n }\n\n const sgrOrControls = new RegExp(`${SGR.source}|${control}`, 'g');\n return (text) => {\n if (!test.test(text)) return text;\n // only colors and newlines, e.g. multi-line text with baked styles\n if (!unsafe.test(text)) {\n const result = matchNewlines ? replaceNewlines(text, newline) : text;\n return result.includes('\\x1b') ? `${result}${SGR_RESET}` : result;\n }\n // set by the replacer, which control flow analysis doesn't follow\n let colored = false as boolean;\n const escaped = text.replace(sgrOrControls, (match) => {\n if (match.length === 1) return replaceControl(match);\n colored = true;\n return match;\n });\n return colored ? `${escaped}${SGR_RESET}` : escaped;\n };\n};\n\nconst keepText = (text: string): string => text;\n\nconst NO_SANITIZER: Sanitizer = { text: keepText, label: keepText };\n\n/**\n * Creates the sanitizing functions of a given setting. Create it once (e.g. in\n * a plugin factory) and reuse it for every log.\n *\n * @param sanitize Preset or custom rules. Default: `'safe'`.\n */\nexport const createSanitizer = (sanitize: Sanitize = 'safe'): Sanitizer => {\n if (sanitize === 'none') return NO_SANITIZER;\n const rules: SanitizeRules =\n sanitize === 'safe' ? {}\n : sanitize === 'strict' ? { colors: 'escape', newlines: 'escape' }\n : sanitize;\n const { colors = 'keep', newlines = 'indent' } = rules;\n // the functions keep no state, so equal rules share them and their regexes\n const key = `${colors}:${newlines}`;\n const cached = sanitizers.get(key);\n if (cached !== undefined) return cached;\n const label = createEscape(colors === 'keep', 'escape');\n const sanitizer = {\n text:\n newlines === 'escape' ? label : createEscape(colors === 'keep', newlines),\n label,\n };\n sanitizers.set(key, sanitizer);\n return sanitizer;\n};\n\n/**\n * Sanitizers by resolved rules: building one compiles several regular\n * expressions (about 2 µs).\n */\nconst sanitizers = new Map<string, Sanitizer>();\n\n/**\n * Length of text without SGR sequences: the columns it takes on a terminal,\n * for single-width characters. Sanitized text contains no other sequences.\n * `textWidth` also counts wide characters as two columns.\n */\nexport const visibleLength = (text: string): number => {\n if (!text.includes('\\x1b')) return text.length;\n let length = text.length;\n for (const [sequence] of text.matchAll(SGR)) length -= sequence.length;\n return length;\n};\n\n/* eslint-disable no-control-regex -- matching control characters is the point */\nconst SGR_AT = /\\x1B\\[[0-9;:]*m/y;\n/* eslint-enable no-control-regex */\n\n/**\n * Characters that are not one terminal column wide, escape codes and tabs:\n * lines without them are wrapped by slicing. Box drawing and block\n * characters (graphs) are not in it.\n */\n/* eslint-disable no-misleading-character-class -- ranges of combining marks, matched one code unit at a time on purpose */\nexport const SLOW_CHARS = new RegExp(\n '[\\\\x00-\\\\x1f\\\\x7f-\\\\x9f\\\\u0300-\\\\u036f\\\\u1100-\\\\u115f\\\\u200b-\\\\u200f' +\n '\\\\u231a-\\\\u23f3\\\\u25fd-\\\\u27bf\\\\u2b1b-\\\\u2b55\\\\u2e80-\\\\ua4cf' +\n '\\\\ua960-\\\\ua97f\\\\uac00-\\\\ud7a3\\\\ud800-\\\\udfff\\\\uf900-\\\\ufaff' +\n '\\\\ufe00-\\\\ufe6f\\\\uff00-\\\\uff60\\\\uffe0-\\\\uffe6]'\n);\n/* eslint-enable no-misleading-character-class */\n\n/**\n * East Asian Wide and Fullwidth ranges and emoji shown as two columns, as\n * `first, last` pairs in ascending order. An approximation: emoji\n * sequences (ZWJ, flags) are measured per code point.\n */\nconst WIDE_RANGES = [\n 0x1100, 0x115f, 0x231a, 0x231b, 0x2329, 0x232a, 0x23e9, 0x23ec, 0x23f0,\n 0x23f0, 0x23f3, 0x23f3, 0x25fd, 0x25fe, 0x2614, 0x2615, 0x2648, 0x2653,\n 0x267f, 0x267f, 0x2693, 0x2693, 0x26a1, 0x26a1, 0x26aa, 0x26ab, 0x26bd,\n 0x26be, 0x26c4, 0x26c5, 0x26ce, 0x26ce, 0x26d4, 0x26d4, 0x26ea, 0x26ea,\n 0x26f2, 0x26f3, 0x26f5, 0x26f5, 0x26fa, 0x26fa, 0x26fd, 0x26fd, 0x2705,\n 0x2705, 0x270a, 0x270b, 0x2728, 0x2728, 0x274c, 0x274c, 0x274e, 0x274e,\n 0x2753, 0x2755, 0x2757, 0x2757, 0x2795, 0x2797, 0x27b0, 0x27b0, 0x27bf,\n 0x27bf, 0x2b1b, 0x2b1c, 0x2b50, 0x2b50, 0x2b55, 0x2b55, 0x2e80, 0x303e,\n 0x3041, 0x33ff, 0x3400, 0x4dbf, 0x4e00, 0x9fff, 0xa000, 0xa4cf, 0xa960,\n 0xa97f, 0xac00, 0xd7a3, 0xf900, 0xfaff, 0xfe10, 0xfe19, 0xfe30, 0xfe6f,\n 0xff00, 0xff60, 0xffe0, 0xffe6, 0x16fe0, 0x18aff, 0x1b000, 0x1b2ff, 0x1f004,\n 0x1f004, 0x1f0cf, 0x1f0cf, 0x1f18e, 0x1f18e, 0x1f191, 0x1f19a, 0x1f200,\n 0x1f251, 0x1f300, 0x1f320, 0x1f32d, 0x1f335, 0x1f337, 0x1f37c, 0x1f37e,\n 0x1f393, 0x1f3a0, 0x1f3ca, 0x1f3cf, 0x1f3d3, 0x1f3e0, 0x1f3f0, 0x1f3f4,\n 0x1f3f4, 0x1f3f8, 0x1f43e, 0x1f440, 0x1f440, 0x1f442, 0x1f4fc, 0x1f4ff,\n 0x1f53d, 0x1f54b, 0x1f54e, 0x1f550, 0x1f567, 0x1f57a, 0x1f57a, 0x1f595,\n 0x1f596, 0x1f5a4, 0x1f5a4, 0x1f5fb, 0x1f64f, 0x1f680, 0x1f6c5, 0x1f6cc,\n 0x1f6cc, 0x1f6d0, 0x1f6d2, 0x1f6d5, 0x1f6d7, 0x1f6eb, 0x1f6ec, 0x1f6f4,\n 0x1f6fc, 0x1f7e0, 0x1f7eb, 0x1f90c, 0x1f93a, 0x1f93c, 0x1f945, 0x1f947,\n 0x1f9ff, 0x1fa70, 0x1faff, 0x20000, 0x3fffd,\n];\n\nconst isWide = (codePoint: number): boolean => {\n // binary search over the ranges\n let low = 0;\n let high = WIDE_RANGES.length / 2 - 1;\n while (low <= high) {\n const middle = (low + high) >> 1;\n if (codePoint < (WIDE_RANGES[middle * 2] ?? 0)) high = middle - 1;\n else if (codePoint > (WIDE_RANGES[middle * 2 + 1] ?? 0)) low = middle + 1;\n else return true;\n }\n return false;\n};\n\nconst isZeroWidth = (codePoint: number): boolean =>\n codePoint < 0x20 ||\n (codePoint >= 0x7f && codePoint <= 0x9f) ||\n (codePoint >= 0x300 && codePoint <= 0x36f) ||\n (codePoint >= 0x200b && codePoint <= 0x200f) ||\n (codePoint >= 0xfe00 && codePoint <= 0xfe0f) ||\n (codePoint >= 0x1f3fb && codePoint <= 0x1f3ff) ||\n (codePoint >= 0xe0100 && codePoint <= 0xe01ef);\n\n/**\n * Terminal columns a code point takes: 0 for controls, combining marks,\n * zero-width characters, variation selectors and skin tones, 2 for East\n * Asian wide characters and most emoji, 1 otherwise.\n */\nexport const charWidth = (codePoint: number): number =>\n isZeroWidth(codePoint) ? 0\n : isWide(codePoint) ? 2\n : 1;\n\n/**\n * Terminal columns a text takes: SGR sequences take none, wide characters\n * two. Tabs count as one column; `wrapText` expands them.\n */\nexport const textWidth = (text: string): number => {\n if (!SLOW_CHARS.test(text)) return text.length;\n let width = 0;\n for (let index = 0; index < text.length;) {\n if (text.charCodeAt(index) === 0x1b) {\n SGR_AT.lastIndex = index;\n const sgr = SGR_AT.exec(text);\n if (sgr !== null) {\n index += sgr[0].length;\n continue;\n }\n }\n const codePoint = text.codePointAt(index) ?? 0;\n width += codePoint === 0x09 ? 1 : charWidth(codePoint);\n index += codePoint > 0xffff ? 2 : 1;\n }\n return width;\n};\n\n/**\n * Describes a thrown value as `Name: message`. Never throws, even for thrown\n * values with throwing getters or revoked proxies.\n */\nexport const describeThrown = (thrown: unknown): string => {\n try {\n return thrown instanceof Error ?\n `${thrown.name}: ${thrown.message}`\n : String(thrown);\n } catch {\n return 'unknown error';\n }\n};\n\n/**\n * Splits an error to its `name: message` head, which can span multiple\n * lines, and its stack frames. Never throws: a head or stack that can't be\n * read (throwing getters, `Error.prepareStackTrace`) becomes a placeholder.\n */\nexport const splitError = (error: Error): [head: string, frames: string[]] => {\n let head: string;\n try {\n head = String(error);\n } catch (thrown) {\n head = `[Unreadable error: ${describeThrown(thrown)}]`;\n }\n let stack: unknown;\n try {\n stack = error.stack;\n } catch (thrown) {\n return [head, [`[Unreadable stack: ${describeThrown(thrown)}]`]];\n }\n if (typeof stack !== 'string') return [head, []];\n const frames = stack.startsWith(head) ? stack.slice(head.length) : stack;\n return [head, frames.split('\\n').filter(Boolean)];\n};\n\n/**\n * Output size limits, like `util.inspect`'s `maxArrayLength` and\n * `maxStringLength`. They keep a single log of a large buffer, array or\n * string from blocking the process and flooding the output.\n */\nexport interface OutputLimits {\n /**\n * Maximum rendered array, buffer and typed array elements, object keys and\n * map and set entries. `Infinity` for no limit. Default: `100`.\n */\n readonly items?: number;\n /**\n * Maximum characters of a string, key, error message or JSON value, cut\n * before sanitizing. `Infinity` for no limit. Default: `10_000`.\n */\n readonly stringLength?: number;\n}\n\nexport const DEFAULT_OUTPUT_LIMITS = {\n items: 100,\n stringLength: 10_000,\n} as const satisfies Required<OutputLimits>;\n\n/**\n * No output limits: the default of the text utilities, which only truncate\n * when given limits.\n */\nexport const NO_OUTPUT_LIMITS = {\n items: Infinity,\n stringLength: Infinity,\n} as const satisfies Required<OutputLimits>;\n\n/**\n * Fills in the default output limits and validates them.\n *\n * @param what Prefix of error messages, e.g. `messagePlugin`.\n * @throws RangeError if a limit is not a positive integer or `Infinity`.\n */\nexport const resolveOutputLimits = (\n limits: OutputLimits | undefined,\n what: string\n): Required<OutputLimits> => {\n const resolved = {\n items: limits?.items ?? DEFAULT_OUTPUT_LIMITS.items,\n stringLength: limits?.stringLength ?? DEFAULT_OUTPUT_LIMITS.stringLength,\n };\n for (const [name, value] of Object.entries(resolved))\n if (value !== Infinity && !(Number.isInteger(value) && value >= 1))\n throw new RangeError(\n `${what}: limits.${name} must be a positive integer or Infinity, got ${String(value)}.`\n );\n return resolved;\n};\n\n/**\n * Note on what output limits left out: `… 3 more items`, `… 1 more item`.\n */\nexport const describeLeftOut = (\n count: number,\n unit: 'character' | 'item' | 'byte' | 'entry' | 'frame'\n): string =>\n `… ${String(count)} more ${\n count === 1 ? unit\n : unit === 'entry' ? 'entries'\n : `${unit}s`\n }`;\n\n/**\n * Cuts text to `maxLength` characters, never inside a surrogate pair, and\n * tells how many were left out: `xxx… 1000 more characters`. Shorter text is\n * returned as is.\n */\nexport const truncate = (text: string, maxLength: number): string => {\n if (text.length <= maxLength) return text;\n const end = cutIndex(text, maxLength);\n return `${text.slice(0, end)}${describeLeftOut(text.length - end, 'character')}`;\n};\n\n/**\n * Where to cut text longer than `maxLength`, so a surrogate pair stays whole.\n */\nconst cutIndex = (text: string, maxLength: number): number => {\n const code = text.charCodeAt(maxLength - 1);\n return code >= 0xd800 && code <= 0xdbff ? maxLength - 1 : maxLength;\n};\n\n/**\n * Keys of an object to render, at most `items`. Large arrays are indexed\n * without listing all their keys first.\n *\n * @returns The keys and the number of keys left out.\n */\nexport const limitKeys = (\n data: object,\n items: number\n): [keys: string[], more: number] => {\n if (Array.isArray(data) && data.length > items) {\n const keys: string[] = [];\n for (let index = 0; index < items; index++) keys.push(String(index));\n return [keys, data.length - items];\n }\n const keys = Object.keys(data);\n return keys.length > items ?\n [keys.slice(0, items), keys.length - items]\n : [keys, 0];\n};\n\n/**\n * JSON of an object property. Never throws: a getter that throws gives a\n * placeholder, so one bad property doesn't hide the others.\n */\nexport const stringifyProperty = (\n data: object,\n key: string,\n limits: Required<OutputLimits> = NO_OUTPUT_LIMITS\n): string => {\n let value: unknown;\n try {\n value = (data as Record<string, unknown>)[key];\n } catch (thrown) {\n return `[Getter threw: ${describeThrown(thrown)}]`;\n }\n return safeStringify(value, limits);\n};\n\n/**\n * Short description of a function, like `util.inspect`: `[Function: name]`\n * or `[class Name]`, never its source code.\n */\nexport const describeFunction = (fn: object): string => {\n const { name } = fn as { name?: unknown };\n const label = typeof name === 'string' && name ? name : '(anonymous)';\n // V8 returns a slice of the cached source: checking the prefix copies nothing\n return Function.prototype.toString.call(fn).startsWith('class') ?\n `[class ${label}]`\n : `[Function: ${label}]`;\n};\n\n/**\n * Describes buffers and typed arrays in one line, like `util.inspect`:\n * `<Buffer 68 69 … 998 more bytes>`, `Uint8Array(3) [1, 2, 3]`. Their JSON\n * (and their keys) would list every element.\n */\nexport const describeBinary = (\n view: ArrayBufferView,\n items: number\n): string => {\n if (view instanceof DataView) return `DataView(${String(view.byteLength)})`;\n const elements = view as unknown as ArrayLike<number | bigint>;\n const { name } = (view.constructor as { name?: unknown } | undefined) ?? {};\n const isBuffer = name === 'Buffer';\n const shown = Math.min(elements.length, items);\n let text = '';\n for (let index = 0; index < shown; index++) {\n const element = elements[index] ?? 0;\n text +=\n isBuffer ?\n `${index ? ' ' : ''}${element.toString(16).padStart(2, '0')}`\n : `${index ? ', ' : ''}${String(element)}${typeof element === 'bigint' ? 'n' : ''}`;\n }\n const more = elements.length - shown;\n if (isBuffer)\n return `<Buffer${text ? ` ${text}` : ''}${more ? ` ${describeLeftOut(more, 'byte')}` : ''}>`;\n return `${typeof name === 'string' ? name : 'TypedArray'}(${String(elements.length)}) [${text}${more ? `, ${describeLeftOut(more, 'item')}` : ''}]`;\n};\n\n/**\n * Checks for errors of other realms (`vm` contexts, workers), which fail\n * `instanceof Error`.\n */\nexport const isForeignError = (value: object): boolean =>\n Object.prototype.toString.call(value) === '[object Error]';\n\n/**\n * `Name: message` of an error, followed by the JSON of its own enumerable\n * properties, if any, e.g. `Error: refused {\"code\":\"ECONNREFUSED\"}`.\n */\nconst describeErrorValue = (error: object): string => {\n const head = describeThrown(error);\n let props: string | undefined;\n try {\n props = JSON.stringify(error);\n } catch {\n // properties that can't be serialized are left out\n }\n return props === undefined || props === '{}' ? head : `${head} ${props}`;\n};\n\n/**\n * Entries of a map or set, at most `items`, stopping early once longer than\n * `stringLength`.\n */\nconst describeEntries = (\n entries: Iterable<unknown>,\n size: number,\n limits: Required<OutputLimits>,\n describeEntry: (entry: unknown) => string\n): string => {\n let text = '';\n let shown = 0;\n for (const entry of entries) {\n if (shown === limits.items || text.length > limits.stringLength) break;\n text += `${shown ? ', ' : ''}${describeEntry(entry)}`;\n shown++;\n }\n const more = size - shown;\n return more ? `${text}, ${describeLeftOut(more, 'entry')}` : text;\n};\n\n/**\n * Describes objects JSON shows as `{}`: dates (ISO), maps, sets, regular\n * expressions and errors of other realms, like `util.inspect`. Entries of\n * maps and sets are JSON, so nesting can't recurse.\n *\n * @returns `undefined` for other objects.\n */\nexport const describeObject = (\n value: object,\n limits: Required<OutputLimits> = NO_OUTPUT_LIMITS\n): string | undefined => {\n if (value instanceof Date)\n return Number.isNaN(value.getTime()) ? 'Invalid Date' : value.toISOString();\n if (value instanceof Map)\n return `Map(${String(value.size)}) {${describeEntries(\n value as Map<unknown, unknown>,\n value.size,\n limits,\n (entry) => {\n const [key, item] = entry as [unknown, unknown];\n return `${stringifyValue(key, false, limits)} => ${stringifyValue(item, false, limits)}`;\n }\n )}}`;\n if (value instanceof Set)\n return `Set(${String(value.size)}) {${describeEntries(\n value as Set<unknown>,\n value.size,\n limits,\n (item) => stringifyValue(item, false, limits)\n )}}`;\n if (value instanceof RegExp) return String(value);\n if (isForeignError(value)) return describeErrorValue(value);\n return undefined;\n};\n\n/**\n * @param describe Describe objects JSON shows as `{}` (see `describeObject`).\n */\nconst stringifyValue = (\n value: unknown,\n describe: boolean,\n limits: Required<OutputLimits>\n): string => {\n let text: string;\n try {\n // long strings are cut before JSON, which would copy them whole\n if (typeof value === 'string' && value.length > limits.stringLength) {\n const end = cutIndex(value, limits.stringLength);\n return `${JSON.stringify(value.slice(0, end))}${describeLeftOut(value.length - end, 'character')}`;\n }\n if (typeof value === 'function') text = describeFunction(value);\n else if (typeof value === 'bigint') text = `${String(value)}n`;\n else if (value instanceof Error) text = describeErrorValue(value);\n else if (ArrayBuffer.isView(value))\n text = describeBinary(value, limits.items);\n else {\n // undefined for symbols and undefined, despite the lib typing\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n text = JSON.stringify(value) ?? String(value);\n if (\n describe &&\n text === '{}' &&\n typeof value === 'object' &&\n value !== null\n )\n text = describeObject(value, limits) ?? text;\n }\n } catch {\n return '\"[Unserializable]\"';\n }\n return truncate(text, limits.stringLength);\n};\n\n/**\n * `JSON.stringify` that never throws and describes what JSON can't:\n * - functions and classes: `[Function: name]`, `[class Name]`, no source;\n * - bigints: `1n`;\n * - errors: `Name: message` and their own properties' JSON;\n * - buffers and typed arrays: see `describeBinary`;\n * - dates, maps, sets, regular expressions and errors of other realms that\n * JSON shows as `{}`: see `describeObject`;\n * - symbols and `undefined`: `String`;\n * - circular structures: `\"[Unserializable]\"`.\n *\n * Nested values are serialized whole by the native `JSON.stringify` and the\n * result is cut to `limits.stringLength`.\n *\n * @param limits Output limits. Default: none.\n */\nexport const safeStringify = (\n value: unknown,\n limits: Required<OutputLimits> = NO_OUTPUT_LIMITS\n): string => stringifyValue(value, true, limits);\n\n/**\n * Text of a top-level value that is neither a string nor an object:\n * functions and classes are described, bigints get their `n` suffix.\n */\nexport const stringifyPrimitive = (value: unknown): string =>\n typeof value === 'function' ? describeFunction(value)\n : typeof value === 'bigint' ? `${String(value)}n`\n : String(value);\n\nconst stringifyError = (\n error: Error,\n { text, label }: Sanitizer,\n { items, stringLength }: Required<OutputLimits>\n): string => {\n const [head, frames] = splitError(error);\n let result = text(truncate(head, stringLength));\n const shown = Math.min(frames.length, items);\n for (let index = 0; index < shown; index++)\n result += `\\n${label(truncate(frames[index] ?? '', stringLength))}`;\n if (frames.length > shown)\n result += `\\n${describeLeftOut(frames.length - shown, 'frame')}`;\n return result;\n};\n\n/**\n * Converts any log data to text:\n * - strings are returned as is;\n * - errors are represented by their `name: message` and stack frames;\n * - buffers and typed arrays are described in one line;\n * - objects and arrays print each own property as `key: JSON` on a new line;\n * - everything else is converted with `String`.\n *\n * Never throws: data that can't be read (throwing getters, revoked proxies,\n * broken errors) gives placeholders.\n *\n * @param sanitizer Sanitizes strings (`text`), keys, values and stack frames\n * (`label`). Default: none.\n * @param limits Output limits. Default: none.\n */\nexport const stringifyData = (\n data: unknown,\n sanitizer: Sanitizer = NO_SANITIZER,\n limits: Required<OutputLimits> = NO_OUTPUT_LIMITS\n): string => {\n const { text, label } = sanitizer;\n const { items, stringLength } = limits;\n try {\n if (typeof data === 'string') return text(truncate(data, stringLength));\n if (data instanceof Error) return stringifyError(data, sanitizer, limits);\n if (typeof data === 'object' && data !== null) {\n if (ArrayBuffer.isView(data)) return label(describeBinary(data, items));\n const [keys, more] = limitKeys(data, items);\n if (!keys.length) {\n // errors of other realms have no enumerable keys either\n if (isForeignError(data))\n return stringifyError(data as Error, sanitizer, limits);\n return label(\n truncate(\n describeObject(data, limits) ?? safeStringify(data),\n stringLength\n )\n );\n }\n const lines: string[] = [];\n for (const key of keys)\n lines.push(\n `${label(truncate(key, stringLength))}: ${label(stringifyProperty(data, key, limits))}`\n );\n if (more) lines.push(describeLeftOut(more, 'item'));\n return lines.join('\\n');\n }\n return text(truncate(stringifyPrimitive(data), stringLength));\n } catch (thrown) {\n return `[Unrenderable: ${label(describeThrown(thrown))}]`;\n }\n};\n\n/**\n * How the source cells overlapping a new cell are combined:\n * - `'average'`: weighted average, a smooth trend that keeps the overall mean;\n * - `'max'`: the largest value, keeps peaks;\n * - `'min'`: the smallest value, keeps dips.\n */\nexport type Aggregate = 'average' | 'max' | 'min';\n\n/**\n * Overlaps below this are floating point noise at bucket edges, not real\n * overlaps, and must not leak a neighbour's peak into `'max'`/`'min'`.\n */\nconst MIN_OVERLAP = 1e-9;\n\n/**\n * Scales an array to a new length by combining the overlapping source cells\n * of each new cell.\n *\n * @param data Values to scale.\n * @param newLength Length of the result.\n * @param aggregate How overlapping cells are combined. Default: `'average'`.\n * @throws TypeError if `newLength` is not a non-negative integer.\n */\nexport const scaleArray = (\n data: readonly number[],\n newLength: number,\n aggregate: Aggregate = 'average'\n): number[] => {\n if (!Number.isInteger(newLength) || newLength < 0)\n throw new TypeError('scaleArray: new length is not a positive integer.');\n const dataLength = data.length;\n if (dataLength === newLength) return [...data];\n if (dataLength === 0) return Array<number>(newLength).fill(0);\n\n const bucketSize = dataLength / newLength;\n const result: number[] = [];\n\n for (let i = 0; i < newLength; i++) {\n const bucketStart = i * bucketSize;\n const bucketEnd = bucketStart + bucketSize;\n const indexEnd = Math.min(dataLength, Math.ceil(bucketEnd));\n let sum = 0;\n let totalWeight = 0;\n let max = -Infinity;\n let min = Infinity;\n\n for (let n = Math.floor(bucketStart); n < indexEnd; n++) {\n const weight = Math.min(bucketEnd, n + 1) - Math.max(bucketStart, n);\n if (weight < MIN_OVERLAP) continue;\n const value = data[n] ?? 0;\n sum += value * weight;\n totalWeight += weight;\n if (value > max) max = value;\n if (value < min) min = value;\n }\n\n result.push(\n !totalWeight ? 0\n : aggregate === 'max' ? max\n : aggregate === 'min' ? min\n : sum / totalWeight\n );\n }\n\n return result;\n};\n"],"names":[],"mappings":"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EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;AACtE,IAAA,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;AACtE,IAAA,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;AACtE,IAAA,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;AACtE,IAAA,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;AACtE,IAAA,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;AACtE,IAAA,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;AAC3E,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;AACtE,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;AACtE,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;AACtE,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;AACtE,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;AACtE,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;AACtE,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EA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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { BaseLogger, Logger, type LoggerConstructor, templateTransformer, } from './logger.js';
|
|
2
|
+
export { compileTimestamp, DEFAULT_TIMESTAMP_FORMAT, type CompileTimestampOptions, type TimestampFormatter, } from './time.js';
|
|
3
|
+
export { assertLogLevel, isLogLevel, isLogType, LogLevels, LOG_TYPES, LOG_TYPE_MAX_LENGTH, LOG_TYPE_VALUES, shouldLog, } from './levels.js';
|
|
4
|
+
export { consoleOutput, joinedOutput } from './outputs.js';
|
|
5
|
+
export { messagePlugin, renderMessageData, type MessageMethods, type MessagePluginMethods, type MessagePluginOptions, } from './plugins/message.js';
|
|
6
|
+
export { jsonPlugin, renderJsonData, type JsonMethods, type JsonPluginMethods, type JsonPluginOptions, type JsonTime, } from './plugins/json.js';
|
|
7
|
+
export { DEFAULT_GRAPH_LIMITS, formatAxisLabel, graphPlugin, renderGraph, valuesToBars, type GraphAxis, type GraphBaseline, type GraphData, type GraphDataWithSettings, type GraphLimits, type GraphMethod, type GraphMethods, type GraphPluginOptions, type GraphSettings, } from './plugins/graph.js';
|
|
8
|
+
export { columnsPlugin, DEFAULT_COLUMNS_WRAP, wrapText, type ColumnsMethods, type ColumnsPluginOptions, type ColumnsWrap, type WrapMode, type WrapTextOptions, } from './plugins/columns.js';
|
|
9
|
+
export { DEFAULT_SYMBOLS, DEFAULT_TEXT_STYLES, headerTemplates, mergeStyleSheets, paint, paintUnrenderable, type HeaderOptions, type SanitizeOptions, type Symbols, } from './plugins/shared.js';
|
|
10
|
+
export { charWidth, createSanitizer, DEFAULT_OUTPUT_LIMITS, describeBinary, describeLeftOut, describeFunction, describeObject, describeThrown, isForeignError, justifyLeftRight, limitKeys, NO_OUTPUT_LIMITS, padTextMiddle, resolveOutputLimits, safeStringify, scaleArray, splitError, stringifyData, stringifyPrimitive, stringifyProperty, textWidth, truncate, visibleLength, type Aggregate, type OutputLimits, type Sanitize, type SanitizeRules, type Sanitizer, } from './utils/text.js';
|
|
11
|
+
export type * from './types.js';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { LogLevel, LogType } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Numeric expression of the log levels. The lower the value, the less the
|
|
4
|
+
* output.
|
|
5
|
+
*/
|
|
6
|
+
export declare const LogLevels: {
|
|
7
|
+
readonly silent: 100;
|
|
8
|
+
readonly fatal: 200;
|
|
9
|
+
readonly error: 300;
|
|
10
|
+
readonly warning: 400;
|
|
11
|
+
readonly info: 500;
|
|
12
|
+
readonly debug: 600;
|
|
13
|
+
readonly trace: 700;
|
|
14
|
+
readonly verbose: 800;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* All log types, ordered by level.
|
|
18
|
+
*/
|
|
19
|
+
export declare const LOG_TYPES: readonly ["fatal", "error", "warning", "info", "debug", "trace", "verbose"];
|
|
20
|
+
/**
|
|
21
|
+
* Length of the longest log type name.
|
|
22
|
+
*/
|
|
23
|
+
export declare const LOG_TYPE_MAX_LENGTH: number;
|
|
24
|
+
/**
|
|
25
|
+
* Checks if a message of a given type passes the current level.
|
|
26
|
+
*/
|
|
27
|
+
export declare const shouldLog: (type: LogType, level: LogLevel) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Numeric values of the log types, without `'silent'`. A plain literal, so
|
|
30
|
+
* V8 keeps fast properties: the lookup runs on every log, filtered ones
|
|
31
|
+
* included. Inherited keys (`'toString'`) give non-numbers, so callers check
|
|
32
|
+
* `typeof value === 'number'`.
|
|
33
|
+
*/
|
|
34
|
+
export declare const LOG_TYPE_VALUES: Readonly<Record<string, number | undefined>>;
|
|
35
|
+
/**
|
|
36
|
+
* Runtime check of a log level, e.g. one read from an environment variable.
|
|
37
|
+
*/
|
|
38
|
+
export declare const isLogLevel: (value: unknown) => value is LogLevel;
|
|
39
|
+
/**
|
|
40
|
+
* Runtime check of a log type. `'silent'` is a level, not a type.
|
|
41
|
+
*/
|
|
42
|
+
export declare const isLogType: (value: unknown) => value is LogType;
|
|
43
|
+
/**
|
|
44
|
+
* @throws RangeError naming the valid levels.
|
|
45
|
+
*/
|
|
46
|
+
export declare const assertLogLevel: (value: unknown) => asserts value is LogLevel;
|
|
47
|
+
/**
|
|
48
|
+
* Error for a log call with an unknown type, naming the valid types.
|
|
49
|
+
*/
|
|
50
|
+
export declare const unknownLogTypeError: (value: unknown) => TypeError;
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import type { BakedStyles, LoggerOptions, LoggerPlugin, LogLevel, Override, PluginMethods, LogType, Output, StyleSheet, TemplateMap, Transformer } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Passes each entry property through the template map of the entry's kind.
|
|
4
|
+
* Properties without a template function stay unchanged. Part of every
|
|
5
|
+
* logger's default transformers.
|
|
6
|
+
*/
|
|
7
|
+
export declare const templateTransformer: Transformer;
|
|
8
|
+
/**
|
|
9
|
+
* Logger implementation without plugin method typing. Use `Logger` instead,
|
|
10
|
+
* which types the methods of plugins passed to the constructor.
|
|
11
|
+
*
|
|
12
|
+
* Every `log` call creates an entry with `id`, `timestamp`, `type`, `kind` and
|
|
13
|
+
* `data`; runs it through `transformers` (which by default contains
|
|
14
|
+
* `templateTransformer`) and hands the result to the output registered for the
|
|
15
|
+
* entry's kind, or the default output.
|
|
16
|
+
*/
|
|
17
|
+
export declare class BaseLogger {
|
|
18
|
+
/** Pipeline steps, executed in order for every log. */
|
|
19
|
+
readonly transformers: Transformer[];
|
|
20
|
+
/** Template maps keyed by log kind. */
|
|
21
|
+
readonly templateMaps: Record<string, TemplateMap>;
|
|
22
|
+
/** Kind of logs created without an explicit kind. */
|
|
23
|
+
defaultKind: string;
|
|
24
|
+
private currentLevel;
|
|
25
|
+
/** Numeric value of `level`, compared on every log. */
|
|
26
|
+
private threshold;
|
|
27
|
+
private nextId;
|
|
28
|
+
private readonly useStyles;
|
|
29
|
+
private readonly clock;
|
|
30
|
+
/** Default clock, read inline: no call through the reader. */
|
|
31
|
+
private readonly wallClock;
|
|
32
|
+
private readonly formatTimestamp;
|
|
33
|
+
/** Time of the current log, written by the clock: no allocation per log. */
|
|
34
|
+
private readonly now;
|
|
35
|
+
private readonly defaultOutput;
|
|
36
|
+
private readonly outputs;
|
|
37
|
+
private readonly styleSheets;
|
|
38
|
+
private bakedStyles;
|
|
39
|
+
private readonly pluginNames;
|
|
40
|
+
constructor(options?: LoggerOptions);
|
|
41
|
+
/**
|
|
42
|
+
* Registers a plugin: its styles, template maps, transformers, outputs,
|
|
43
|
+
* default kind and methods.
|
|
44
|
+
*
|
|
45
|
+
* @returns The same logger, typed with the plugin's methods. Methods the
|
|
46
|
+
* plugin re-declares replace the logger's signatures and docs.
|
|
47
|
+
* @throws Error if a plugin with the same name is already used or a plugin
|
|
48
|
+
* method would override an existing logger property.
|
|
49
|
+
*/
|
|
50
|
+
use<T extends object, M extends object>(this: T, plugin: LoggerPlugin<M>): Override<T, M>;
|
|
51
|
+
/**
|
|
52
|
+
* Checks if a plugin with a given name is used.
|
|
53
|
+
*/
|
|
54
|
+
hasPlugin(name: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Registers a plugin atomically: everything is validated and prepared
|
|
57
|
+
* first, so a plugin that throws leaves the logger unchanged and can be
|
|
58
|
+
* fixed and used again.
|
|
59
|
+
*/
|
|
60
|
+
private register;
|
|
61
|
+
/**
|
|
62
|
+
* Inserts transformer at a given position. Default: end of the pipeline.
|
|
63
|
+
*/
|
|
64
|
+
addTransformer(transformer: Transformer, position?: number): void;
|
|
65
|
+
/**
|
|
66
|
+
* Removes a transformer.
|
|
67
|
+
*
|
|
68
|
+
* @returns `true` if the transformer was found and removed.
|
|
69
|
+
*/
|
|
70
|
+
removeTransformer(transformer: Transformer): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Replaces a transformer in place.
|
|
73
|
+
*
|
|
74
|
+
* @returns `true` if the old transformer was found and replaced.
|
|
75
|
+
*/
|
|
76
|
+
replaceTransformer(oldTransformer: Transformer, transformer: Transformer): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Adds template functions for a given kind. Existing functions for the same
|
|
79
|
+
* property are replaced.
|
|
80
|
+
*
|
|
81
|
+
* Maps are stored without a prototype, so entry keys like `toString` or
|
|
82
|
+
* `hasOwnProperty`, or keys added to `Object.prototype` by other code, are
|
|
83
|
+
* never mistaken for template functions.
|
|
84
|
+
*/
|
|
85
|
+
addTemplateMap(kind: string, map: TemplateMap): void;
|
|
86
|
+
/**
|
|
87
|
+
* Sets output for a given kind.
|
|
88
|
+
*/
|
|
89
|
+
setOutput(kind: string, output: Output): void;
|
|
90
|
+
/**
|
|
91
|
+
* Output used for a given kind: the one set for it, or the default output.
|
|
92
|
+
* For plugins that wrap an output for a while and put it back later.
|
|
93
|
+
*/
|
|
94
|
+
getOutput(kind: string): Output;
|
|
95
|
+
/**
|
|
96
|
+
* Adds styles and rebakes the escape code strings of all log types. Later
|
|
97
|
+
* style sheets override earlier ones.
|
|
98
|
+
*
|
|
99
|
+
* @throws TypeError if a style can't be converted to a string. The sheet is
|
|
100
|
+
* not added then, so the logger keeps working.
|
|
101
|
+
*/
|
|
102
|
+
addStyles(styleSheet: StyleSheet): void;
|
|
103
|
+
/**
|
|
104
|
+
* Returns the baked styles of a given log type.
|
|
105
|
+
*/
|
|
106
|
+
getStyles(type: LogType): BakedStyles;
|
|
107
|
+
/**
|
|
108
|
+
* Minimum level to output. Checked when set, because levels often come
|
|
109
|
+
* from configuration or environment variables as plain strings: a typo
|
|
110
|
+
* like `'warn'` would otherwise silently turn off all logs.
|
|
111
|
+
*
|
|
112
|
+
* @throws RangeError if the level is unknown.
|
|
113
|
+
*/
|
|
114
|
+
get level(): LogLevel;
|
|
115
|
+
set level(level: LogLevel);
|
|
116
|
+
/**
|
|
117
|
+
* Creates a log entry, transforms it and passes it to the output. Does
|
|
118
|
+
* nothing if the type does not pass the current level.
|
|
119
|
+
*
|
|
120
|
+
* @throws TypeError if the type is unknown, e.g. `'silent'` (a level, not a
|
|
121
|
+
* type) from untyped callers.
|
|
122
|
+
*
|
|
123
|
+
* @param type Log type.
|
|
124
|
+
* @param data Logged data.
|
|
125
|
+
* @param kind Log kind that selects template map and output.
|
|
126
|
+
* Default: `defaultKind`.
|
|
127
|
+
*/
|
|
128
|
+
log(type: LogType, data: unknown, kind?: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Logs a fatal error that leads to an immediate halt of all operations.
|
|
131
|
+
*
|
|
132
|
+
* Without plugins the output is the log entry object:
|
|
133
|
+
* `{ id, timestamp, type: 'fatal', kind, data }`.
|
|
134
|
+
*
|
|
135
|
+
* @param data Any value, stored as the entry's `data`.
|
|
136
|
+
* @param kind Log kind that selects the template map and output.
|
|
137
|
+
* Default: `defaultKind`.
|
|
138
|
+
*/
|
|
139
|
+
fatal(data: unknown, kind?: string): void;
|
|
140
|
+
/**
|
|
141
|
+
* Logs an error that might lead to a halt of the current operation.
|
|
142
|
+
*
|
|
143
|
+
* Without plugins the output is the log entry object:
|
|
144
|
+
* `{ id, timestamp, type: 'error', kind, data }`.
|
|
145
|
+
*
|
|
146
|
+
* @param data Any value, stored as the entry's `data`.
|
|
147
|
+
* @param kind Log kind that selects the template map and output.
|
|
148
|
+
* Default: `defaultKind`.
|
|
149
|
+
*/
|
|
150
|
+
error(data: unknown, kind?: string): void;
|
|
151
|
+
/**
|
|
152
|
+
* Logs a warning about something that might produce an unexpected result
|
|
153
|
+
* later in the execution.
|
|
154
|
+
*
|
|
155
|
+
* Without plugins the output is the log entry object:
|
|
156
|
+
* `{ id, timestamp, type: 'warning', kind, data }`.
|
|
157
|
+
*
|
|
158
|
+
* @param data Any value, stored as the entry's `data`.
|
|
159
|
+
* @param kind Log kind that selects the template map and output.
|
|
160
|
+
* Default: `defaultKind`.
|
|
161
|
+
*/
|
|
162
|
+
warning(data: unknown, kind?: string): void;
|
|
163
|
+
/**
|
|
164
|
+
* Logs an important milestone of the execution flow, relevant in production.
|
|
165
|
+
*
|
|
166
|
+
* Without plugins the output is the log entry object:
|
|
167
|
+
* `{ id, timestamp, type: 'info', kind, data }`.
|
|
168
|
+
*
|
|
169
|
+
* @param data Any value, stored as the entry's `data`.
|
|
170
|
+
* @param kind Log kind that selects the template map and output.
|
|
171
|
+
* Default: `defaultKind`.
|
|
172
|
+
*/
|
|
173
|
+
info(data: unknown, kind?: string): void;
|
|
174
|
+
/**
|
|
175
|
+
* Logs information that helps to debug a problem.
|
|
176
|
+
*
|
|
177
|
+
* Without plugins the output is the log entry object:
|
|
178
|
+
* `{ id, timestamp, type: 'debug', kind, data }`.
|
|
179
|
+
*
|
|
180
|
+
* @param data Any value, stored as the entry's `data`.
|
|
181
|
+
* @param kind Log kind that selects the template map and output.
|
|
182
|
+
* Default: `defaultKind`.
|
|
183
|
+
*/
|
|
184
|
+
debug(data: unknown, kind?: string): void;
|
|
185
|
+
/**
|
|
186
|
+
* Logs an execution checkpoint, to narrow down the execution path.
|
|
187
|
+
*
|
|
188
|
+
* Without plugins the output is the log entry object:
|
|
189
|
+
* `{ id, timestamp, type: 'trace', kind, data }`.
|
|
190
|
+
*
|
|
191
|
+
* @param data Any value, stored as the entry's `data`.
|
|
192
|
+
* @param kind Log kind that selects the template map and output.
|
|
193
|
+
* Default: `defaultKind`.
|
|
194
|
+
*/
|
|
195
|
+
trace(data: unknown, kind?: string): void;
|
|
196
|
+
/**
|
|
197
|
+
* Logs information of importance during a close examination of the
|
|
198
|
+
* execution flow.
|
|
199
|
+
*
|
|
200
|
+
* Without plugins the output is the log entry object:
|
|
201
|
+
* `{ id, timestamp, type: 'verbose', kind, data }`.
|
|
202
|
+
*
|
|
203
|
+
* @param data Any value, stored as the entry's `data`.
|
|
204
|
+
* @param kind Log kind that selects the template map and output.
|
|
205
|
+
* Default: `defaultKind`.
|
|
206
|
+
*/
|
|
207
|
+
verbose(data: unknown, kind?: string): void;
|
|
208
|
+
private createEntry;
|
|
209
|
+
private mergeTemplateMap;
|
|
210
|
+
/**
|
|
211
|
+
* Bakes style sheets to escape code strings per log type, without changing
|
|
212
|
+
* the logger. Styles are converted even when `useStyles` is off, so invalid
|
|
213
|
+
* ones always fail when added.
|
|
214
|
+
*
|
|
215
|
+
* @param what Prefix of error messages, e.g. `Plugin "theme"`.
|
|
216
|
+
* @throws TypeError if a style can't be converted to a string.
|
|
217
|
+
*/
|
|
218
|
+
private bake;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Logger with the methods of its plugins. Plugin methods with the same name as
|
|
222
|
+
* logger methods replace their signatures and docs.
|
|
223
|
+
*
|
|
224
|
+
* @template M Methods added or re-declared by plugins.
|
|
225
|
+
*/
|
|
226
|
+
export type Logger<M = unknown> = Override<BaseLogger, M>;
|
|
227
|
+
export interface LoggerConstructor {
|
|
228
|
+
/**
|
|
229
|
+
* Creates a logger. Plugins passed in `options.plugins` are used in order
|
|
230
|
+
* and their methods are added to the logger's type.
|
|
231
|
+
*/
|
|
232
|
+
new <const P extends readonly LoggerPlugin[] = []>(options?: LoggerOptions<P>): Logger<PluginMethods<P>>;
|
|
233
|
+
readonly prototype: BaseLogger;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Logger extensible by plugins. Plugins can be passed to the constructor or
|
|
237
|
+
* chained with `use`; both type the added methods:
|
|
238
|
+
*
|
|
239
|
+
* ```ts
|
|
240
|
+
* const logger = new Logger({ plugins: [messagePlugin(), graphPlugin()] });
|
|
241
|
+
* const same = new Logger().use(messagePlugin()).use(graphPlugin());
|
|
242
|
+
* logger.infoGraph([1, 2, 3]);
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
export declare const Logger: LoggerConstructor;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Output } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Default output. Writes the entry object as is.
|
|
4
|
+
*/
|
|
5
|
+
export declare const consoleOutput: Output;
|
|
6
|
+
/**
|
|
7
|
+
* Creates output that joins all entry values into one string. Suitable for
|
|
8
|
+
* entries whose properties were rendered to strings by template maps.
|
|
9
|
+
*
|
|
10
|
+
* @param write String destination. Default: `console.log`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const joinedOutput: (write?: (text: string) => void) => Output;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { LoggerPlugin } from '../types.js';
|
|
2
|
+
export interface ColumnsPluginOptions {
|
|
3
|
+
/** Number of columns, from 1 to 100. Default: `2`. */
|
|
4
|
+
readonly columns?: number;
|
|
5
|
+
/**
|
|
6
|
+
* Width of each column in terminal columns, frame excluded, from 2 to
|
|
7
|
+
* 10,000. Default: the terminal width (`process.stdout.columns`, 80 when it
|
|
8
|
+
* is unknown) minus the frames, split evenly; read once, when the plugin is
|
|
9
|
+
* created.
|
|
10
|
+
*/
|
|
11
|
+
readonly width?: number;
|
|
12
|
+
/** Text between columns, without control characters. Default: `' | '`. */
|
|
13
|
+
readonly frame?: string;
|
|
14
|
+
/** Style name of the frame. Default: `'textDim'`. */
|
|
15
|
+
readonly frameStyle?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Kinds laid out in columns. Kinds without a template map (no plugin
|
|
18
|
+
* renders them) are skipped; never list JSON kinds. Default:
|
|
19
|
+
* `['message', 'graph']`.
|
|
20
|
+
*/
|
|
21
|
+
readonly kinds?: readonly string[];
|
|
22
|
+
/**
|
|
23
|
+
* How lines longer than the width are fitted, per kind (see `WrapMode`).
|
|
24
|
+
* A mode sets the default for all kinds; an object sets kinds by name,
|
|
25
|
+
* `'*'` for the others, merged over `DEFAULT_COLUMNS_WRAP`
|
|
26
|
+
* (`{ '*': 'hard', graph: 'truncate' }`): a graph wider than its column is
|
|
27
|
+
* cut with a dim `…`, never wrapped into a mess. Kinds of other plugins
|
|
28
|
+
* are set by their kind name, e.g. `{ cpu: 'truncate' }` for
|
|
29
|
+
* `graphPlugin({ kind: 'cpu' })`.
|
|
30
|
+
*/
|
|
31
|
+
readonly wrap?: ColumnsWrap;
|
|
32
|
+
/**
|
|
33
|
+
* Spaces at the start of lines created by wrapping, so a continuation
|
|
34
|
+
* doesn't look like a new log, from 0 to `width - 1`. The cell's own
|
|
35
|
+
* lines (object keys, stack frames, graph rows) are not indented. Default:
|
|
36
|
+
* `0`.
|
|
37
|
+
*/
|
|
38
|
+
readonly indent?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Redraw the rows that can still change on every log, so the grid fills
|
|
41
|
+
* on screen as the calls come in. Needs a terminal: with the default
|
|
42
|
+
* `write`, output that is not a TTY (piped or redirected) is written row
|
|
43
|
+
* by row instead, and so is a grid wider than the terminal. A custom
|
|
44
|
+
* `write` must go to the terminal. Default: `false`.
|
|
45
|
+
*/
|
|
46
|
+
readonly live?: boolean;
|
|
47
|
+
/** Line destination. Default: `console.log`. */
|
|
48
|
+
readonly write?: (text: string) => void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Wrap mode of all kinds, or modes by kind name with `'*'` for the others.
|
|
52
|
+
*/
|
|
53
|
+
export type ColumnsWrap = WrapMode | Readonly<Record<string, WrapMode>>;
|
|
54
|
+
/**
|
|
55
|
+
* Wrap modes used unless `wrap` overrides them: graphs are cut (a wrapped
|
|
56
|
+
* graph is unreadable, a cut one shows the width is off), everything else
|
|
57
|
+
* wraps hard.
|
|
58
|
+
*/
|
|
59
|
+
export declare const DEFAULT_COLUMNS_WRAP: Readonly<Record<string, WrapMode>>;
|
|
60
|
+
/**
|
|
61
|
+
* Methods added by `columnsPlugin`. Logs of the plugin's kinds become cells
|
|
62
|
+
* of a grid: `column` and `row` move the cell the next log goes to. A row is
|
|
63
|
+
* a row of cells, as tall as its tallest cell, not a terminal line.
|
|
64
|
+
*/
|
|
65
|
+
export interface ColumnsMethods {
|
|
66
|
+
/**
|
|
67
|
+
* Makes a column active: the next log goes to that column's next row.
|
|
68
|
+
* Without an index, moves to the next column; from the last column it
|
|
69
|
+
* writes the grid and starts a new one in column 0. The first call starts
|
|
70
|
+
* the grid.
|
|
71
|
+
*
|
|
72
|
+
* @throws RangeError if the index is not an integer below `columns`.
|
|
73
|
+
*/
|
|
74
|
+
column(index?: number): void;
|
|
75
|
+
/**
|
|
76
|
+
* Moves the active column's cursor: the next log goes to row `index`,
|
|
77
|
+
* replacing what is there, and later logs continue below it. Without an
|
|
78
|
+
* index, moves one row down: the cell at the cursor is left as it is
|
|
79
|
+
* (empty if nothing was logged there). A row that was
|
|
80
|
+
* already written (scrolled off in live mode) can't change: logs for it
|
|
81
|
+
* go to the column's next free row. Starts the grid in column 0 if
|
|
82
|
+
* needed.
|
|
83
|
+
*
|
|
84
|
+
* @throws RangeError if the index is not an integer from 0 to the number
|
|
85
|
+
* of rows (an existing row or the next new one).
|
|
86
|
+
*/
|
|
87
|
+
row(index?: number): void;
|
|
88
|
+
/**
|
|
89
|
+
* Writes the rest of the grid, empty cells blank, and returns to normal
|
|
90
|
+
* output. Does nothing without a grid.
|
|
91
|
+
*/
|
|
92
|
+
endColumns(): void;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* How lines longer than the column width are fitted:
|
|
96
|
+
* - `'hard'`: wrapped at exactly the width, even mid-word;
|
|
97
|
+
* - `'word'`: wrapped at the last space that fits (the space is dropped);
|
|
98
|
+
* words longer than the width are wrapped hard;
|
|
99
|
+
* - `'truncate'`: cut at the width, with a dim `…` in the last column. The
|
|
100
|
+
* cell's own lines are kept.
|
|
101
|
+
*/
|
|
102
|
+
export type WrapMode = 'hard' | 'word' | 'truncate';
|
|
103
|
+
export interface WrapTextOptions {
|
|
104
|
+
/** How lines longer than the width are fitted. Default: `'hard'`. */
|
|
105
|
+
readonly mode?: WrapMode;
|
|
106
|
+
/** Text ending a cut line, one column wide. Default: `'…'`. */
|
|
107
|
+
readonly marker?: string;
|
|
108
|
+
/**
|
|
109
|
+
* Spaces at the start of lines created by wrapping (`'hard'` and
|
|
110
|
+
* `'word'`), below the width. The text's own lines are not indented.
|
|
111
|
+
* Default: `0`.
|
|
112
|
+
*/
|
|
113
|
+
readonly indent?: number;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Splits rendered text into lines of exactly `width` terminal columns, each
|
|
117
|
+
* padded with spaces. Lines longer than the width are wrapped or cut, see
|
|
118
|
+
* `WrapMode`. Never splits an SGR sequence, a surrogate pair or a wide
|
|
119
|
+
* character; styles in effect are closed at the end of each line and
|
|
120
|
+
* reopened on the next one. Tabs become spaces up to the next multiple of 8.
|
|
121
|
+
*/
|
|
122
|
+
export declare const wrapText: (text: string, width: number, options?: WrapTextOptions) => string[];
|
|
123
|
+
/**
|
|
124
|
+
* Lays out logs in columns, side by side. Each log of the laid out kinds
|
|
125
|
+
* (by default messages and graphs) is a cell, and `column()` / `row()` pick
|
|
126
|
+
* the cell. Calls go call for call: the n-th log of each column shares a
|
|
127
|
+
* row, and a row is as tall as its tallest cell. Lines are wrapped at
|
|
128
|
+
* exactly `width` terminal columns (wide characters take two) and padded,
|
|
129
|
+
* except in the last column.
|
|
130
|
+
*
|
|
131
|
+
* ```ts
|
|
132
|
+
* const logger = new Logger()
|
|
133
|
+
* .use(messagePlugin())
|
|
134
|
+
* .use(graphPlugin({ width: 64 }))
|
|
135
|
+
* .use(columnsPlugin({ columns: 2, width: 64 }));
|
|
136
|
+
* for (const column of [0, 1]) {
|
|
137
|
+
* logger.column(column);
|
|
138
|
+
* logger.info('styled by default');
|
|
139
|
+
* logger.infoGraph(values);
|
|
140
|
+
* }
|
|
141
|
+
* logger.endColumns();
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* Rows are written as soon as every column has moved past them or, with
|
|
145
|
+
* `live`, redrawn on every log. Outside `column()` … `endColumns()` the
|
|
146
|
+
* logger is not slowed down: the outputs are only swapped while a grid is
|
|
147
|
+
* open. Use after the plugins that render the kinds.
|
|
148
|
+
*
|
|
149
|
+
* @throws RangeError or TypeError for invalid options.
|
|
150
|
+
*/
|
|
151
|
+
export declare const columnsPlugin: (options?: ColumnsPluginOptions) => LoggerPlugin<ColumnsMethods>;
|