lifecycleion 0.0.20 → 0.0.21

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.
Files changed (72) hide show
  1. package/README.md +39 -36
  2. package/dist/lib/event-emitter.cjs +195 -9
  3. package/dist/lib/event-emitter.cjs.map +1 -1
  4. package/dist/lib/event-emitter.js +195 -9
  5. package/dist/lib/event-emitter.js.map +1 -1
  6. package/dist/lib/global-event-target.cjs +217 -0
  7. package/dist/lib/global-event-target.cjs.map +1 -0
  8. package/dist/lib/global-event-target.d.cts +70 -0
  9. package/dist/lib/global-event-target.d.ts +70 -0
  10. package/dist/lib/global-event-target.js +189 -0
  11. package/dist/lib/global-event-target.js.map +1 -0
  12. package/dist/lib/http-client/index.cjs +554 -193
  13. package/dist/lib/http-client/index.cjs.map +1 -1
  14. package/dist/lib/http-client/index.d.cts +9 -3
  15. package/dist/lib/http-client/index.d.ts +9 -3
  16. package/dist/lib/http-client/index.js +554 -193
  17. package/dist/lib/http-client/index.js.map +1 -1
  18. package/dist/lib/http-client-mock/index.cjs +71 -10
  19. package/dist/lib/http-client-mock/index.cjs.map +1 -1
  20. package/dist/lib/http-client-mock/index.d.cts +50 -3
  21. package/dist/lib/http-client-mock/index.d.ts +50 -3
  22. package/dist/lib/http-client-mock/index.js +71 -10
  23. package/dist/lib/http-client-mock/index.js.map +1 -1
  24. package/dist/lib/http-client-node/index.cjs +98 -19
  25. package/dist/lib/http-client-node/index.cjs.map +1 -1
  26. package/dist/lib/http-client-node/index.d.cts +2 -2
  27. package/dist/lib/http-client-node/index.d.ts +2 -2
  28. package/dist/lib/http-client-node/index.js +98 -19
  29. package/dist/lib/http-client-node/index.js.map +1 -1
  30. package/dist/lib/http-client-xhr/index.cjs.map +1 -1
  31. package/dist/lib/http-client-xhr/index.d.cts +2 -2
  32. package/dist/lib/http-client-xhr/index.d.ts +2 -2
  33. package/dist/lib/http-client-xhr/index.js.map +1 -1
  34. package/dist/lib/lifecycle-manager/index.cjs +199 -13
  35. package/dist/lib/lifecycle-manager/index.cjs.map +1 -1
  36. package/dist/lib/lifecycle-manager/index.js +199 -13
  37. package/dist/lib/lifecycle-manager/index.js.map +1 -1
  38. package/dist/lib/logger/index.cjs +203 -21
  39. package/dist/lib/logger/index.cjs.map +1 -1
  40. package/dist/lib/logger/index.d.cts +5 -1
  41. package/dist/lib/logger/index.d.ts +5 -1
  42. package/dist/lib/logger/index.js +203 -21
  43. package/dist/lib/logger/index.js.map +1 -1
  44. package/dist/lib/lru-cache/index.cjs +195 -9
  45. package/dist/lib/lru-cache/index.cjs.map +1 -1
  46. package/dist/lib/lru-cache/index.js +195 -9
  47. package/dist/lib/lru-cache/index.js.map +1 -1
  48. package/dist/lib/process-signal-manager.cjs +199 -13
  49. package/dist/lib/process-signal-manager.cjs.map +1 -1
  50. package/dist/lib/process-signal-manager.js +199 -13
  51. package/dist/lib/process-signal-manager.js.map +1 -1
  52. package/dist/lib/promise-protected-resolver.cjs +195 -9
  53. package/dist/lib/promise-protected-resolver.cjs.map +1 -1
  54. package/dist/lib/promise-protected-resolver.js +195 -9
  55. package/dist/lib/promise-protected-resolver.js.map +1 -1
  56. package/dist/lib/retry-utils/index.cjs +195 -9
  57. package/dist/lib/retry-utils/index.cjs.map +1 -1
  58. package/dist/lib/retry-utils/index.js +195 -9
  59. package/dist/lib/retry-utils/index.js.map +1 -1
  60. package/dist/lib/safe-handle-callback.cjs +196 -18
  61. package/dist/lib/safe-handle-callback.cjs.map +1 -1
  62. package/dist/lib/safe-handle-callback.d.cts +14 -4
  63. package/dist/lib/safe-handle-callback.d.ts +14 -4
  64. package/dist/lib/safe-handle-callback.js +196 -18
  65. package/dist/lib/safe-handle-callback.js.map +1 -1
  66. package/dist/lib/single-event-observer.cjs +195 -9
  67. package/dist/lib/single-event-observer.cjs.map +1 -1
  68. package/dist/lib/single-event-observer.js +195 -9
  69. package/dist/lib/single-event-observer.js.map +1 -1
  70. package/dist/{types-6G59m8U9.d.cts → types-BFvpJPMt.d.cts} +71 -10
  71. package/dist/{types-CG10j6Lc.d.ts → types-BONtIhQ5.d.ts} +71 -10
  72. package/package.json +12 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/strings.ts","../../src/lib/constants.ts","../../src/lib/padding-utils.ts","../../src/lib/ascii-tables/ascii-table-utils.ts","../../src/lib/ascii-tables/multi-column-ascii-table.ts","../../src/lib/ascii-tables/key-value-ascii-table.ts","../../src/lib/clamp.ts","../../src/lib/error-to-string.ts","../../src/lib/is-promise.ts","../../src/lib/is-function.ts","../../src/lib/safe-handle-callback.ts","../../src/lib/single-event-observer.ts"],"sourcesContent":["import { removeEmptyStringsFromArray } from './arrays';\n\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/**\n * Converts a string or an array of strings to Pascal Case.\n *\n * This function takes an input string or an array of strings, each potentially containing hyphens,\n * and converts them to Pascal Case. It removes any characters that are not letters or numbers,\n * capitalizes the first letter of each substring, and ensures the rest of the substring\n * is in lowercase. Finally, it concatenates all these substrings to produce a Pascal Case\n * output.\n *\n * @param {string | string[]} input - The input string or array of strings to be converted to Pascal Case.\n * @returns {string} The converted string in Pascal Case.\n *\n * Examples:\n * toPascalCase(\"hello-world-123!$\") will return \"HelloWorld123\"\n * toPascalCase([\"hello\", \"world-123!$\"]) will return \"HelloWorld123\"\n */\n\nexport function toPascalCase(input: string | string[]): string {\n // Ensure input is an array\n const inputArray = Array.isArray(input) ? input : [input];\n\n // Process each string in the array\n const parts: string[] = [];\n\n for (const item of inputArray) {\n // Clean the string, split by hyphen, and remove empty strings\n const cleanedItem = item.replace(/[^a-zA-Z0-9-]/g, '');\n parts.push(...removeEmptyStringsFromArray(cleanedItem.split('-')));\n }\n\n // Process and rejoin the input strings\n return parts\n .map(\n (subString) =>\n subString.charAt(0).toUpperCase() + subString.slice(1).toLowerCase(),\n )\n .join('');\n}\n\n/**\n * Converts a string or an array of strings to Camel Case.\n *\n * This function takes an input string or an array of strings, each potentially containing hyphens,\n * and converts them to Camel Case. It removes any characters that are not letters or numbers,\n * capitalizes the first letter of each substring after the first one, and ensures the rest of the substring\n * is in lowercase. For the first substring, it ensures the entire substring is in lowercase.\n * Finally, it concatenates all these substrings to produce a Camel Case output.\n *\n * @param {string | string[]} input - The input string or array of strings to be converted to Camel Case.\n * @returns {string} The converted string in Camel Case.\n *\n * Examples:\n * toCamelCase(\"hello-world-123!$\") will return \"helloWorld123\"\n * toCamelCase([\"hello\", \"world-123!$\"]) will return \"helloWorld123\"\n */\n\nexport function toCamelCase(input: string | string[]): string {\n // Ensure input is an array\n const inputArray = Array.isArray(input) ? input : [input];\n\n // Process each string in the array\n const parts: string[] = [];\n\n for (const item of inputArray) {\n // Clean the string, split by hyphen, and remove empty strings\n const cleanedItem = item.replace(/[^a-zA-Z0-9-]/g, '');\n parts.push(...removeEmptyStringsFromArray(cleanedItem.split('-')));\n }\n\n // Process and rejoin the input strings\n return parts\n .map((subString, index) =>\n index === 0\n ? subString.toLowerCase()\n : subString.charAt(0).toUpperCase() + subString.slice(1).toLowerCase(),\n )\n .join('');\n}\n\n/**\n * This method converts a string or an array of strings to camel case,\n * but if starting with a leading hyphen, it will convert to Pascal case.\n */\n\nexport function toCamelCaseWithPascalOverride(\n input: string | string[],\n): string {\n if (isString(input) && input.startsWith('-')) {\n return toPascalCase(input);\n } else if (\n Array.isArray(input) &&\n input.length > 0 &&\n input[0].startsWith('-')\n ) {\n return toPascalCase(input);\n } else {\n return toCamelCase(input);\n }\n}\n\n/**\n * Converts a string or an array of strings to constant case.\n *\n * The function takes a string or an array of strings, where each string can be separated by a '-',\n * and converts them into a constant case format (all uppercase with underscores between words).\n * It first cleans the input by removing non-alphanumeric characters (except for hyphens), splits the\n * string into parts on hyphens, and then joins these parts with underscores, converting the entire\n * result to uppercase.\n *\n * @param {string | string[]} input - The input string or array of strings to be converted.\n * @returns {string} The converted string in constant case.\n *\n * Example:\n * toConstantCase(\"hello-world\") will return \"HELLO_WORLD\"\n * toConstantCase([\"hello\", \"world\"]) will return \"HELLO_WORLD\"\n */\n\nexport function toConstantCase(input: string | string[]): string {\n // Ensure input is an array\n const inputArray = Array.isArray(input) ? input : [input];\n\n // Process each string in the array\n let parts: string[] = [];\n\n for (const item of inputArray) {\n // Clean the string and split by hyphen\n const cleanedItem = item.replace(/[^a-zA-Z0-9-]/g, '');\n parts.push(...cleanedItem.split('-'));\n }\n\n // Remove empty strings from the array\n parts = removeEmptyStringsFromArray(parts);\n\n // Join parts with underscore and convert to uppercase\n return parts.join('_').toUpperCase();\n}\n\nexport function splitGraphemes(text: string): string[] {\n const graphemes: string[] = [];\n let grapheme = '';\n let zwjSequence = '';\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n const nextChar = text[i + 1] || '';\n const code = char.charCodeAt(0);\n\n // Handling combining marks and zero width joiner\n if (\n (code >= 0x0300 && code <= 0x036f) || // Combining Diacritical Marks\n (code >= 0x1ab0 && code <= 0x1aff) || // Combining Diacritical Marks Extended\n (code >= 0x1dc0 && code <= 0x1dff) || // Combining Diacritical Marks Supplement\n (code >= 0xfe20 && code <= 0xfe2f) || // Combining Half Marks\n (code >= 0x0e31 && code <= 0x0e3a) || // Thai combining marks\n (code >= 0x0e47 && code <= 0x0e4e)\n ) {\n // Thai combining marks\n grapheme += char;\n } else if (char === '\\u200d') {\n // Zero Width Joiner (ZWJ)\n zwjSequence += grapheme + char;\n grapheme = '';\n } else {\n if (grapheme) {\n if (zwjSequence) {\n graphemes.push(zwjSequence + grapheme);\n zwjSequence = '';\n } else {\n graphemes.push(grapheme);\n }\n }\n grapheme = char;\n\n // Handle surrogate pairs (needed for certain characters including emojis)\n if (\n char >= '\\ud800' &&\n char <= '\\udbff' &&\n nextChar >= '\\udc00' &&\n nextChar <= '\\udfff'\n ) {\n grapheme += nextChar;\n i++;\n }\n }\n }\n\n if (grapheme) {\n if (zwjSequence) {\n graphemes.push(zwjSequence + grapheme);\n } else {\n graphemes.push(grapheme);\n }\n }\n\n return graphemes;\n}\n\nexport function skipTrailingNewLines(str: string): string {\n return str.replace(/\\n+$/, '');\n}\n\n/**\n * Filters a string to include only specified characters, optionally replacing disallowed characters.\n *\n * @param str - The input string to be filtered.\n * @param list - An array of allowed characters.\n * @param caseInsensitive - Optional. If true, the filtering is case-insensitive. Default is false.\n * @param replacementChar - Optional. Character to replace disallowed characters. If empty, disallowed characters are removed. Default is ''.\n * @returns A new string containing only the allowed characters from the input string, with disallowed characters optionally replaced.\n *\n * @example\n * // Case-sensitive usage, removing disallowed characters\n * characterAllowedOnly(\"Hello123!\", [\"H\", \"e\", \"l\", \"o\"]);\n * // Returns: \"Hello\"\n *\n * @example\n * // Case-insensitive usage, removing disallowed characters\n * characterAllowedOnly(\"Hello123!\", [\"h\", \"E\", \"L\", \"O\"], true);\n * // Returns: \"Hello\"\n *\n * @example\n * // Using replacement character\n * characterAllowedOnly(\"Hello123!\", [\"H\", \"e\", \"l\", \"o\"], false, \"-\");\n * // Returns: \"Hello---\"\n */\n\nexport function characterAllowedOnly(\n str: string,\n list: string[],\n // eslint-disable-next-line @typescript-eslint/naming-convention\n caseInsensitive = false,\n replacementChar = '',\n): string {\n let newStr = '';\n\n // Convert the allowed list to lowercase if case-insensitive\n if (caseInsensitive) {\n list = Array.from(new Set(list.map((item) => item.toLowerCase())));\n }\n\n // Convert the entire input string to lowercase if case-insensitive\n const processedStr = caseInsensitive ? str.toLowerCase() : str;\n\n for (const c of processedStr) {\n if (list.includes(c)) {\n newStr += c;\n } else if (replacementChar !== '') {\n newStr += replacementChar;\n }\n }\n\n return newStr;\n}\n\n// functions to chop characters from a string.\n\n/**\n * Will remove the matching first character from a string\n * @param str\n * @param char\n * @returns\n */\n\nexport function chopBeginningCharacter(str: string, char: string): string {\n if (str.startsWith(char)) {\n return str.slice(1);\n } else {\n return str;\n }\n}\n\n/**\n * Will remove the matching last character from the string\n * @param str\n * @param char\n * @returns\n */\nexport function chopEndingCharacter(str: string, char: string): string {\n if (str.endsWith(char)) {\n return str.slice(0, -1);\n } else {\n return str;\n }\n}\n\n/**\n * Will remove the matching character, from the beginning and/or end of the string if matching\n * @param str\n * @param char\n * @returns\n */\n\nexport function chopBothBeginningAndEndingCharacters(\n str: string,\n char: string,\n): string {\n return chopBeginningCharacter(chopEndingCharacter(str, char), char);\n}\n","// prettier-ignore\nexport const BLANK_SPACE = ' ';\n\nexport const EOL = '\\n';\nexport const DOUBLE_EOL = EOL + EOL;\nexport const INDENT = ' '.repeat(4);\nexport const DOUBLE_INDENT = INDENT + INDENT;\n\n// prettier-ignore\nexport const SINGLE_QUOTE = \"'\";\n\n// similar to Python string library\nexport const ASCII_LOWERCASE = 'abcdefghijklmnopqrstuvwxyz';\nexport const ASCII_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\nexport const ASCII_LETTERS = ASCII_LOWERCASE + ASCII_UPPERCASE;\nexport const DIGITS = '0123456789';\nexport const HEX_DIGITS = DIGITS + 'abcdefABCDEF';\nexport const OCT_DIGITS = '01234567';\nexport const PUNCTUATION = '!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~';\nexport const WHITESPACE = ' \\t\\n\\r\\v\\f';\nexport const PRINTABLE = DIGITS + ASCII_LETTERS + PUNCTUATION + WHITESPACE;\n","/**\n * Utilities to pad strings with another string up to a defined length.\n * Each function takes a string, length to pad and the string to be used for padding (but defaults to a blank space if not provided) and returns the modified string\n *\n * This only pads on the left side, so text is added to the front until the total string equals the given length.\n *\n * ```typescript\n * padLeft('Hey', 6, '*'); // returns ***Hey\n * ```\n * @category String Padding\n */\n\nimport { BLANK_SPACE } from './constants';\n\nexport function padLeft(\n str: string,\n length: number,\n padStr = BLANK_SPACE,\n): string {\n return str.padStart(length, padStr);\n}\n\n/**\n * This only pads on the right side, so text is added to the end until the total string equals the given length.\n *\n * ```typescript\n * padRight('Hey', 6, '*'); // returns Hey***\n * ```\n *\n * @category String Padding\n */\n\nexport function padRight(\n str: string,\n length: number,\n padStr = BLANK_SPACE,\n): string {\n return str.padEnd(length, padStr);\n}\n\n/**\n * Same as `padCenterPreferLeft` and `padCenterPreferRight` but you can pass in a string with `left` or `right` before the padStr to use more direct.\n *\n * Defaults to `left`\n *\n * @category String Padding\n */\n\nexport function padCenter(\n str: string,\n length: number,\n prefer: 'left' | 'right' = 'left',\n padStr = BLANK_SPACE,\n): string {\n const midStrLength = length - str.length;\n\n if (midStrLength > 0) {\n const padLeftAmount =\n prefer === 'left'\n ? Math.ceil(midStrLength / 2)\n : Math.floor(midStrLength / 2);\n\n const padRightAmount =\n prefer === 'left'\n ? Math.floor(midStrLength / 2)\n : Math.ceil(midStrLength / 2);\n\n return (\n padLeft('', padLeftAmount, padStr) +\n str +\n padRight('', padRightAmount, padStr)\n );\n } else {\n return str;\n }\n}\n\n/**\n * It tries to pad equally on both sides in an attempt to center your text. However if it can't the extra character will be added to the left side\n *\n * @category String Padding\n */\n\nexport function padCenterPreferLeft(\n str: string,\n length: number,\n padStr = BLANK_SPACE,\n): string {\n return padCenter(str, length, 'left', padStr);\n}\n\n/**\n * It tries to pad equally, but if it can't the extra character will be added to the right side\n *\n * @category String Padding\n */\n\nexport function padCenterPreferRight(\n str: string,\n length: number,\n padStr = BLANK_SPACE,\n): string {\n return padCenter(str, length, 'right', padStr);\n}\n","import { padCenterPreferRight, padRight } from '../padding-utils';\nimport stringWidth from 'string-width';\nimport { splitGraphemes } from '../strings';\n\nexport class ASCIITableUtils {\n public static centerText(text: string, width: number): string {\n return padCenterPreferRight(text, width, ' ');\n }\n\n public static createSeparator(\n columnWidths: number[],\n character: string = '=',\n ): string {\n const totalWidth =\n columnWidths.reduce((sum, width) => sum + width + 3, 0) - 1;\n\n return `+${padRight('', totalWidth, character)}+`;\n }\n\n public static wrapText(text: string, maxLength: number): string[] {\n const words = text.split(' ');\n const lines: string[] = [];\n let currentLine = '';\n\n for (const word of words) {\n if (stringWidth(currentLine) + stringWidth(word) + 1 <= maxLength) {\n currentLine += (currentLine ? ' ' : '') + word;\n } else {\n if (currentLine) {\n lines.push(currentLine);\n }\n\n if (stringWidth(word) <= maxLength) {\n currentLine = word;\n } else {\n const subWords = ASCIITableUtils.splitWord(word, maxLength);\n lines.push(...subWords.slice(0, -1));\n currentLine = subWords[subWords.length - 1];\n }\n }\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n\n return lines;\n }\n\n public static splitWord(word: string, maxLength: number): string[] {\n const graphemes = splitGraphemes(word);\n const subWords: string[] = [];\n let currentSubWord = '';\n\n for (const grapheme of graphemes) {\n if (stringWidth(currentSubWord + grapheme) <= maxLength) {\n currentSubWord += grapheme;\n } else {\n subWords.push(currentSubWord);\n currentSubWord = grapheme;\n }\n }\n\n if (currentSubWord) {\n subWords.push(currentSubWord);\n }\n\n return subWords;\n }\n}\n","import { ASCIITableUtils } from './ascii-table-utils';\nimport stringWidth from 'string-width';\n\ninterface MultiColumnASCIITableOptions {\n tableWidth?: number;\n emptyMessage?: string;\n widthMode?: 'flex' | 'fixed';\n}\n\nexport class MultiColumnASCIITable {\n private headers: string[];\n private rows: string[][];\n private tableWidth: number;\n private emptyMessage: string;\n private widthMode: 'flex' | 'fixed';\n\n constructor(headers: string[], options: MultiColumnASCIITableOptions = {}) {\n this.headers = headers;\n this.rows = [];\n this.tableWidth = options.tableWidth || 80;\n this.emptyMessage = options.emptyMessage || '';\n this.widthMode = options.widthMode || 'flex';\n\n const minTableWidth = this.getMinimumWidth();\n\n if (this.tableWidth < minTableWidth) {\n throw new Error(\n `Table width must be at least ${minTableWidth} to accommodate the headers.`,\n );\n }\n }\n\n public getMinimumWidth(): number {\n return this.headers.length * 4 + 1;\n }\n\n public addRow(row: string[]): void {\n if (row.length !== this.headers.length) {\n throw new Error(\n `Number of values in the row (${row.length}) must match the number of headers (${this.headers.length}).`,\n );\n }\n\n this.rows.push(row);\n }\n\n public toString(options: MultiColumnASCIITableOptions = {}): string {\n const tableWidth = options.tableWidth || this.tableWidth;\n const emptyMessage = options.emptyMessage || this.emptyMessage;\n\n if (this.rows.length === 0) {\n const emptyTableWidth = Math.min(tableWidth, 40);\n\n const separator = '+' + '-'.repeat(emptyTableWidth - 2) + '+';\n const emptyMessageLines = ASCIITableUtils.wrapText(\n emptyMessage,\n emptyTableWidth - 4,\n );\n\n const emptyRows = emptyMessageLines.map((line) => {\n const paddingLeft = ' '.repeat(\n Math.floor((emptyTableWidth - stringWidth(line) - 4) / 2),\n );\n\n const paddingRight = ' '.repeat(\n Math.ceil((emptyTableWidth - stringWidth(line) - 4) / 2),\n );\n\n return `| ${paddingLeft}${line}${paddingRight} |`;\n });\n\n if (emptyRows.length === 0) {\n emptyRows.push(`| ${' '.repeat(emptyTableWidth - 4)} |`);\n }\n\n return [separator, ...emptyRows, separator].join('\\n');\n }\n\n const columnWidths = this.calculateColumnWidths(options);\n\n const headerSeparator = ASCIITableUtils.createSeparator(columnWidths);\n const rowSeparator = ASCIITableUtils.createSeparator(columnWidths, '-');\n let tableString = headerSeparator + '\\n';\n\n const header = this.renderRow(this.headers, columnWidths);\n tableString += header + '\\n' + rowSeparator + '\\n';\n\n const rows = this.rows.map((row) => {\n return this.renderRow(row, columnWidths);\n });\n\n tableString += rows.join('\\n' + rowSeparator + '\\n');\n tableString += '\\n' + headerSeparator;\n\n return tableString;\n }\n\n public calculateColumnWidths(\n options: MultiColumnASCIITableOptions = {},\n ): number[] {\n const tableWidth = options.tableWidth || this.tableWidth;\n const widthMode = options.widthMode || this.widthMode;\n\n const numColumns = this.headers.length;\n\n if (widthMode === 'fixed') {\n const availableWidth = tableWidth - (numColumns + 1) * 3 + 1;\n const columnWidth = Math.floor(availableWidth / numColumns);\n const extraWidth = availableWidth % numColumns;\n const columnWidths = new Array(numColumns).fill(columnWidth);\n\n // if there is any remaining width (extraWidth), we distribute it evenly among the columns starting from the first column.\n for (let i = 0; i < extraWidth; i++) {\n columnWidths[i] += 1;\n }\n\n return columnWidths as number[];\n }\n\n const availableWidth = tableWidth - (numColumns + 1) * 3 + 1;\n const maxColumnWidth = Math.floor(availableWidth / numColumns);\n const totalContentWidth = this.headers.reduce(\n (sum, header) => sum + stringWidth(header),\n 0,\n );\n\n if (availableWidth >= totalContentWidth) {\n const remainingWidth = availableWidth - totalContentWidth;\n const extraCharWidth = Math.floor(remainingWidth / numColumns);\n const extraCharRemainder = remainingWidth % numColumns;\n\n const columnWidths = this.headers.map((header, index) => {\n const extraWidth = index < extraCharRemainder ? 1 : 0;\n return stringWidth(header) + extraCharWidth + extraWidth;\n });\n\n return columnWidths;\n } else {\n const columnWidths = this.headers.map(() => maxColumnWidth);\n\n return columnWidths;\n }\n }\n\n private renderRow(row: string[], columnWidths: number[]): string {\n const wrappedCells = row.map((value, index) => {\n const wrappedLines = ASCIITableUtils.wrapText(value, columnWidths[index]);\n\n return wrappedLines\n .map((line) => line.padEnd(columnWidths[index]))\n .join('\\n');\n });\n\n const maxLines = Math.max(\n ...wrappedCells.map((cell) => cell.split('\\n').length),\n );\n\n const paddedRows = [];\n\n for (let i = 0; i < maxLines; i++) {\n const rowLine = wrappedCells.map((cell, index) => {\n const cellLines = cell.split('\\n');\n const cellLine = cellLines[i] || '';\n const padding = ' '.repeat(columnWidths[index] - stringWidth(cellLine));\n\n return ' ' + cellLine + padding + ' ';\n });\n\n paddedRows.push('|' + rowLine.join('|') + '|');\n }\n\n return paddedRows.join('\\n');\n }\n}\n","import { isString } from '../strings';\nimport { padRight } from '../padding-utils';\nimport { MultiColumnASCIITable } from './multi-column-ascii-table';\nimport { ASCIITableUtils } from './ascii-table-utils';\nimport stringWidth from 'string-width';\nimport { clamp } from '../clamp';\n\nexport type TableRowValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | KeyValueASCIITable\n | MultiColumnASCIITable\n | NestedKeyValueEntry[];\n\ntype TableRow = TableRowRegular | TableRowOwn;\n\ninterface TableRowRegular {\n kind: 'regular';\n key: string;\n value: TableRowValue;\n}\n\ninterface TableRowOwn {\n kind: 'own';\n key: string;\n value: string | NestedKeyValueEntry[];\n}\n\nexport interface NestedKeyValueEntry {\n key: string;\n value: string | KeyValueASCIITable | NestedKeyValueEntry[];\n}\n\ninterface KeyValueASCIITableOptions {\n tableWidth?: number;\n autoAdjustWidthWhenPossible?: boolean;\n emptyMessage?: string;\n}\n\nexport class KeyValueASCIITable {\n public readonly tableWidth: number;\n private emptyMessage: string;\n private autoAdjustWidthWhenPossible: boolean = true;\n\n private rows: TableRow[] = [];\n\n constructor(options: KeyValueASCIITableOptions = {}) {\n const minTableWidth = this.getMinimumWidth();\n\n if (options.tableWidth && options.tableWidth < minTableWidth) {\n throw new Error(\n `Table width must be at least ${minTableWidth} to accommodate the table structure.`,\n );\n }\n\n this.tableWidth = options.tableWidth || 80;\n this.autoAdjustWidthWhenPossible =\n options.autoAdjustWidthWhenPossible ?? true;\n this.emptyMessage = options.emptyMessage || '';\n }\n\n public getMinimumWidth(): number {\n // The minimum width for the KeyValueASCIITable is 9 characters:\n // - 2 character for the '| ' at the start\n // - 1 character for the minimum key column width\n // - 3 character for the ' | ' separating the key and value columns\n // - 1 character for the minimum value column width\n // - 2 character for the ' |' at the end\n\n return 9;\n }\n\n /**\n * Adds key and value to the table but placing the value on its own row.\n *\n * @param key\n * @param value\n */\n\n public addValueOnSeparateRow(key: string, value: string): void {\n const row: TableRow = { kind: 'own', key, value };\n\n this.rows.push(row);\n }\n\n /**\n * Adds key and value to the table.\n *\n * If provided value is an instance of ASCIITable or MultiColumnASCIITable, it will be rendered as a nested table on its own row for readability.\n *\n * @param key\n * @param value\n */\n\n public addRow(key: string, value: TableRowValue): void {\n const row: TableRow = { kind: 'regular', key, value };\n\n this.rows.push(row);\n }\n\n public toString(options: KeyValueASCIITableOptions = {}): string {\n const tableWidth = options.tableWidth || this.tableWidth;\n const canAutoAdjustWidthWhenPossible =\n options.autoAdjustWidthWhenPossible ?? this.autoAdjustWidthWhenPossible;\n\n const emptyMessage = options.emptyMessage || this.emptyMessage;\n\n if (this.rows.length === 0) {\n const emptyTableWidth = Math.min(tableWidth, 40);\n\n const separator = '+' + '-'.repeat(emptyTableWidth - 2) + '+';\n const emptyMessageLines = ASCIITableUtils.wrapText(\n emptyMessage,\n emptyTableWidth - 4,\n );\n\n const emptyRows = emptyMessageLines.map((line) => {\n const paddingLeft = padRight(\n '',\n Math.floor((emptyTableWidth - stringWidth(line) - 4) / 2),\n ' ',\n );\n\n const paddingRight = padRight(\n '',\n Math.ceil((emptyTableWidth - stringWidth(line) - 4) / 2),\n ' ',\n );\n\n return `| ${paddingLeft}${line}${paddingRight} |`;\n });\n\n if (emptyRows.length === 0) {\n emptyRows.push(`| ${' '.repeat(emptyTableWidth - 4)} |`);\n }\n\n return [separator, ...emptyRows, separator].join('\\n');\n }\n\n const columnWidths = this.calculateColumnWidths(options);\n\n const headerSeparator = ASCIITableUtils.createSeparator(columnWidths);\n const rowSeparator = ASCIITableUtils.createSeparator(columnWidths, '-');\n\n let tableString = headerSeparator + '\\n';\n\n for (const [rowIndex, row] of this.rows.entries()) {\n const { kind, key, value } = row;\n\n if (\n kind === 'own' ||\n value instanceof KeyValueASCIITable ||\n value instanceof MultiColumnASCIITable ||\n Array.isArray(value)\n ) {\n const keyString = ASCIITableUtils.centerText(\n key,\n columnWidths[0] + columnWidths[1] + 3,\n );\n\n tableString += `| ${keyString} |\\n`;\n tableString += rowSeparator + '\\n';\n\n let valueString = '';\n\n if (value instanceof KeyValueASCIITable) {\n valueString = this.formatValue(\n value,\n tableWidth - 4,\n canAutoAdjustWidthWhenPossible,\n '',\n );\n } else if (value instanceof MultiColumnASCIITable) {\n valueString = this.formatValue(\n value,\n tableWidth - 4,\n canAutoAdjustWidthWhenPossible,\n '',\n );\n } else if (Array.isArray(value)) {\n valueString = this.formatValue(\n value,\n tableWidth - 4,\n canAutoAdjustWidthWhenPossible,\n '',\n );\n } else if (row.kind === 'own') {\n valueString = this.formatTableRowOnOwnRow(\n value as string,\n tableWidth - 4,\n tableWidth,\n );\n }\n\n const valueLines = valueString.split('\\n');\n const paddedValueLines = valueLines.map((line) => {\n const padding = padRight('', tableWidth - stringWidth(line) - 4, ' ');\n\n return `| ${line}${padding} |`;\n });\n\n tableString += paddedValueLines.join('\\n') + '\\n';\n tableString += headerSeparator + '\\n';\n } else {\n const keyLines = ASCIITableUtils.wrapText(key, columnWidths[0]);\n\n const valueLines = ASCIITableUtils.wrapText(\n this.formatValue(\n value,\n columnWidths[1],\n canAutoAdjustWidthWhenPossible,\n '',\n ),\n columnWidths[1],\n );\n\n const maxLines = Math.max(keyLines.length, valueLines.length);\n\n for (let i = 0; i < maxLines; i++) {\n const keyLine = keyLines[i] || '';\n const valueLine = valueLines[i] || '';\n\n const keyPadding = ' '.repeat(columnWidths[0] - stringWidth(keyLine));\n\n const valuePadding = ' '.repeat(\n columnWidths[1] - stringWidth(valueLine),\n );\n\n tableString += `| ${keyLine}${keyPadding} | ${valueLine}${valuePadding} |\\n`;\n\n if (i === maxLines - 1) {\n if (rowIndex === this.rows.length - 1) {\n tableString += headerSeparator + '\\n';\n } else {\n tableString += rowSeparator + '\\n';\n }\n }\n }\n }\n }\n\n return tableString.trim();\n }\n\n private calculateColumnWidths(\n options: KeyValueASCIITableOptions = {},\n ): number[] {\n const tableWidth = options.tableWidth || this.tableWidth;\n const canAutoAdjustWidthWhenPossible =\n options.autoAdjustWidthWhenPossible ?? this.autoAdjustWidthWhenPossible;\n\n const columnWidths: number[] = [0, 0];\n\n for (const row of this.rows) {\n const { key, value } = row;\n\n const keyWidth = stringWidth(key);\n const maxKeyWidth = Math.floor((tableWidth - 7) / 2);\n\n if (keyWidth > columnWidths[0]) {\n columnWidths[0] = Math.min(keyWidth, maxKeyWidth);\n columnWidths[1] = Math.max(0, tableWidth - columnWidths[0] - 7);\n }\n\n if (typeof value === 'string') {\n const valueWidth = Math.max(\n ...value.split('\\n').map((line) => stringWidth(line)),\n );\n\n if (valueWidth > columnWidths[1]) {\n columnWidths[1] = Math.min(\n valueWidth,\n tableWidth - columnWidths[0] - 7,\n );\n\n columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);\n }\n } else if (row.kind === 'own') {\n let valueWidth = 0;\n\n if (isString(value)) {\n valueWidth = Math.max(\n ...value.split('\\n').map((line) => stringWidth(line)),\n );\n }\n\n if (valueWidth > columnWidths[1]) {\n columnWidths[1] = Math.min(\n valueWidth,\n tableWidth - columnWidths[0] - 7,\n );\n\n columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);\n }\n } else if (value instanceof KeyValueASCIITable) {\n // Update column widths based on the nested table\n let nestedTableColumnWidths: number[] = [];\n\n if (canAutoAdjustWidthWhenPossible) {\n const minWidth = value.getMinimumWidth();\n\n const availableWidth = tableWidth - columnWidths[0] - 7;\n const adjustedWidth = clamp(availableWidth, minWidth, availableWidth);\n\n nestedTableColumnWidths = value.calculateColumnWidths({\n tableWidth: adjustedWidth,\n });\n } else {\n nestedTableColumnWidths = value.calculateColumnWidths();\n }\n\n const nestedTableWidth =\n nestedTableColumnWidths.reduce((sum, width) => sum + width, 0) +\n nestedTableColumnWidths.length * 3 -\n 1;\n\n const availableWidth = tableWidth - columnWidths[0] - 7;\n\n if (nestedTableWidth > availableWidth) {\n columnWidths[1] = availableWidth;\n } else {\n columnWidths[1] = Math.max(columnWidths[1], nestedTableWidth);\n }\n } else if (value instanceof MultiColumnASCIITable) {\n // Update column widths based on the nested multi-column table\n let nestedTableColumnWidths: number[] = [];\n\n if (canAutoAdjustWidthWhenPossible) {\n const minWidth = value.getMinimumWidth();\n\n const availableWidth = tableWidth - columnWidths[0] - 7;\n const adjustedWidth = clamp(availableWidth, minWidth, availableWidth);\n\n nestedTableColumnWidths = value.calculateColumnWidths({\n tableWidth: adjustedWidth,\n });\n } else {\n nestedTableColumnWidths = value.calculateColumnWidths();\n }\n\n const nestedTableWidth =\n nestedTableColumnWidths.reduce((sum, width) => sum + width, 0) +\n nestedTableColumnWidths.length * 3 -\n 1;\n\n const availableWidth = tableWidth - columnWidths[0] - 7;\n\n if (nestedTableWidth > availableWidth) {\n columnWidths[1] = availableWidth;\n } else {\n columnWidths[1] = Math.max(columnWidths[1], nestedTableWidth);\n }\n } else if (Array.isArray(value)) {\n for (const nestedCell of value) {\n const nestedKeyWidth = stringWidth(nestedCell.key);\n const maxNestedKeyWidth = Math.floor((tableWidth - 7) / 2);\n\n if (nestedKeyWidth > columnWidths[0]) {\n columnWidths[0] = Math.min(nestedKeyWidth, maxNestedKeyWidth);\n columnWidths[1] = Math.max(0, tableWidth - columnWidths[0] - 7);\n }\n\n if (typeof nestedCell.value === 'string') {\n const nestedValueWidth = Math.max(\n ...nestedCell.value.split('\\n').map((line) => stringWidth(line)),\n );\n\n if (nestedValueWidth > columnWidths[1]) {\n columnWidths[1] = Math.min(\n nestedValueWidth,\n tableWidth - columnWidths[0] - 7,\n );\n columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);\n }\n }\n }\n }\n }\n\n return columnWidths;\n }\n\n private formatValue(\n value:\n | string\n | number\n | boolean\n | null\n | undefined\n | KeyValueASCIITable\n | MultiColumnASCIITable\n | NestedKeyValueEntry[],\n cellWidth: number,\n canAutoAdjustWidthWhenPossible: boolean,\n indent = '',\n ): string {\n if (typeof value === 'string') {\n return value;\n } else if (typeof value === 'number') {\n return String(value);\n } else if (typeof value === 'boolean') {\n return String(value);\n } else if (value === null) {\n return 'null';\n } else if (value === undefined) {\n return 'undefined';\n } else if (value instanceof KeyValueASCIITable) {\n let nestedTableLines: string[];\n\n if (canAutoAdjustWidthWhenPossible) {\n const minWidth = value.getMinimumWidth();\n\n const adjustedWidth = clamp(cellWidth, minWidth, cellWidth);\n\n nestedTableLines = value\n .toString({ tableWidth: adjustedWidth })\n .split('\\n');\n } else {\n nestedTableLines = value.toString().split('\\n');\n }\n\n const indentedLines = nestedTableLines.map((line) => `${indent}${line}`);\n\n return indentedLines.join('\\n');\n } else if (value instanceof MultiColumnASCIITable) {\n let nestedTableLines: string[];\n\n if (canAutoAdjustWidthWhenPossible) {\n const minWidth = value.getMinimumWidth();\n\n const adjustedWidth = clamp(cellWidth, minWidth, cellWidth);\n nestedTableLines = value\n .toString({ tableWidth: adjustedWidth })\n .split('\\n');\n } else {\n nestedTableLines = value.toString().split('\\n');\n }\n\n const indentedLines = nestedTableLines.map((line) => `${indent}${line}`);\n\n return indentedLines.join('\\n');\n } else if (Array.isArray(value)) {\n const nestedValueLines: string[] = [];\n\n for (const { key, value: nestedValue } of value) {\n const formattedKey = `${indent}${key}:`;\n const formattedValue = this.formatValue(\n nestedValue,\n cellWidth - indent.length - stringWidth(key) - 2,\n canAutoAdjustWidthWhenPossible,\n `${indent}`,\n );\n\n const wrappedSpacer = padRight('', 4, ' ');\n\n const wrappedValue = formattedValue\n .split('\\n')\n .map((line) => `${indent}${wrappedSpacer}${line}`);\n\n nestedValueLines.push(formattedKey);\n nestedValueLines.push(...wrappedValue);\n nestedValueLines.push('');\n }\n\n return nestedValueLines.slice(0, -1).join('\\n');\n } else {\n throw new TypeError('Invalid value type provided');\n }\n }\n\n private formatTableRowOnOwnRow(\n value: string,\n width: number,\n maxRowLength: number,\n ): string {\n const lines = value.split('\\n');\n\n const paddedLines = lines.map((line) => {\n const wrappedLines = ASCIITableUtils.wrapText(line, maxRowLength - 4);\n\n return wrappedLines\n .map((wrappedLine) => {\n const padding = padRight(\n '',\n width - stringWidth(wrappedLine) - 2,\n ' ',\n );\n\n return `${wrappedLine}${padding}`;\n })\n .join('\\n');\n });\n\n return paddedLines.join('\\n');\n }\n}\n","export function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(value, max));\n}\n\n/**\n * Clamps a value to a minimum, returning a default if the value is not finite or is undefined/null.\n *\n * Useful for config/settings validation where you want to:\n * - Enforce a minimum value\n * - Handle invalid inputs (Infinity, NaN, undefined, null) gracefully\n *\n * @param value - The value to clamp (can be undefined or null)\n * @param min - The minimum allowed value\n * @param defaultValue - The default to return if value is not finite or is undefined/null\n * @returns The clamped value, or defaultValue if value is not finite/undefined/null\n *\n * @example\n * ```typescript\n * finiteClampMin(5000, 1000, 3000) // 5000 (value > min)\n * finiteClampMin(500, 1000, 3000) // 1000 (enforces min)\n * finiteClampMin(Infinity, 1000, 3000) // 3000 (not finite, use default)\n * finiteClampMin(NaN, 1000, 3000) // 3000 (not finite, use default)\n * finiteClampMin(undefined, 1000, 3000) // 3000 (undefined, use default)\n * finiteClampMin(null, 1000, 3000) // 3000 (null, use default)\n * ```\n */\nexport function finiteClampMin(\n value: number | undefined | null,\n min: number,\n defaultValue: number,\n): number {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return defaultValue;\n }\n\n return Math.max(value, min);\n}\n","import type { NestedKeyValueEntry } from './ascii-tables/key-value-ascii-table';\nimport { KeyValueASCIITable } from './ascii-tables/key-value-ascii-table';\n\nfunction safeStringify(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value);\n }\n\n switch (typeof value) {\n case 'string':\n return value;\n case 'number':\n case 'boolean':\n case 'bigint':\n return String(value);\n case 'object':\n return JSON.stringify(value);\n case 'function':\n return '[Function]';\n case 'symbol':\n return value.toString();\n default: {\n // This should never happen, but satisfy the linter\n const fallback = value as string | number | boolean;\n return String(fallback);\n }\n }\n}\n\nexport function errorToString(error: unknown, maxRowLength = 80): string {\n const table = errorToASCIITable(error, maxRowLength);\n\n return table.toString();\n}\n\nfunction errorToASCIITable(\n error: unknown,\n maxRowLength: number,\n): KeyValueASCIITable {\n const table = new KeyValueASCIITable({\n tableWidth: maxRowLength,\n autoAdjustWidthWhenPossible: true,\n });\n\n if (error && typeof error === 'object') {\n const err = error as Record<string, unknown>;\n table.addRow('Key', 'Value');\n\n if (err['message']) {\n table.addRow('Message', safeStringify(err['message']));\n }\n\n if (err['name']) {\n table.addRow('Name', safeStringify(err['name']));\n }\n\n if (err['code']) {\n table.addRow('Code', safeStringify(err['code']));\n }\n\n if (err['errno']) {\n table.addRow('Errno', safeStringify(err['errno']));\n }\n\n // other conventional that might be used to enhance the error object\n if (err['errPrefix']) {\n table.addRow('Prefix', safeStringify(err['errPrefix']));\n }\n\n if (err['errType']) {\n table.addRow('errType', safeStringify(err['errType']));\n }\n\n if (err['errCode']) {\n table.addRow('errCode', safeStringify(err['errCode']));\n }\n\n if (err['additionalInfo']) {\n const additionalInfo = err['additionalInfo'] as Record<string, unknown>;\n const sensitiveFieldNames =\n (err['sensitiveFieldNames'] as string[]) || [];\n\n for (const key in additionalInfo) {\n if (sensitiveFieldNames.includes(key)) {\n table.addRow(`AdditionalInfo.${key}`, '***');\n } else {\n const value = additionalInfo[key];\n\n table.addRow(\n `AdditionalInfo.${key}`,\n stringifyValue(value, table, maxRowLength),\n );\n }\n }\n }\n\n if (err['stack']) {\n table.addValueOnSeparateRow('Stack', safeStringify(err['stack']));\n }\n }\n\n return table;\n}\n\nfunction stringifyValue(\n value: unknown,\n table: KeyValueASCIITable,\n maxRowLength: number,\n): string | KeyValueASCIITable | NestedKeyValueEntry[] {\n if (typeof value === 'string') {\n return value;\n } else if (Array.isArray(value)) {\n // Handle arrays differently\n return value\n .map((item) => {\n const result = stringifyValue(item, table, maxRowLength);\n // Convert complex types to strings for joining\n if (typeof result === 'string') {\n return result;\n } else if (result instanceof KeyValueASCIITable) {\n return result.toString();\n } else {\n return JSON.stringify(result);\n }\n })\n .join(', ');\n } else if (typeof value === 'object' && value !== null) {\n if (value instanceof Error) {\n return errorToASCIITable(value, maxRowLength - 4);\n } else {\n // Handle objects differently\n const entries: NestedKeyValueEntry[] = Object.entries(value).map(\n ([key, val]) => ({\n key,\n value: stringifyValue(val, table, maxRowLength - 4),\n }),\n );\n\n return entries;\n }\n } else {\n return String(value);\n }\n}\n","// Helper from https://github.com/then/is-promise/tree/master\n// For some reason the @types/is-promise package stopped being picked up on\n\nexport function isPromise(obj: unknown): obj is Promise<unknown> {\n return (\n !!obj &&\n (typeof obj === 'object' || typeof obj === 'function') &&\n // @ts-expect-error - obj is checked to be object/function, then property access works at runtime\n typeof obj['then'] === 'function'\n );\n}\n","export function isFunction(value: unknown): boolean {\n return typeof value === 'function' || value instanceof Function;\n}\n","import { errorToString } from './error-to-string';\nimport { isPromise } from './is-promise';\nimport { isFunction } from './is-function';\nimport { DOUBLE_EOL } from './constants';\n\n/**\n * Safely handles a callback function by catching any errors and reporting them\n * using the global `reportError` event (supported in Node.js 25+, Bun, Deno, and browsers).\n * This function can seamlessly handle both synchronous and asynchronous (Promise-based) callback functions.\n *\n * Errors are dispatched as ErrorEvent objects with type 'reportError' via `globalThis.dispatchEvent()`.\n * You can listen for these errors using `globalThis.addEventListener('reportError', handler)`.\n *\n * This function is a \"fire-and-forget\" type of function, meaning it doesn't wait\n * for the callback to complete and doesn't return any result or error. If you need\n * to handle the result or error of the callback, consider using the\n * `safeHandleCallbackAndWait` function instead.\n *\n * @param {string} callbackName - The name of the callback function, used for error reporting.\n * @param {unknown} callback - The callback function to be executed. It can be either a\n * synchronous function or a function that returns a Promise.\n * @param {...unknown[]} args - Additional arguments to pass to the callback function.\n */\n\nexport function safeHandleCallback(\n callbackName: string,\n callback: unknown,\n ...args: unknown[]\n): void {\n const handleError = (error: Error): void => {\n // Dispatch error using the standard reportError event API\n // Supported in Node.js 25+, Bun, Deno, and browsers\n if (\n typeof (globalThis as Record<string, unknown>).dispatchEvent ===\n 'function'\n ) {\n (\n globalThis as unknown as {\n dispatchEvent: (event: Event) => void;\n }\n ).dispatchEvent(\n new ErrorEvent('reportError', {\n error: new Error(\n `Error in a callback ${callbackName}: ${DOUBLE_EOL}${errorToString(error)}`,\n ),\n }),\n );\n }\n };\n\n if (isFunction(callback)) {\n try {\n // We need to cast callback to the appropriate function type now\n const result = (callback as (...args: unknown[]) => unknown)(...args);\n\n if (isPromise(result)) {\n // Fire-and-forget async callback\n result.catch((error: unknown) => {\n handleError(error as Error);\n });\n }\n } catch (error) {\n handleError(error as Error);\n }\n } else {\n handleError(\n new Error(`Callback provided for ${callbackName} is not a function`),\n );\n }\n}\n\ninterface CallbackResult<T> {\n success: boolean;\n value?: T;\n error?: Error;\n}\n\n/**\n * Safely handles a callback function by catching any errors and reporting them\n * using the global `reportError` event (supported in Node.js 25+, Bun, Deno, and browsers).\n * This function can seamlessly handle both synchronous and asynchronous (Promise-based) callback\n * functions, and it waits for the callback to complete before returning the result or an error.\n *\n * Errors are dispatched as ErrorEvent objects with type 'reportError' via `globalThis.dispatchEvent()`.\n * You can listen for these errors using `globalThis.addEventListener('reportError', handler)`.\n *\n * @param {string} callbackName - The name of the callback function, used for error reporting.\n * @param {unknown} callback - The callback function to be executed. It can be either a\n * synchronous function or a function that returns a Promise.\n * @param {...unknown[]} args - Additional arguments to pass to the callback function.\n * @returns {Promise<CallbackResult<unknown>>} - A promise that resolves with an object containing\n * the success status, value (if any), and error (if any).\n */\n\nexport async function safeHandleCallbackAndWait<T>(\n callbackName: string,\n callback: unknown,\n ...args: unknown[]\n): Promise<CallbackResult<T>> {\n const handleError = (error: Error): CallbackResult<T> => {\n // Dispatch error using the standard reportError event API\n // Supported in Node.js 25+, Bun, Deno, and browsers\n if (\n typeof (globalThis as Record<string, unknown>).dispatchEvent ===\n 'function'\n ) {\n (\n globalThis as unknown as {\n dispatchEvent: (event: Event) => void;\n }\n ).dispatchEvent(\n new ErrorEvent('reportError', {\n error: new Error(\n `Error in a callback ${callbackName}: ${DOUBLE_EOL}${errorToString(error)}`,\n ),\n }),\n );\n }\n\n return { success: false, error };\n };\n\n if (isFunction(callback)) {\n try {\n // We need to cast callback to the appropriate function type now\n const result = (callback as (...args: unknown[]) => unknown)(...args);\n\n if (isPromise(result)) {\n // Wait for the async callback to complete\n const value = await (result as Promise<T>);\n\n return { success: true, value };\n } else {\n return { success: true, value: result as T };\n }\n } catch (error) {\n return handleError(error as Error);\n }\n } else {\n return handleError(\n new Error(`Callback provided for ${callbackName} is not a function`),\n );\n }\n}\n","import { safeHandleCallback } from './safe-handle-callback';\n\n/**\n * Instead of using `SingleEventObserver`, you could extend `SingleEventObserverProtected`\n * if you want the notify method to be protected, and allow only your class to emit events.\n *\n * A base class for implementing the observer pattern with protected notify method.\n * This class allows subscription to a single type of event and notifies all subscribers\n * when the event occurs.\n *\n * @template T The type of data that will be passed to subscribers when notifying.\n */\n\nexport class SingleEventObserverProtected<T> {\n /**\n * Set of subscriber functions.\n */\n\n private subscribers = new Set<(data: T) => void | Promise<void>>();\n\n /**\n * Subscribes a function to the observer.\n * @param fn The function to be subscribed.\n */\n\n public subscribe(fn: (data: T) => void | Promise<void>): void {\n this.subscribers.add(fn);\n }\n\n /**\n * Unsubscribes a function from the observer.\n * @param fn The function to be unsubscribed.\n */\n\n public unsubscribe(fn: (data: T) => void | Promise<void>): void {\n this.subscribers.delete(fn);\n }\n\n /**\n * Checks if a specific function is subscribed to the observer.\n * @param fn The function to check.\n * @returns A boolean indicating if the function is subscribed.\n */\n\n public hasSubscriber(fn: (data: T) => void | Promise<void>): boolean {\n return this.subscribers.has(fn);\n }\n\n /**\n * Notifies all subscribers with the given data.\n * This method is protected to allow only derived classes to trigger notifications.\n * @param data The data to pass to all subscribers.\n */\n\n protected notify(data: T): void {\n for (const subscriber of this.subscribers) {\n safeHandleCallback(\n `SingleEventObserver_${(subscriber as EventListener).name || 'anonymous'}`,\n subscriber,\n data,\n );\n }\n }\n}\n\n/**\n * A class that implements the observer pattern with public notify method.\n * This class extends SingleEventObserverProtected and makes the notify method public.\n *\n * @template T The type of data that will be passed to subscribers when notifying.\n */\n\nexport class SingleEventObserver<T> extends SingleEventObserverProtected<T> {\n /**\n * Notifies all subscribers with the given data.\n * This method is public, allowing any code with access to the observer to trigger notifications.\n * @param data The data to pass to all subscribers.\n */\n\n public notify(data: T): void {\n super.notify(data);\n }\n}\n"],"mappings":"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","names":["stringWidth","availableWidth","stringWidth","stringWidth","availableWidth"]}
1
+ {"version":3,"sources":["../../src/lib/strings.ts","../../src/lib/constants.ts","../../src/lib/padding-utils.ts","../../src/lib/ascii-tables/ascii-table-utils.ts","../../src/lib/ascii-tables/multi-column-ascii-table.ts","../../src/lib/ascii-tables/key-value-ascii-table.ts","../../src/lib/clamp.ts","../../src/lib/error-to-string.ts","../../src/lib/is-promise.ts","../../src/lib/is-function.ts","../../src/lib/global-event-target.ts","../../src/lib/safe-handle-callback.ts","../../src/lib/single-event-observer.ts"],"sourcesContent":["import { removeEmptyStringsFromArray } from './arrays';\n\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/**\n * Converts a string or an array of strings to Pascal Case.\n *\n * This function takes an input string or an array of strings, each potentially containing hyphens,\n * and converts them to Pascal Case. It removes any characters that are not letters or numbers,\n * capitalizes the first letter of each substring, and ensures the rest of the substring\n * is in lowercase. Finally, it concatenates all these substrings to produce a Pascal Case\n * output.\n *\n * @param {string | string[]} input - The input string or array of strings to be converted to Pascal Case.\n * @returns {string} The converted string in Pascal Case.\n *\n * Examples:\n * toPascalCase(\"hello-world-123!$\") will return \"HelloWorld123\"\n * toPascalCase([\"hello\", \"world-123!$\"]) will return \"HelloWorld123\"\n */\n\nexport function toPascalCase(input: string | string[]): string {\n // Ensure input is an array\n const inputArray = Array.isArray(input) ? input : [input];\n\n // Process each string in the array\n const parts: string[] = [];\n\n for (const item of inputArray) {\n // Clean the string, split by hyphen, and remove empty strings\n const cleanedItem = item.replace(/[^a-zA-Z0-9-]/g, '');\n parts.push(...removeEmptyStringsFromArray(cleanedItem.split('-')));\n }\n\n // Process and rejoin the input strings\n return parts\n .map(\n (subString) =>\n subString.charAt(0).toUpperCase() + subString.slice(1).toLowerCase(),\n )\n .join('');\n}\n\n/**\n * Converts a string or an array of strings to Camel Case.\n *\n * This function takes an input string or an array of strings, each potentially containing hyphens,\n * and converts them to Camel Case. It removes any characters that are not letters or numbers,\n * capitalizes the first letter of each substring after the first one, and ensures the rest of the substring\n * is in lowercase. For the first substring, it ensures the entire substring is in lowercase.\n * Finally, it concatenates all these substrings to produce a Camel Case output.\n *\n * @param {string | string[]} input - The input string or array of strings to be converted to Camel Case.\n * @returns {string} The converted string in Camel Case.\n *\n * Examples:\n * toCamelCase(\"hello-world-123!$\") will return \"helloWorld123\"\n * toCamelCase([\"hello\", \"world-123!$\"]) will return \"helloWorld123\"\n */\n\nexport function toCamelCase(input: string | string[]): string {\n // Ensure input is an array\n const inputArray = Array.isArray(input) ? input : [input];\n\n // Process each string in the array\n const parts: string[] = [];\n\n for (const item of inputArray) {\n // Clean the string, split by hyphen, and remove empty strings\n const cleanedItem = item.replace(/[^a-zA-Z0-9-]/g, '');\n parts.push(...removeEmptyStringsFromArray(cleanedItem.split('-')));\n }\n\n // Process and rejoin the input strings\n return parts\n .map((subString, index) =>\n index === 0\n ? subString.toLowerCase()\n : subString.charAt(0).toUpperCase() + subString.slice(1).toLowerCase(),\n )\n .join('');\n}\n\n/**\n * This method converts a string or an array of strings to camel case,\n * but if starting with a leading hyphen, it will convert to Pascal case.\n */\n\nexport function toCamelCaseWithPascalOverride(\n input: string | string[],\n): string {\n if (isString(input) && input.startsWith('-')) {\n return toPascalCase(input);\n } else if (\n Array.isArray(input) &&\n input.length > 0 &&\n input[0].startsWith('-')\n ) {\n return toPascalCase(input);\n } else {\n return toCamelCase(input);\n }\n}\n\n/**\n * Converts a string or an array of strings to constant case.\n *\n * The function takes a string or an array of strings, where each string can be separated by a '-',\n * and converts them into a constant case format (all uppercase with underscores between words).\n * It first cleans the input by removing non-alphanumeric characters (except for hyphens), splits the\n * string into parts on hyphens, and then joins these parts with underscores, converting the entire\n * result to uppercase.\n *\n * @param {string | string[]} input - The input string or array of strings to be converted.\n * @returns {string} The converted string in constant case.\n *\n * Example:\n * toConstantCase(\"hello-world\") will return \"HELLO_WORLD\"\n * toConstantCase([\"hello\", \"world\"]) will return \"HELLO_WORLD\"\n */\n\nexport function toConstantCase(input: string | string[]): string {\n // Ensure input is an array\n const inputArray = Array.isArray(input) ? input : [input];\n\n // Process each string in the array\n let parts: string[] = [];\n\n for (const item of inputArray) {\n // Clean the string and split by hyphen\n const cleanedItem = item.replace(/[^a-zA-Z0-9-]/g, '');\n parts.push(...cleanedItem.split('-'));\n }\n\n // Remove empty strings from the array\n parts = removeEmptyStringsFromArray(parts);\n\n // Join parts with underscore and convert to uppercase\n return parts.join('_').toUpperCase();\n}\n\nexport function splitGraphemes(text: string): string[] {\n const graphemes: string[] = [];\n let grapheme = '';\n let zwjSequence = '';\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n const nextChar = text[i + 1] || '';\n const code = char.charCodeAt(0);\n\n // Handling combining marks and zero width joiner\n if (\n (code >= 0x0300 && code <= 0x036f) || // Combining Diacritical Marks\n (code >= 0x1ab0 && code <= 0x1aff) || // Combining Diacritical Marks Extended\n (code >= 0x1dc0 && code <= 0x1dff) || // Combining Diacritical Marks Supplement\n (code >= 0xfe20 && code <= 0xfe2f) || // Combining Half Marks\n (code >= 0x0e31 && code <= 0x0e3a) || // Thai combining marks\n (code >= 0x0e47 && code <= 0x0e4e)\n ) {\n // Thai combining marks\n grapheme += char;\n } else if (char === '\\u200d') {\n // Zero Width Joiner (ZWJ)\n zwjSequence += grapheme + char;\n grapheme = '';\n } else {\n if (grapheme) {\n if (zwjSequence) {\n graphemes.push(zwjSequence + grapheme);\n zwjSequence = '';\n } else {\n graphemes.push(grapheme);\n }\n }\n grapheme = char;\n\n // Handle surrogate pairs (needed for certain characters including emojis)\n if (\n char >= '\\ud800' &&\n char <= '\\udbff' &&\n nextChar >= '\\udc00' &&\n nextChar <= '\\udfff'\n ) {\n grapheme += nextChar;\n i++;\n }\n }\n }\n\n if (grapheme) {\n if (zwjSequence) {\n graphemes.push(zwjSequence + grapheme);\n } else {\n graphemes.push(grapheme);\n }\n }\n\n return graphemes;\n}\n\nexport function skipTrailingNewLines(str: string): string {\n return str.replace(/\\n+$/, '');\n}\n\n/**\n * Filters a string to include only specified characters, optionally replacing disallowed characters.\n *\n * @param str - The input string to be filtered.\n * @param list - An array of allowed characters.\n * @param caseInsensitive - Optional. If true, the filtering is case-insensitive. Default is false.\n * @param replacementChar - Optional. Character to replace disallowed characters. If empty, disallowed characters are removed. Default is ''.\n * @returns A new string containing only the allowed characters from the input string, with disallowed characters optionally replaced.\n *\n * @example\n * // Case-sensitive usage, removing disallowed characters\n * characterAllowedOnly(\"Hello123!\", [\"H\", \"e\", \"l\", \"o\"]);\n * // Returns: \"Hello\"\n *\n * @example\n * // Case-insensitive usage, removing disallowed characters\n * characterAllowedOnly(\"Hello123!\", [\"h\", \"E\", \"L\", \"O\"], true);\n * // Returns: \"Hello\"\n *\n * @example\n * // Using replacement character\n * characterAllowedOnly(\"Hello123!\", [\"H\", \"e\", \"l\", \"o\"], false, \"-\");\n * // Returns: \"Hello---\"\n */\n\nexport function characterAllowedOnly(\n str: string,\n list: string[],\n // eslint-disable-next-line @typescript-eslint/naming-convention\n caseInsensitive = false,\n replacementChar = '',\n): string {\n let newStr = '';\n\n // Convert the allowed list to lowercase if case-insensitive\n if (caseInsensitive) {\n list = Array.from(new Set(list.map((item) => item.toLowerCase())));\n }\n\n // Convert the entire input string to lowercase if case-insensitive\n const processedStr = caseInsensitive ? str.toLowerCase() : str;\n\n for (const c of processedStr) {\n if (list.includes(c)) {\n newStr += c;\n } else if (replacementChar !== '') {\n newStr += replacementChar;\n }\n }\n\n return newStr;\n}\n\n// functions to chop characters from a string.\n\n/**\n * Will remove the matching first character from a string\n * @param str\n * @param char\n * @returns\n */\n\nexport function chopBeginningCharacter(str: string, char: string): string {\n if (str.startsWith(char)) {\n return str.slice(1);\n } else {\n return str;\n }\n}\n\n/**\n * Will remove the matching last character from the string\n * @param str\n * @param char\n * @returns\n */\nexport function chopEndingCharacter(str: string, char: string): string {\n if (str.endsWith(char)) {\n return str.slice(0, -1);\n } else {\n return str;\n }\n}\n\n/**\n * Will remove the matching character, from the beginning and/or end of the string if matching\n * @param str\n * @param char\n * @returns\n */\n\nexport function chopBothBeginningAndEndingCharacters(\n str: string,\n char: string,\n): string {\n return chopBeginningCharacter(chopEndingCharacter(str, char), char);\n}\n","// prettier-ignore\nexport const BLANK_SPACE = ' ';\n\nexport const EOL = '\\n';\nexport const DOUBLE_EOL = EOL + EOL;\nexport const INDENT = ' '.repeat(4);\nexport const DOUBLE_INDENT = INDENT + INDENT;\n\n// prettier-ignore\nexport const SINGLE_QUOTE = \"'\";\n\n// similar to Python string library\nexport const ASCII_LOWERCASE = 'abcdefghijklmnopqrstuvwxyz';\nexport const ASCII_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\nexport const ASCII_LETTERS = ASCII_LOWERCASE + ASCII_UPPERCASE;\nexport const DIGITS = '0123456789';\nexport const HEX_DIGITS = DIGITS + 'abcdefABCDEF';\nexport const OCT_DIGITS = '01234567';\nexport const PUNCTUATION = '!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~';\nexport const WHITESPACE = ' \\t\\n\\r\\v\\f';\nexport const PRINTABLE = DIGITS + ASCII_LETTERS + PUNCTUATION + WHITESPACE;\n","/**\n * Utilities to pad strings with another string up to a defined length.\n * Each function takes a string, length to pad and the string to be used for padding (but defaults to a blank space if not provided) and returns the modified string\n *\n * This only pads on the left side, so text is added to the front until the total string equals the given length.\n *\n * ```typescript\n * padLeft('Hey', 6, '*'); // returns ***Hey\n * ```\n * @category String Padding\n */\n\nimport { BLANK_SPACE } from './constants';\n\nexport function padLeft(\n str: string,\n length: number,\n padStr = BLANK_SPACE,\n): string {\n return str.padStart(length, padStr);\n}\n\n/**\n * This only pads on the right side, so text is added to the end until the total string equals the given length.\n *\n * ```typescript\n * padRight('Hey', 6, '*'); // returns Hey***\n * ```\n *\n * @category String Padding\n */\n\nexport function padRight(\n str: string,\n length: number,\n padStr = BLANK_SPACE,\n): string {\n return str.padEnd(length, padStr);\n}\n\n/**\n * Same as `padCenterPreferLeft` and `padCenterPreferRight` but you can pass in a string with `left` or `right` before the padStr to use more direct.\n *\n * Defaults to `left`\n *\n * @category String Padding\n */\n\nexport function padCenter(\n str: string,\n length: number,\n prefer: 'left' | 'right' = 'left',\n padStr = BLANK_SPACE,\n): string {\n const midStrLength = length - str.length;\n\n if (midStrLength > 0) {\n const padLeftAmount =\n prefer === 'left'\n ? Math.ceil(midStrLength / 2)\n : Math.floor(midStrLength / 2);\n\n const padRightAmount =\n prefer === 'left'\n ? Math.floor(midStrLength / 2)\n : Math.ceil(midStrLength / 2);\n\n return (\n padLeft('', padLeftAmount, padStr) +\n str +\n padRight('', padRightAmount, padStr)\n );\n } else {\n return str;\n }\n}\n\n/**\n * It tries to pad equally on both sides in an attempt to center your text. However if it can't the extra character will be added to the left side\n *\n * @category String Padding\n */\n\nexport function padCenterPreferLeft(\n str: string,\n length: number,\n padStr = BLANK_SPACE,\n): string {\n return padCenter(str, length, 'left', padStr);\n}\n\n/**\n * It tries to pad equally, but if it can't the extra character will be added to the right side\n *\n * @category String Padding\n */\n\nexport function padCenterPreferRight(\n str: string,\n length: number,\n padStr = BLANK_SPACE,\n): string {\n return padCenter(str, length, 'right', padStr);\n}\n","import { padCenterPreferRight, padRight } from '../padding-utils';\nimport stringWidth from 'string-width';\nimport { splitGraphemes } from '../strings';\n\nexport class ASCIITableUtils {\n public static centerText(text: string, width: number): string {\n return padCenterPreferRight(text, width, ' ');\n }\n\n public static createSeparator(\n columnWidths: number[],\n character: string = '=',\n ): string {\n const totalWidth =\n columnWidths.reduce((sum, width) => sum + width + 3, 0) - 1;\n\n return `+${padRight('', totalWidth, character)}+`;\n }\n\n public static wrapText(text: string, maxLength: number): string[] {\n const words = text.split(' ');\n const lines: string[] = [];\n let currentLine = '';\n\n for (const word of words) {\n if (stringWidth(currentLine) + stringWidth(word) + 1 <= maxLength) {\n currentLine += (currentLine ? ' ' : '') + word;\n } else {\n if (currentLine) {\n lines.push(currentLine);\n }\n\n if (stringWidth(word) <= maxLength) {\n currentLine = word;\n } else {\n const subWords = ASCIITableUtils.splitWord(word, maxLength);\n lines.push(...subWords.slice(0, -1));\n currentLine = subWords[subWords.length - 1];\n }\n }\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n\n return lines;\n }\n\n public static splitWord(word: string, maxLength: number): string[] {\n const graphemes = splitGraphemes(word);\n const subWords: string[] = [];\n let currentSubWord = '';\n\n for (const grapheme of graphemes) {\n if (stringWidth(currentSubWord + grapheme) <= maxLength) {\n currentSubWord += grapheme;\n } else {\n subWords.push(currentSubWord);\n currentSubWord = grapheme;\n }\n }\n\n if (currentSubWord) {\n subWords.push(currentSubWord);\n }\n\n return subWords;\n }\n}\n","import { ASCIITableUtils } from './ascii-table-utils';\nimport stringWidth from 'string-width';\n\ninterface MultiColumnASCIITableOptions {\n tableWidth?: number;\n emptyMessage?: string;\n widthMode?: 'flex' | 'fixed';\n}\n\nexport class MultiColumnASCIITable {\n private headers: string[];\n private rows: string[][];\n private tableWidth: number;\n private emptyMessage: string;\n private widthMode: 'flex' | 'fixed';\n\n constructor(headers: string[], options: MultiColumnASCIITableOptions = {}) {\n this.headers = headers;\n this.rows = [];\n this.tableWidth = options.tableWidth || 80;\n this.emptyMessage = options.emptyMessage || '';\n this.widthMode = options.widthMode || 'flex';\n\n const minTableWidth = this.getMinimumWidth();\n\n if (this.tableWidth < minTableWidth) {\n throw new Error(\n `Table width must be at least ${minTableWidth} to accommodate the headers.`,\n );\n }\n }\n\n public getMinimumWidth(): number {\n return this.headers.length * 4 + 1;\n }\n\n public addRow(row: string[]): void {\n if (row.length !== this.headers.length) {\n throw new Error(\n `Number of values in the row (${row.length}) must match the number of headers (${this.headers.length}).`,\n );\n }\n\n this.rows.push(row);\n }\n\n public toString(options: MultiColumnASCIITableOptions = {}): string {\n const tableWidth = options.tableWidth || this.tableWidth;\n const emptyMessage = options.emptyMessage || this.emptyMessage;\n\n if (this.rows.length === 0) {\n const emptyTableWidth = Math.min(tableWidth, 40);\n\n const separator = '+' + '-'.repeat(emptyTableWidth - 2) + '+';\n const emptyMessageLines = ASCIITableUtils.wrapText(\n emptyMessage,\n emptyTableWidth - 4,\n );\n\n const emptyRows = emptyMessageLines.map((line) => {\n const paddingLeft = ' '.repeat(\n Math.floor((emptyTableWidth - stringWidth(line) - 4) / 2),\n );\n\n const paddingRight = ' '.repeat(\n Math.ceil((emptyTableWidth - stringWidth(line) - 4) / 2),\n );\n\n return `| ${paddingLeft}${line}${paddingRight} |`;\n });\n\n if (emptyRows.length === 0) {\n emptyRows.push(`| ${' '.repeat(emptyTableWidth - 4)} |`);\n }\n\n return [separator, ...emptyRows, separator].join('\\n');\n }\n\n const columnWidths = this.calculateColumnWidths(options);\n\n const headerSeparator = ASCIITableUtils.createSeparator(columnWidths);\n const rowSeparator = ASCIITableUtils.createSeparator(columnWidths, '-');\n let tableString = headerSeparator + '\\n';\n\n const header = this.renderRow(this.headers, columnWidths);\n tableString += header + '\\n' + rowSeparator + '\\n';\n\n const rows = this.rows.map((row) => {\n return this.renderRow(row, columnWidths);\n });\n\n tableString += rows.join('\\n' + rowSeparator + '\\n');\n tableString += '\\n' + headerSeparator;\n\n return tableString;\n }\n\n public calculateColumnWidths(\n options: MultiColumnASCIITableOptions = {},\n ): number[] {\n const tableWidth = options.tableWidth || this.tableWidth;\n const widthMode = options.widthMode || this.widthMode;\n\n const numColumns = this.headers.length;\n\n if (widthMode === 'fixed') {\n const availableWidth = tableWidth - (numColumns + 1) * 3 + 1;\n const columnWidth = Math.floor(availableWidth / numColumns);\n const extraWidth = availableWidth % numColumns;\n const columnWidths = new Array(numColumns).fill(columnWidth);\n\n // if there is any remaining width (extraWidth), we distribute it evenly among the columns starting from the first column.\n for (let i = 0; i < extraWidth; i++) {\n columnWidths[i] += 1;\n }\n\n return columnWidths as number[];\n }\n\n const availableWidth = tableWidth - (numColumns + 1) * 3 + 1;\n const maxColumnWidth = Math.floor(availableWidth / numColumns);\n const totalContentWidth = this.headers.reduce(\n (sum, header) => sum + stringWidth(header),\n 0,\n );\n\n if (availableWidth >= totalContentWidth) {\n const remainingWidth = availableWidth - totalContentWidth;\n const extraCharWidth = Math.floor(remainingWidth / numColumns);\n const extraCharRemainder = remainingWidth % numColumns;\n\n const columnWidths = this.headers.map((header, index) => {\n const extraWidth = index < extraCharRemainder ? 1 : 0;\n return stringWidth(header) + extraCharWidth + extraWidth;\n });\n\n return columnWidths;\n } else {\n const columnWidths = this.headers.map(() => maxColumnWidth);\n\n return columnWidths;\n }\n }\n\n private renderRow(row: string[], columnWidths: number[]): string {\n const wrappedCells = row.map((value, index) => {\n const wrappedLines = ASCIITableUtils.wrapText(value, columnWidths[index]);\n\n return wrappedLines\n .map((line) => line.padEnd(columnWidths[index]))\n .join('\\n');\n });\n\n const maxLines = Math.max(\n ...wrappedCells.map((cell) => cell.split('\\n').length),\n );\n\n const paddedRows = [];\n\n for (let i = 0; i < maxLines; i++) {\n const rowLine = wrappedCells.map((cell, index) => {\n const cellLines = cell.split('\\n');\n const cellLine = cellLines[i] || '';\n const padding = ' '.repeat(columnWidths[index] - stringWidth(cellLine));\n\n return ' ' + cellLine + padding + ' ';\n });\n\n paddedRows.push('|' + rowLine.join('|') + '|');\n }\n\n return paddedRows.join('\\n');\n }\n}\n","import { isString } from '../strings';\nimport { padRight } from '../padding-utils';\nimport { MultiColumnASCIITable } from './multi-column-ascii-table';\nimport { ASCIITableUtils } from './ascii-table-utils';\nimport stringWidth from 'string-width';\nimport { clamp } from '../clamp';\n\nexport type TableRowValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | KeyValueASCIITable\n | MultiColumnASCIITable\n | NestedKeyValueEntry[];\n\ntype TableRow = TableRowRegular | TableRowOwn;\n\ninterface TableRowRegular {\n kind: 'regular';\n key: string;\n value: TableRowValue;\n}\n\ninterface TableRowOwn {\n kind: 'own';\n key: string;\n value: string | NestedKeyValueEntry[];\n}\n\nexport interface NestedKeyValueEntry {\n key: string;\n value: string | KeyValueASCIITable | NestedKeyValueEntry[];\n}\n\ninterface KeyValueASCIITableOptions {\n tableWidth?: number;\n autoAdjustWidthWhenPossible?: boolean;\n emptyMessage?: string;\n}\n\nexport class KeyValueASCIITable {\n public readonly tableWidth: number;\n private emptyMessage: string;\n private autoAdjustWidthWhenPossible: boolean = true;\n\n private rows: TableRow[] = [];\n\n constructor(options: KeyValueASCIITableOptions = {}) {\n const minTableWidth = this.getMinimumWidth();\n\n if (options.tableWidth && options.tableWidth < minTableWidth) {\n throw new Error(\n `Table width must be at least ${minTableWidth} to accommodate the table structure.`,\n );\n }\n\n this.tableWidth = options.tableWidth || 80;\n this.autoAdjustWidthWhenPossible =\n options.autoAdjustWidthWhenPossible ?? true;\n this.emptyMessage = options.emptyMessage || '';\n }\n\n public getMinimumWidth(): number {\n // The minimum width for the KeyValueASCIITable is 9 characters:\n // - 2 character for the '| ' at the start\n // - 1 character for the minimum key column width\n // - 3 character for the ' | ' separating the key and value columns\n // - 1 character for the minimum value column width\n // - 2 character for the ' |' at the end\n\n return 9;\n }\n\n /**\n * Adds key and value to the table but placing the value on its own row.\n *\n * @param key\n * @param value\n */\n\n public addValueOnSeparateRow(key: string, value: string): void {\n const row: TableRow = { kind: 'own', key, value };\n\n this.rows.push(row);\n }\n\n /**\n * Adds key and value to the table.\n *\n * If provided value is an instance of ASCIITable or MultiColumnASCIITable, it will be rendered as a nested table on its own row for readability.\n *\n * @param key\n * @param value\n */\n\n public addRow(key: string, value: TableRowValue): void {\n const row: TableRow = { kind: 'regular', key, value };\n\n this.rows.push(row);\n }\n\n public toString(options: KeyValueASCIITableOptions = {}): string {\n const tableWidth = options.tableWidth || this.tableWidth;\n const canAutoAdjustWidthWhenPossible =\n options.autoAdjustWidthWhenPossible ?? this.autoAdjustWidthWhenPossible;\n\n const emptyMessage = options.emptyMessage || this.emptyMessage;\n\n if (this.rows.length === 0) {\n const emptyTableWidth = Math.min(tableWidth, 40);\n\n const separator = '+' + '-'.repeat(emptyTableWidth - 2) + '+';\n const emptyMessageLines = ASCIITableUtils.wrapText(\n emptyMessage,\n emptyTableWidth - 4,\n );\n\n const emptyRows = emptyMessageLines.map((line) => {\n const paddingLeft = padRight(\n '',\n Math.floor((emptyTableWidth - stringWidth(line) - 4) / 2),\n ' ',\n );\n\n const paddingRight = padRight(\n '',\n Math.ceil((emptyTableWidth - stringWidth(line) - 4) / 2),\n ' ',\n );\n\n return `| ${paddingLeft}${line}${paddingRight} |`;\n });\n\n if (emptyRows.length === 0) {\n emptyRows.push(`| ${' '.repeat(emptyTableWidth - 4)} |`);\n }\n\n return [separator, ...emptyRows, separator].join('\\n');\n }\n\n const columnWidths = this.calculateColumnWidths(options);\n\n const headerSeparator = ASCIITableUtils.createSeparator(columnWidths);\n const rowSeparator = ASCIITableUtils.createSeparator(columnWidths, '-');\n\n let tableString = headerSeparator + '\\n';\n\n for (const [rowIndex, row] of this.rows.entries()) {\n const { kind, key, value } = row;\n\n if (\n kind === 'own' ||\n value instanceof KeyValueASCIITable ||\n value instanceof MultiColumnASCIITable ||\n Array.isArray(value)\n ) {\n const keyString = ASCIITableUtils.centerText(\n key,\n columnWidths[0] + columnWidths[1] + 3,\n );\n\n tableString += `| ${keyString} |\\n`;\n tableString += rowSeparator + '\\n';\n\n let valueString = '';\n\n if (value instanceof KeyValueASCIITable) {\n valueString = this.formatValue(\n value,\n tableWidth - 4,\n canAutoAdjustWidthWhenPossible,\n '',\n );\n } else if (value instanceof MultiColumnASCIITable) {\n valueString = this.formatValue(\n value,\n tableWidth - 4,\n canAutoAdjustWidthWhenPossible,\n '',\n );\n } else if (Array.isArray(value)) {\n valueString = this.formatValue(\n value,\n tableWidth - 4,\n canAutoAdjustWidthWhenPossible,\n '',\n );\n } else if (row.kind === 'own') {\n valueString = this.formatTableRowOnOwnRow(\n value as string,\n tableWidth - 4,\n tableWidth,\n );\n }\n\n const valueLines = valueString.split('\\n');\n const paddedValueLines = valueLines.map((line) => {\n const padding = padRight('', tableWidth - stringWidth(line) - 4, ' ');\n\n return `| ${line}${padding} |`;\n });\n\n tableString += paddedValueLines.join('\\n') + '\\n';\n tableString += headerSeparator + '\\n';\n } else {\n const keyLines = ASCIITableUtils.wrapText(key, columnWidths[0]);\n\n const valueLines = ASCIITableUtils.wrapText(\n this.formatValue(\n value,\n columnWidths[1],\n canAutoAdjustWidthWhenPossible,\n '',\n ),\n columnWidths[1],\n );\n\n const maxLines = Math.max(keyLines.length, valueLines.length);\n\n for (let i = 0; i < maxLines; i++) {\n const keyLine = keyLines[i] || '';\n const valueLine = valueLines[i] || '';\n\n const keyPadding = ' '.repeat(columnWidths[0] - stringWidth(keyLine));\n\n const valuePadding = ' '.repeat(\n columnWidths[1] - stringWidth(valueLine),\n );\n\n tableString += `| ${keyLine}${keyPadding} | ${valueLine}${valuePadding} |\\n`;\n\n if (i === maxLines - 1) {\n if (rowIndex === this.rows.length - 1) {\n tableString += headerSeparator + '\\n';\n } else {\n tableString += rowSeparator + '\\n';\n }\n }\n }\n }\n }\n\n return tableString.trim();\n }\n\n private calculateColumnWidths(\n options: KeyValueASCIITableOptions = {},\n ): number[] {\n const tableWidth = options.tableWidth || this.tableWidth;\n const canAutoAdjustWidthWhenPossible =\n options.autoAdjustWidthWhenPossible ?? this.autoAdjustWidthWhenPossible;\n\n const columnWidths: number[] = [0, 0];\n\n for (const row of this.rows) {\n const { key, value } = row;\n\n const keyWidth = stringWidth(key);\n const maxKeyWidth = Math.floor((tableWidth - 7) / 2);\n\n if (keyWidth > columnWidths[0]) {\n columnWidths[0] = Math.min(keyWidth, maxKeyWidth);\n columnWidths[1] = Math.max(0, tableWidth - columnWidths[0] - 7);\n }\n\n if (typeof value === 'string') {\n const valueWidth = Math.max(\n ...value.split('\\n').map((line) => stringWidth(line)),\n );\n\n if (valueWidth > columnWidths[1]) {\n columnWidths[1] = Math.min(\n valueWidth,\n tableWidth - columnWidths[0] - 7,\n );\n\n columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);\n }\n } else if (row.kind === 'own') {\n let valueWidth = 0;\n\n if (isString(value)) {\n valueWidth = Math.max(\n ...value.split('\\n').map((line) => stringWidth(line)),\n );\n }\n\n if (valueWidth > columnWidths[1]) {\n columnWidths[1] = Math.min(\n valueWidth,\n tableWidth - columnWidths[0] - 7,\n );\n\n columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);\n }\n } else if (value instanceof KeyValueASCIITable) {\n // Update column widths based on the nested table\n let nestedTableColumnWidths: number[] = [];\n\n if (canAutoAdjustWidthWhenPossible) {\n const minWidth = value.getMinimumWidth();\n\n const availableWidth = tableWidth - columnWidths[0] - 7;\n const adjustedWidth = clamp(availableWidth, minWidth, availableWidth);\n\n nestedTableColumnWidths = value.calculateColumnWidths({\n tableWidth: adjustedWidth,\n });\n } else {\n nestedTableColumnWidths = value.calculateColumnWidths();\n }\n\n const nestedTableWidth =\n nestedTableColumnWidths.reduce((sum, width) => sum + width, 0) +\n nestedTableColumnWidths.length * 3 -\n 1;\n\n const availableWidth = tableWidth - columnWidths[0] - 7;\n\n if (nestedTableWidth > availableWidth) {\n columnWidths[1] = availableWidth;\n } else {\n columnWidths[1] = Math.max(columnWidths[1], nestedTableWidth);\n }\n } else if (value instanceof MultiColumnASCIITable) {\n // Update column widths based on the nested multi-column table\n let nestedTableColumnWidths: number[] = [];\n\n if (canAutoAdjustWidthWhenPossible) {\n const minWidth = value.getMinimumWidth();\n\n const availableWidth = tableWidth - columnWidths[0] - 7;\n const adjustedWidth = clamp(availableWidth, minWidth, availableWidth);\n\n nestedTableColumnWidths = value.calculateColumnWidths({\n tableWidth: adjustedWidth,\n });\n } else {\n nestedTableColumnWidths = value.calculateColumnWidths();\n }\n\n const nestedTableWidth =\n nestedTableColumnWidths.reduce((sum, width) => sum + width, 0) +\n nestedTableColumnWidths.length * 3 -\n 1;\n\n const availableWidth = tableWidth - columnWidths[0] - 7;\n\n if (nestedTableWidth > availableWidth) {\n columnWidths[1] = availableWidth;\n } else {\n columnWidths[1] = Math.max(columnWidths[1], nestedTableWidth);\n }\n } else if (Array.isArray(value)) {\n for (const nestedCell of value) {\n const nestedKeyWidth = stringWidth(nestedCell.key);\n const maxNestedKeyWidth = Math.floor((tableWidth - 7) / 2);\n\n if (nestedKeyWidth > columnWidths[0]) {\n columnWidths[0] = Math.min(nestedKeyWidth, maxNestedKeyWidth);\n columnWidths[1] = Math.max(0, tableWidth - columnWidths[0] - 7);\n }\n\n if (typeof nestedCell.value === 'string') {\n const nestedValueWidth = Math.max(\n ...nestedCell.value.split('\\n').map((line) => stringWidth(line)),\n );\n\n if (nestedValueWidth > columnWidths[1]) {\n columnWidths[1] = Math.min(\n nestedValueWidth,\n tableWidth - columnWidths[0] - 7,\n );\n columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);\n }\n }\n }\n }\n }\n\n return columnWidths;\n }\n\n private formatValue(\n value:\n | string\n | number\n | boolean\n | null\n | undefined\n | KeyValueASCIITable\n | MultiColumnASCIITable\n | NestedKeyValueEntry[],\n cellWidth: number,\n canAutoAdjustWidthWhenPossible: boolean,\n indent = '',\n ): string {\n if (typeof value === 'string') {\n return value;\n } else if (typeof value === 'number') {\n return String(value);\n } else if (typeof value === 'boolean') {\n return String(value);\n } else if (value === null) {\n return 'null';\n } else if (value === undefined) {\n return 'undefined';\n } else if (value instanceof KeyValueASCIITable) {\n let nestedTableLines: string[];\n\n if (canAutoAdjustWidthWhenPossible) {\n const minWidth = value.getMinimumWidth();\n\n const adjustedWidth = clamp(cellWidth, minWidth, cellWidth);\n\n nestedTableLines = value\n .toString({ tableWidth: adjustedWidth })\n .split('\\n');\n } else {\n nestedTableLines = value.toString().split('\\n');\n }\n\n const indentedLines = nestedTableLines.map((line) => `${indent}${line}`);\n\n return indentedLines.join('\\n');\n } else if (value instanceof MultiColumnASCIITable) {\n let nestedTableLines: string[];\n\n if (canAutoAdjustWidthWhenPossible) {\n const minWidth = value.getMinimumWidth();\n\n const adjustedWidth = clamp(cellWidth, minWidth, cellWidth);\n nestedTableLines = value\n .toString({ tableWidth: adjustedWidth })\n .split('\\n');\n } else {\n nestedTableLines = value.toString().split('\\n');\n }\n\n const indentedLines = nestedTableLines.map((line) => `${indent}${line}`);\n\n return indentedLines.join('\\n');\n } else if (Array.isArray(value)) {\n const nestedValueLines: string[] = [];\n\n for (const { key, value: nestedValue } of value) {\n const formattedKey = `${indent}${key}:`;\n const formattedValue = this.formatValue(\n nestedValue,\n cellWidth - indent.length - stringWidth(key) - 2,\n canAutoAdjustWidthWhenPossible,\n `${indent}`,\n );\n\n const wrappedSpacer = padRight('', 4, ' ');\n\n const wrappedValue = formattedValue\n .split('\\n')\n .map((line) => `${indent}${wrappedSpacer}${line}`);\n\n nestedValueLines.push(formattedKey);\n nestedValueLines.push(...wrappedValue);\n nestedValueLines.push('');\n }\n\n return nestedValueLines.slice(0, -1).join('\\n');\n } else {\n throw new TypeError('Invalid value type provided');\n }\n }\n\n private formatTableRowOnOwnRow(\n value: string,\n width: number,\n maxRowLength: number,\n ): string {\n const lines = value.split('\\n');\n\n const paddedLines = lines.map((line) => {\n const wrappedLines = ASCIITableUtils.wrapText(line, maxRowLength - 4);\n\n return wrappedLines\n .map((wrappedLine) => {\n const padding = padRight(\n '',\n width - stringWidth(wrappedLine) - 2,\n ' ',\n );\n\n return `${wrappedLine}${padding}`;\n })\n .join('\\n');\n });\n\n return paddedLines.join('\\n');\n }\n}\n","export function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(value, max));\n}\n\n/**\n * Clamps a value to a minimum, returning a default if the value is not finite or is undefined/null.\n *\n * Useful for config/settings validation where you want to:\n * - Enforce a minimum value\n * - Handle invalid inputs (Infinity, NaN, undefined, null) gracefully\n *\n * @param value - The value to clamp (can be undefined or null)\n * @param min - The minimum allowed value\n * @param defaultValue - The default to return if value is not finite or is undefined/null\n * @returns The clamped value, or defaultValue if value is not finite/undefined/null\n *\n * @example\n * ```typescript\n * finiteClampMin(5000, 1000, 3000) // 5000 (value > min)\n * finiteClampMin(500, 1000, 3000) // 1000 (enforces min)\n * finiteClampMin(Infinity, 1000, 3000) // 3000 (not finite, use default)\n * finiteClampMin(NaN, 1000, 3000) // 3000 (not finite, use default)\n * finiteClampMin(undefined, 1000, 3000) // 3000 (undefined, use default)\n * finiteClampMin(null, 1000, 3000) // 3000 (null, use default)\n * ```\n */\nexport function finiteClampMin(\n value: number | undefined | null,\n min: number,\n defaultValue: number,\n): number {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return defaultValue;\n }\n\n return Math.max(value, min);\n}\n","import type { NestedKeyValueEntry } from './ascii-tables/key-value-ascii-table';\nimport { KeyValueASCIITable } from './ascii-tables/key-value-ascii-table';\n\nfunction safeStringify(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value);\n }\n\n switch (typeof value) {\n case 'string':\n return value;\n case 'number':\n case 'boolean':\n case 'bigint':\n return String(value);\n case 'object':\n return JSON.stringify(value);\n case 'function':\n return '[Function]';\n case 'symbol':\n return value.toString();\n default: {\n // This should never happen, but satisfy the linter\n const fallback = value as string | number | boolean;\n return String(fallback);\n }\n }\n}\n\nexport function errorToString(error: unknown, maxRowLength = 80): string {\n const table = errorToASCIITable(error, maxRowLength);\n\n return table.toString();\n}\n\nfunction errorToASCIITable(\n error: unknown,\n maxRowLength: number,\n): KeyValueASCIITable {\n const table = new KeyValueASCIITable({\n tableWidth: maxRowLength,\n autoAdjustWidthWhenPossible: true,\n });\n\n if (error && typeof error === 'object') {\n const err = error as Record<string, unknown>;\n table.addRow('Key', 'Value');\n\n if (err['message']) {\n table.addRow('Message', safeStringify(err['message']));\n }\n\n if (err['name']) {\n table.addRow('Name', safeStringify(err['name']));\n }\n\n if (err['code']) {\n table.addRow('Code', safeStringify(err['code']));\n }\n\n if (err['errno']) {\n table.addRow('Errno', safeStringify(err['errno']));\n }\n\n // other conventional that might be used to enhance the error object\n if (err['errPrefix']) {\n table.addRow('Prefix', safeStringify(err['errPrefix']));\n }\n\n if (err['errType']) {\n table.addRow('errType', safeStringify(err['errType']));\n }\n\n if (err['errCode']) {\n table.addRow('errCode', safeStringify(err['errCode']));\n }\n\n if (err['additionalInfo']) {\n const additionalInfo = err['additionalInfo'] as Record<string, unknown>;\n const sensitiveFieldNames =\n (err['sensitiveFieldNames'] as string[]) || [];\n\n for (const key in additionalInfo) {\n if (sensitiveFieldNames.includes(key)) {\n table.addRow(`AdditionalInfo.${key}`, '***');\n } else {\n const value = additionalInfo[key];\n\n table.addRow(\n `AdditionalInfo.${key}`,\n stringifyValue(value, table, maxRowLength),\n );\n }\n }\n }\n\n if (err['stack']) {\n table.addValueOnSeparateRow('Stack', safeStringify(err['stack']));\n }\n }\n\n return table;\n}\n\nfunction stringifyValue(\n value: unknown,\n table: KeyValueASCIITable,\n maxRowLength: number,\n): string | KeyValueASCIITable | NestedKeyValueEntry[] {\n if (typeof value === 'string') {\n return value;\n } else if (Array.isArray(value)) {\n // Handle arrays differently\n return value\n .map((item) => {\n const result = stringifyValue(item, table, maxRowLength);\n // Convert complex types to strings for joining\n if (typeof result === 'string') {\n return result;\n } else if (result instanceof KeyValueASCIITable) {\n return result.toString();\n } else {\n return JSON.stringify(result);\n }\n })\n .join(', ');\n } else if (typeof value === 'object' && value !== null) {\n if (value instanceof Error) {\n return errorToASCIITable(value, maxRowLength - 4);\n } else {\n // Handle objects differently\n const entries: NestedKeyValueEntry[] = Object.entries(value).map(\n ([key, val]) => ({\n key,\n value: stringifyValue(val, table, maxRowLength - 4),\n }),\n );\n\n return entries;\n }\n } else {\n return String(value);\n }\n}\n","// Helper from https://github.com/then/is-promise/tree/master\n// For some reason the @types/is-promise package stopped being picked up on\n\nexport function isPromise(obj: unknown): obj is Promise<unknown> {\n return (\n !!obj &&\n (typeof obj === 'object' || typeof obj === 'function') &&\n // @ts-expect-error - obj is checked to be object/function, then property access works at runtime\n typeof obj['then'] === 'function'\n );\n}\n","export function isFunction(value: unknown): boolean {\n return typeof value === 'function' || value instanceof Function;\n}\n","/**\n * Global event target polyfill.\n *\n * Some Lifecycleion libraries (`safe-handle-callback`, `logger`) report errors using\n * Lifecycleion's `'reportError'` convention: an `ErrorEvent` dispatched through\n * `globalThis.dispatchEvent()` and observed with `globalThis.addEventListener('reportError', ...)`.\n *\n * Browsers, Bun, and Deno expose the `EventTarget` methods on the global object, so the\n * convention works there out of the box. Node.js does not: as of Node 25 the `ErrorEvent`\n * constructor is a global, but `globalThis` is still not an `EventTarget`, so\n * `globalThis.addEventListener` / `removeEventListener` / `dispatchEvent` are all `undefined`.\n *\n * This module fills that gap by backing the three missing methods with a single shared\n * `EventTarget` instance. It is deliberately conservative:\n *\n * - It only installs when all three methods are absent, so native or user-installed\n * implementations are never overwritten.\n * - A partial/foreign implementation (some methods present, others missing) is left alone\n * rather than mixing methods from unrelated targets.\n * - Installation is idempotent, and the backing target is shared across repeated\n * initialization and across multiple copies of Lifecycleion.\n * - Installed properties are non-enumerable and bound to the backing target.\n */\n\n// Stored in globalThis so state survives module re-evaluation and works across\n// module boundaries, the same way `dev-mode` and `process-signal-manager` do it.\nconst GLOBAL_KEY = '__lifecycleion_global_event_target__';\n\nconst METHOD_NAMES = [\n 'addEventListener',\n 'removeEventListener',\n 'dispatchEvent',\n] as const;\n\n/**\n * Shared state: the backing target, plus whether the global methods in place are ours.\n */\ninterface GlobalEventTargetState {\n target: EventTarget;\n isInstalled: boolean;\n}\n\n/**\n * Outcome of {@link installGlobalEventTarget}.\n *\n * - `native` - the environment already provides all three methods (browser, Bun, Deno).\n * - `installed` - this call installed the polyfill.\n * - `already-installed` - a previous call (or another copy of Lifecycleion) installed it.\n * - `partial` - the environment provides some but not all of the methods; nothing was\n * installed, because mixing a foreign implementation with a polyfilled one would\n * dispatch to a different target than listeners registered through it.\n * - `unsupported` - the methods are missing and there is nothing to back them with:\n * either no `EventTarget` constructor at all, or one that cannot produce an\n * instance able to service the three methods (it throws, or hands back\n * something unusable).\n * - `blocked` - the global object refused the definition (it is non-extensible, or one of\n * the properties already exists and is non-configurable). Nothing was installed.\n */\nexport type GlobalEventTargetInstallResult =\n | 'native'\n | 'installed'\n | 'already-installed'\n | 'partial'\n | 'unsupported'\n | 'blocked';\n\n// Cast once at module level — avoids repeating the assertion in every function.\nconst g = globalThis as typeof globalThis & Record<string, unknown>;\n\nfunction getState(): GlobalEventTargetState | undefined {\n const value = readGlobal(GLOBAL_KEY);\n\n return value === UNREADABLE ? undefined : asUsableState(value);\n}\n\n/**\n * Narrow a value found at {@link GLOBAL_KEY} to state this module can reuse.\n *\n * The value comes from a shared global, so it may be anything: another copy of\n * Lifecycleion, a test stub, or an object built to misbehave. Every field is read\n * through {@link readMember}, since a getter can throw. A value that does not\n * check out is treated as absent, so installation replaces it — this key is\n * Lifecycleion's own namespace.\n */\nfunction asUsableState(value: unknown): GlobalEventTargetState | undefined {\n if (typeof value !== 'object' || value === null) {\n return undefined;\n }\n\n return asUsableTarget(readMember(value, 'target')) === null\n ? undefined\n : (value as GlobalEventTargetState);\n}\n\n/**\n * Narrow a value read from the `target` field to a usable backing target.\n *\n * Applied on every read rather than once: the field belongs to an object this\n * module does not own, so a getter may return a real `EventTarget` the first time\n * and something else the next.\n */\nfunction asUsableTarget(value: unknown): EventTarget | null {\n if (typeof value !== 'object' || value === null) {\n return null;\n }\n\n // A usable backing target is one that can actually service all three methods.\n for (const name of METHOD_NAMES) {\n if (typeof readMember(value, name) !== 'function') {\n return null;\n }\n }\n\n return value as EventTarget;\n}\n\n/**\n * Read the three methods off a candidate target and bind them, in one pass.\n *\n * The values installed on the global object come from here rather than from a\n * later `target[name]` in the definition loop — that would reopen the\n * validate-once-use-a-later-read gap {@link asUsableTarget} closes, one level in.\n *\n * `null` means this target cannot back an install: a method missing, no longer\n * callable, whose read or `bind` threw, or whose `bind` returned a non-function.\n * The caller falls back to a fresh target rather than failing.\n *\n * @returns The bound methods by name, or `null` if any could not be taken.\n */\nfunction bindTargetMethods(\n target: EventTarget,\n): Record<string, (...args: unknown[]) => unknown> | null {\n const bound: Record<string, (...args: unknown[]) => unknown> = {};\n\n for (const name of METHOD_NAMES) {\n const method = readMember(target, name);\n\n if (typeof method !== 'function') {\n return null;\n }\n\n let boundMethod: unknown;\n\n try {\n boundMethod = (method as (...args: unknown[]) => unknown).bind(target);\n } catch {\n // `bind` is itself a property read on somebody else's function.\n return null;\n }\n\n // What `bind` handed back is checked, not assumed: `bind` is an ordinary\n // property, so a hostile target can replace it with something that returns a\n // non-function without throwing. Guarding only the throw would leave\n // `globalThis.addEventListener` set to a non-callable and report\n // `'installed'` — worse than not installing, since the methods were absent.\n if (typeof boundMethod !== 'function') {\n return null;\n }\n\n bound[name] = boundMethod as (...args: unknown[]) => unknown;\n }\n\n return bound;\n}\n\n/** Whether shared state records a completed install by this module. */\nfunction isStateInstalled(state: GlobalEventTargetState | undefined): boolean {\n return state !== undefined && readMember(state, 'isInstalled') === true;\n}\n\n/**\n * The backing target from shared state, or `null` when there is none to vouch for.\n *\n * {@link asUsableState} validated this field but returns the original object, so\n * this is a fresh read of somebody else's property and is re-validated.\n */\nfunction readStateTarget(\n state: GlobalEventTargetState | undefined,\n): EventTarget | null {\n if (state === undefined) {\n return null;\n }\n\n return asUsableTarget(readMember(state, 'target'));\n}\n\n/** Returned by {@link readGlobal} when the read threw, so it cannot collide with a value. */\nconst UNREADABLE = Symbol('lifecycleion.unreadable');\n\n/**\n * Read a global without trusting it.\n *\n * A plain property read invokes any getter defined for it, and a getter is free to\n * throw. Every read here runs during module initialization, so an unguarded one would\n * crash the import of `safe-handle-callback` and everything downstream of it.\n *\n * @returns The value, or {@link UNREADABLE} if reading it threw.\n */\nfunction readGlobal(name: string): unknown {\n try {\n return g[name];\n } catch {\n return UNREADABLE;\n }\n}\n\n/**\n * Read a property from an object that may be hostile, without trusting it. Same\n * reasoning as {@link readGlobal}, one level in: the shared state object is\n * reachable by anyone, so its accessors are not ours to rely on.\n */\nfunction readMember(source: object, key: string): unknown {\n try {\n return (source as Record<string, unknown>)[key];\n } catch {\n return UNREADABLE;\n }\n}\n\n/**\n * What a global event method currently holds.\n *\n * - `usable` - a callable value.\n * - `occupied` - present, but something we cannot use (`null`, an object, ...).\n * - `absent` - `undefined`, which is indistinguishable from never having been set.\n * - `hostile` - reading it threw, so the property is an accessor belonging to somebody\n * else. It cannot be probed, and must not be touched.\n */\ntype MemberState = 'usable' | 'occupied' | 'absent' | 'hostile';\n\nfunction probeMember(name: string): MemberState {\n const value = readGlobal(name);\n\n if (value === UNREADABLE) {\n return 'hostile';\n }\n\n if (typeof value === 'function') {\n return 'usable';\n }\n\n return value === undefined ? 'absent' : 'occupied';\n}\n\n/**\n * Whether a property can be defined on the global object without throwing.\n *\n * `Object.defineProperty` throws on a non-extensible target when the property does not\n * already exist, and on any target when an existing property is non-configurable and\n * cannot be redefined. Both are possible after `Object.freeze(globalThis)` or\n * `Object.preventExtensions(globalThis)`, and this function runs during module\n * initialization — a throw here would break the import of every dependent module.\n */\nfunction canDefineProperty(key: string): boolean {\n const descriptor = Object.getOwnPropertyDescriptor(g, key);\n\n if (descriptor === undefined) {\n return Object.isExtensible(g);\n }\n\n return descriptor.configurable === true;\n}\n\n/**\n * Install `addEventListener`, `removeEventListener`, and `dispatchEvent` on `globalThis`\n * when — and only when — all three are missing.\n *\n * Safe to call any number of times; repeated calls keep the same backing target.\n *\n * @returns What the call did, or why it did nothing. See {@link GlobalEventTargetInstallResult}.\n */\nexport function installGlobalEventTarget(): GlobalEventTargetInstallResult {\n // Occupied-but-unusable is somebody else's doing and must not be overwritten; a plain\n // `undefined` is treated as absent, since assigning `undefined` is the ordinary way to\n // clear a global and is indistinguishable from never having set it.\n const members = METHOD_NAMES.map((name) => probeMember(name));\n\n if (members.every((member) => member === 'usable')) {\n // Never overwrite an existing implementation, ours or the environment's.\n return isStateInstalled(getState()) ? 'already-installed' : 'native';\n }\n\n if (members.some((member) => member !== 'absent')) {\n // Partial/incompatible surface: some member exists but the set is unusable as a\n // whole. Filling in the gaps would split listeners and dispatches across two\n // unrelated targets, and clobbering what is there would destroy someone else's\n // work — so leave the environment exactly as it is. A `hostile` member lands here\n // too: it cannot be read, so it certainly cannot be replaced safely.\n return 'partial';\n }\n\n // Captured rather than read twice: the constructor is a global like any other, so it\n // can be an accessor that throws, and re-reading it could yield something else.\n const eventTargetConstructor = readGlobal('EventTarget');\n\n if (typeof eventTargetConstructor !== 'function') {\n // Covers UNREADABLE too: a constructor we cannot read is one we cannot use.\n return 'unsupported';\n }\n\n // Preflight every property before touching anything, so a frozen or sealed global\n // object leaves with nothing half-installed — and, more importantly, without throwing\n // out of the module initialization that calls this.\n const isDefinable = [...METHOD_NAMES, GLOBAL_KEY].every((key) =>\n canDefineProperty(key),\n );\n\n if (!isDefinable) {\n return 'blocked';\n }\n\n const existingState = getState();\n const defined: string[] = [];\n\n // The state key as found, so a rollback can put back what was there.\n //\n // This call cannot be the first to throw: the preflight above already read\n // this exact descriptor through `canDefineProperty`, so an object hostile\n // enough to reject the read has already returned `'blocked'`.\n const priorStateDescriptor = Object.getOwnPropertyDescriptor(g, GLOBAL_KEY);\n\n /** Undo a partial installation when a later definition is rejected after all. */\n const rollback = (): void => {\n for (const key of defined) {\n // The state key may have held somebody else's object that this call\n // overwrote. Deleting it is not an undo there — a failed install would have\n // destroyed that object as a side effect, the one thing rollback exists to\n // prevent — so the original descriptor goes back instead.\n //\n // Restored in place rather than deleted first: whatever rejected the\n // definition may have sealed the global object, and re-adding a key to a\n // non-extensible object throws, while redefining a configurable one that\n // never left is always allowed.\n if (key === GLOBAL_KEY && priorStateDescriptor !== undefined) {\n try {\n Object.defineProperty(g, GLOBAL_KEY, priorStateDescriptor);\n } catch {\n // Nothing better to do here: the original could not be put back.\n }\n\n continue;\n }\n\n try {\n Reflect.deleteProperty(g, key);\n } catch {\n // Nothing better to do here: the property could not be defined *or* removed.\n }\n }\n };\n\n // Re-read `target` rather than reusing what `asUsableState` saw, and take the\n // three methods off it in the same pass. These are the values the globals are\n // actually bound to, so these are the reads that have to validate; trusting the\n // earlier probe would bind them to something that never passed a check.\n //\n // A target that no longer vouches for itself is treated as absent, so a fresh\n // one is made. Nothing is orphaned: a target that cannot service the three\n // methods never had listeners registered through this module.\n const reusableTarget = readStateTarget(existingState);\n const reusableMethods =\n reusableTarget === null ? null : bindTargetMethods(reusableTarget);\n\n let state: GlobalEventTargetState;\n let methods: Record<string, (...args: unknown[]) => unknown>;\n\n try {\n if (existingState === undefined || reusableMethods === null) {\n let target: EventTarget;\n\n try {\n target = new (eventTargetConstructor as new () => EventTarget)();\n } catch {\n // The constructor read from the global object cannot produce an\n // instance at all (a shim exposing `EventTarget` as non-constructible\n // throws here), so there is nothing to back the methods with. Reported\n // the same way as a constructor whose instances are unusable: nothing\n // was ever offered to the global object, so `'blocked'` would be the\n // wrong story, and nothing has been defined yet to undo.\n return 'unsupported';\n }\n\n const freshMethods = bindTargetMethods(target);\n\n if (freshMethods === null) {\n // The constructor read from the global object produced something that\n // cannot service the three methods, so there is nothing to back them\n // with. Nothing has been defined yet, so there is nothing to undo.\n return 'unsupported';\n }\n\n state = { target, isInstalled: false };\n methods = freshMethods;\n\n Object.defineProperty(g, GLOBAL_KEY, {\n value: state,\n enumerable: false,\n writable: false,\n configurable: true,\n });\n\n defined.push(GLOBAL_KEY);\n } else {\n // Another copy of Lifecycleion already made the target; reuse it so listeners\n // registered through it keep working.\n state = existingState;\n methods = reusableMethods;\n }\n\n for (const name of METHOD_NAMES) {\n Object.defineProperty(g, name, {\n value: methods[name],\n enumerable: false,\n writable: true,\n configurable: true,\n });\n\n defined.push(name);\n }\n\n // Flipped last, so the state only claims an install once all three are in\n // place, and inside the guarded block because a shared state object may be\n // frozen or have a throwing setter, which must not escape module init.\n //\n // Skipped when the flag already reads `true`: a non-writable property throws\n // on assignment in strict mode even for a same-value write. Otherwise a\n // frozen state left by a copy that already installed would roll back the\n // three methods just defined and report `blocked`, leaving the global with no\n // event methods. A frozen state still reading `false` keeps failing, as it\n // must: nothing can record that install.\n if (readMember(state, 'isInstalled') !== true) {\n state.isInstalled = true;\n }\n } catch {\n // The preflight passed but a definition or the state write was still rejected\n // (an exotic global object, a Proxy trap, a host restriction, frozen shared\n // state). Leave nothing behind and report no install.\n rollback();\n\n return 'blocked';\n }\n\n return 'installed';\n}\n\n/**\n * Get the shared `EventTarget` backing the polyfilled global methods.\n *\n * @returns The backing target, or `null` when the polyfill is not in use (native\n * environments, or environments where installation was skipped).\n */\nexport function getGlobalEventTarget(): EventTarget | null {\n return readStateTarget(getState());\n}\n\n/**\n * Whether the global event methods currently in place were installed by this polyfill.\n *\n * Reflects what was installed, not what is callable right now: an application that\n * replaces the global methods afterwards does not reset this.\n */\nexport function isGlobalEventTargetPolyfilled(): boolean {\n return isStateInstalled(getState());\n}\n\n/**\n * Whether `globalThis` exposes everything Lifecycleion's `'reportError'` convention needs:\n * the three `EventTarget` methods plus the `ErrorEvent` constructor.\n */\nexport function isGlobalEventTargetAvailable(): boolean {\n return (\n METHOD_NAMES.every((name) => probeMember(name) === 'usable') &&\n probeMember('ErrorEvent') === 'usable'\n );\n}\n","import { errorToString } from './error-to-string';\nimport { isPromise } from './is-promise';\nimport { isFunction } from './is-function';\nimport { DOUBLE_EOL } from './constants';\nimport {\n installGlobalEventTarget,\n isGlobalEventTargetAvailable,\n} from './global-event-target';\n\n// Node.js has a global `ErrorEvent` constructor (Node 25+) but does not make `globalThis`\n// an EventTarget, so the global event methods must be supplied before anything can be\n// dispatched or listened for. No-op in browsers, Bun, and Deno.\ninstallGlobalEventTarget();\n\n/**\n * Report a callback failure using Lifecycleion's `'reportError'` convention: an `ErrorEvent`\n * dispatched through `globalThis.dispatchEvent()`.\n *\n * Silently does nothing when the environment provides neither native nor polyfilled global\n * event primitives (see `global-event-target`).\n */\nfunction reportCallbackError(callbackName: string, error: Error): void {\n // Also installed at module load, above. Repeating it here costs a few typeof checks on\n // an error path and makes reporting independent of whether a bundler kept that\n // top-level call, so a failure can never be swallowed for a packaging reason.\n installGlobalEventTarget();\n\n // Probed rather than read directly: a global can be an accessor that throws, and this\n // runs on an error path that must not raise one of its own.\n if (!isGlobalEventTargetAvailable()) {\n return;\n }\n\n try {\n (\n globalThis as unknown as {\n dispatchEvent: (event: Event) => void;\n }\n ).dispatchEvent(\n new ErrorEvent('reportError', {\n error: new Error(\n `Error in a callback ${callbackName}: ${DOUBLE_EOL}${errorToString(error)}`,\n ),\n }),\n );\n } catch {\n // The probe above passed, so this is an environment actively fighting us — a global\n // that throws only on a later read, or a dispatch implementation that rejects the\n // event. Reporting a failure must never manufacture a second one, and neither\n // `safeHandleCallback` nor `safeHandleCallbackAndWait` may throw from this path.\n // Listener errors do not surface here: EventTarget does not propagate them.\n }\n}\n\n/**\n * Safely handles a callback function by catching any errors and reporting them via\n * Lifecycleion's `'reportError'` reporting convention, built from web-standard primitives\n * (`ErrorEvent` + global `EventTarget` methods).\n * This function can seamlessly handle both synchronous and asynchronous (Promise-based) callback functions.\n *\n * Errors are dispatched as ErrorEvent objects with type 'reportError' via `globalThis.dispatchEvent()`.\n * You can listen for these errors using `globalThis.addEventListener('reportError', handler)`.\n *\n * Browsers, Bun, and Deno expose these globals natively. Node.js provides `ErrorEvent` (Node 25+)\n * but not the global event methods, so importing this module installs them via a shared\n * `EventTarget` (see `global-event-target`) without overwriting existing implementations.\n *\n * This function is a \"fire-and-forget\" type of function, meaning it doesn't wait\n * for the callback to complete and doesn't return any result or error. If you need\n * to handle the result or error of the callback, consider using the\n * `safeHandleCallbackAndWait` function instead.\n *\n * @param {string} callbackName - The name of the callback function, used for error reporting.\n * @param {unknown} callback - The callback function to be executed. It can be either a\n * synchronous function or a function that returns a Promise.\n * @param {...unknown[]} args - Additional arguments to pass to the callback function.\n */\n\nexport function safeHandleCallback(\n callbackName: string,\n callback: unknown,\n ...args: unknown[]\n): void {\n const handleError = (error: Error): void => {\n reportCallbackError(callbackName, error);\n };\n\n if (isFunction(callback)) {\n try {\n // We need to cast callback to the appropriate function type now\n const result = (callback as (...args: unknown[]) => unknown)(...args);\n\n if (isPromise(result)) {\n // Fire-and-forget async callback\n result.catch((error: unknown) => {\n handleError(error as Error);\n });\n }\n } catch (error) {\n handleError(error as Error);\n }\n } else {\n handleError(\n new Error(`Callback provided for ${callbackName} is not a function`),\n );\n }\n}\n\ninterface CallbackResult<T> {\n success: boolean;\n value?: T;\n error?: Error;\n}\n\n/**\n * Safely handles a callback function by catching any errors and reporting them via\n * Lifecycleion's `'reportError'` reporting convention, built from web-standard primitives\n * (`ErrorEvent` + global `EventTarget` methods).\n * This function can seamlessly handle both synchronous and asynchronous (Promise-based) callback\n * functions, and it waits for the callback to complete before returning the result or an error.\n *\n * Errors are dispatched as ErrorEvent objects with type 'reportError' via `globalThis.dispatchEvent()`.\n * You can listen for these errors using `globalThis.addEventListener('reportError', handler)`.\n *\n * Browsers, Bun, and Deno expose these globals natively. Node.js provides `ErrorEvent` (Node 25+)\n * but not the global event methods, so importing this module installs them via a shared\n * `EventTarget` (see `global-event-target`) without overwriting existing implementations.\n *\n * @param {string} callbackName - The name of the callback function, used for error reporting.\n * @param {unknown} callback - The callback function to be executed. It can be either a\n * synchronous function or a function that returns a Promise.\n * @param {...unknown[]} args - Additional arguments to pass to the callback function.\n * @returns {Promise<CallbackResult<unknown>>} - A promise that resolves with an object containing\n * the success status, value (if any), and error (if any).\n */\n\nexport async function safeHandleCallbackAndWait<T>(\n callbackName: string,\n callback: unknown,\n ...args: unknown[]\n): Promise<CallbackResult<T>> {\n const handleError = (error: Error): CallbackResult<T> => {\n reportCallbackError(callbackName, error);\n\n return { success: false, error };\n };\n\n if (isFunction(callback)) {\n try {\n // We need to cast callback to the appropriate function type now\n const result = (callback as (...args: unknown[]) => unknown)(...args);\n\n if (isPromise(result)) {\n // Wait for the async callback to complete\n const value = await (result as Promise<T>);\n\n return { success: true, value };\n } else {\n return { success: true, value: result as T };\n }\n } catch (error) {\n return handleError(error as Error);\n }\n } else {\n return handleError(\n new Error(`Callback provided for ${callbackName} is not a function`),\n );\n }\n}\n","import { safeHandleCallback } from './safe-handle-callback';\n\n/**\n * Instead of using `SingleEventObserver`, you could extend `SingleEventObserverProtected`\n * if you want the notify method to be protected, and allow only your class to emit events.\n *\n * A base class for implementing the observer pattern with protected notify method.\n * This class allows subscription to a single type of event and notifies all subscribers\n * when the event occurs.\n *\n * @template T The type of data that will be passed to subscribers when notifying.\n */\n\nexport class SingleEventObserverProtected<T> {\n /**\n * Set of subscriber functions.\n */\n\n private subscribers = new Set<(data: T) => void | Promise<void>>();\n\n /**\n * Subscribes a function to the observer.\n * @param fn The function to be subscribed.\n */\n\n public subscribe(fn: (data: T) => void | Promise<void>): void {\n this.subscribers.add(fn);\n }\n\n /**\n * Unsubscribes a function from the observer.\n * @param fn The function to be unsubscribed.\n */\n\n public unsubscribe(fn: (data: T) => void | Promise<void>): void {\n this.subscribers.delete(fn);\n }\n\n /**\n * Checks if a specific function is subscribed to the observer.\n * @param fn The function to check.\n * @returns A boolean indicating if the function is subscribed.\n */\n\n public hasSubscriber(fn: (data: T) => void | Promise<void>): boolean {\n return this.subscribers.has(fn);\n }\n\n /**\n * Notifies all subscribers with the given data.\n * This method is protected to allow only derived classes to trigger notifications.\n * @param data The data to pass to all subscribers.\n */\n\n protected notify(data: T): void {\n for (const subscriber of this.subscribers) {\n safeHandleCallback(\n `SingleEventObserver_${(subscriber as EventListener).name || 'anonymous'}`,\n subscriber,\n data,\n );\n }\n }\n}\n\n/**\n * A class that implements the observer pattern with public notify method.\n * This class extends SingleEventObserverProtected and makes the notify method public.\n *\n * @template T The type of data that will be passed to subscribers when notifying.\n */\n\nexport class SingleEventObserver<T> extends SingleEventObserverProtected<T> {\n /**\n * Notifies all subscribers with the given data.\n * This method is public, allowing any code with access to the observer to trigger notifications.\n * @param data The data to pass to all subscribers.\n */\n\n public notify(data: T): void {\n super.notify(data);\n }\n}\n"],"mappings":";AAEO,SAAS,SAAS,OAAiC;AACxD,SAAO,OAAO,UAAU;AAC1B;AA2IO,SAAS,eAAe,MAAwB;AACrD,QAAM,YAAsB,CAAC;AAC7B,MAAI,WAAW;AACf,MAAI,cAAc;AAElB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,OAAO,KAAK,CAAC;AACnB,UAAM,WAAW,KAAK,IAAI,CAAC,KAAK;AAChC,UAAM,OAAO,KAAK,WAAW,CAAC;AAG9B,QACG,QAAQ,OAAU,QAAQ;AAAA,IAC1B,QAAQ,QAAU,QAAQ;AAAA,IAC1B,QAAQ,QAAU,QAAQ;AAAA,IAC1B,QAAQ,SAAU,QAAQ;AAAA,IAC1B,QAAQ,QAAU,QAAQ;AAAA,IAC1B,QAAQ,QAAU,QAAQ,MAC3B;AAEA,kBAAY;AAAA,IACd,WAAW,SAAS,UAAU;AAE5B,qBAAe,WAAW;AAC1B,iBAAW;AAAA,IACb,OAAO;AACL,UAAI,UAAU;AACZ,YAAI,aAAa;AACf,oBAAU,KAAK,cAAc,QAAQ;AACrC,wBAAc;AAAA,QAChB,OAAO;AACL,oBAAU,KAAK,QAAQ;AAAA,QACzB;AAAA,MACF;AACA,iBAAW;AAGX,UACE,QAAQ,YACR,QAAQ,YACR,YAAY,YACZ,YAAY,UACZ;AACA,oBAAY;AACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU;AACZ,QAAI,aAAa;AACf,gBAAU,KAAK,cAAc,QAAQ;AAAA,IACvC,OAAO;AACL,gBAAU,KAAK,QAAQ;AAAA,IACzB;AAAA,EACF;AAEA,SAAO;AACT;;;ACxMO,IAAM,cAAc;AAEpB,IAAM,MAAM;AACZ,IAAM,aAAa,MAAM;AACzB,IAAM,SAAS,IAAI,OAAO,CAAC;AAC3B,IAAM,gBAAgB,SAAS;AAM/B,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAM,gBAAgB,kBAAkB;AACxC,IAAM,SAAS;AACf,IAAM,aAAa,SAAS;AAE5B,IAAM,cAAc;AACpB,IAAM,aAAa;AACnB,IAAM,YAAY,SAAS,gBAAgB,cAAc;;;ACNzD,SAAS,QACd,KACA,QACA,SAAS,aACD;AACR,SAAO,IAAI,SAAS,QAAQ,MAAM;AACpC;AAYO,SAAS,SACd,KACA,QACA,SAAS,aACD;AACR,SAAO,IAAI,OAAO,QAAQ,MAAM;AAClC;AAUO,SAAS,UACd,KACA,QACA,SAA2B,QAC3B,SAAS,aACD;AACR,QAAM,eAAe,SAAS,IAAI;AAElC,MAAI,eAAe,GAAG;AACpB,UAAM,gBACJ,WAAW,SACP,KAAK,KAAK,eAAe,CAAC,IAC1B,KAAK,MAAM,eAAe,CAAC;AAEjC,UAAM,iBACJ,WAAW,SACP,KAAK,MAAM,eAAe,CAAC,IAC3B,KAAK,KAAK,eAAe,CAAC;AAEhC,WACE,QAAQ,IAAI,eAAe,MAAM,IACjC,MACA,SAAS,IAAI,gBAAgB,MAAM;AAAA,EAEvC,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAsBO,SAAS,qBACd,KACA,QACA,SAAS,aACD;AACR,SAAO,UAAU,KAAK,QAAQ,SAAS,MAAM;AAC/C;;;ACtGA,OAAO,iBAAiB;AAGjB,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EAC3B,OAAc,WAAW,MAAc,OAAuB;AAC5D,WAAO,qBAAqB,MAAM,OAAO,GAAG;AAAA,EAC9C;AAAA,EAEA,OAAc,gBACZ,cACA,YAAoB,KACZ;AACR,UAAM,aACJ,aAAa,OAAO,CAAC,KAAK,UAAU,MAAM,QAAQ,GAAG,CAAC,IAAI;AAE5D,WAAO,IAAI,SAAS,IAAI,YAAY,SAAS,CAAC;AAAA,EAChD;AAAA,EAEA,OAAc,SAAS,MAAc,WAA6B;AAChE,UAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,UAAM,QAAkB,CAAC;AACzB,QAAI,cAAc;AAElB,eAAW,QAAQ,OAAO;AACxB,UAAI,YAAY,WAAW,IAAI,YAAY,IAAI,IAAI,KAAK,WAAW;AACjE,wBAAgB,cAAc,MAAM,MAAM;AAAA,MAC5C,OAAO;AACL,YAAI,aAAa;AACf,gBAAM,KAAK,WAAW;AAAA,QACxB;AAEA,YAAI,YAAY,IAAI,KAAK,WAAW;AAClC,wBAAc;AAAA,QAChB,OAAO;AACL,gBAAM,WAAW,iBAAgB,UAAU,MAAM,SAAS;AAC1D,gBAAM,KAAK,GAAG,SAAS,MAAM,GAAG,EAAE,CAAC;AACnC,wBAAc,SAAS,SAAS,SAAS,CAAC;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAEA,QAAI,aAAa;AACf,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAc,UAAU,MAAc,WAA6B;AACjE,UAAM,YAAY,eAAe,IAAI;AACrC,UAAM,WAAqB,CAAC;AAC5B,QAAI,iBAAiB;AAErB,eAAW,YAAY,WAAW;AAChC,UAAI,YAAY,iBAAiB,QAAQ,KAAK,WAAW;AACvD,0BAAkB;AAAA,MACpB,OAAO;AACL,iBAAS,KAAK,cAAc;AAC5B,yBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,gBAAgB;AAClB,eAAS,KAAK,cAAc;AAAA,IAC9B;AAEA,WAAO;AAAA,EACT;AACF;;;ACpEA,OAAOA,kBAAiB;AAQjB,IAAM,wBAAN,MAA4B;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAAmB,UAAwC,CAAC,GAAG;AACzE,SAAK,UAAU;AACf,SAAK,OAAO,CAAC;AACb,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,eAAe,QAAQ,gBAAgB;AAC5C,SAAK,YAAY,QAAQ,aAAa;AAEtC,UAAM,gBAAgB,KAAK,gBAAgB;AAE3C,QAAI,KAAK,aAAa,eAAe;AACnC,YAAM,IAAI;AAAA,QACR,gCAAgC,aAAa;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAAA,EAEO,kBAA0B;AAC/B,WAAO,KAAK,QAAQ,SAAS,IAAI;AAAA,EACnC;AAAA,EAEO,OAAO,KAAqB;AACjC,QAAI,IAAI,WAAW,KAAK,QAAQ,QAAQ;AACtC,YAAM,IAAI;AAAA,QACR,gCAAgC,IAAI,MAAM,uCAAuC,KAAK,QAAQ,MAAM;AAAA,MACtG;AAAA,IACF;AAEA,SAAK,KAAK,KAAK,GAAG;AAAA,EACpB;AAAA,EAEO,SAAS,UAAwC,CAAC,GAAW;AAClE,UAAM,aAAa,QAAQ,cAAc,KAAK;AAC9C,UAAM,eAAe,QAAQ,gBAAgB,KAAK;AAElD,QAAI,KAAK,KAAK,WAAW,GAAG;AAC1B,YAAM,kBAAkB,KAAK,IAAI,YAAY,EAAE;AAE/C,YAAM,YAAY,MAAM,IAAI,OAAO,kBAAkB,CAAC,IAAI;AAC1D,YAAM,oBAAoB,gBAAgB;AAAA,QACxC;AAAA,QACA,kBAAkB;AAAA,MACpB;AAEA,YAAM,YAAY,kBAAkB,IAAI,CAAC,SAAS;AAChD,cAAM,cAAc,IAAI;AAAA,UACtB,KAAK,OAAO,kBAAkBA,aAAY,IAAI,IAAI,KAAK,CAAC;AAAA,QAC1D;AAEA,cAAM,eAAe,IAAI;AAAA,UACvB,KAAK,MAAM,kBAAkBA,aAAY,IAAI,IAAI,KAAK,CAAC;AAAA,QACzD;AAEA,eAAO,KAAK,WAAW,GAAG,IAAI,GAAG,YAAY;AAAA,MAC/C,CAAC;AAED,UAAI,UAAU,WAAW,GAAG;AAC1B,kBAAU,KAAK,KAAK,IAAI,OAAO,kBAAkB,CAAC,CAAC,IAAI;AAAA,MACzD;AAEA,aAAO,CAAC,WAAW,GAAG,WAAW,SAAS,EAAE,KAAK,IAAI;AAAA,IACvD;AAEA,UAAM,eAAe,KAAK,sBAAsB,OAAO;AAEvD,UAAM,kBAAkB,gBAAgB,gBAAgB,YAAY;AACpE,UAAM,eAAe,gBAAgB,gBAAgB,cAAc,GAAG;AACtE,QAAI,cAAc,kBAAkB;AAEpC,UAAM,SAAS,KAAK,UAAU,KAAK,SAAS,YAAY;AACxD,mBAAe,SAAS,OAAO,eAAe;AAE9C,UAAM,OAAO,KAAK,KAAK,IAAI,CAAC,QAAQ;AAClC,aAAO,KAAK,UAAU,KAAK,YAAY;AAAA,IACzC,CAAC;AAED,mBAAe,KAAK,KAAK,OAAO,eAAe,IAAI;AACnD,mBAAe,OAAO;AAEtB,WAAO;AAAA,EACT;AAAA,EAEO,sBACL,UAAwC,CAAC,GAC/B;AACV,UAAM,aAAa,QAAQ,cAAc,KAAK;AAC9C,UAAM,YAAY,QAAQ,aAAa,KAAK;AAE5C,UAAM,aAAa,KAAK,QAAQ;AAEhC,QAAI,cAAc,SAAS;AACzB,YAAMC,kBAAiB,cAAc,aAAa,KAAK,IAAI;AAC3D,YAAM,cAAc,KAAK,MAAMA,kBAAiB,UAAU;AAC1D,YAAM,aAAaA,kBAAiB;AACpC,YAAM,eAAe,IAAI,MAAM,UAAU,EAAE,KAAK,WAAW;AAG3D,eAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,qBAAa,CAAC,KAAK;AAAA,MACrB;AAEA,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,cAAc,aAAa,KAAK,IAAI;AAC3D,UAAM,iBAAiB,KAAK,MAAM,iBAAiB,UAAU;AAC7D,UAAM,oBAAoB,KAAK,QAAQ;AAAA,MACrC,CAAC,KAAK,WAAW,MAAMD,aAAY,MAAM;AAAA,MACzC;AAAA,IACF;AAEA,QAAI,kBAAkB,mBAAmB;AACvC,YAAM,iBAAiB,iBAAiB;AACxC,YAAM,iBAAiB,KAAK,MAAM,iBAAiB,UAAU;AAC7D,YAAM,qBAAqB,iBAAiB;AAE5C,YAAM,eAAe,KAAK,QAAQ,IAAI,CAAC,QAAQ,UAAU;AACvD,cAAM,aAAa,QAAQ,qBAAqB,IAAI;AACpD,eAAOA,aAAY,MAAM,IAAI,iBAAiB;AAAA,MAChD,CAAC;AAED,aAAO;AAAA,IACT,OAAO;AACL,YAAM,eAAe,KAAK,QAAQ,IAAI,MAAM,cAAc;AAE1D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,UAAU,KAAe,cAAgC;AAC/D,UAAM,eAAe,IAAI,IAAI,CAAC,OAAO,UAAU;AAC7C,YAAM,eAAe,gBAAgB,SAAS,OAAO,aAAa,KAAK,CAAC;AAExE,aAAO,aACJ,IAAI,CAAC,SAAS,KAAK,OAAO,aAAa,KAAK,CAAC,CAAC,EAC9C,KAAK,IAAI;AAAA,IACd,CAAC;AAED,UAAM,WAAW,KAAK;AAAA,MACpB,GAAG,aAAa,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,EAAE,MAAM;AAAA,IACvD;AAEA,UAAM,aAAa,CAAC;AAEpB,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,UAAU,aAAa,IAAI,CAAC,MAAM,UAAU;AAChD,cAAM,YAAY,KAAK,MAAM,IAAI;AACjC,cAAM,WAAW,UAAU,CAAC,KAAK;AACjC,cAAM,UAAU,IAAI,OAAO,aAAa,KAAK,IAAIA,aAAY,QAAQ,CAAC;AAEtE,eAAO,MAAM,WAAW,UAAU;AAAA,MACpC,CAAC;AAED,iBAAW,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,GAAG;AAAA,IAC/C;AAEA,WAAO,WAAW,KAAK,IAAI;AAAA,EAC7B;AACF;;;ACzKA,OAAOE,kBAAiB;;;ACJjB,SAAS,MAAM,OAAe,KAAa,KAAqB;AACrE,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,OAAO,GAAG,CAAC;AAC3C;;;ADwCO,IAAM,qBAAN,MAAM,oBAAmB;AAAA,EACd;AAAA,EACR;AAAA,EACA,8BAAuC;AAAA,EAEvC,OAAmB,CAAC;AAAA,EAE5B,YAAY,UAAqC,CAAC,GAAG;AACnD,UAAM,gBAAgB,KAAK,gBAAgB;AAE3C,QAAI,QAAQ,cAAc,QAAQ,aAAa,eAAe;AAC5D,YAAM,IAAI;AAAA,QACR,gCAAgC,aAAa;AAAA,MAC/C;AAAA,IACF;AAEA,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,8BACH,QAAQ,+BAA+B;AACzC,SAAK,eAAe,QAAQ,gBAAgB;AAAA,EAC9C;AAAA,EAEO,kBAA0B;AAQ/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,sBAAsB,KAAa,OAAqB;AAC7D,UAAM,MAAgB,EAAE,MAAM,OAAO,KAAK,MAAM;AAEhD,SAAK,KAAK,KAAK,GAAG;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,OAAO,KAAa,OAA4B;AACrD,UAAM,MAAgB,EAAE,MAAM,WAAW,KAAK,MAAM;AAEpD,SAAK,KAAK,KAAK,GAAG;AAAA,EACpB;AAAA,EAEO,SAAS,UAAqC,CAAC,GAAW;AAC/D,UAAM,aAAa,QAAQ,cAAc,KAAK;AAC9C,UAAM,iCACJ,QAAQ,+BAA+B,KAAK;AAE9C,UAAM,eAAe,QAAQ,gBAAgB,KAAK;AAElD,QAAI,KAAK,KAAK,WAAW,GAAG;AAC1B,YAAM,kBAAkB,KAAK,IAAI,YAAY,EAAE;AAE/C,YAAM,YAAY,MAAM,IAAI,OAAO,kBAAkB,CAAC,IAAI;AAC1D,YAAM,oBAAoB,gBAAgB;AAAA,QACxC;AAAA,QACA,kBAAkB;AAAA,MACpB;AAEA,YAAM,YAAY,kBAAkB,IAAI,CAAC,SAAS;AAChD,cAAM,cAAc;AAAA,UAClB;AAAA,UACA,KAAK,OAAO,kBAAkBC,aAAY,IAAI,IAAI,KAAK,CAAC;AAAA,UACxD;AAAA,QACF;AAEA,cAAM,eAAe;AAAA,UACnB;AAAA,UACA,KAAK,MAAM,kBAAkBA,aAAY,IAAI,IAAI,KAAK,CAAC;AAAA,UACvD;AAAA,QACF;AAEA,eAAO,KAAK,WAAW,GAAG,IAAI,GAAG,YAAY;AAAA,MAC/C,CAAC;AAED,UAAI,UAAU,WAAW,GAAG;AAC1B,kBAAU,KAAK,KAAK,IAAI,OAAO,kBAAkB,CAAC,CAAC,IAAI;AAAA,MACzD;AAEA,aAAO,CAAC,WAAW,GAAG,WAAW,SAAS,EAAE,KAAK,IAAI;AAAA,IACvD;AAEA,UAAM,eAAe,KAAK,sBAAsB,OAAO;AAEvD,UAAM,kBAAkB,gBAAgB,gBAAgB,YAAY;AACpE,UAAM,eAAe,gBAAgB,gBAAgB,cAAc,GAAG;AAEtE,QAAI,cAAc,kBAAkB;AAEpC,eAAW,CAAC,UAAU,GAAG,KAAK,KAAK,KAAK,QAAQ,GAAG;AACjD,YAAM,EAAE,MAAM,KAAK,MAAM,IAAI;AAE7B,UACE,SAAS,SACT,iBAAiB,uBACjB,iBAAiB,yBACjB,MAAM,QAAQ,KAAK,GACnB;AACA,cAAM,YAAY,gBAAgB;AAAA,UAChC;AAAA,UACA,aAAa,CAAC,IAAI,aAAa,CAAC,IAAI;AAAA,QACtC;AAEA,uBAAe,KAAK,SAAS;AAAA;AAC7B,uBAAe,eAAe;AAE9B,YAAI,cAAc;AAElB,YAAI,iBAAiB,qBAAoB;AACvC,wBAAc,KAAK;AAAA,YACjB;AAAA,YACA,aAAa;AAAA,YACb;AAAA,YACA;AAAA,UACF;AAAA,QACF,WAAW,iBAAiB,uBAAuB;AACjD,wBAAc,KAAK;AAAA,YACjB;AAAA,YACA,aAAa;AAAA,YACb;AAAA,YACA;AAAA,UACF;AAAA,QACF,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,wBAAc,KAAK;AAAA,YACjB;AAAA,YACA,aAAa;AAAA,YACb;AAAA,YACA;AAAA,UACF;AAAA,QACF,WAAW,IAAI,SAAS,OAAO;AAC7B,wBAAc,KAAK;AAAA,YACjB;AAAA,YACA,aAAa;AAAA,YACb;AAAA,UACF;AAAA,QACF;AAEA,cAAM,aAAa,YAAY,MAAM,IAAI;AACzC,cAAM,mBAAmB,WAAW,IAAI,CAAC,SAAS;AAChD,gBAAM,UAAU,SAAS,IAAI,aAAaA,aAAY,IAAI,IAAI,GAAG,GAAG;AAEpE,iBAAO,KAAK,IAAI,GAAG,OAAO;AAAA,QAC5B,CAAC;AAED,uBAAe,iBAAiB,KAAK,IAAI,IAAI;AAC7C,uBAAe,kBAAkB;AAAA,MACnC,OAAO;AACL,cAAM,WAAW,gBAAgB,SAAS,KAAK,aAAa,CAAC,CAAC;AAE9D,cAAM,aAAa,gBAAgB;AAAA,UACjC,KAAK;AAAA,YACH;AAAA,YACA,aAAa,CAAC;AAAA,YACd;AAAA,YACA;AAAA,UACF;AAAA,UACA,aAAa,CAAC;AAAA,QAChB;AAEA,cAAM,WAAW,KAAK,IAAI,SAAS,QAAQ,WAAW,MAAM;AAE5D,iBAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,gBAAM,UAAU,SAAS,CAAC,KAAK;AAC/B,gBAAM,YAAY,WAAW,CAAC,KAAK;AAEnC,gBAAM,aAAa,IAAI,OAAO,aAAa,CAAC,IAAIA,aAAY,OAAO,CAAC;AAEpE,gBAAM,eAAe,IAAI;AAAA,YACvB,aAAa,CAAC,IAAIA,aAAY,SAAS;AAAA,UACzC;AAEA,yBAAe,KAAK,OAAO,GAAG,UAAU,MAAM,SAAS,GAAG,YAAY;AAAA;AAEtE,cAAI,MAAM,WAAW,GAAG;AACtB,gBAAI,aAAa,KAAK,KAAK,SAAS,GAAG;AACrC,6BAAe,kBAAkB;AAAA,YACnC,OAAO;AACL,6BAAe,eAAe;AAAA,YAChC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,YAAY,KAAK;AAAA,EAC1B;AAAA,EAEQ,sBACN,UAAqC,CAAC,GAC5B;AACV,UAAM,aAAa,QAAQ,cAAc,KAAK;AAC9C,UAAM,iCACJ,QAAQ,+BAA+B,KAAK;AAE9C,UAAM,eAAyB,CAAC,GAAG,CAAC;AAEpC,eAAW,OAAO,KAAK,MAAM;AAC3B,YAAM,EAAE,KAAK,MAAM,IAAI;AAEvB,YAAM,WAAWA,aAAY,GAAG;AAChC,YAAM,cAAc,KAAK,OAAO,aAAa,KAAK,CAAC;AAEnD,UAAI,WAAW,aAAa,CAAC,GAAG;AAC9B,qBAAa,CAAC,IAAI,KAAK,IAAI,UAAU,WAAW;AAChD,qBAAa,CAAC,IAAI,KAAK,IAAI,GAAG,aAAa,aAAa,CAAC,IAAI,CAAC;AAAA,MAChE;AAEA,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,aAAa,KAAK;AAAA,UACtB,GAAG,MAAM,MAAM,IAAI,EAAE,IAAI,CAAC,SAASA,aAAY,IAAI,CAAC;AAAA,QACtD;AAEA,YAAI,aAAa,aAAa,CAAC,GAAG;AAChC,uBAAa,CAAC,IAAI,KAAK;AAAA,YACrB;AAAA,YACA,aAAa,aAAa,CAAC,IAAI;AAAA,UACjC;AAEA,uBAAa,CAAC,IAAI,KAAK,IAAI,GAAG,aAAa,aAAa,CAAC,IAAI,CAAC;AAAA,QAChE;AAAA,MACF,WAAW,IAAI,SAAS,OAAO;AAC7B,YAAI,aAAa;AAEjB,YAAI,SAAS,KAAK,GAAG;AACnB,uBAAa,KAAK;AAAA,YAChB,GAAG,MAAM,MAAM,IAAI,EAAE,IAAI,CAAC,SAASA,aAAY,IAAI,CAAC;AAAA,UACtD;AAAA,QACF;AAEA,YAAI,aAAa,aAAa,CAAC,GAAG;AAChC,uBAAa,CAAC,IAAI,KAAK;AAAA,YACrB;AAAA,YACA,aAAa,aAAa,CAAC,IAAI;AAAA,UACjC;AAEA,uBAAa,CAAC,IAAI,KAAK,IAAI,GAAG,aAAa,aAAa,CAAC,IAAI,CAAC;AAAA,QAChE;AAAA,MACF,WAAW,iBAAiB,qBAAoB;AAE9C,YAAI,0BAAoC,CAAC;AAEzC,YAAI,gCAAgC;AAClC,gBAAM,WAAW,MAAM,gBAAgB;AAEvC,gBAAMC,kBAAiB,aAAa,aAAa,CAAC,IAAI;AACtD,gBAAM,gBAAgB,MAAMA,iBAAgB,UAAUA,eAAc;AAEpE,oCAA0B,MAAM,sBAAsB;AAAA,YACpD,YAAY;AAAA,UACd,CAAC;AAAA,QACH,OAAO;AACL,oCAA0B,MAAM,sBAAsB;AAAA,QACxD;AAEA,cAAM,mBACJ,wBAAwB,OAAO,CAAC,KAAK,UAAU,MAAM,OAAO,CAAC,IAC7D,wBAAwB,SAAS,IACjC;AAEF,cAAM,iBAAiB,aAAa,aAAa,CAAC,IAAI;AAEtD,YAAI,mBAAmB,gBAAgB;AACrC,uBAAa,CAAC,IAAI;AAAA,QACpB,OAAO;AACL,uBAAa,CAAC,IAAI,KAAK,IAAI,aAAa,CAAC,GAAG,gBAAgB;AAAA,QAC9D;AAAA,MACF,WAAW,iBAAiB,uBAAuB;AAEjD,YAAI,0BAAoC,CAAC;AAEzC,YAAI,gCAAgC;AAClC,gBAAM,WAAW,MAAM,gBAAgB;AAEvC,gBAAMA,kBAAiB,aAAa,aAAa,CAAC,IAAI;AACtD,gBAAM,gBAAgB,MAAMA,iBAAgB,UAAUA,eAAc;AAEpE,oCAA0B,MAAM,sBAAsB;AAAA,YACpD,YAAY;AAAA,UACd,CAAC;AAAA,QACH,OAAO;AACL,oCAA0B,MAAM,sBAAsB;AAAA,QACxD;AAEA,cAAM,mBACJ,wBAAwB,OAAO,CAAC,KAAK,UAAU,MAAM,OAAO,CAAC,IAC7D,wBAAwB,SAAS,IACjC;AAEF,cAAM,iBAAiB,aAAa,aAAa,CAAC,IAAI;AAEtD,YAAI,mBAAmB,gBAAgB;AACrC,uBAAa,CAAC,IAAI;AAAA,QACpB,OAAO;AACL,uBAAa,CAAC,IAAI,KAAK,IAAI,aAAa,CAAC,GAAG,gBAAgB;AAAA,QAC9D;AAAA,MACF,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,mBAAW,cAAc,OAAO;AAC9B,gBAAM,iBAAiBD,aAAY,WAAW,GAAG;AACjD,gBAAM,oBAAoB,KAAK,OAAO,aAAa,KAAK,CAAC;AAEzD,cAAI,iBAAiB,aAAa,CAAC,GAAG;AACpC,yBAAa,CAAC,IAAI,KAAK,IAAI,gBAAgB,iBAAiB;AAC5D,yBAAa,CAAC,IAAI,KAAK,IAAI,GAAG,aAAa,aAAa,CAAC,IAAI,CAAC;AAAA,UAChE;AAEA,cAAI,OAAO,WAAW,UAAU,UAAU;AACxC,kBAAM,mBAAmB,KAAK;AAAA,cAC5B,GAAG,WAAW,MAAM,MAAM,IAAI,EAAE,IAAI,CAAC,SAASA,aAAY,IAAI,CAAC;AAAA,YACjE;AAEA,gBAAI,mBAAmB,aAAa,CAAC,GAAG;AACtC,2BAAa,CAAC,IAAI,KAAK;AAAA,gBACrB;AAAA,gBACA,aAAa,aAAa,CAAC,IAAI;AAAA,cACjC;AACA,2BAAa,CAAC,IAAI,KAAK,IAAI,GAAG,aAAa,aAAa,CAAC,IAAI,CAAC;AAAA,YAChE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,YACN,OASA,WACA,gCACA,SAAS,IACD;AACR,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO;AAAA,IACT,WAAW,OAAO,UAAU,UAAU;AACpC,aAAO,OAAO,KAAK;AAAA,IACrB,WAAW,OAAO,UAAU,WAAW;AACrC,aAAO,OAAO,KAAK;AAAA,IACrB,WAAW,UAAU,MAAM;AACzB,aAAO;AAAA,IACT,WAAW,UAAU,QAAW;AAC9B,aAAO;AAAA,IACT,WAAW,iBAAiB,qBAAoB;AAC9C,UAAI;AAEJ,UAAI,gCAAgC;AAClC,cAAM,WAAW,MAAM,gBAAgB;AAEvC,cAAM,gBAAgB,MAAM,WAAW,UAAU,SAAS;AAE1D,2BAAmB,MAChB,SAAS,EAAE,YAAY,cAAc,CAAC,EACtC,MAAM,IAAI;AAAA,MACf,OAAO;AACL,2BAAmB,MAAM,SAAS,EAAE,MAAM,IAAI;AAAA,MAChD;AAEA,YAAM,gBAAgB,iBAAiB,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,IAAI,EAAE;AAEvE,aAAO,cAAc,KAAK,IAAI;AAAA,IAChC,WAAW,iBAAiB,uBAAuB;AACjD,UAAI;AAEJ,UAAI,gCAAgC;AAClC,cAAM,WAAW,MAAM,gBAAgB;AAEvC,cAAM,gBAAgB,MAAM,WAAW,UAAU,SAAS;AAC1D,2BAAmB,MAChB,SAAS,EAAE,YAAY,cAAc,CAAC,EACtC,MAAM,IAAI;AAAA,MACf,OAAO;AACL,2BAAmB,MAAM,SAAS,EAAE,MAAM,IAAI;AAAA,MAChD;AAEA,YAAM,gBAAgB,iBAAiB,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,IAAI,EAAE;AAEvE,aAAO,cAAc,KAAK,IAAI;AAAA,IAChC,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,YAAM,mBAA6B,CAAC;AAEpC,iBAAW,EAAE,KAAK,OAAO,YAAY,KAAK,OAAO;AAC/C,cAAM,eAAe,GAAG,MAAM,GAAG,GAAG;AACpC,cAAM,iBAAiB,KAAK;AAAA,UAC1B;AAAA,UACA,YAAY,OAAO,SAASA,aAAY,GAAG,IAAI;AAAA,UAC/C;AAAA,UACA,GAAG,MAAM;AAAA,QACX;AAEA,cAAM,gBAAgB,SAAS,IAAI,GAAG,GAAG;AAEzC,cAAM,eAAe,eAClB,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,aAAa,GAAG,IAAI,EAAE;AAEnD,yBAAiB,KAAK,YAAY;AAClC,yBAAiB,KAAK,GAAG,YAAY;AACrC,yBAAiB,KAAK,EAAE;AAAA,MAC1B;AAEA,aAAO,iBAAiB,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI;AAAA,IAChD,OAAO;AACL,YAAM,IAAI,UAAU,6BAA6B;AAAA,IACnD;AAAA,EACF;AAAA,EAEQ,uBACN,OACA,OACA,cACQ;AACR,UAAM,QAAQ,MAAM,MAAM,IAAI;AAE9B,UAAM,cAAc,MAAM,IAAI,CAAC,SAAS;AACtC,YAAM,eAAe,gBAAgB,SAAS,MAAM,eAAe,CAAC;AAEpE,aAAO,aACJ,IAAI,CAAC,gBAAgB;AACpB,cAAM,UAAU;AAAA,UACd;AAAA,UACA,QAAQA,aAAY,WAAW,IAAI;AAAA,UACnC;AAAA,QACF;AAEA,eAAO,GAAG,WAAW,GAAG,OAAO;AAAA,MACjC,CAAC,EACA,KAAK,IAAI;AAAA,IACd,CAAC;AAED,WAAO,YAAY,KAAK,IAAI;AAAA,EAC9B;AACF;;;AE/eA,SAAS,cAAc,OAAwB;AAC7C,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,OAAO,KAAK;AAAA,IACrB,KAAK;AACH,aAAO,KAAK,UAAU,KAAK;AAAA,IAC7B,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,MAAM,SAAS;AAAA,IACxB,SAAS;AAEP,YAAM,WAAW;AACjB,aAAO,OAAO,QAAQ;AAAA,IACxB;AAAA,EACF;AACF;AAEO,SAAS,cAAc,OAAgB,eAAe,IAAY;AACvE,QAAM,QAAQ,kBAAkB,OAAO,YAAY;AAEnD,SAAO,MAAM,SAAS;AACxB;AAEA,SAAS,kBACP,OACA,cACoB;AACpB,QAAM,QAAQ,IAAI,mBAAmB;AAAA,IACnC,YAAY;AAAA,IACZ,6BAA6B;AAAA,EAC/B,CAAC;AAED,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,MAAM;AACZ,UAAM,OAAO,OAAO,OAAO;AAE3B,QAAI,IAAI,SAAS,GAAG;AAClB,YAAM,OAAO,WAAW,cAAc,IAAI,SAAS,CAAC,CAAC;AAAA,IACvD;AAEA,QAAI,IAAI,MAAM,GAAG;AACf,YAAM,OAAO,QAAQ,cAAc,IAAI,MAAM,CAAC,CAAC;AAAA,IACjD;AAEA,QAAI,IAAI,MAAM,GAAG;AACf,YAAM,OAAO,QAAQ,cAAc,IAAI,MAAM,CAAC,CAAC;AAAA,IACjD;AAEA,QAAI,IAAI,OAAO,GAAG;AAChB,YAAM,OAAO,SAAS,cAAc,IAAI,OAAO,CAAC,CAAC;AAAA,IACnD;AAGA,QAAI,IAAI,WAAW,GAAG;AACpB,YAAM,OAAO,UAAU,cAAc,IAAI,WAAW,CAAC,CAAC;AAAA,IACxD;AAEA,QAAI,IAAI,SAAS,GAAG;AAClB,YAAM,OAAO,WAAW,cAAc,IAAI,SAAS,CAAC,CAAC;AAAA,IACvD;AAEA,QAAI,IAAI,SAAS,GAAG;AAClB,YAAM,OAAO,WAAW,cAAc,IAAI,SAAS,CAAC,CAAC;AAAA,IACvD;AAEA,QAAI,IAAI,gBAAgB,GAAG;AACzB,YAAM,iBAAiB,IAAI,gBAAgB;AAC3C,YAAM,sBACH,IAAI,qBAAqB,KAAkB,CAAC;AAE/C,iBAAW,OAAO,gBAAgB;AAChC,YAAI,oBAAoB,SAAS,GAAG,GAAG;AACrC,gBAAM,OAAO,kBAAkB,GAAG,IAAI,KAAK;AAAA,QAC7C,OAAO;AACL,gBAAM,QAAQ,eAAe,GAAG;AAEhC,gBAAM;AAAA,YACJ,kBAAkB,GAAG;AAAA,YACrB,eAAe,OAAO,OAAO,YAAY;AAAA,UAC3C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,IAAI,OAAO,GAAG;AAChB,YAAM,sBAAsB,SAAS,cAAc,IAAI,OAAO,CAAC,CAAC;AAAA,IAClE;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,eACP,OACA,OACA,cACqD;AACrD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT,WAAW,MAAM,QAAQ,KAAK,GAAG;AAE/B,WAAO,MACJ,IAAI,CAAC,SAAS;AACb,YAAM,SAAS,eAAe,MAAM,OAAO,YAAY;AAEvD,UAAI,OAAO,WAAW,UAAU;AAC9B,eAAO;AAAA,MACT,WAAW,kBAAkB,oBAAoB;AAC/C,eAAO,OAAO,SAAS;AAAA,MACzB,OAAO;AACL,eAAO,KAAK,UAAU,MAAM;AAAA,MAC9B;AAAA,IACF,CAAC,EACA,KAAK,IAAI;AAAA,EACd,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AACtD,QAAI,iBAAiB,OAAO;AAC1B,aAAO,kBAAkB,OAAO,eAAe,CAAC;AAAA,IAClD,OAAO;AAEL,YAAM,UAAiC,OAAO,QAAQ,KAAK,EAAE;AAAA,QAC3D,CAAC,CAAC,KAAK,GAAG,OAAO;AAAA,UACf;AAAA,UACA,OAAO,eAAe,KAAK,OAAO,eAAe,CAAC;AAAA,QACpD;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,EACF,OAAO;AACL,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;;;AC5IO,SAAS,UAAU,KAAuC;AAC/D,SACE,CAAC,CAAC,QACD,OAAO,QAAQ,YAAY,OAAO,QAAQ;AAAA,EAE3C,OAAO,IAAI,MAAM,MAAM;AAE3B;;;ACVO,SAAS,WAAW,OAAyB;AAClD,SAAO,OAAO,UAAU,cAAc,iBAAiB;AACzD;;;ACwBA,IAAM,aAAa;AAEnB,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AACF;AAmCA,IAAM,IAAI;AAEV,SAAS,WAA+C;AACtD,QAAM,QAAQ,WAAW,UAAU;AAEnC,SAAO,UAAU,aAAa,SAAY,cAAc,KAAK;AAC/D;AAWA,SAAS,cAAc,OAAoD;AACzE,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AAEA,SAAO,eAAe,WAAW,OAAO,QAAQ,CAAC,MAAM,OACnD,SACC;AACP;AASA,SAAS,eAAe,OAAoC;AAC1D,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AAGA,aAAW,QAAQ,cAAc;AAC/B,QAAI,OAAO,WAAW,OAAO,IAAI,MAAM,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAeA,SAAS,kBACP,QACwD;AACxD,QAAM,QAAyD,CAAC;AAEhE,aAAW,QAAQ,cAAc;AAC/B,UAAM,SAAS,WAAW,QAAQ,IAAI;AAEtC,QAAI,OAAO,WAAW,YAAY;AAChC,aAAO;AAAA,IACT;AAEA,QAAI;AAEJ,QAAI;AACF,oBAAe,OAA2C,KAAK,MAAM;AAAA,IACvE,QAAQ;AAEN,aAAO;AAAA,IACT;AAOA,QAAI,OAAO,gBAAgB,YAAY;AACrC,aAAO;AAAA,IACT;AAEA,UAAM,IAAI,IAAI;AAAA,EAChB;AAEA,SAAO;AACT;AAGA,SAAS,iBAAiB,OAAoD;AAC5E,SAAO,UAAU,UAAa,WAAW,OAAO,aAAa,MAAM;AACrE;AAQA,SAAS,gBACP,OACoB;AACpB,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,SAAO,eAAe,WAAW,OAAO,QAAQ,CAAC;AACnD;AAGA,IAAM,aAAa,uBAAO,yBAAyB;AAWnD,SAAS,WAAW,MAAuB;AACzC,MAAI;AACF,WAAO,EAAE,IAAI;AAAA,EACf,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOA,SAAS,WAAW,QAAgB,KAAsB;AACxD,MAAI;AACF,WAAQ,OAAmC,GAAG;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAaA,SAAS,YAAY,MAA2B;AAC9C,QAAM,QAAQ,WAAW,IAAI;AAE7B,MAAI,UAAU,YAAY;AACxB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,YAAY;AAC/B,WAAO;AAAA,EACT;AAEA,SAAO,UAAU,SAAY,WAAW;AAC1C;AAWA,SAAS,kBAAkB,KAAsB;AAC/C,QAAM,aAAa,OAAO,yBAAyB,GAAG,GAAG;AAEzD,MAAI,eAAe,QAAW;AAC5B,WAAO,OAAO,aAAa,CAAC;AAAA,EAC9B;AAEA,SAAO,WAAW,iBAAiB;AACrC;AAUO,SAAS,2BAA2D;AAIzE,QAAM,UAAU,aAAa,IAAI,CAAC,SAAS,YAAY,IAAI,CAAC;AAE5D,MAAI,QAAQ,MAAM,CAAC,WAAW,WAAW,QAAQ,GAAG;AAElD,WAAO,iBAAiB,SAAS,CAAC,IAAI,sBAAsB;AAAA,EAC9D;AAEA,MAAI,QAAQ,KAAK,CAAC,WAAW,WAAW,QAAQ,GAAG;AAMjD,WAAO;AAAA,EACT;AAIA,QAAM,yBAAyB,WAAW,aAAa;AAEvD,MAAI,OAAO,2BAA2B,YAAY;AAEhD,WAAO;AAAA,EACT;AAKA,QAAM,cAAc,CAAC,GAAG,cAAc,UAAU,EAAE;AAAA,IAAM,CAAC,QACvD,kBAAkB,GAAG;AAAA,EACvB;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,SAAS;AAC/B,QAAM,UAAoB,CAAC;AAO3B,QAAM,uBAAuB,OAAO,yBAAyB,GAAG,UAAU;AAG1E,QAAM,WAAW,MAAY;AAC3B,eAAW,OAAO,SAAS;AAUzB,UAAI,QAAQ,cAAc,yBAAyB,QAAW;AAC5D,YAAI;AACF,iBAAO,eAAe,GAAG,YAAY,oBAAoB;AAAA,QAC3D,QAAQ;AAAA,QAER;AAEA;AAAA,MACF;AAEA,UAAI;AACF,gBAAQ,eAAe,GAAG,GAAG;AAAA,MAC/B,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAUA,QAAM,iBAAiB,gBAAgB,aAAa;AACpD,QAAM,kBACJ,mBAAmB,OAAO,OAAO,kBAAkB,cAAc;AAEnE,MAAI;AACJ,MAAI;AAEJ,MAAI;AACF,QAAI,kBAAkB,UAAa,oBAAoB,MAAM;AAC3D,UAAI;AAEJ,UAAI;AACF,iBAAS,IAAK,uBAAiD;AAAA,MACjE,QAAQ;AAON,eAAO;AAAA,MACT;AAEA,YAAM,eAAe,kBAAkB,MAAM;AAE7C,UAAI,iBAAiB,MAAM;AAIzB,eAAO;AAAA,MACT;AAEA,cAAQ,EAAE,QAAQ,aAAa,MAAM;AACrC,gBAAU;AAEV,aAAO,eAAe,GAAG,YAAY;AAAA,QACnC,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,cAAc;AAAA,MAChB,CAAC;AAED,cAAQ,KAAK,UAAU;AAAA,IACzB,OAAO;AAGL,cAAQ;AACR,gBAAU;AAAA,IACZ;AAEA,eAAW,QAAQ,cAAc;AAC/B,aAAO,eAAe,GAAG,MAAM;AAAA,QAC7B,OAAO,QAAQ,IAAI;AAAA,QACnB,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,cAAc;AAAA,MAChB,CAAC;AAED,cAAQ,KAAK,IAAI;AAAA,IACnB;AAYA,QAAI,WAAW,OAAO,aAAa,MAAM,MAAM;AAC7C,YAAM,cAAc;AAAA,IACtB;AAAA,EACF,QAAQ;AAIN,aAAS;AAET,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AA0BO,SAAS,+BAAwC;AACtD,SACE,aAAa,MAAM,CAAC,SAAS,YAAY,IAAI,MAAM,QAAQ,KAC3D,YAAY,YAAY,MAAM;AAElC;;;AC9cA,yBAAyB;AASzB,SAAS,oBAAoB,cAAsB,OAAoB;AAIrE,2BAAyB;AAIzB,MAAI,CAAC,6BAA6B,GAAG;AACnC;AAAA,EACF;AAEA,MAAI;AACF,IACE,WAGA;AAAA,MACA,IAAI,WAAW,eAAe;AAAA,QAC5B,OAAO,IAAI;AAAA,UACT,uBAAuB,YAAY,KAAK,UAAU,GAAG,cAAc,KAAK,CAAC;AAAA,QAC3E;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,QAAQ;AAAA,EAMR;AACF;AA0BO,SAAS,mBACd,cACA,aACG,MACG;AACN,QAAM,cAAc,CAAC,UAAuB;AAC1C,wBAAoB,cAAc,KAAK;AAAA,EACzC;AAEA,MAAI,WAAW,QAAQ,GAAG;AACxB,QAAI;AAEF,YAAM,SAAU,SAA6C,GAAG,IAAI;AAEpE,UAAI,UAAU,MAAM,GAAG;AAErB,eAAO,MAAM,CAAC,UAAmB;AAC/B,sBAAY,KAAc;AAAA,QAC5B,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,kBAAY,KAAc;AAAA,IAC5B;AAAA,EACF,OAAO;AACL;AAAA,MACE,IAAI,MAAM,yBAAyB,YAAY,oBAAoB;AAAA,IACrE;AAAA,EACF;AACF;;;AC7FO,IAAM,+BAAN,MAAsC;AAAA;AAAA;AAAA;AAAA,EAKnC,cAAc,oBAAI,IAAuC;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1D,UAAU,IAA6C;AAC5D,SAAK,YAAY,IAAI,EAAE;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,YAAY,IAA6C;AAC9D,SAAK,YAAY,OAAO,EAAE;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,cAAc,IAAgD;AACnE,WAAO,KAAK,YAAY,IAAI,EAAE;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,OAAO,MAAe;AAC9B,eAAW,cAAc,KAAK,aAAa;AACzC;AAAA,QACE,uBAAwB,WAA6B,QAAQ,WAAW;AAAA,QACxE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AASO,IAAM,sBAAN,cAAqC,6BAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOnE,OAAO,MAAe;AAC3B,UAAM,OAAO,IAAI;AAAA,EACnB;AACF;","names":["stringWidth","availableWidth","stringWidth","stringWidth","availableWidth"]}
@@ -246,12 +246,30 @@ interface AdapterResponse {
246
246
  */
247
247
  isTransportError?: boolean;
248
248
  /**
249
- * Set to `false` when the adapter knows the request/response progressed far
250
- * enough that replay is unsafe, even if `status` would normally be retried
251
- * by the client (for example a mid-upload socket write failure after some
252
- * bytes may already have left the process).
249
+ * Set to `false` when no attempt can succeed, whatever the method a rejected
250
+ * TLS certificate, say. Honoured for every method, and it overrides
251
+ * `retryNonIdempotentMethods`.
252
+ *
253
+ * Do **not** set it for a failure that merely might have been delivered, such
254
+ * as one that struck mid-upload: that vetoes retries for methods where replay
255
+ * is safe by definition. Report
256
+ * {@link AdapterResponse.wasDefinitelyNotSent} instead, or report nothing.
257
+ *
258
+ * Only `false` carries meaning. `true` is a hint, and never authorizes
259
+ * replaying a non-idempotent request.
253
260
  */
254
261
  isRetryable?: boolean;
262
+ /**
263
+ * Set to `true` only when the adapter can prove no request bytes reached the
264
+ * server — a refused connection, a name that did not resolve. Absence means
265
+ * "not known", never "known to be safe".
266
+ *
267
+ * Deliberately separate from {@link AdapterResponse.isRetryable}, which is a
268
+ * hint that says nothing about delivery. The client uses this to decide whether
269
+ * a `POST` or `PATCH` may be retried after a transport failure, and ignores it
270
+ * when a real response came back.
271
+ */
272
+ wasDefinitelyNotSent?: boolean;
255
273
  /**
256
274
  * Final request headers actually used by the adapter after adapter-local
257
275
  * mutations (for example multipart Content-Type/Content-Length added by the
@@ -276,12 +294,19 @@ interface AdapterResponse {
276
294
  */
277
295
  isStreamed?: boolean;
278
296
  /**
279
- * Set by NodeAdapter when response-body delivery fails after headers arrive
280
- * (for example buffered-download truncation, writable errors, or upstream
281
- * response-stream errors). The client treats this as a terminal stream
282
- * failure: isStreamError: true. The real HTTP status is preserved (not
283
- * zeroed) so observers can tell the server responded but body delivery still
284
- * failed locally/in-flight.
297
+ * Set when response-body delivery fails after headers arrive — buffered
298
+ * download truncation, writable errors, upstream response-stream errors.
299
+ * NodeAdapter, FetchAdapter and MockAdapter all report it, and the client
300
+ * synthesizes it for a per-attempt timeout that strikes mid-body. XHRAdapter
301
+ * cannot: `XMLHttpRequest` zeroes the status on error.
302
+ *
303
+ * The client treats this as a terminal stream failure. The real HTTP status is
304
+ * preserved (not zeroed) so observers can tell the server responded but body
305
+ * delivery still failed.
306
+ *
307
+ * For replay decisions this groups with a real response, **not** with a
308
+ * transport failure: headers arrived, so the server processed the request and
309
+ * may have committed it, the same thing a 500 tells you.
285
310
  */
286
311
  isStreamError?: boolean;
287
312
  /**
@@ -395,6 +420,23 @@ interface AttemptEndEvent {
395
420
  attemptNumber: number;
396
421
  isRetry: boolean;
397
422
  willRetry: boolean;
423
+ /**
424
+ * Why no retry happened, when a retry was genuinely available to suppress — a
425
+ * policy is configured, it has attempts left, and the status alone would have
426
+ * allowed one. Absent otherwise, since nothing was suppressed.
427
+ *
428
+ * - `adapter_veto` — the adapter reported `isRetryable: false`. Not produced by
429
+ * a real transport, which pairs that flag with the non-retryable `495`;
430
+ * reachable from `MockAdapter` and custom adapters.
431
+ * - `stream_error` — the body failed after headers arrived, so the server
432
+ * received the request and the outcome is unknown.
433
+ * - `non_idempotent_method` — a `POST` or `PATCH` with no proof the request
434
+ * went undelivered. Set `retryNonIdempotentMethods` to allow it.
435
+ *
436
+ * Exists so a suppressed retry is self-explaining: `willRetry: false` alone is
437
+ * indistinguishable from a policy declining.
438
+ */
439
+ retrySuppressedReason?: 'adapter_veto' | 'stream_error' | 'non_idempotent_method';
398
440
  /** Present only when a retry has been scheduled after this attempt. */
399
441
  nextRetryDelayMS?: number;
400
442
  /** Epoch ms for the scheduled retry, when a retry has been scheduled. */
@@ -423,6 +465,20 @@ interface HTTPClientConfig {
423
465
  timeout?: number;
424
466
  cookieJar?: CookieJar | null;
425
467
  retryPolicy?: RetryPolicyOptions;
468
+ /**
469
+ * Whether a retry policy may replay `POST` and `PATCH`, the methods RFC 9110
470
+ * does not define as idempotent. Defaults to `false`.
471
+ *
472
+ * When `false`, such a request is never retried after a real HTTP response —
473
+ * a 500 still means the handler ran and may have committed — and after a
474
+ * transport failure only when the adapter reports
475
+ * {@link AdapterResponse.wasDefinitelyNotSent}. A bare transport failure is not
476
+ * enough, and neither is `isRetryable: true`.
477
+ *
478
+ * Set to `true` when writes are guarded by an idempotency key or are naturally
479
+ * safe to repeat. Idempotent methods are unaffected either way.
480
+ */
481
+ retryNonIdempotentMethods?: boolean;
426
482
  includeRequestID?: boolean;
427
483
  includeAttemptHeader?: boolean;
428
484
  userAgent?: string;
@@ -448,6 +504,11 @@ interface HTTPRequestOptions {
448
504
  timeout?: number;
449
505
  signal?: AbortSignal;
450
506
  retryPolicy?: RetryPolicyOptions | null;
507
+ /**
508
+ * Per-request override for {@link HTTPClientConfig.retryNonIdempotentMethods}.
509
+ * Falls back to the client config when omitted.
510
+ */
511
+ retryNonIdempotentMethods?: boolean;
451
512
  label?: string;
452
513
  onUploadProgress?: (event: HTTPProgressEvent) => void;
453
514
  onDownloadProgress?: (event: HTTPProgressEvent) => void;