lifecycleion 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +125 -0
  3. package/dist/index.cjs +7 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +2 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +5 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/lib/arrays.cjs +95 -0
  10. package/dist/lib/arrays.cjs.map +1 -0
  11. package/dist/lib/arrays.d.cts +15 -0
  12. package/dist/lib/arrays.d.ts +15 -0
  13. package/dist/lib/arrays.js +63 -0
  14. package/dist/lib/arrays.js.map +1 -0
  15. package/dist/lib/ascii-tables/index.cjs +642 -0
  16. package/dist/lib/ascii-tables/index.cjs.map +1 -0
  17. package/dist/lib/ascii-tables/index.d.cts +66 -0
  18. package/dist/lib/ascii-tables/index.d.ts +66 -0
  19. package/dist/lib/ascii-tables/index.js +603 -0
  20. package/dist/lib/ascii-tables/index.js.map +1 -0
  21. package/dist/lib/clamp.cjs +41 -0
  22. package/dist/lib/clamp.cjs.map +1 -0
  23. package/dist/lib/clamp.d.cts +26 -0
  24. package/dist/lib/clamp.d.ts +26 -0
  25. package/dist/lib/clamp.js +15 -0
  26. package/dist/lib/clamp.js.map +1 -0
  27. package/dist/lib/constants.cjs +73 -0
  28. package/dist/lib/constants.cjs.map +1 -0
  29. package/dist/lib/constants.d.cts +17 -0
  30. package/dist/lib/constants.d.ts +17 -0
  31. package/dist/lib/constants.js +34 -0
  32. package/dist/lib/constants.js.map +1 -0
  33. package/dist/lib/curly-brackets.cjs +77 -0
  34. package/dist/lib/curly-brackets.cjs.map +1 -0
  35. package/dist/lib/curly-brackets.d.cts +17 -0
  36. package/dist/lib/curly-brackets.d.ts +17 -0
  37. package/dist/lib/curly-brackets.js +52 -0
  38. package/dist/lib/curly-brackets.js.map +1 -0
  39. package/dist/lib/deep-clone.cjs +87 -0
  40. package/dist/lib/deep-clone.cjs.map +1 -0
  41. package/dist/lib/deep-clone.d.cts +19 -0
  42. package/dist/lib/deep-clone.d.ts +19 -0
  43. package/dist/lib/deep-clone.js +62 -0
  44. package/dist/lib/deep-clone.js.map +1 -0
  45. package/dist/lib/error-to-string.cjs +743 -0
  46. package/dist/lib/error-to-string.cjs.map +1 -0
  47. package/dist/lib/error-to-string.d.cts +3 -0
  48. package/dist/lib/error-to-string.d.ts +3 -0
  49. package/dist/lib/error-to-string.js +706 -0
  50. package/dist/lib/error-to-string.js.map +1 -0
  51. package/dist/lib/event-emitter.cjs +899 -0
  52. package/dist/lib/event-emitter.cjs.map +1 -0
  53. package/dist/lib/event-emitter.d.cts +78 -0
  54. package/dist/lib/event-emitter.d.ts +78 -0
  55. package/dist/lib/event-emitter.js +861 -0
  56. package/dist/lib/event-emitter.js.map +1 -0
  57. package/dist/lib/id-helpers.cjs +205 -0
  58. package/dist/lib/id-helpers.cjs.map +1 -0
  59. package/dist/lib/id-helpers.d.cts +198 -0
  60. package/dist/lib/id-helpers.d.ts +198 -0
  61. package/dist/lib/id-helpers.js +170 -0
  62. package/dist/lib/id-helpers.js.map +1 -0
  63. package/dist/lib/is-boolean.cjs +33 -0
  64. package/dist/lib/is-boolean.cjs.map +1 -0
  65. package/dist/lib/is-boolean.d.cts +19 -0
  66. package/dist/lib/is-boolean.d.ts +19 -0
  67. package/dist/lib/is-boolean.js +8 -0
  68. package/dist/lib/is-boolean.js.map +1 -0
  69. package/dist/lib/is-function.cjs +33 -0
  70. package/dist/lib/is-function.cjs.map +1 -0
  71. package/dist/lib/is-function.d.cts +3 -0
  72. package/dist/lib/is-function.d.ts +3 -0
  73. package/dist/lib/is-function.js +8 -0
  74. package/dist/lib/is-function.js.map +1 -0
  75. package/dist/lib/is-number.cjs +38 -0
  76. package/dist/lib/is-number.cjs.map +1 -0
  77. package/dist/lib/is-number.d.cts +38 -0
  78. package/dist/lib/is-number.d.ts +38 -0
  79. package/dist/lib/is-number.js +12 -0
  80. package/dist/lib/is-number.js.map +1 -0
  81. package/dist/lib/is-plain-object.cjs +33 -0
  82. package/dist/lib/is-plain-object.cjs.map +1 -0
  83. package/dist/lib/is-plain-object.d.cts +20 -0
  84. package/dist/lib/is-plain-object.d.ts +20 -0
  85. package/dist/lib/is-plain-object.js +8 -0
  86. package/dist/lib/is-plain-object.js.map +1 -0
  87. package/dist/lib/is-promise.cjs +34 -0
  88. package/dist/lib/is-promise.cjs.map +1 -0
  89. package/dist/lib/is-promise.d.cts +3 -0
  90. package/dist/lib/is-promise.d.ts +3 -0
  91. package/dist/lib/is-promise.js +9 -0
  92. package/dist/lib/is-promise.js.map +1 -0
  93. package/dist/lib/json-helpers.cjs +49 -0
  94. package/dist/lib/json-helpers.cjs.map +1 -0
  95. package/dist/lib/json-helpers.d.cts +10 -0
  96. package/dist/lib/json-helpers.d.ts +10 -0
  97. package/dist/lib/json-helpers.js +22 -0
  98. package/dist/lib/json-helpers.js.map +1 -0
  99. package/dist/lib/lifecycle-manager/index.cjs +5594 -0
  100. package/dist/lib/lifecycle-manager/index.cjs.map +1 -0
  101. package/dist/lib/lifecycle-manager/index.d.cts +2044 -0
  102. package/dist/lib/lifecycle-manager/index.d.ts +2044 -0
  103. package/dist/lib/lifecycle-manager/index.js +5543 -0
  104. package/dist/lib/lifecycle-manager/index.js.map +1 -0
  105. package/dist/lib/logger/index.cjs +2514 -0
  106. package/dist/lib/logger/index.cjs.map +1 -0
  107. package/dist/lib/logger/index.d.cts +630 -0
  108. package/dist/lib/logger/index.d.ts +630 -0
  109. package/dist/lib/logger/index.js +2470 -0
  110. package/dist/lib/logger/index.js.map +1 -0
  111. package/dist/lib/padding-utils.cjs +77 -0
  112. package/dist/lib/padding-utils.cjs.map +1 -0
  113. package/dist/lib/padding-utils.d.cts +44 -0
  114. package/dist/lib/padding-utils.d.ts +44 -0
  115. package/dist/lib/padding-utils.js +46 -0
  116. package/dist/lib/padding-utils.js.map +1 -0
  117. package/dist/lib/process-signal-manager.cjs +1306 -0
  118. package/dist/lib/process-signal-manager.cjs.map +1 -0
  119. package/dist/lib/process-signal-manager.d.cts +305 -0
  120. package/dist/lib/process-signal-manager.d.ts +305 -0
  121. package/dist/lib/process-signal-manager.js +1269 -0
  122. package/dist/lib/process-signal-manager.js.map +1 -0
  123. package/dist/lib/promise-protected-resolver.cjs +828 -0
  124. package/dist/lib/promise-protected-resolver.cjs.map +1 -0
  125. package/dist/lib/promise-protected-resolver.d.cts +17 -0
  126. package/dist/lib/promise-protected-resolver.d.ts +17 -0
  127. package/dist/lib/promise-protected-resolver.js +791 -0
  128. package/dist/lib/promise-protected-resolver.js.map +1 -0
  129. package/dist/lib/retry-utils/index.cjs +2183 -0
  130. package/dist/lib/retry-utils/index.cjs.map +1 -0
  131. package/dist/lib/retry-utils/index.d.cts +321 -0
  132. package/dist/lib/retry-utils/index.d.ts +321 -0
  133. package/dist/lib/retry-utils/index.js +2133 -0
  134. package/dist/lib/retry-utils/index.js.map +1 -0
  135. package/dist/lib/safe-handle-callback.cjs +818 -0
  136. package/dist/lib/safe-handle-callback.cjs.map +1 -0
  137. package/dist/lib/safe-handle-callback.d.cts +43 -0
  138. package/dist/lib/safe-handle-callback.d.ts +43 -0
  139. package/dist/lib/safe-handle-callback.js +780 -0
  140. package/dist/lib/safe-handle-callback.js.map +1 -0
  141. package/dist/lib/serialize-error/index.cjs +93 -0
  142. package/dist/lib/serialize-error/index.cjs.map +1 -0
  143. package/dist/lib/serialize-error/index.d.cts +26 -0
  144. package/dist/lib/serialize-error/index.d.ts +26 -0
  145. package/dist/lib/serialize-error/index.js +64 -0
  146. package/dist/lib/serialize-error/index.js.map +1 -0
  147. package/dist/lib/single-event-observer.cjs +841 -0
  148. package/dist/lib/single-event-observer.cjs.map +1 -0
  149. package/dist/lib/single-event-observer.d.cts +54 -0
  150. package/dist/lib/single-event-observer.d.ts +54 -0
  151. package/dist/lib/single-event-observer.js +803 -0
  152. package/dist/lib/single-event-observer.js.map +1 -0
  153. package/dist/lib/sleep.cjs +37 -0
  154. package/dist/lib/sleep.cjs.map +1 -0
  155. package/dist/lib/sleep.d.cts +11 -0
  156. package/dist/lib/sleep.d.ts +11 -0
  157. package/dist/lib/sleep.js +12 -0
  158. package/dist/lib/sleep.js.map +1 -0
  159. package/dist/lib/strings.cjs +186 -0
  160. package/dist/lib/strings.cjs.map +1 -0
  161. package/dist/lib/strings.d.cts +107 -0
  162. package/dist/lib/strings.d.ts +107 -0
  163. package/dist/lib/strings.js +149 -0
  164. package/dist/lib/strings.js.map +1 -0
  165. package/dist/lib/tmp-dir.cjs +254 -0
  166. package/dist/lib/tmp-dir.cjs.map +1 -0
  167. package/dist/lib/tmp-dir.d.cts +63 -0
  168. package/dist/lib/tmp-dir.d.ts +63 -0
  169. package/dist/lib/tmp-dir.js +211 -0
  170. package/dist/lib/tmp-dir.js.map +1 -0
  171. package/dist/lib/unix-time-helpers.cjs +53 -0
  172. package/dist/lib/unix-time-helpers.cjs.map +1 -0
  173. package/dist/lib/unix-time-helpers.d.cts +56 -0
  174. package/dist/lib/unix-time-helpers.d.ts +56 -0
  175. package/dist/lib/unix-time-helpers.js +24 -0
  176. package/dist/lib/unix-time-helpers.js.map +1 -0
  177. package/package.json +220 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/lifecycle-manager/index.ts","../../../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/event-emitter.ts","../../../src/lib/lifecycle-manager/component-lifecycle.ts","../../../src/lib/lifecycle-manager/events.ts","../../../src/lib/lifecycle-manager/errors.ts","../../../src/lib/process-signal-manager.ts","../../../src/lib/lifecycle-manager/lifecycle-manager.ts","../../../src/lib/lifecycle-manager/base-component.ts"],"sourcesContent":["/**\n * LifecycleManager - Comprehensive lifecycle orchestration system\n *\n * Manages startup, shutdown, and runtime control of application components with:\n * - Multi-phase shutdown (global warning -> per-component graceful -> force)\n * - Dependency-ordered component startup\n * - Process signal integration (SIGINT, SIGTERM, SIGHUP, etc.)\n * - Component messaging and value sharing\n * - Health checks and monitoring\n * - Event-driven architecture\n *\n * @module lifecycle-manager\n */\n\n// Core classes\nexport { LifecycleManager } from './lifecycle-manager';\nexport { BaseComponent } from './base-component';\nexport {\n LifecycleManagerEvents,\n type LifecycleManagerEventMap,\n type LifecycleManagerEventName,\n type LifecycleManagerEmit,\n} from './events';\n\n// Types\nexport type {\n ComponentOptions,\n ComponentState,\n ComponentStatus,\n ComponentStallInfo,\n ShutdownMethod,\n BaseOperationResult,\n ComponentOperationResult,\n ComponentOperationFailureCode,\n StartComponentOptions,\n StopComponentOptions,\n StopAllOptions,\n RestartComponentOptions,\n UnregisterComponentResult,\n UnregisterFailureCode,\n StartupResult,\n ShutdownResult,\n RestartResult,\n MessageResult,\n SendMessageOptions,\n BroadcastResult,\n BroadcastOptions,\n ComponentHealthResult,\n HealthCheckResult,\n HealthReport,\n SignalBroadcastResult,\n ComponentSignalResult,\n ValueResult,\n ComponentValueResult,\n GetValueOptions,\n SystemState,\n RegisterOptions,\n UnregisterOptions,\n StartupOptions,\n InsertPosition,\n RegistrationFailureCode,\n StartupOrderFailureCode,\n StartupOrderResult,\n RegisterComponentResult,\n InsertComponentAtResult,\n LifecycleManagerOptions,\n LifecycleManagerStatus,\n DependencyValidationResult,\n} from './types';\n\n// Errors\nexport {\n InvalidComponentNameError,\n ComponentRegistrationError,\n DependencyCycleError,\n MissingDependencyError,\n ComponentStartupError,\n ComponentStartTimeoutError,\n ComponentStopTimeoutError,\n StartupTimeoutError,\n ComponentNotFoundError,\n lifecycleManagerErrPrefix,\n lifecycleManagerErrTypes,\n lifecycleManagerErrCodes,\n} from './errors';\n","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 return String(value as string | number | boolean);\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 (standard API available in Node.js 15+, 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 // Available in Node.js 15+, 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 (standard API available in Node.js 15+, 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 // Available in Node.js 15+, 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","/**\n * Instead of using `EventEmitter`, you could extend `EventEmitterProtected`\n * if you want the emit method to be protected, and allow only your class to emit events.\n *\n * A simplified event emitter implementation that works in both browser and Node.js environments.\n * This provides basic event handling functionality with type safety and memory management.\n */\n\nimport { safeHandleCallback } from './safe-handle-callback';\n\ntype EventCallback<T = unknown> = (data: T) => void | Promise<void>;\n\nexport class EventEmitterProtected {\n private events: Map<string, Set<EventCallback<unknown>>>;\n\n constructor() {\n this.events = new Map();\n }\n\n /**\n * Subscribe to an event\n * @param event The event name to subscribe to\n * @param callback The callback function to be called when the event is emitted\n * @returns A function to unsubscribe from the event\n */\n public on<T = unknown>(\n event: string,\n callback: EventCallback<T>,\n ): () => void {\n if (!this.events.has(event)) {\n this.events.set(event, new Set());\n }\n const callbacks = this.events.get(event);\n\n if (callbacks) {\n callbacks.add(callback as EventCallback<unknown>);\n }\n\n // Return unsubscribe function for cleanup\n return () => {\n const callbacks = this.events.get(event);\n if (callbacks) {\n callbacks.delete(callback as EventCallback<unknown>);\n\n if (callbacks.size === 0) {\n this.events.delete(event);\n }\n }\n };\n }\n\n /**\n * Subscribe to an event once - automatically unsubscribes after first emission\n * @param event The event name to subscribe to\n * @param callback The callback function to be called when the event is emitted\n * @returns A function to unsubscribe from the event before it's called\n */\n public once<T = unknown>(\n event: string,\n callback: EventCallback<T>,\n ): () => void {\n const unsubscribe = this.on(event, (data: T) => {\n unsubscribe();\n return callback(data);\n });\n\n return unsubscribe;\n }\n\n /**\n * Check if a specific callback is registered for an event.\n * Note: For 'once' handlers, this will return true for the wrapper function, not the original callback.\n * This means hasListener will return false when checking for the original callback of a 'once' subscription.\n *\n * @param event The event name to check\n * @param callback The callback function to look for\n * @returns true if the exact callback is registered, false otherwise\n */\n public hasListener<T = unknown>(\n event: string,\n callback: EventCallback<T>,\n ): boolean {\n const callbacks = this.events.get(event);\n return callbacks?.has(callback as EventCallback<unknown>) ?? false;\n }\n\n /**\n * Check if an event has any subscribers\n * @param event The event name to check\n * @returns true if the event has subscribers, false otherwise\n */\n public hasListeners(event: string): boolean {\n const callbacks = this.events.get(event);\n return callbacks !== undefined && callbacks.size > 0;\n }\n\n /**\n * Get the number of subscribers for an event\n * @param event The event name to check\n * @returns The number of subscribers\n */\n public listenerCount(event: string): number {\n const callbacks = this.events.get(event);\n return callbacks ? callbacks.size : 0;\n }\n\n /**\n * Remove all event listeners\n * @param event Optional event name. If not provided, removes all listeners for all events\n */\n public clear(event?: string): void {\n if (event) {\n this.events.delete(event);\n } else {\n this.events.clear();\n }\n }\n\n /**\n * Emit an event with optional data\n * This method is protected to allow only derived classes to trigger events.\n * @param event The event name to emit\n * @param data Optional data to pass to the event handlers\n */\n protected emit<T = unknown>(event: string, data?: T): void {\n const callbacks = this.events.get(event);\n if (callbacks) {\n for (const callback of callbacks) {\n safeHandleCallback(`event handler for ${event}`, callback, data);\n }\n }\n }\n}\n\n/**\n * A class that implements the event emitter pattern with public emit method.\n * This class extends EventEmitterProtected and makes the emit method public.\n *\n * Use this when you want any code with access to the emitter to be able to trigger events.\n * If you want to control who can emit events, extend EventEmitterProtected instead.\n */\n\nexport class EventEmitter extends EventEmitterProtected {\n /**\n * Emit an event with optional data\n * This method is public, allowing any code with access to the emitter to trigger events.\n * @param event The event name to emit\n * @param data Optional data to pass to the event handlers\n */\n\n public emit<T = unknown>(event: string, data?: T): void {\n super.emit(event, data);\n }\n}\n","import type {\n LifecycleCommon,\n ComponentLifecycleRef,\n ComponentOperationResult,\n ComponentStatus,\n ComponentStallInfo,\n LifecycleManagerStatus,\n DependencyValidationResult,\n LifecycleSignalStatus,\n RestartComponentOptions,\n RestartResult,\n RestartAllOptions,\n ShutdownResult,\n SignalBroadcastResult,\n StartComponentOptions,\n StartupOptions,\n StartupOrderResult,\n StartupResult,\n StopComponentOptions,\n StopAllOptions,\n SystemState,\n MessageResult,\n BroadcastResult,\n BroadcastOptions,\n SendMessageOptions,\n GetValueOptions,\n HealthCheckResult,\n HealthReport,\n ValueResult,\n LifecycleInternalCallbacks,\n} from './types';\n\nexport class ComponentLifecycle implements ComponentLifecycleRef {\n private readonly manager: LifecycleCommon;\n private readonly componentName: string;\n private readonly internalCallbacks: LifecycleInternalCallbacks;\n\n constructor(\n manager: LifecycleCommon,\n componentName: string,\n internalCallbacks: LifecycleInternalCallbacks,\n ) {\n this.manager = manager;\n this.componentName = componentName;\n this.internalCallbacks = internalCallbacks;\n }\n\n public on<T = unknown>(\n event: string,\n callback: (data: T) => void | Promise<void>,\n ): () => void {\n return this.manager.on(event, callback);\n }\n\n public once<T = unknown>(\n event: string,\n callback: (data: T) => void | Promise<void>,\n ): () => void {\n return this.manager.once(event, callback);\n }\n\n public hasListener<T = unknown>(\n event: string,\n callback: (data: T) => void | Promise<void>,\n ): boolean {\n return this.manager.hasListener(event, callback);\n }\n\n public hasListeners(event: string): boolean {\n return this.manager.hasListeners(event);\n }\n\n public listenerCount(event: string): number {\n return this.manager.listenerCount(event);\n }\n\n public hasComponent(name: string): boolean {\n return this.manager.hasComponent(name);\n }\n\n public isComponentRunning(name: string): boolean {\n return this.manager.isComponentRunning(name);\n }\n\n public getComponentNames(): string[] {\n return this.manager.getComponentNames();\n }\n\n public getRunningComponentNames(): string[] {\n return this.manager.getRunningComponentNames();\n }\n\n public getComponentCount(): number {\n return this.manager.getComponentCount();\n }\n\n public getRunningComponentCount(): number {\n return this.manager.getRunningComponentCount();\n }\n\n public getStalledComponentCount(): number {\n return this.manager.getStalledComponentCount();\n }\n\n public getStoppedComponentCount(): number {\n return this.manager.getStoppedComponentCount();\n }\n\n public getComponentStatus(name: string): ComponentStatus | undefined {\n return this.manager.getComponentStatus(name);\n }\n\n public getAllComponentStatuses(): ComponentStatus[] {\n return this.manager.getAllComponentStatuses();\n }\n\n public getSystemState(): SystemState {\n return this.manager.getSystemState();\n }\n\n public getStatus(): LifecycleManagerStatus {\n return this.manager.getStatus();\n }\n\n public getStalledComponents(): ComponentStallInfo[] {\n return this.manager.getStalledComponents();\n }\n\n public getStalledComponentNames(): string[] {\n return this.manager.getStalledComponentNames();\n }\n\n public getStoppedComponentNames(): string[] {\n return this.manager.getStoppedComponentNames();\n }\n\n public getStartupOrder(): StartupOrderResult {\n return this.manager.getStartupOrder();\n }\n\n public validateDependencies(): DependencyValidationResult {\n return this.manager.validateDependencies();\n }\n\n public startAllComponents(options?: StartupOptions): Promise<StartupResult> {\n return this.manager.startAllComponents(options);\n }\n\n public stopAllComponents(options?: StopAllOptions): Promise<ShutdownResult> {\n return this.manager.stopAllComponents(options);\n }\n\n public restartAllComponents(\n options?: RestartAllOptions,\n ): Promise<RestartResult> {\n return this.manager.restartAllComponents(options);\n }\n\n public startComponent(\n name: string,\n options?: StartComponentOptions,\n ): Promise<ComponentOperationResult> {\n return this.manager.startComponent(name, options);\n }\n\n public stopComponent(\n name: string,\n options?: StopComponentOptions,\n ): Promise<ComponentOperationResult> {\n return this.manager.stopComponent(name, options);\n }\n\n public restartComponent(\n name: string,\n options?: RestartComponentOptions,\n ): Promise<ComponentOperationResult> {\n return this.manager.restartComponent(name, options);\n }\n\n public attachSignals(): void {\n this.manager.attachSignals();\n }\n\n public detachSignals(): void {\n this.manager.detachSignals();\n }\n\n public getSignalStatus(): LifecycleSignalStatus {\n return this.manager.getSignalStatus();\n }\n\n public triggerReload(): Promise<SignalBroadcastResult> {\n return this.manager.triggerReload();\n }\n\n public triggerInfo(): Promise<SignalBroadcastResult> {\n return this.manager.triggerInfo();\n }\n\n public triggerDebug(): Promise<SignalBroadcastResult> {\n return this.manager.triggerDebug();\n }\n\n // ============================================================================\n // Component Messaging (with automatic 'from' tracking)\n // ============================================================================\n\n /**\n * Send a message to another component\n *\n * When called from within a component, automatically tracks the sender.\n * The 'from' parameter will be set to this component's name.\n *\n * @param componentName - Target component name\n * @param payload - Message payload\n * @param options - Optional message options (timeout override)\n * @returns Result with sent status, data, and any errors\n */\n public sendMessageToComponent(\n componentName: string,\n payload: unknown,\n options?: SendMessageOptions,\n ): Promise<MessageResult> {\n // Call internal callback with automatic 'from' tracking\n // Automatically passes this component's name as 'from'\n return this.internalCallbacks.sendMessageInternal(\n componentName,\n payload,\n this.componentName,\n options,\n );\n }\n\n /**\n * Broadcast a message to multiple components\n *\n * When called from within a component, automatically tracks the sender.\n * The 'from' parameter will be set to this component's name.\n *\n * @param payload - Message payload\n * @param options - Filtering options and message timeout override\n * @returns Array of results, one per component\n */\n public broadcastMessage(\n payload: unknown,\n options?: BroadcastOptions,\n ): Promise<BroadcastResult[]> {\n // Call internal callback with automatic 'from' tracking\n // Automatically passes this component's name as 'from'\n return this.internalCallbacks.broadcastMessageInternal(\n payload,\n this.componentName,\n options,\n );\n }\n\n // ============================================================================\n // Health Checks\n // ============================================================================\n\n /**\n * Check the health of a specific component\n *\n * @param name - Component name\n * @returns Health check result\n */\n public checkComponentHealth(name: string): Promise<HealthCheckResult> {\n return this.manager.checkComponentHealth(name);\n }\n\n /**\n * Check the health of all running components\n *\n * @returns Aggregate health report\n */\n public checkAllHealth(): Promise<HealthReport> {\n return this.manager.checkAllHealth();\n }\n\n // ============================================================================\n // Shared Values (with automatic 'from' tracking)\n // ============================================================================\n\n /**\n * Request a value from another component\n *\n * When called from within a component, automatically tracks the requester.\n * The 'from' parameter will be set to this component's name.\n *\n * @param componentName - Target component name\n * @param key - Value key\n * @returns Result with found status, value, and metadata\n */\n public getValue<T = unknown>(\n componentName: string,\n key: string,\n options?: GetValueOptions,\n ): ValueResult<T> {\n // Call internal callback with automatic 'from' tracking\n // Automatically passes this component's name as 'from'\n return this.internalCallbacks.getValueInternal<T>(\n componentName,\n key,\n this.componentName,\n options,\n );\n }\n}\n","import type {\n BroadcastResult,\n ComponentHealthResult,\n ComponentStallInfo,\n ComponentStatus,\n InsertComponentAtResult,\n MessageResult,\n RegistrationFailureCode,\n RegisterComponentResult,\n ShutdownMethod,\n StartupResult,\n ValueResult,\n} from './types';\nimport type { ShutdownSignal } from '../process-signal-manager';\n\nexport interface LifecycleManagerEventMap {\n 'component:unregistered': { name: string; duringShutdown?: boolean };\n 'component:start-skipped': { name: string; reason: string };\n 'component:start-failed-optional': { name: string; error?: Error };\n 'lifecycle-manager:started': {\n startedComponents: string[];\n failedOptionalComponents: StartupResult['failedOptionalComponents'];\n skippedComponents: string[];\n };\n 'lifecycle-manager:signals-attached': undefined;\n 'lifecycle-manager:signals-detached': undefined;\n 'component:health-check-started': { name: string };\n 'component:health-check-completed': {\n name: string;\n healthy: boolean;\n message?: string;\n details?: ComponentHealthResult['details'];\n durationMS: number;\n timedOut: boolean;\n };\n 'component:health-check-failed': { name: string; error: Error };\n 'component:message-sent': {\n componentName: string;\n from: string | null;\n payload: unknown;\n };\n 'component:message-failed': {\n componentName: string;\n from: string | null;\n error: Error;\n timedOut: boolean;\n code: MessageResult['code'];\n componentFound?: boolean;\n componentRunning?: boolean;\n handlerImplemented?: boolean;\n data?: unknown;\n };\n 'component:broadcast-started': { from: string | null; payload: unknown };\n 'component:broadcast-completed': {\n from: string | null;\n resultsCount: number;\n results: BroadcastResult[];\n };\n 'component:value-requested': {\n componentName: string;\n key: string;\n from: string | null;\n };\n 'component:value-returned': {\n componentName: string;\n key: string;\n from: string | null;\n found: boolean;\n value: unknown;\n componentFound: boolean;\n componentRunning: boolean;\n handlerImplemented: boolean;\n requestedBy: string | null;\n code: ValueResult['code'];\n };\n 'component:registration-rejected': {\n name: string;\n reason: RegistrationFailureCode;\n message?: string;\n target?: string | null;\n cycle?: string[];\n registrationIndexBefore?: number | null;\n registrationIndexAfter?: number | null;\n startupOrder?: string[];\n requestedPosition?: InsertComponentAtResult['requestedPosition'];\n manualPositionRespected?: boolean;\n targetFound?: boolean;\n };\n 'component:registered': {\n name: string;\n index: number | null;\n action:\n | RegisterComponentResult['action']\n | InsertComponentAtResult['action'];\n registrationIndexBefore: number | null;\n registrationIndexAfter: number | null;\n startupOrder: string[];\n requestedPosition?: InsertComponentAtResult['requestedPosition'];\n actualPosition?: InsertComponentAtResult['actualPosition'];\n manualPositionRespected?: boolean;\n targetFound?: boolean;\n duringStartup?: boolean;\n autoStartAttempted?: boolean;\n autoStartSucceeded?: boolean;\n };\n 'lifecycle-manager:shutdown-initiated': {\n method: ShutdownMethod;\n duringStartup: boolean;\n };\n 'lifecycle-manager:shutdown-completed': {\n durationMS: number;\n stoppedComponents: string[];\n stalledComponents: ComponentStallInfo[];\n method: ShutdownMethod;\n duringStartup: boolean;\n };\n 'component:starting': { name: string };\n 'component:started': { name: string; status?: ComponentStatus };\n 'component:start-timeout': {\n name: string;\n error: Error;\n timeoutMS?: number;\n reason?: string;\n };\n 'component:start-failed': {\n name: string;\n error: Error;\n reason?: string;\n };\n 'lifecycle-manager:shutdown-warning': { timeoutMS: number };\n 'component:shutdown-warning': { name: string };\n 'component:shutdown-warning-completed': { name: string };\n 'lifecycle-manager:shutdown-warning-completed': { timeoutMS: number };\n 'component:shutdown-warning-timeout': { name: string; timeoutMS: number };\n 'lifecycle-manager:shutdown-warning-timeout': {\n timeoutMS: number;\n pending: string[];\n };\n 'component:stopping': { name: string };\n 'component:stopped': { name: string; status?: ComponentStatus };\n 'component:stop-timeout': {\n name: string;\n error: Error;\n timeoutMS?: number;\n reason?: string;\n };\n 'component:shutdown-force': {\n name: string;\n context: { gracefulPhaseRan: boolean; gracefulTimedOut: boolean };\n };\n 'component:stalled': {\n name: string;\n stallInfo: ComponentStallInfo;\n reason?: string;\n code?: string;\n };\n 'component:shutdown-force-completed': { name: string };\n 'component:shutdown-force-timeout': { name: string; timeoutMS: number };\n 'component:startup-rollback': { name: string };\n 'signal:shutdown': { method: ShutdownSignal };\n 'signal:reload': undefined;\n 'signal:info': undefined;\n 'signal:debug': undefined;\n 'component:reload-started': { name: string };\n 'component:reload-completed': { name: string };\n 'component:reload-failed': { name: string; error: Error };\n 'component:info-started': { name: string };\n 'component:info-completed': { name: string };\n 'component:info-failed': { name: string; error: Error };\n 'component:debug-started': { name: string };\n 'component:debug-completed': { name: string };\n 'component:debug-failed': { name: string; error: Error };\n}\n\nexport type LifecycleManagerEventName = keyof LifecycleManagerEventMap;\n\nexport type LifecycleManagerEmit = <K extends LifecycleManagerEventName>(\n event: K,\n data: LifecycleManagerEventMap[K],\n) => void;\n\nexport class LifecycleManagerEvents {\n constructor(private readonly emit: LifecycleManagerEmit) {}\n\n public componentUnregistered(\n name: string,\n wasDuringShutdown?: boolean,\n ): void {\n this.emit('component:unregistered', {\n name,\n duringShutdown: wasDuringShutdown,\n });\n }\n\n public componentStartSkipped(name: string, reason: string): void {\n this.emit('component:start-skipped', { name, reason });\n }\n\n public componentStartFailedOptional(name: string, error?: Error): void {\n this.emit('component:start-failed-optional', { name, error });\n }\n\n public lifecycleManagerStarted(\n startedComponents: string[],\n failedOptionalComponents: StartupResult['failedOptionalComponents'],\n skippedComponents: string[],\n ): void {\n this.emit('lifecycle-manager:started', {\n startedComponents,\n failedOptionalComponents,\n skippedComponents,\n });\n }\n\n public lifecycleManagerSignalsAttached(): void {\n this.emit('lifecycle-manager:signals-attached', undefined);\n }\n\n public lifecycleManagerSignalsDetached(): void {\n this.emit('lifecycle-manager:signals-detached', undefined);\n }\n\n public componentHealthCheckStarted(name: string): void {\n this.emit('component:health-check-started', { name });\n }\n\n public componentHealthCheckCompleted(input: {\n name: string;\n healthy: boolean;\n message?: string;\n details?: ComponentHealthResult['details'];\n durationMS: number;\n timedOut: boolean;\n }): void {\n this.emit('component:health-check-completed', input);\n }\n\n public componentHealthCheckFailed(name: string, error: Error): void {\n this.emit('component:health-check-failed', { name, error });\n }\n\n public componentMessageSent(input: {\n componentName: string;\n from: string | null;\n payload: unknown;\n }): void {\n this.emit('component:message-sent', input);\n }\n\n public componentMessageFailed(\n componentName: string,\n from: string | null,\n error: Error,\n info?: {\n timedOut?: boolean;\n code?: MessageResult['code'];\n componentFound?: boolean;\n componentRunning?: boolean;\n handlerImplemented?: boolean;\n data?: unknown;\n },\n ): void {\n this.emit('component:message-failed', {\n componentName,\n from,\n error,\n timedOut: info?.timedOut ?? false,\n code: info?.code ?? 'error',\n componentFound: info?.componentFound,\n componentRunning: info?.componentRunning,\n handlerImplemented: info?.handlerImplemented,\n data: info?.data,\n });\n }\n\n public componentBroadcastStarted(\n from: string | null,\n payload: unknown,\n ): void {\n this.emit('component:broadcast-started', { from, payload });\n }\n\n public componentBroadcastCompleted(\n from: string | null,\n resultsCount: number,\n results: BroadcastResult[],\n ): void {\n this.emit('component:broadcast-completed', { from, resultsCount, results });\n }\n\n public componentValueRequested(\n componentName: string,\n key: string,\n from: string | null,\n ): void {\n this.emit('component:value-requested', { componentName, key, from });\n }\n\n public componentValueReturned(\n componentName: string,\n key: string,\n from: string | null,\n input: {\n found: boolean;\n value: unknown;\n componentFound: boolean;\n componentRunning: boolean;\n handlerImplemented: boolean;\n requestedBy: string | null;\n code: ValueResult['code'];\n },\n ): void {\n this.emit('component:value-returned', {\n componentName,\n key,\n from,\n ...input,\n });\n }\n\n public componentRegistrationRejected(input: {\n name: string;\n reason: RegistrationFailureCode;\n message?: string;\n target?: string | null;\n cycle?: string[];\n registrationIndexBefore?: number | null;\n registrationIndexAfter?: number | null;\n startupOrder?: string[];\n requestedPosition?: InsertComponentAtResult['requestedPosition'];\n manualPositionRespected?: boolean;\n targetFound?: boolean;\n }): void {\n this.emit('component:registration-rejected', input);\n }\n\n public componentRegistered(input: {\n name: string;\n index: number | null;\n action:\n | RegisterComponentResult['action']\n | InsertComponentAtResult['action'];\n registrationIndexBefore: number | null;\n registrationIndexAfter: number | null;\n startupOrder: string[];\n requestedPosition?: InsertComponentAtResult['requestedPosition'];\n actualPosition?: InsertComponentAtResult['actualPosition'];\n manualPositionRespected?: boolean;\n targetFound?: boolean;\n duringStartup?: boolean;\n autoStartAttempted?: boolean;\n autoStartSucceeded?: boolean;\n }): void {\n this.emit('component:registered', input);\n }\n\n public lifecycleManagerShutdownInitiated(\n method: ShutdownMethod,\n isDuringStartup: boolean,\n ): void {\n this.emit('lifecycle-manager:shutdown-initiated', {\n method,\n duringStartup: isDuringStartup,\n });\n }\n\n public lifecycleManagerShutdownCompleted(input: {\n durationMS: number;\n stoppedComponents: string[];\n stalledComponents: ComponentStallInfo[];\n method: ShutdownMethod;\n duringStartup: boolean;\n }): void {\n this.emit('lifecycle-manager:shutdown-completed', input);\n }\n\n public componentStarting(name: string): void {\n this.emit('component:starting', { name });\n }\n\n public componentStarted(name: string, status?: ComponentStatus): void {\n this.emit('component:started', { name, status });\n }\n\n public componentStartTimeout(\n name: string,\n error: Error,\n info?: { timeoutMS?: number; reason?: string },\n ): void {\n this.emit('component:start-timeout', {\n name,\n error,\n timeoutMS: info?.timeoutMS,\n reason: info?.reason,\n });\n }\n\n public componentStartFailed(\n name: string,\n error: Error,\n info?: { reason?: string },\n ): void {\n this.emit('component:start-failed', {\n name,\n error,\n reason: info?.reason,\n });\n }\n\n public lifecycleManagerShutdownWarning(timeoutMS: number): void {\n this.emit('lifecycle-manager:shutdown-warning', { timeoutMS });\n }\n\n public componentShutdownWarning(name: string): void {\n this.emit('component:shutdown-warning', { name });\n }\n\n public componentShutdownWarningCompleted(name: string): void {\n this.emit('component:shutdown-warning-completed', { name });\n }\n\n public lifecycleManagerShutdownWarningCompleted(timeoutMS: number): void {\n this.emit('lifecycle-manager:shutdown-warning-completed', { timeoutMS });\n }\n\n public componentShutdownWarningTimeout(\n name: string,\n timeoutMS: number,\n ): void {\n this.emit('component:shutdown-warning-timeout', { name, timeoutMS });\n }\n\n public lifecycleManagerShutdownWarningTimeout(\n timeoutMS: number,\n pending: string[],\n ): void {\n this.emit('lifecycle-manager:shutdown-warning-timeout', {\n timeoutMS,\n pending,\n });\n }\n\n public componentStopping(name: string): void {\n this.emit('component:stopping', { name });\n }\n\n public componentStopped(name: string, status?: ComponentStatus): void {\n this.emit('component:stopped', { name, status });\n }\n\n public componentStopTimeout(\n name: string,\n error: Error,\n info?: { timeoutMS?: number; reason?: string },\n ): void {\n this.emit('component:stop-timeout', {\n name,\n error,\n timeoutMS: info?.timeoutMS,\n reason: info?.reason,\n });\n }\n\n public componentShutdownForce(input: {\n name: string;\n context: { gracefulPhaseRan: boolean; gracefulTimedOut: boolean };\n }): void {\n this.emit('component:shutdown-force', input);\n }\n\n public componentStalled(\n name: string,\n stallInfo: ComponentStallInfo,\n info?: { reason?: string; code?: string },\n ): void {\n this.emit('component:stalled', {\n name,\n stallInfo,\n reason: info?.reason,\n code: info?.code,\n });\n }\n\n public componentShutdownForceCompleted(name: string): void {\n this.emit('component:shutdown-force-completed', { name });\n }\n\n public componentShutdownForceTimeout(name: string, timeoutMS: number): void {\n this.emit('component:shutdown-force-timeout', { name, timeoutMS });\n }\n\n public componentStartupRollback(name: string): void {\n this.emit('component:startup-rollback', { name });\n }\n\n public signalShutdown(method: ShutdownSignal): void {\n this.emit('signal:shutdown', { method });\n }\n\n public signalReload(): void {\n this.emit('signal:reload', undefined);\n }\n\n public signalInfo(): void {\n this.emit('signal:info', undefined);\n }\n\n public signalDebug(): void {\n this.emit('signal:debug', undefined);\n }\n\n public componentReloadStarted(name: string): void {\n this.emit('component:reload-started', { name });\n }\n\n public componentReloadCompleted(name: string): void {\n this.emit('component:reload-completed', { name });\n }\n\n public componentReloadFailed(name: string, error: Error): void {\n this.emit('component:reload-failed', { name, error });\n }\n\n public componentInfoStarted(name: string): void {\n this.emit('component:info-started', { name });\n }\n\n public componentInfoCompleted(name: string): void {\n this.emit('component:info-completed', { name });\n }\n\n public componentInfoFailed(name: string, error: Error): void {\n this.emit('component:info-failed', { name, error });\n }\n\n public componentDebugStarted(name: string): void {\n this.emit('component:debug-started', { name });\n }\n\n public componentDebugCompleted(name: string): void {\n this.emit('component:debug-completed', { name });\n }\n\n public componentDebugFailed(name: string, error: Error): void {\n this.emit('component:debug-failed', { name, error });\n }\n}\n","/**\n * Error thrown when a component name doesn't match kebab-case validation\n *\n * Component names must match the pattern: `/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/`\n *\n * Valid names: 'database', 'web-server', 'api-gateway-v2'\n * Invalid names: 'Database', 'web_server', 'WebServer', '', 'my server'\n */\nexport class InvalidComponentNameError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Component';\n public errCode = 'InvalidName';\n public additionalInfo: { name: string };\n\n constructor(additionalInfo: { name: string }) {\n super(\n `Invalid component name: \"${additionalInfo.name}\". Component names must be kebab-case (lowercase letters, numbers, and hyphens only).`,\n );\n this.name = 'InvalidComponentNameError';\n this.additionalInfo = additionalInfo;\n }\n}\n\n/**\n * Error thrown when component registration fails\n *\n * Common causes:\n * - Duplicate component name\n * - Registration attempted during shutdown\n * - Invalid registration options\n */\nexport class ComponentRegistrationError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Component';\n public errCode = 'RegistrationFailed';\n public additionalInfo: Record<string, unknown>;\n\n constructor(message: string, additionalInfo: Record<string, unknown> = {}) {\n super(message);\n this.name = 'ComponentRegistrationError';\n this.additionalInfo = additionalInfo;\n }\n}\n\n/**\n * Error thrown when a circular dependency is detected\n *\n * Example: Component A depends on B, B depends on C, C depends on A\n */\nexport class DependencyCycleError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Dependency';\n public errCode = 'CyclicDependency';\n public additionalInfo: { cycle: string[] };\n\n constructor(additionalInfo: { cycle: string[] }) {\n super(\n `Circular dependency detected: ${additionalInfo.cycle.join(' -> ')} -> ${additionalInfo.cycle[0]}`,\n );\n this.name = 'DependencyCycleError';\n this.additionalInfo = additionalInfo;\n }\n}\n\n/**\n * Error thrown when a component depends on another component that doesn't exist\n */\nexport class MissingDependencyError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Dependency';\n public errCode = 'NotFound';\n public additionalInfo: { componentName: string; missingDependency: string };\n\n constructor(additionalInfo: {\n componentName: string;\n missingDependency: string;\n }) {\n super(\n `Component \"${additionalInfo.componentName}\" depends on \"${additionalInfo.missingDependency}\", but it is not registered.`,\n );\n this.name = 'MissingDependencyError';\n this.additionalInfo = additionalInfo;\n }\n}\n\n/**\n * Error thrown when a component fails to start\n *\n * This wraps the underlying error and provides context about which component failed\n */\nexport class ComponentStartupError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Component';\n public errCode = 'StartupFailed';\n public additionalInfo: { componentName: string };\n public cause?: Error;\n\n constructor(additionalInfo: { componentName: string }, cause?: Error) {\n const causeMessage = cause ? `: ${cause.message}` : '';\n super(\n `Component \"${additionalInfo.componentName}\" failed to start${causeMessage}`,\n );\n this.name = 'ComponentStartupError';\n this.additionalInfo = additionalInfo;\n if (cause) {\n this.cause = cause;\n }\n }\n}\n\n/**\n * Error thrown when a component start operation times out\n */\nexport class ComponentStartTimeoutError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Component';\n public errCode = 'StartTimeout';\n public additionalInfo: { componentName: string; timeoutMS: number };\n\n constructor(additionalInfo: { componentName: string; timeoutMS: number }) {\n super(\n `Component \"${additionalInfo.componentName}\" start timed out after ${additionalInfo.timeoutMS}ms`,\n );\n this.name = 'ComponentStartTimeoutError';\n this.additionalInfo = additionalInfo;\n }\n}\n\n/**\n * Error thrown when a component stop operation times out\n */\nexport class ComponentStopTimeoutError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Component';\n public errCode = 'StopTimeout';\n public additionalInfo: { componentName: string; timeoutMS: number };\n\n constructor(additionalInfo: { componentName: string; timeoutMS: number }) {\n super(\n `Component \"${additionalInfo.componentName}\" stop timed out after ${additionalInfo.timeoutMS}ms`,\n );\n this.name = 'ComponentStopTimeoutError';\n this.additionalInfo = additionalInfo;\n }\n}\n\n/**\n * Error thrown when the global startup timeout is exceeded\n */\nexport class StartupTimeoutError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Lifecycle';\n public errCode = 'StartupTimeout';\n public additionalInfo: { timeoutMS: number; startedCount: number };\n\n constructor(additionalInfo: { timeoutMS: number; startedCount: number }) {\n super(\n `Startup timed out after ${additionalInfo.timeoutMS}ms (${additionalInfo.startedCount} components started)`,\n );\n this.name = 'StartupTimeoutError';\n this.additionalInfo = additionalInfo;\n }\n}\n\n/**\n * Error thrown when a component is not found in the registry\n */\nexport class ComponentNotFoundError extends Error {\n public errPrefix = 'LifecycleManagerErr';\n public errType = 'Component';\n public errCode = 'NotFound';\n public additionalInfo: { componentName: string };\n\n constructor(additionalInfo: { componentName: string }) {\n super(`Component \"${additionalInfo.componentName}\" not found in registry`);\n this.name = 'ComponentNotFoundError';\n this.additionalInfo = additionalInfo;\n }\n}\n\n/**\n * Error prefix constant for all lifecycle manager errors\n */\nexport const lifecycleManagerErrPrefix = 'LifecycleManagerErr';\n\n/**\n * Error type constants\n */\nexport const lifecycleManagerErrTypes = {\n Component: 'Component',\n Dependency: 'Dependency',\n Lifecycle: 'Lifecycle',\n} as const;\n\n/**\n * Error code constants\n */\nexport const lifecycleManagerErrCodes = {\n InvalidName: 'InvalidName',\n RegistrationFailed: 'RegistrationFailed',\n CyclicDependency: 'CyclicDependency',\n NotFound: 'NotFound',\n StartupFailed: 'StartupFailed',\n StartupTimeout: 'StartupTimeout',\n StartTimeout: 'StartTimeout',\n StopTimeout: 'StopTimeout',\n} as const;\n","import { safeHandleCallback } from './safe-handle-callback';\nimport { ulid } from 'ulid';\nimport readline from 'readline';\n\n/**\n * The shutdown signal types that can trigger the shutdown callback\n */\nexport type ShutdownSignal = 'SIGINT' | 'SIGTERM' | 'SIGTRAP';\n\n/**\n * Shared state stored on globalThis to survive module duplication from bundlers.\n * Uses Symbol.for() to ensure the same symbol across all copies of this module.\n */\ninterface ProcessSignalManagerSharedState {\n /**\n * Whether emitKeypressEvents was called on process.stdin.\n * Since process.stdin is a global singleton, this prevents multiple calls.\n */\n keypressEventsEmittedOnStdin: boolean;\n\n /**\n * Set of instance IDs that have successfully attached.\n * Used to coordinate shared resources (raw mode, stdin pause/resume).\n */\n attachedInstances: Set<string>;\n\n /**\n * The instance ID that enabled raw mode, or null if raw mode wasn't enabled by us.\n * Only this instance (or the last remaining instance) should disable raw mode.\n */\n rawModeOwner: string | null;\n\n /**\n * Whether raw mode was enabled by ProcessSignalManager.\n *\n * This is necessary because an instance may fail to disable raw mode during detach,\n * leaving stdin in raw mode while the recorded owner is stale. When a new instance\n * later attaches and finds raw mode already enabled, it can safely adopt ownership\n * *only if* this flag indicates we were responsible for enabling raw mode.\n *\n * If raw mode was enabled by external code, this stays false and we will not disable it.\n */\n rawModeEnabledByManager: boolean;\n}\n\n// Use Symbol.for() for a global symbol registry - survives module duplication\nconst SHARED_STATE_KEY = Symbol.for('lifecycleion.ProcessSignalManager.v1');\n\n/**\n * Get or initialize the shared state on globalThis.\n * This ensures all copies of this module (from bundler duplication) share the same state.\n */\nfunction getSharedState(): ProcessSignalManagerSharedState {\n const g = globalThis as Record<\n symbol,\n ProcessSignalManagerSharedState | undefined\n >;\n if (!g[SHARED_STATE_KEY]) {\n g[SHARED_STATE_KEY] = {\n keypressEventsEmittedOnStdin: false,\n attachedInstances: new Set(),\n rawModeOwner: null,\n rawModeEnabledByManager: false,\n };\n }\n return g[SHARED_STATE_KEY];\n}\n\n/**\n * Transfer raw mode ownership to another attached instance, or clear it if none remain.\n * This is a centralized helper to ensure ownership is always valid.\n *\n * @param shared - The shared state object\n * @param currentOwner - The instance ID giving up ownership (only transfers if this matches current owner)\n * @returns The new owner ID, or null if ownership was cleared\n */\nfunction transferRawModeOwnership(\n shared: ProcessSignalManagerSharedState,\n currentOwner: string,\n): string | null {\n // Only transfer if we're actually the current owner\n if (shared.rawModeOwner !== currentOwner) {\n return shared.rawModeOwner;\n }\n\n // If no instances remain, clear ownership\n if (shared.attachedInstances.size === 0) {\n shared.rawModeOwner = null;\n return null;\n }\n\n // Find a valid new owner from remaining instances\n // Re-validate that the chosen instance is still attached (defensive against concurrent modifications)\n for (const candidateID of shared.attachedInstances) {\n if (shared.attachedInstances.has(candidateID)) {\n shared.rawModeOwner = candidateID;\n return candidateID;\n }\n }\n\n // Fallback: no valid instances (shouldn't happen, but be safe)\n shared.rawModeOwner = null;\n return null;\n}\n\n/**\n * Status information about what the manager is attached to\n */\nexport interface ProcessSignalManagerStatus {\n /**\n * Whether the manager is currently attached to signals and keypresses\n */\n isAttached: boolean;\n\n /**\n * Which handlers are registered\n */\n handlers: {\n /**\n * Whether a shutdown handler is registered\n */\n shutdown: boolean;\n\n /**\n * Whether a reload handler is registered\n */\n reload: boolean;\n\n /**\n * Whether an info handler is registered\n */\n info: boolean;\n\n /**\n * Whether a debug handler is registered\n */\n debug: boolean;\n };\n\n /**\n * What events are currently being listened for (only populated when isListening is true)\n */\n listeningFor: {\n /**\n * Listening for shutdown signals (SIGINT, SIGTERM, SIGTRAP)\n */\n shutdownSignals: boolean;\n\n /**\n * Listening for reload signal (SIGHUP)\n */\n reloadSignal: boolean;\n\n /**\n * Listening for info signal (SIGUSR1)\n */\n infoSignal: boolean;\n\n /**\n * Listening for debug signal (SIGUSR2)\n */\n debugSignal: boolean;\n\n /**\n * Listening for keypresses (Ctrl+C, Escape, R, I, D)\n */\n keypresses: boolean;\n };\n}\n\n/**\n * Configuration options for ProcessSignalManager\n */\nexport interface ProcessSignalManagerOptions {\n /**\n * Optional callback invoked when a shutdown signal is received.\n *\n * Triggered by:\n * - Process signals: SIGINT, SIGTERM, SIGTRAP\n * - Keyboard: Ctrl+C, Escape\n */\n onShutdownRequested?: (method: ShutdownSignal) => void | Promise<void>;\n\n /**\n * Optional callback invoked when reload is requested.\n *\n * Triggered by:\n * - Process signal: SIGHUP\n * - Keyboard: R key press (case-insensitive)\n */\n onReloadRequested?: () => void | Promise<unknown>;\n\n /**\n * Optional callback invoked when info/stats are requested.\n *\n * Triggered by:\n * - Process signal: SIGUSR1\n * - Keyboard: I key press (case-insensitive)\n *\n * Common uses: Print stats, health check, show metrics\n */\n onInfoRequested?: () => void | Promise<unknown>;\n\n /**\n * Optional callback invoked when debug mode is toggled or verbose info is requested.\n *\n * Triggered by:\n * - Process signal: SIGUSR2\n * - Keyboard: D key press (case-insensitive)\n *\n * Common uses: Toggle debug mode, dump full state, enable verbose logging\n */\n onDebugRequested?: () => void | Promise<unknown>;\n\n /**\n * Custom name for the shutdown callback used in error reporting.\n * @default 'onShutdownRequested'\n */\n shutdownCallbackName?: string;\n\n /**\n * Custom name for the reload callback used in error reporting.\n * @default 'onReloadRequested'\n */\n reloadCallbackName?: string;\n\n /**\n * Custom name for the info callback used in error reporting.\n * @default 'onInfoRequested'\n */\n infoCallbackName?: string;\n\n /**\n * Custom name for the debug callback used in error reporting.\n * @default 'onDebugRequested'\n */\n debugCallbackName?: string;\n\n /**\n * Throttle interval in milliseconds for keyboard events (leading-edge rate limiting).\n * Allows an action to trigger at most once per interval. First press fires immediately,\n * subsequent presses within the window are ignored.\n * This prevents accidental double-triggers while allowing predictable repeated actions.\n *\n * Note: This only affects keyboard events, not process signals.\n * Process signals are never throttled as they may come from external sources\n * that expect immediate handling.\n *\n * @default 200 (200ms throttle, allowing 5 triggers per second maximum)\n * @example 300 // Custom 300ms throttle (3.33 triggers per second max)\n * @example 0 // Disable throttling entirely\n */\n keypressThrottleMS?: number;\n}\n\n/**\n * Manages process signals and keyboard events for graceful shutdown, reload, and info/debug functionality.\n *\n * Handles:\n * - Shutdown signals: SIGINT, SIGTERM, SIGTRAP\n * - Reload signal: SIGHUP\n * - Info signal: SIGUSR1\n * - Debug signal: SIGUSR2\n * - Keyboard shortcuts: Ctrl+C, Escape (shutdown), R (reload), I (info), D (debug)\n * All letter keys are case-insensitive\n *\n * All callbacks are executed safely with automatic error handling.\n */\nexport class ProcessSignalManager {\n // Unique identifier for this instance, used for tracking in shared state\n private readonly instanceID: string;\n\n private onShutdownRequested?: (\n method: ShutdownSignal,\n ) => void | Promise<void>;\n private onReloadRequested?: () => void | Promise<unknown>;\n private onInfoRequested?: () => void | Promise<unknown>;\n private onDebugRequested?: () => void | Promise<unknown>;\n\n private shutdownCallbackName: string;\n private reloadCallbackName: string;\n private infoCallbackName: string;\n private debugCallbackName: string;\n\n private shutdownSignalListeners?: {\n [key in ShutdownSignal]: () => void;\n };\n private reloadSignalListener?: () => void;\n private infoSignalListener?: () => void;\n private debugSignalListener?: () => void;\n private keypressHandler?: (str: string, key: unknown) => void;\n private _isAttached = false;\n\n // Throttle state for keyboard events (default 200ms, 0 disables)\n // Track throttle separately per action type so different keys don't interfere with each other\n // Use -Infinity to ensure first press is never throttled (always fires immediately)\n private keypressThrottleMS: number;\n private lastActionTimes = {\n shutdown: -Infinity,\n reload: -Infinity,\n info: -Infinity,\n debug: -Infinity,\n };\n\n constructor(options: ProcessSignalManagerOptions) {\n // Generate unique ID for this instance to track it in the activeInstances Set\n this.instanceID = ulid();\n\n this.onShutdownRequested = options.onShutdownRequested;\n this.onReloadRequested = options.onReloadRequested;\n this.onInfoRequested = options.onInfoRequested;\n this.onDebugRequested = options.onDebugRequested;\n this.shutdownCallbackName =\n options.shutdownCallbackName ?? 'onShutdownRequested';\n this.reloadCallbackName = options.reloadCallbackName ?? 'onReloadRequested';\n this.infoCallbackName = options.infoCallbackName ?? 'onInfoRequested';\n this.debugCallbackName = options.debugCallbackName ?? 'onDebugRequested';\n // Default to 200ms throttle (leading-edge rate limiting), 0 disables\n this.keypressThrottleMS = options.keypressThrottleMS ?? 200;\n\n // Initialize shutdown signal handlers if callback is provided (not yet registered with process)\n // These will be registered when listen() is called\n if (this.onShutdownRequested) {\n const shutdownCallback = this.onShutdownRequested;\n this.shutdownSignalListeners = {\n SIGINT: (): void =>\n safeHandleCallback(\n this.shutdownCallbackName,\n shutdownCallback,\n 'SIGINT',\n ),\n SIGTERM: (): void =>\n safeHandleCallback(\n this.shutdownCallbackName,\n shutdownCallback,\n 'SIGTERM',\n ),\n SIGTRAP: (): void =>\n safeHandleCallback(\n this.shutdownCallbackName,\n shutdownCallback,\n 'SIGTRAP',\n ),\n };\n }\n\n // Initialize reload signal handler if callback is provided (not yet registered with process)\n // This will be registered when listen() is called\n if (this.onReloadRequested) {\n const reloadCallback = this.onReloadRequested;\n this.reloadSignalListener = (): void =>\n safeHandleCallback(this.reloadCallbackName, reloadCallback);\n }\n\n // Initialize info signal handler (SIGUSR1) if callback is provided (not yet registered with process)\n // This will be registered when listen() is called\n if (this.onInfoRequested) {\n const infoCallback = this.onInfoRequested;\n this.infoSignalListener = (): void =>\n safeHandleCallback(this.infoCallbackName, infoCallback);\n }\n\n // Initialize debug signal handler (SIGUSR2) if callback is provided (not yet registered with process)\n // This will be registered when listen() is called\n if (this.onDebugRequested) {\n const debugCallback = this.onDebugRequested;\n this.debugSignalListener = (): void =>\n safeHandleCallback(this.debugCallbackName, debugCallback);\n }\n }\n\n /**\n * Check if the manager is currently attached to signals and keypresses.\n */\n public get isAttached(): boolean {\n return this._isAttached;\n }\n\n /**\n * Get detailed status information about what the manager is attached to.\n *\n * @returns Status object with handler registration and attachment state\n */\n public getStatus(): ProcessSignalManagerStatus {\n return {\n isAttached: this._isAttached,\n handlers: {\n shutdown: !!this.onShutdownRequested,\n reload: !!this.onReloadRequested,\n info: !!this.onInfoRequested,\n debug: !!this.onDebugRequested,\n },\n listeningFor: {\n shutdownSignals: this._isAttached && !!this.shutdownSignalListeners,\n reloadSignal: this._isAttached && !!this.reloadSignalListener,\n infoSignal: this._isAttached && !!this.infoSignalListener,\n debugSignal: this._isAttached && !!this.debugSignalListener,\n // Keypresses are only available if stdin is a TTY\n keypresses:\n this._isAttached && process.stdin.isTTY && !!this.keypressHandler,\n },\n };\n }\n\n /**\n * Attach signal handlers and start listening for process signals and keyboard events.\n * Idempotent - calling multiple times has no effect.\n */\n public attach(): void {\n if (this._isAttached) {\n return;\n }\n\n try {\n this.listenForShutdownSignals();\n this.listenForReloadSignal();\n this.listenForInfoSignal();\n this.listenForDebugSignal();\n this.listenForKeyPresses();\n this._isAttached = true;\n } catch (error) {\n // If any listener registration fails, clean up any handlers that were already registered\n // This prevents partial registration and ensures consistent state\n this.stopListeningForShutdownSignals();\n this.stopListeningForReloadSignal();\n this.stopListeningForInfoSignal();\n this.stopListeningForDebugSignal();\n this.restoreStdin();\n throw error;\n }\n }\n\n /**\n * Detach signal handlers and stop listening for process signals and keyboard events.\n * Cleans up all event listeners and restores stdin to normal mode.\n *\n * Idempotent - calling multiple times has no effect.\n */\n public detach(): void {\n if (!this._isAttached) {\n return;\n }\n\n try {\n this.stopListeningForShutdownSignals();\n this.stopListeningForReloadSignal();\n this.stopListeningForInfoSignal();\n this.stopListeningForDebugSignal();\n this.restoreStdin();\n } finally {\n // Always mark as detached, even if cleanup threw an error\n // This prevents the manager from being stuck in an \"attached\" state\n // that blocks re-attachment attempts\n this._isAttached = false;\n }\n }\n\n /**\n * Manually trigger a shutdown event\n * if the manager is attached and a shutdown handler is registered\n *\n * @param method - The shutdown method (SIGINT, SIGTERM, or SIGTRAP) that will be passed to the shutdown callback\n * @param shouldBypassAttachCheck - If true, triggers the callback even when not attached (useful for testing)\n */\n public triggerShutdown(\n method: ShutdownSignal,\n shouldBypassAttachCheck = false,\n ): void {\n if (\n (this._isAttached || shouldBypassAttachCheck) &&\n this.onShutdownRequested\n ) {\n safeHandleCallback(\n this.shutdownCallbackName,\n this.onShutdownRequested,\n method,\n );\n }\n }\n\n /**\n * Manually trigger a reload event\n * if the manager is attached and a reload handler is registered\n *\n * @param shouldBypassAttachCheck - If true, triggers the callback even when not attached (useful for testing)\n */\n public triggerReload(shouldBypassAttachCheck = false): void {\n if (\n (this._isAttached || shouldBypassAttachCheck) &&\n this.onReloadRequested\n ) {\n safeHandleCallback(this.reloadCallbackName, this.onReloadRequested);\n }\n }\n\n /**\n * Manually trigger an info event\n * if the manager is attached and an info handler is registered\n *\n * @param shouldBypassAttachCheck - If true, triggers the callback even when not attached (useful for testing)\n */\n public triggerInfo(shouldBypassAttachCheck = false): void {\n if ((this._isAttached || shouldBypassAttachCheck) && this.onInfoRequested) {\n safeHandleCallback(this.infoCallbackName, this.onInfoRequested);\n }\n }\n\n /**\n * Manually trigger a debug event\n * if the manager is attached and a debug handler is registered\n *\n * @param shouldBypassAttachCheck - If true, triggers the callback even when not attached (useful for testing)\n */\n public triggerDebug(shouldBypassAttachCheck = false): void {\n if (\n (this._isAttached || shouldBypassAttachCheck) &&\n this.onDebugRequested\n ) {\n safeHandleCallback(this.debugCallbackName, this.onDebugRequested);\n }\n }\n\n /**\n * Check if an action should be throttled based on the last time it was successfully triggered.\n * Uses leading-edge throttle: first press fires immediately, subsequent presses within the\n * throttle window are ignored. Only updates timestamp when action is allowed (not throttled).\n *\n * This is the standard pattern for keyboard shortcuts and prevents accidental double-triggers\n * while allowing predictable repeated actions at a maximum rate.\n *\n * @param action - The action type to check throttling for\n * @returns true if the action should be throttled (ignored), false otherwise\n */\n private shouldThrottle(action: keyof typeof this.lastActionTimes): boolean {\n if (this.keypressThrottleMS <= 0) {\n return false; // Throttling disabled\n }\n\n const now = Date.now();\n const timeSinceLastTrigger = now - this.lastActionTimes[action];\n\n if (timeSinceLastTrigger < this.keypressThrottleMS) {\n return true; // Throttled - too soon after last successful trigger\n }\n\n // Only update timestamp when allowing the action (leading-edge throttle)\n // This allows predictable rate limiting: action can fire at most once per interval\n this.lastActionTimes[action] = now;\n return false;\n }\n\n /**\n * Register handlers for all shutdown signals (SIGINT, SIGTERM, SIGTRAP) if callback is provided.\n * Each signal will trigger the shutdown callback with the appropriate method.\n */\n private listenForShutdownSignals(): void {\n if (this.shutdownSignalListeners) {\n for (const signal of Object.keys(\n this.shutdownSignalListeners,\n ) as ShutdownSignal[]) {\n process.on(signal, this.shutdownSignalListeners[signal]);\n }\n }\n }\n\n /**\n * Remove handlers for all shutdown signals if they were registered.\n * Uses the same function references to ensure proper cleanup.\n */\n private stopListeningForShutdownSignals(): void {\n if (this.shutdownSignalListeners) {\n for (const signal of Object.keys(\n this.shutdownSignalListeners,\n ) as ShutdownSignal[]) {\n process.off(signal, this.shutdownSignalListeners[signal]);\n }\n }\n }\n\n /**\n * Register handler for SIGHUP signal if reload callback is provided.\n * SIGHUP is commonly used to trigger configuration reloads.\n */\n private listenForReloadSignal(): void {\n if (this.reloadSignalListener) {\n process.on('SIGHUP', this.reloadSignalListener);\n }\n }\n\n /**\n * Remove handler for SIGHUP signal.\n * Uses the same function reference to ensure proper cleanup.\n */\n private stopListeningForReloadSignal(): void {\n if (this.reloadSignalListener) {\n process.off('SIGHUP', this.reloadSignalListener);\n }\n }\n\n /**\n * Register handler for SIGUSR1 signal if info callback is provided.\n * SIGUSR1 is commonly used for printing stats, health checks, etc.\n */\n private listenForInfoSignal(): void {\n if (this.infoSignalListener) {\n process.on('SIGUSR1', this.infoSignalListener);\n }\n }\n\n /**\n * Remove handler for SIGUSR1 signal.\n * Uses the same function reference to ensure proper cleanup.\n */\n private stopListeningForInfoSignal(): void {\n if (this.infoSignalListener) {\n process.off('SIGUSR1', this.infoSignalListener);\n }\n }\n\n /**\n * Register handler for SIGUSR2 signal if debug callback is provided.\n * SIGUSR2 is commonly used for toggling debug mode, dumping state, etc.\n */\n private listenForDebugSignal(): void {\n if (this.debugSignalListener) {\n process.on('SIGUSR2', this.debugSignalListener);\n }\n }\n\n /**\n * Remove handler for SIGUSR2 signal.\n * Uses the same function reference to ensure proper cleanup.\n */\n private stopListeningForDebugSignal(): void {\n if (this.debugSignalListener) {\n process.off('SIGUSR2', this.debugSignalListener);\n }\n }\n\n /**\n * Enable keyboard event listening if stdin is a TTY.\n * Sets stdin to raw mode and listens for Ctrl+C, Escape, R, I, and D keypresses.\n *\n * Note: Letter keys are case-insensitive (R/r, I/i, D/d all work).\n *\n * Uses add-then-check pattern to prevent race conditions:\n * 1. Add ourselves to attachedInstances first\n * 2. Check if we're the first (size === 1) to enable raw mode\n * This ensures no gap where another instance could read stale state.\n */\n private listenForKeyPresses(): void {\n if (!process.stdin.isTTY || this.keypressHandler) {\n return;\n }\n\n const shared = getSharedState();\n\n // Only call emitKeypressEvents once per stream to avoid duplicate events\n // Node.js warns against calling this multiple times on the same stream\n // IMPORTANT: Set flag BEFORE calling to prevent race condition where two instances\n // both see false and both call emitKeypressEvents. The call is idempotent-ish\n // (just causes warnings), but we want to avoid it.\n if (!shared.keypressEventsEmittedOnStdin) {\n shared.keypressEventsEmittedOnStdin = true;\n readline.emitKeypressEvents(process.stdin);\n }\n\n // Create the keypress handler\n // Note: Keypresses directly invoke callbacks\n // They don't emit actual process signals to avoid recursion and keep it simple\n this.keypressHandler = (str, key): void => {\n const keyObj = key as Record<string, unknown>;\n const keyName = keyObj.name as string;\n // Note: key.name is always lowercase for letter keys, regardless of shift state\n // So checking for 'r' catches both 'r' and 'R' (making it case-insensitive)\n\n // Handle Ctrl+C manually (if shutdown handler is registered)\n if (keyObj.ctrl && keyName === 'c' && this.onShutdownRequested) {\n if (this.shouldThrottle('shutdown')) {\n return;\n }\n\n safeHandleCallback(\n this.shutdownCallbackName,\n this.onShutdownRequested,\n 'SIGINT',\n );\n }\n // Treat escape as a SIGINT signal (if shutdown handler is registered)\n else if (keyName === 'escape' && this.onShutdownRequested) {\n if (this.shouldThrottle('shutdown')) {\n return;\n }\n\n safeHandleCallback(\n this.shutdownCallbackName,\n this.onShutdownRequested,\n 'SIGINT',\n );\n }\n // Handle R key for reload (case-insensitive)\n else if (keyName === 'r' && this.onReloadRequested) {\n if (this.shouldThrottle('reload')) {\n return;\n }\n\n safeHandleCallback(this.reloadCallbackName, this.onReloadRequested);\n }\n // Handle I key for info (case-insensitive)\n else if (keyName === 'i' && this.onInfoRequested) {\n if (this.shouldThrottle('info')) {\n return;\n }\n\n safeHandleCallback(this.infoCallbackName, this.onInfoRequested);\n }\n // Handle D key for debug (case-insensitive)\n else if (keyName === 'd' && this.onDebugRequested) {\n if (this.shouldThrottle('debug')) {\n return;\n }\n\n safeHandleCallback(this.debugCallbackName, this.onDebugRequested);\n }\n };\n\n // ADD FIRST, then check - prevents race condition where two instances\n // both see size === 0 before either adds themselves\n shared.attachedInstances.add(this.instanceID);\n const isFirstInstance = shared.attachedInstances.size === 1;\n\n try {\n // Register this instance's keypress handler\n // Note: Multiple instances can coexist - each gets its own handler, all receive the same keypresses\n process.stdin.on('keypress', this.keypressHandler);\n } catch (error) {\n // If registration fails, clean up and rethrow\n shared.attachedInstances.delete(this.instanceID);\n this.keypressHandler = undefined;\n throw error;\n }\n\n // Enable raw mode only when the first instance attaches\n // Check AFTER adding ourselves to prevent race condition\n if (isFirstInstance) {\n if (!process.stdin.isRaw) {\n try {\n process.stdin.setRawMode(true);\n // Only record ownership AFTER success - prevents rollback race\n shared.rawModeOwner = this.instanceID;\n shared.rawModeEnabledByManager = true;\n } catch (error) {\n // setRawMode failed - clean up the handler we registered\n // Pass attemptedRawModeEnable=true because setRawMode may have enabled raw mode\n // before throwing (edge case with some terminal emulators)\n this.cleanupKeypressHandler(shared, true);\n throw error;\n }\n } else if (\n shared.rawModeEnabledByManager &&\n (shared.rawModeOwner === null ||\n !shared.attachedInstances.has(shared.rawModeOwner))\n ) {\n // Raw mode is already enabled, and we previously enabled it (per shared flag),\n // but ownership is missing or stale (e.g., last detach failed to disable raw mode).\n // Adopt ownership so the eventual last detach will restore the terminal.\n shared.rawModeOwner = this.instanceID;\n } else if (!shared.rawModeEnabledByManager) {\n // If raw mode is already enabled but we didn't enable it, treat it as external.\n // Ensure we don't carry forward a stale owner value from a prior run/version.\n shared.rawModeOwner = null;\n }\n }\n\n // Resume stdin only when first instance attaches\n if (isFirstInstance) {\n try {\n process.stdin.resume();\n } catch (error) {\n // resume() failed - clean up everything\n this.cleanupKeypressHandler(shared);\n throw error;\n }\n }\n }\n\n /**\n * Helper to clean up keypress handler registration on error.\n * Removes handler, clears instance from shared state, and restores raw mode if needed.\n *\n * @param shared - The shared state object\n * @param didAttemptRawModeEnable - If true, we attempted to enable raw mode (even if ownership wasn't recorded).\n * This handles the edge case where setRawMode(true) throws after actually enabling raw mode.\n */\n private cleanupKeypressHandler(\n shared: ProcessSignalManagerSharedState,\n didAttemptRawModeEnable = false,\n ): void {\n if (this.keypressHandler) {\n try {\n process.stdin.off('keypress', this.keypressHandler);\n } catch {\n // Ignore - best effort cleanup\n }\n this.keypressHandler = undefined;\n }\n\n shared.attachedInstances.delete(this.instanceID);\n\n // If we attempted to enable raw mode and it appears to have been enabled,\n // record that raw mode is managed by us (even if the original setRawMode(true) threw).\n // This allows future instances to adopt ownership and restore the terminal.\n if (didAttemptRawModeEnable && process.stdin.isTTY && process.stdin.isRaw) {\n shared.rawModeEnabledByManager = true;\n if (shared.rawModeOwner === null) {\n shared.rawModeOwner = this.instanceID;\n }\n }\n\n // If we were the raw mode owner but other instances remain, transfer ownership.\n // Use centralized helper to ensure atomic ownership transfer.\n if (\n shared.rawModeEnabledByManager &&\n shared.rawModeOwner === this.instanceID &&\n shared.attachedInstances.size > 0\n ) {\n transferRawModeOwnership(shared, this.instanceID);\n } else if (\n shared.rawModeOwner !== null &&\n shared.attachedInstances.size > 0 &&\n shared.rawModeEnabledByManager &&\n !shared.attachedInstances.has(shared.rawModeOwner)\n ) {\n // Defensive: if ownership somehow points to a detached instance, re-anchor it.\n // Find any valid attached instance to take ownership.\n for (const candidateID of shared.attachedInstances) {\n if (shared.attachedInstances.has(candidateID)) {\n shared.rawModeOwner = candidateID;\n break;\n }\n }\n }\n\n // Restore raw mode if we're the last instance AND either:\n // 1. We own raw mode (normal case), OR\n // 2. We attempted to enable raw mode but ownership wasn't recorded (setRawMode threw after enabling)\n const shouldRestoreRawMode =\n shared.attachedInstances.size === 0 &&\n shared.rawModeEnabledByManager &&\n (shared.rawModeOwner === this.instanceID ||\n (didAttemptRawModeEnable && shared.rawModeOwner === null));\n\n if (shouldRestoreRawMode) {\n try {\n if (process.stdin.isTTY && process.stdin.isRaw) {\n process.stdin.setRawMode(false);\n }\n\n // Clear ownership after successful operation\n // (either raw mode was disabled, or it was already off and doesn't need disabling)\n shared.rawModeOwner = null;\n shared.rawModeEnabledByManager = false;\n } catch {\n // If setRawMode(false) fails, ensure there's a non-null owner so future detaches can retry.\n // This matters in the edge case where setRawMode(true) threw after enabling raw mode:\n // rawModeOwner would still be null, and without setting it here we'd never retry disabling.\n if (didAttemptRawModeEnable && shared.rawModeOwner === null) {\n shared.rawModeOwner = this.instanceID;\n }\n // rawModeEnabledByManager stays true so future instances can adopt and retry.\n // Terminal will be restored on process exit anyway.\n }\n }\n }\n\n /**\n * Restore stdin to normal mode and clean up keypress listener.\n * Uses remove-then-check pattern (mirror of add-then-check in attach):\n * 1. Remove ourselves from attachedInstances first\n * 2. Check if we're the last (size === 0) to disable raw mode and pause stdin\n *\n * Note: Can be called even if keypressHandler is undefined (e.g., during error recovery).\n * In that case, we still update shared state and attempt terminal restoration if we\n * were the recorded raw mode owner.\n */\n private restoreStdin(): void {\n const shared = getSharedState();\n\n // Remove handler if it exists\n if (this.keypressHandler) {\n try {\n process.stdin.off('keypress', this.keypressHandler);\n } catch {\n // Best effort - continue with cleanup even if off() fails\n // This is extremely rare (stdin closed mid-operation)\n }\n this.keypressHandler = undefined;\n }\n\n // Remove this instance from shared state even if we never registered a handler.\n // (Set.delete is a safe no-op if we weren't attached.)\n shared.attachedInstances.delete(this.instanceID);\n\n // Re-check ownership AFTER deletion to get accurate state\n // (avoids race where ownership is transferred to us between capture and deletion)\n const isLastInstance = shared.attachedInstances.size === 0;\n const isCurrentOwner = shared.rawModeOwner === this.instanceID;\n\n // If we were the raw mode owner but other instances remain, transfer ownership.\n // Use centralized helper to ensure atomic ownership transfer.\n if (!isLastInstance && isCurrentOwner && shared.rawModeEnabledByManager) {\n transferRawModeOwnership(shared, this.instanceID);\n } else if (\n !isLastInstance &&\n shared.rawModeOwner !== null &&\n shared.rawModeEnabledByManager &&\n !shared.attachedInstances.has(shared.rawModeOwner)\n ) {\n // Defensive: if ownership somehow points to a detached instance, re-anchor it.\n // Find any valid attached instance to take ownership.\n for (const candidateID of shared.attachedInstances) {\n if (shared.attachedInstances.has(candidateID)) {\n shared.rawModeOwner = candidateID;\n break;\n }\n }\n }\n\n // Restore raw mode when last instance detaches, but only if we are the owner.\n // Re-check isCurrentOwner as ownership may have been transferred above (shouldn't happen)\n // if isLastInstance is true, but be defensive).\n if (\n isLastInstance &&\n shared.rawModeOwner === this.instanceID &&\n shared.rawModeEnabledByManager\n ) {\n try {\n if (process.stdin.isTTY && process.stdin.isRaw) {\n process.stdin.setRawMode(false);\n }\n shared.rawModeOwner = null;\n shared.rawModeEnabledByManager = false;\n } catch {\n // If setRawMode fails, leave the owner set so future detaches can retry\n // Terminal will be restored on process exit anyway\n }\n }\n\n // Pause stdin when last instance detaches\n if (isLastInstance) {\n try {\n process.stdin.pause();\n } catch {\n // Best effort - stdin staying active without handlers is harmless\n }\n }\n }\n}\n","import { EventEmitterProtected } from '../event-emitter';\nimport type { Logger } from '../logger';\nimport type { LoggerService } from '../logger/logger-service';\nimport type { BaseComponent } from './base-component';\nimport { ComponentLifecycle } from './component-lifecycle';\nimport type {\n ComponentState,\n ComponentStatus,\n ComponentStallInfo,\n LifecycleManagerStatus,\n ComponentOperationResult,\n StartComponentOptions,\n StopComponentOptions,\n RestartComponentOptions,\n LifecycleManagerOptions,\n RegisterOptions,\n RegisterComponentResult,\n InsertPosition,\n InsertComponentAtResult,\n UnregisterOptions,\n UnregisterComponentResult,\n SystemState,\n RegistrationFailureCode,\n StartupOrderResult,\n StartupOptions,\n StartupResult,\n ShutdownResult,\n StopAllOptions,\n RestartResult,\n RestartAllOptions,\n DependencyValidationResult,\n ShutdownMethod,\n SignalBroadcastResult,\n ComponentSignalResult,\n LifecycleSignalStatus,\n ComponentLifecycleRef,\n LifecycleCommon,\n MessageResult,\n BroadcastResult,\n BroadcastOptions,\n SendMessageOptions,\n GetValueOptions,\n HealthCheckResult,\n HealthReport,\n ValueResult,\n ComponentHealthResult,\n LifecycleInternalCallbacks,\n} from './types';\nimport {\n LifecycleManagerEvents,\n type LifecycleManagerEventMap,\n type LifecycleManagerEventName,\n} from './events';\nimport {\n ComponentStartTimeoutError,\n ComponentStopTimeoutError,\n DependencyCycleError,\n} from './errors';\nimport {\n ProcessSignalManager,\n type ShutdownSignal,\n} from '../process-signal-manager';\nimport { isPromise } from '../is-promise';\n\n/**\n * LifecycleManager - Comprehensive lifecycle orchestration system\n *\n * Manages startup, shutdown, and runtime control of application components.\n * Features:\n * - Multi-phase shutdown (global warning -> per-component graceful -> force)\n * - Dependency-ordered component startup\n * - Process signal integration\n * - Component messaging and value sharing\n * - Health checks and monitoring\n * - Event-driven architecture\n */\nexport class LifecycleManager\n extends EventEmitterProtected\n implements LifecycleCommon\n{\n // Configuration\n private readonly name: string;\n private readonly logger: LoggerService;\n private readonly rootLogger: Logger;\n private readonly shutdownWarningTimeoutMS: number;\n private readonly messageTimeoutMS: number;\n private readonly startupTimeoutMS: number;\n private readonly shutdownOptions?: StopAllOptions;\n private readonly attachSignalsOnStart: boolean;\n private readonly detachSignalsOnStop: boolean;\n\n // Component management\n private components: BaseComponent[] = [];\n private runningComponents: Set<string> = new Set();\n private componentStates: Map<string, ComponentState> = new Map();\n private stalledComponents: Map<string, ComponentStallInfo> = new Map();\n\n // State tracking for individual components\n private componentTimestamps: Map<\n string,\n { startedAt: number | null; stoppedAt: number | null }\n > = new Map();\n private componentErrors: Map<string, Error | null> = new Map();\n\n // State flags\n private isStarting = false;\n private isStarted = false;\n private isShuttingDown = false;\n private shutdownMethod: ShutdownMethod | null = null;\n private lastShutdownResult: ShutdownResult | null = null;\n\n // Signal management\n private processSignalManager: ProcessSignalManager | null = null;\n private readonly onReloadRequested?: (\n broadcastReload: () => Promise<SignalBroadcastResult>,\n ) => void | Promise<void>;\n private readonly onInfoRequested?: (\n broadcastInfo: () => Promise<SignalBroadcastResult>,\n ) => void | Promise<void>;\n private readonly onDebugRequested?: (\n broadcastDebug: () => Promise<SignalBroadcastResult>,\n ) => void | Promise<void>;\n private readonly lifecycleEvents: LifecycleManagerEvents;\n\n constructor(options: LifecycleManagerOptions & { logger: Logger }) {\n super();\n\n if (!options.logger) {\n throw new Error('LifecycleManager requires a root logger');\n }\n\n this.name = options.name ?? 'lifecycle-manager';\n this.rootLogger = options.logger;\n this.logger = this.rootLogger.service(this.name);\n this.shutdownWarningTimeoutMS = options.shutdownWarningTimeoutMS ?? 500;\n this.messageTimeoutMS = options.messageTimeoutMS ?? 5000;\n this.startupTimeoutMS = options.startupTimeoutMS ?? 60000;\n this.shutdownOptions = {\n timeoutMS: 30000,\n retryStalled: true,\n haltOnStall: true,\n ...options.shutdownOptions,\n };\n this.attachSignalsOnStart = options.attachSignalsOnStart ?? false;\n this.detachSignalsOnStop = options.detachSignalsOnStop ?? false;\n\n // Store custom signal callbacks\n this.onReloadRequested = options.onReloadRequested;\n this.onInfoRequested = options.onInfoRequested;\n this.onDebugRequested = options.onDebugRequested;\n this.lifecycleEvents = new LifecycleManagerEvents(this.safeEmit.bind(this));\n\n // Enable logger exit hook if requested\n if (options.enableLoggerExitHook) {\n this.enableLoggerExitHook();\n }\n }\n\n // ============================================================================\n // Component Registration\n // ============================================================================\n\n /**\n * Register a component at the end of the registry list.\n */\n public async registerComponent(\n component: BaseComponent,\n options?: RegisterOptions,\n ): Promise<RegisterComponentResult> {\n const result = await this.registerComponentInternal(\n component,\n 'end',\n undefined,\n false,\n options,\n );\n\n return {\n action: 'register',\n success: result.success,\n registered: result.registered,\n componentName: result.componentName,\n reason: result.reason,\n code: result.code,\n error: result.error,\n registrationIndexBefore: result.registrationIndexBefore,\n registrationIndexAfter: result.registrationIndexAfter,\n startupOrder: result.startupOrder,\n duringStartup: result.duringStartup,\n autoStartAttempted: result.autoStartAttempted,\n autoStartSucceeded: result.autoStartSucceeded,\n startResult: result.startResult,\n };\n }\n\n /**\n * Insert a component at a specific position within the registry list.\n *\n * Notes:\n * - The registry list is a manual ordering preference only.\n * - Dependencies may override this preference; the result object includes `startupOrder`\n * and `manualPositionRespected` so callers can see if the request was achievable.\n */\n public async insertComponentAt(\n component: BaseComponent,\n position: InsertPosition,\n targetComponentName?: string,\n options?: RegisterOptions,\n ): Promise<InsertComponentAtResult> {\n return await this.registerComponentInternal(\n component,\n position,\n targetComponentName,\n true,\n options,\n );\n }\n\n /**\n * Unregister a component\n *\n * @param name - Component name to unregister\n * @param options - Unregister options (stopIfRunning defaults to true)\n *\n * Notes:\n * - Stopped or stalled components can be unregistered directly\n * - Running components are stopped first by default (stopIfRunning: true)\n * - Set stopIfRunning: false to require manual stop before unregister\n * - If stopIfRunning is true and stop fails, unregister is aborted\n * - If stopIfRunning is true and the component is stalled, unregister is aborted\n * @returns True if component was unregistered, false otherwise\n */\n public async unregisterComponent(\n name: string,\n options?: UnregisterOptions,\n ): Promise<UnregisterComponentResult> {\n // Block unregistration during bulk operations\n if (this.isStarting || this.isShuttingDown) {\n this.logger.entity(name).warn('Cannot unregister during bulk operation', {\n params: {\n isStarting: this.isStarting,\n isShuttingDown: this.isShuttingDown,\n },\n });\n\n return {\n success: false,\n componentName: name,\n reason: 'Cannot unregister during bulk operation',\n code: 'bulk_operation_in_progress',\n wasStopped: false,\n wasRegistered: this.hasComponent(name),\n };\n }\n\n const component = this.getComponent(name);\n\n if (!component) {\n this.logger.entity(name).warn('Component not found');\n return {\n success: false,\n componentName: name,\n reason: 'Component not found',\n code: 'component_not_found',\n wasStopped: false,\n wasRegistered: false,\n };\n }\n\n // Default stopIfRunning to true (opt-out behavior)\n const shouldStopIfRunning = options?.stopIfRunning !== false;\n\n const isStalled = this.stalledComponents.has(name);\n\n if (isStalled && shouldStopIfRunning) {\n this.logger\n .entity(name)\n .warn('Cannot unregister stalled component when stopIfRunning is set');\n return {\n success: false,\n componentName: name,\n reason: 'Component is stalled',\n code: 'stop_failed',\n stopFailureReason: 'stalled',\n wasStopped: false,\n wasRegistered: true,\n };\n }\n\n const isRunning = this.isComponentRunning(name);\n\n // If running and stopIfRunning explicitly set to false, reject\n if (isRunning && !shouldStopIfRunning) {\n this.logger\n .entity(name)\n .warn(\n 'Cannot unregister running component. Call stopComponent() first or pass { stopIfRunning: true }',\n );\n return {\n success: false,\n componentName: name,\n reason:\n 'Component is running. Use stopIfRunning: true option or stop manually first',\n code: 'component_running',\n wasStopped: false,\n wasRegistered: true,\n };\n }\n\n // If running and stopIfRunning is true (default), stop first\n let wasStopped = false;\n if (isRunning && shouldStopIfRunning) {\n this.logger.entity(name).info('Stopping component before unregistering');\n const stopResult = await this.stopComponent(name, {\n allowStopWithRunningDependents: options?.forceStop,\n });\n\n // If stop fails and leaves the component stalled, do NOT unregister.\n // Caller expectation: success with stopIfRunning implies the component is stopped and unregistered.\n const stateAfterStopAttempt = this.componentStates.get(name);\n const isRunningAfterStopAttempt = this.isComponentRunning(name);\n\n const isSafelyStopped =\n stopResult.success ||\n (!isRunningAfterStopAttempt && stateAfterStopAttempt === 'stopped');\n\n if (!isSafelyStopped) {\n this.logger\n .entity(name)\n .warn('Failed to stop component before unregistering', {\n params: {\n reason: stopResult.reason,\n code: stopResult.code,\n state: stateAfterStopAttempt,\n },\n });\n\n return {\n success: false,\n componentName: name,\n reason: stopResult.reason ?? 'Failed to stop component',\n code: 'stop_failed',\n stopFailureReason:\n stopResult.code === 'component_shutdown_timeout'\n ? 'timeout'\n : 'error',\n error: stopResult.error,\n wasStopped: false,\n wasRegistered: true,\n };\n }\n\n wasStopped = true;\n }\n\n // Remove from registry\n this.components = this.components.filter((c) => c.getName() !== name);\n\n // Clean up state\n this.componentStates.delete(name);\n this.componentTimestamps.delete(name);\n this.componentErrors.delete(name);\n this.stalledComponents.delete(name);\n this.runningComponents.delete(name);\n this.updateStartedFlag();\n\n // Auto-detach signals if this was the last component and option is enabled\n if (\n this.detachSignalsOnStop &&\n this.runningComponents.size === 0 &&\n this.processSignalManager\n ) {\n this.logger.info(\n 'Auto-detaching process signals on last component unregistered',\n );\n this.detachSignals();\n }\n\n this.logger.entity(name).info('Component unregistered');\n this.lifecycleEvents.componentUnregistered(name, false);\n\n return {\n success: true,\n componentName: name,\n wasStopped,\n wasRegistered: true,\n };\n }\n\n // ============================================================================\n // Status Tracking\n // ============================================================================\n\n /**\n * Check if a component is registered\n */\n public hasComponent(name: string): boolean {\n return this.components.some((c) => c.getName() === name);\n }\n\n /**\n * Check if a component is currently running\n */\n public isComponentRunning(name: string): boolean {\n return this.runningComponents.has(name);\n }\n\n /**\n * Get all registered component names\n */\n public getComponentNames(): string[] {\n return this.components.map((c) => c.getName());\n }\n\n /**\n * Get all running component names\n */\n public getRunningComponentNames(): string[] {\n return Array.from(this.runningComponents);\n }\n\n /**\n * Get the actual component instance by name.\n *\n * Note: This returns the live instance registered with the manager. Mutating it\n * directly can bypass lifecycle invariants, so treat it as read-only unless you\n * fully control the component and understand the implications.\n */\n public getComponentInstance(name: string): BaseComponent | undefined {\n return this.getComponent(name);\n }\n\n /**\n * Get total component count\n */\n public getComponentCount(): number {\n return this.components.length;\n }\n\n /**\n * Get running component count\n */\n public getRunningComponentCount(): number {\n // Stalled components are not counted as running.\n return this.runningComponents.size;\n }\n\n /**\n * Get stalled component count\n */\n public getStalledComponentCount(): number {\n return this.stalledComponents.size;\n }\n\n /**\n * Get stopped (not running, not stalled) component count\n */\n public getStoppedComponentCount(): number {\n return this.getStoppedComponentNames().length;\n }\n\n /**\n * Get components whose last start attempt timed out\n */\n public getStartTimedOutComponentCount(): number {\n return this.getStartTimedOutComponentNames().length;\n }\n\n /**\n * Get detailed status for a specific component\n */\n public getComponentStatus(name: string): ComponentStatus | undefined {\n const component = this.getComponent(name);\n if (!component) {\n return undefined;\n }\n\n const state = this.componentStates.get(name) || 'registered';\n const timestamps = this.componentTimestamps.get(name) || {\n startedAt: null,\n stoppedAt: null,\n };\n const lastError = this.componentErrors.get(name) || null;\n const stallInfo = this.stalledComponents.get(name) || null;\n\n return {\n name,\n state,\n startedAt: timestamps.startedAt,\n stoppedAt: timestamps.stoppedAt,\n lastError,\n stallInfo,\n };\n }\n\n /**\n * Get statuses for all components\n */\n public getAllComponentStatuses(): ComponentStatus[] {\n return this.components\n .map((component) => this.getComponentStatus(component.getName()))\n .filter((status): status is ComponentStatus => status !== undefined);\n }\n\n /**\n * Get overall system state\n */\n public getSystemState(): SystemState {\n const totalCount = this.getComponentCount();\n const runningCount = this.getRunningComponentCount();\n\n if (this.isShuttingDown) {\n return 'shutting-down';\n }\n\n if (this.isStarting) {\n return 'starting';\n }\n\n if (totalCount === 0) {\n return 'no-components';\n }\n\n // Check for stalled components (failed to stop)\n if (this.stalledComponents.size > 0) {\n return 'stalled';\n }\n\n if (runningCount === 0) {\n return 'ready';\n }\n\n if (runningCount === totalCount) {\n return 'running';\n }\n\n // Some components running, some not - this is valid for individual start/stop\n // Just report as 'running' since something is running\n if (runningCount > 0) {\n return 'running';\n }\n\n return 'ready';\n }\n\n /**\n * Get aggregated status snapshot for the manager.\n */\n public getStatus(): LifecycleManagerStatus {\n const running = this.getRunningComponentCount();\n const stalled = this.getStalledComponentCount();\n const stopped = this.getStoppedComponentCount();\n const startTimedOut = this.getStartTimedOutComponentCount();\n const registeredNames = this.getComponentNames();\n const runningNames = this.getRunningComponentNames();\n const stalledNames = this.getStalledComponentNames();\n const stoppedNames = this.getStoppedComponentNames();\n const startTimedOutNames = this.getStartTimedOutComponentNames();\n\n return {\n systemState: this.getSystemState(),\n isStarted: this.isStarted,\n isStarting: this.isStarting,\n isShuttingDown: this.isShuttingDown,\n counts: {\n total: this.getComponentCount(),\n running,\n stopped,\n stalled,\n startTimedOut,\n },\n components: {\n registered: registeredNames,\n running: runningNames,\n stopped: stoppedNames,\n stalled: stalledNames,\n startTimedOut: startTimedOutNames,\n },\n };\n }\n\n /**\n * Get information about components that are stalled (failed to stop)\n */\n public getStalledComponents(): ComponentStallInfo[] {\n return Array.from(this.stalledComponents.values());\n }\n\n /**\n * Get stalled component names\n */\n public getStalledComponentNames(): string[] {\n return Array.from(this.stalledComponents.keys());\n }\n\n /**\n * Get components whose last start attempt timed out\n */\n public getStartTimedOutComponentNames(): string[] {\n return this.getComponentNames().filter(\n (name) => this.componentStates.get(name) === 'starting-timed-out',\n );\n }\n\n /**\n * Get stopped (not running, not stalled) component names\n */\n public getStoppedComponentNames(): string[] {\n const registeredNames = this.getComponentNames();\n const runningNameSet = new Set(this.getRunningComponentNames());\n const stalledNameSet = new Set(this.getStalledComponentNames());\n\n return registeredNames.filter(\n (name) => !runningNameSet.has(name) && !stalledNameSet.has(name),\n );\n }\n\n /**\n * Get resolved startup order after applying dependency constraints.\n */\n public getStartupOrder(): StartupOrderResult {\n try {\n return {\n success: true,\n startupOrder: this.getStartupOrderInternal(),\n };\n } catch (error) {\n const err = error as Error;\n const code =\n err instanceof DependencyCycleError\n ? 'dependency_cycle'\n : 'unknown_error';\n\n this.logger.error('Failed to resolve startup order', {\n params: { error: err },\n });\n\n return {\n success: false,\n startupOrder: [],\n reason: err.message,\n code,\n error: err,\n };\n }\n }\n\n /**\n * Validate all component dependencies without throwing.\n *\n * Returns a report of dependency issues:\n * - Missing dependencies (components that depend on non-registered components)\n * - Circular dependency cycles (e.g., A→B→C→A)\n *\n * Reports all issues regardless of whether components are optional.\n * The optional flag affects startup behavior (whether failures trigger rollback),\n * not whether dependencies must exist in the registry.\n *\n * This is useful for pre-flight checks before starting components.\n */\n public validateDependencies(): DependencyValidationResult {\n const missingDependencies: Array<{\n componentName: string;\n componentIsOptional: boolean;\n missingDependency: string;\n }> = [];\n\n // Check for missing dependencies\n for (const component of this.components) {\n const componentName = component.getName();\n const isComponentOptional = component.isOptional();\n const dependencies = component.getDependencies();\n\n for (const dep of dependencies) {\n if (!this.hasComponent(dep)) {\n missingDependencies.push({\n componentName,\n componentIsOptional: isComponentOptional,\n missingDependency: dep,\n });\n }\n }\n }\n\n // Build adjacency graph for cycle detection\n const names = this.components.map((c) => c.getName());\n const adjacency = new Map<string, Set<string>>();\n\n for (const name of names) {\n adjacency.set(name, new Set());\n }\n\n // Build edges: dependency -> dependent (only when dependency is registered)\n for (const component of this.components) {\n const dependent = component.getName();\n for (const dep of component.getDependencies()) {\n if (adjacency.has(dep)) {\n adjacency.get(dep)?.add(dependent);\n }\n }\n }\n\n // Find circular dependency cycles\n const circularCycles = this.findAllCircularCycles(adjacency);\n\n const isValid =\n missingDependencies.length === 0 && circularCycles.length === 0;\n\n // Calculate summary counts\n const totalMissingDependencies = missingDependencies.length;\n const requiredMissingDependencies = missingDependencies.filter(\n (md) => !md.componentIsOptional,\n ).length;\n const optionalMissingDependencies = missingDependencies.filter(\n (md) => md.componentIsOptional,\n ).length;\n\n return {\n valid: isValid,\n missingDependencies,\n circularCycles,\n summary: {\n totalMissingDependencies,\n requiredMissingDependencies,\n optionalMissingDependencies,\n totalCircularCycles: circularCycles.length,\n },\n };\n }\n\n /**\n * Get the result of the last shutdown operation.\n * Useful for debugging stalled components or tracking shutdown metrics.\n * Returns null if no shutdown has occurred yet or after a successful restart.\n *\n * @returns The last shutdown result or null\n */\n public getLastShutdownResult(): ShutdownResult | null {\n return this.lastShutdownResult;\n }\n\n // ============================================================================\n // Bulk Operations\n // ============================================================================\n\n /**\n * Start all registered components in dependency order.\n *\n * Components start in topological order (dependencies before dependents).\n * Shutdown occurs in reverse topological order.\n *\n * Behavior:\n * - Rejects if some components are already running (partial state)\n * - Sets isStarting flag during operation\n * - On failure: triggers rollback (stops all started components)\n * - Optional components don't trigger rollback on failure\n * - Dependents still attempt to start if an optional dependency fails\n * - Handles shutdown signal during startup (aborts and rolls back)\n */\n public async startAllComponents(\n options?: StartupOptions,\n ): Promise<StartupResult> {\n const startTime = Date.now();\n\n // Reject if already starting\n if (this.isStarting) {\n this.logger.warn(\n 'Cannot start all components: startup already in progress',\n );\n\n return {\n success: false,\n startedComponents: [],\n failedOptionalComponents: [],\n skippedDueToDependency: [],\n reason: 'Startup already in progress',\n code: 'already_in_progress',\n durationMS: Date.now() - startTime,\n };\n }\n\n // Reject if shutdown is in progress\n if (this.isShuttingDown) {\n this.logger.warn('Cannot start all components: shutdown in progress');\n return {\n success: false,\n startedComponents: [],\n failedOptionalComponents: [],\n skippedDueToDependency: [],\n reason: 'Shutdown in progress',\n code: 'shutdown_in_progress',\n durationMS: Date.now() - startTime,\n };\n }\n\n const totalCount = this.getComponentCount();\n const runningCount = this.getRunningComponentCount();\n\n if (totalCount === 0) {\n this.logger.warn('Cannot start all components: none registered');\n\n return {\n success: false,\n startedComponents: [],\n failedOptionalComponents: [],\n skippedDueToDependency: [],\n reason: 'No components registered',\n code: 'no_components_registered',\n durationMS: Date.now() - startTime,\n };\n }\n\n // Check for stalled components\n if (this.stalledComponents.size > 0 && !options?.ignoreStalledComponents) {\n const stalledNames = Array.from(this.stalledComponents.keys());\n this.logger.warn('Cannot start: stalled components exist', {\n params: { stalled: stalledNames },\n });\n\n return {\n success: false,\n startedComponents: [],\n failedOptionalComponents: [],\n skippedDueToDependency: [],\n blockedByStalledComponents: stalledNames,\n reason: 'Stalled components exist',\n code: 'stalled_components_exist',\n durationMS: Date.now() - startTime,\n };\n }\n\n // All running - nothing to do\n if (runningCount === totalCount && totalCount > 0) {\n this.logger.info('All components already running');\n return {\n success: true,\n startedComponents: this.components\n .filter((c) => this.runningComponents.has(c.getName()))\n .map((c) => c.getName()),\n failedOptionalComponents: [],\n skippedDueToDependency: [],\n durationMS: Date.now() - startTime,\n };\n }\n\n // Partial state - reject to avoid inconsistent startup\n if (runningCount > 0) {\n this.logger.error(\n `Cannot start: ${runningCount}/${totalCount} components already running. ` +\n `Call stopAllComponents() first to ensure clean state.`,\n );\n\n return {\n success: false,\n startedComponents: this.components\n .filter((c) => this.runningComponents.has(c.getName()))\n .map((c) => c.getName()),\n failedOptionalComponents: [],\n skippedDueToDependency: [],\n reason: `${runningCount} of ${totalCount} components already running`,\n code: 'partial_state',\n durationMS: Date.now() - startTime,\n };\n }\n\n // Set starting flag and clear previous shutdown state\n this.isStarting = true;\n this.shutdownMethod = null; // Clear previous shutdown method on fresh start\n this.lastShutdownResult = null; // Clear last shutdown result on fresh start\n this.logger.info('Starting all components');\n\n const effectiveTimeout = options?.timeoutMS ?? this.startupTimeoutMS;\n let hasTimedOut = false;\n let timeoutHandle: NodeJS.Timeout | undefined;\n\n // Race startup against timeout if specified\n if (effectiveTimeout > 0) {\n timeoutHandle = setTimeout(() => {\n hasTimedOut = true;\n\n this.logger.warn(\n 'Startup timeout exceeded, returning partial results',\n {\n params: { timeoutMS: effectiveTimeout },\n },\n );\n }, effectiveTimeout);\n }\n\n try {\n // Get startup order (topological sort)\n let startupOrder: string[];\n\n try {\n startupOrder = this.getStartupOrderInternal();\n } catch (error) {\n const err = error as Error;\n const code =\n err instanceof DependencyCycleError\n ? 'dependency_cycle'\n : 'unknown_error';\n\n this.logger.error('Failed to resolve startup order', {\n params: { error: err.message },\n });\n\n return {\n success: false,\n startedComponents: [],\n failedOptionalComponents: [],\n skippedDueToDependency: [],\n reason: err.message,\n code,\n error: err,\n durationMS: Date.now() - startTime,\n };\n }\n\n const startedComponents: string[] = [];\n const failedOptionalComponents: Array<{ name: string; error: Error }> =\n [];\n const skippedDueToDependency = new Set<string>();\n const skippedDueToStall = new Set<string>();\n\n // Start each component in dependency order\n for (const name of startupOrder) {\n // Check if startup has timed out\n if (hasTimedOut) {\n this.logger.warn(\n 'Startup timeout reached, stopping component initiation',\n );\n break;\n }\n\n const component = this.getComponent(name);\n if (!component) {\n // Should not happen since unregisterComponent() is blocked during startup\n this.logger\n .entity(name)\n .error('Component not found in startup order');\n continue;\n }\n\n // Skip stalled components during bulk startup (even with ignoreStalledComponents:true bulk option)\n if (this.stalledComponents.has(name)) {\n this.logger\n .entity(name)\n .info('Skipping stalled component during startup');\n skippedDueToStall.add(name);\n continue;\n }\n\n // Check if any required dependency failed or was skipped\n const dependencies = component.getDependencies();\n let shouldSkip = false;\n let skipReason = '';\n\n for (const depName of dependencies) {\n if (skippedDueToStall.has(depName)) {\n shouldSkip = true;\n skipReason = `Dependency \"${depName}\" is stalled`;\n break;\n }\n\n const depComponent = this.getComponent(depName);\n const isDependencyOptional = depComponent?.isOptional() ?? false;\n\n if (skippedDueToDependency.has(depName)) {\n if (!isDependencyOptional) {\n shouldSkip = true;\n skipReason = `Dependency \"${depName}\" was skipped`;\n break;\n }\n continue;\n }\n\n if (depComponent) {\n const depState = this.componentStates.get(depName);\n if (depState === 'failed' && !isDependencyOptional) {\n shouldSkip = true;\n skipReason = `Dependency \"${depName}\" failed to start`;\n break;\n }\n }\n }\n\n if (shouldSkip) {\n this.logger\n .entity(name)\n .warn('Skipping component due to dependency', {\n params: { reason: skipReason },\n });\n this.lifecycleEvents.componentStartSkipped(name, skipReason);\n skippedDueToDependency.add(name);\n continue;\n }\n\n // Check if shutdown was triggered during startup\n if (this.isShuttingDown) {\n this.logger.warn('Shutdown signal received during startup, aborting');\n\n // Rollback: stop all started components in reverse order\n // Note: Do NOT emit shutdown-initiated/shutdown-completed here, as\n // stopAllComponents() has already emitted them. We just need to rollback.\n await this.rollbackStartup(startedComponents);\n\n return {\n success: false,\n startedComponents: [],\n failedOptionalComponents: [],\n skippedDueToDependency: [],\n reason: 'Shutdown triggered during startup',\n code: 'shutdown_in_progress',\n durationMS: Date.now() - startTime,\n };\n }\n\n // Start the component (allow during bulk startup since we ARE the bulk operation)\n const result = await this.startComponentInternal(name, {\n allowDuringBulkStartup: true,\n });\n\n if (result.success) {\n startedComponents.push(name);\n } else if (result.code === 'component_already_running') {\n // Component is already running - this is fine (might have been started manually)\n // Add to startedComponents so it's tracked as part of this bulk operation\n startedComponents.push(name);\n } else {\n // Check if component is optional\n if (component.isOptional()) {\n this.logger\n .entity(name)\n .warn('Optional component failed to start, continuing', {\n params: { error: result.error?.message },\n });\n\n this.lifecycleEvents.componentStartFailedOptional(\n name,\n result.error,\n );\n\n // Mark as failed state\n this.componentStates.set(name, 'failed');\n if (result.error) {\n this.componentErrors.set(name, result.error);\n }\n\n failedOptionalComponents.push({\n name,\n error:\n result.error || new Error(result.reason || 'Unknown error'),\n });\n } else {\n // Required component failed - trigger rollback\n this.logger\n .entity(name)\n .error('Required component failed to start, rolling back', {\n params: { error: result.error?.message },\n });\n\n await this.rollbackStartup(startedComponents);\n\n return {\n success: false,\n startedComponents: [],\n failedOptionalComponents,\n skippedDueToDependency: Array.from(skippedDueToDependency),\n reason:\n result.reason ||\n `Required component \"${name}\" failed: ${result.code || 'unknown'}`,\n code: 'required_component_failed',\n error: result.error,\n durationMS: Date.now() - startTime,\n };\n }\n }\n }\n\n // Check if startup timed out during the process\n if (hasTimedOut) {\n const durationMS = Date.now() - startTime;\n\n this.logger.warn('Startup completed with timeout', {\n params: {\n started: startedComponents.length,\n failed: failedOptionalComponents.length,\n skipped: skippedDueToDependency.size + skippedDueToStall.size,\n durationMS,\n timeoutMS: effectiveTimeout,\n },\n });\n\n return {\n success: false,\n startedComponents,\n failedOptionalComponents,\n skippedDueToDependency: Array.from(skippedDueToDependency),\n durationMS,\n timedOut: true,\n reason: `Startup timeout exceeded (${effectiveTimeout}ms)`,\n code: 'startup_timeout',\n };\n }\n\n // Success - all components started (or optional ones failed gracefully)\n this.updateStartedFlag();\n const skippedComponentsArray = [\n ...Array.from(skippedDueToDependency),\n ...Array.from(skippedDueToStall),\n ];\n\n const durationMS = Date.now() - startTime;\n\n this.logger.success('All components started', {\n params: {\n started: startedComponents.length,\n failed: failedOptionalComponents.length,\n skipped: skippedComponentsArray.length,\n durationMS,\n },\n });\n\n this.lifecycleEvents.lifecycleManagerStarted(\n startedComponents,\n failedOptionalComponents,\n skippedComponentsArray,\n );\n\n return {\n success: true,\n startedComponents,\n failedOptionalComponents,\n skippedDueToDependency: Array.from(skippedDueToDependency),\n durationMS,\n timedOut: hasTimedOut,\n };\n } finally {\n // Clear timeout if still running\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n this.isStarting = false;\n }\n }\n\n /**\n * Stop all running components in reverse dependency order\n *\n * Components stop in reverse topological order (dependents before dependencies).\n *\n * @param options - Optional shutdown options\n */\n\n public async stopAllComponents(\n options?: StopAllOptions,\n ): Promise<ShutdownResult> {\n // always use manual method for external public API as not from a signal\n return this.stopAllComponentsInternal('manual', {\n ...this.shutdownOptions,\n ...options,\n });\n }\n\n /**\n * Restart all components (stop then start)\n */\n public async restartAllComponents(\n options?: RestartAllOptions,\n ): Promise<RestartResult> {\n this.logger.info('Restarting all components');\n\n // Phase 1: Stop all components (explicit defaults for restart semantics)\n const shutdownResult = await this.stopAllComponentsInternal('manual', {\n ...this.shutdownOptions,\n timeoutMS:\n options?.shutdownTimeoutMS ?? this.shutdownOptions?.timeoutMS ?? 30000,\n // Always retry/halt during restart for deterministic shutdown behavior.\n retryStalled: true,\n haltOnStall: true,\n });\n\n // Phase 2: Start all components\n const startupResult = await this.startAllComponents(\n options?.startupOptions,\n );\n\n const isSuccess = shutdownResult.success && startupResult.success;\n\n this.logger[isSuccess ? 'success' : 'warn']('Restart completed', {\n params: {\n shutdownSuccess: shutdownResult.success,\n startupSuccess: startupResult.success,\n },\n });\n\n return {\n shutdownResult,\n startupResult,\n success: isSuccess,\n };\n }\n\n // ============================================================================\n // Individual Component Lifecycle\n // ============================================================================\n\n /**\n * Start a specific component\n */\n public async startComponent(\n name: string,\n options?: StartComponentOptions,\n ): Promise<ComponentOperationResult> {\n return this.startComponentInternal(name, options);\n }\n\n /**\n * Stop a specific component\n */\n public async stopComponent(\n name: string,\n options?: StopComponentOptions,\n ): Promise<ComponentOperationResult> {\n // Reject during bulk operations\n if (this.isStarting) {\n this.logger\n .entity(name)\n .warn('Cannot stop component during bulk startup', {\n params: { isStarting: this.isStarting },\n });\n\n return {\n success: false,\n componentName: name,\n reason: 'Bulk startup in progress',\n code: 'startup_in_progress',\n };\n }\n\n if (this.isShuttingDown) {\n this.logger.entity(name).warn('Cannot stop component during shutdown', {\n params: { isShuttingDown: this.isShuttingDown },\n });\n\n return {\n success: false,\n componentName: name,\n reason: 'Shutdown in progress',\n code: 'shutdown_in_progress',\n };\n }\n\n // Check for running dependents unless allowStopWithRunningDependents option is true\n if (!options?.allowStopWithRunningDependents) {\n const runningDependents = this.getRunningDependents(name);\n if (runningDependents.length > 0) {\n this.logger\n .entity(name)\n .warn('Cannot stop component with running dependents', {\n params: { runningDependents },\n });\n\n return {\n success: false,\n componentName: name,\n reason: `Component has running dependents: ${runningDependents.join(', ')}. Use { allowStopWithRunningDependents: true } option to bypass.`,\n code: 'has_running_dependents',\n };\n }\n }\n\n return this.stopComponentInternal(name, options);\n }\n\n /**\n * Restart a component (stop then start)\n */\n public async restartComponent(\n name: string,\n options?: RestartComponentOptions,\n ): Promise<ComponentOperationResult> {\n // Reject during bulk operations\n if (this.isStarting || this.isShuttingDown) {\n this.logger\n .entity(name)\n .warn('Cannot restart component during bulk operation', {\n params: {\n isStarting: this.isStarting,\n isShuttingDown: this.isShuttingDown,\n },\n });\n\n return {\n success: false,\n componentName: name,\n reason: this.isStarting\n ? 'Bulk startup in progress'\n : 'Shutdown in progress',\n code: this.isStarting ? 'startup_in_progress' : 'shutdown_in_progress',\n };\n }\n\n // First stop the component\n const stopResult = await this.stopComponent(name, options?.stopOptions);\n\n if (!stopResult.success) {\n return {\n success: false,\n componentName: name,\n reason: `Failed to stop: ${stopResult.reason}`,\n code: 'restart_stop_failed',\n error: stopResult.error,\n };\n }\n\n // Then start it\n const startResult = await this.startComponent(name, options?.startOptions);\n\n if (!startResult.success) {\n return {\n success: false,\n componentName: name,\n reason: `Failed to start: ${startResult.reason}`,\n code: 'restart_start_failed',\n error: startResult.error,\n };\n }\n\n return {\n success: true,\n componentName: name,\n status: this.getComponentStatus(name),\n };\n }\n\n // ============================================================================\n // Signal Integration\n // ============================================================================\n\n /**\n * Attach signal handlers for graceful shutdown, reload, info, and debug.\n * Creates ProcessSignalManager instance if needed and attaches it.\n * Idempotent - calling multiple times has no effect.\n */\n public attachSignals(): void {\n // Check if already attached (not just if instance exists)\n if (this.processSignalManager?.getStatus().isAttached) {\n return; // Already attached\n }\n\n // Create instance if it doesn't exist\n if (!this.processSignalManager) {\n this.processSignalManager = new ProcessSignalManager({\n onShutdownRequested: (method: ShutdownSignal) => {\n this.handleShutdownRequest(method);\n },\n // Note: Signal-triggered handlers are fire-and-forget by design.\n // Node.js signal handlers (process.on) cannot return values, so these\n // async handlers execute but their return values are not accessible.\n // Use triggerReload(), triggerInfo(), triggerDebug() for programmatic\n // access to results.\n onReloadRequested: () => this.handleReloadRequest('signal'),\n onInfoRequested: () => this.handleInfoRequest('signal'),\n onDebugRequested: () => this.handleDebugRequest('signal'),\n });\n }\n\n this.processSignalManager.attach();\n this.lifecycleEvents.lifecycleManagerSignalsAttached();\n }\n\n /**\n * Detach signal handlers.\n * Idempotent - calling multiple times has no effect.\n */\n public detachSignals(): void {\n if (!this.processSignalManager?.getStatus().isAttached) {\n return; // Not attached\n }\n\n this.processSignalManager.detach();\n this.lifecycleEvents.lifecycleManagerSignalsDetached();\n }\n\n /**\n * Get status information about signal handling.\n */\n public getSignalStatus(): LifecycleSignalStatus {\n if (!this.processSignalManager) {\n return {\n isAttached: false,\n handlers: {\n shutdown: false,\n reload: false,\n info: false,\n debug: false,\n },\n listeningFor: {\n shutdownSignals: false,\n reloadSignal: false,\n infoSignal: false,\n debugSignal: false,\n keypresses: false,\n },\n shutdownMethod: this.shutdownMethod,\n };\n }\n\n return {\n ...this.processSignalManager.getStatus(),\n shutdownMethod: this.shutdownMethod,\n };\n }\n\n /**\n * Enable Logger exit hook integration\n *\n * Sets up the logger's beforeExit callback to trigger graceful component shutdown.\n * When `logger.exit(code)` is called (or `logger.error('msg', { exitCode: 1 })`),\n * the LifecycleManager will stop all components before the process exits.\n *\n * The shutdown is subject to the configured shutdown timeout (default: 30000ms).\n * If shutdown exceeds this timeout, the process will exit anyway to prevent hanging.\n *\n * This method is idempotent and can be called multiple times safely.\n *\n * **Note:** This overwrites any existing beforeExit callback on the logger.\n * If you need custom exit logic, set it up manually with `logger.setBeforeExitCallback()`.\n *\n * @example\n * ```typescript\n * const logger = new Logger();\n * const lifecycle = new LifecycleManager({\n * logger,\n * enableLoggerExitHook: true, // Auto-enable\n * shutdownOptions: { timeoutMS: 30000 }, // Max 30s for shutdown\n * });\n *\n * // Or enable manually later\n * lifecycle.enableLoggerExitHook();\n *\n * // Now logger.exit() will trigger graceful shutdown\n * logger.error('Fatal error', { exitCode: 1 });\n * // Components stop gracefully (up to shutdown timeout) before process exits\n * ```\n */\n public enableLoggerExitHook(): void {\n this.rootLogger.setBeforeExitCallback(\n async (exitCode: number, isFirstExit: boolean) => {\n // If shutdown is already in progress, tell logger to wait\n if (this.isShuttingDown) {\n this.logger.debug('Logger exit called during shutdown, waiting...', {\n params: { exitCode },\n });\n\n return { action: 'wait' as const };\n }\n\n if (isFirstExit) {\n this.logger.info('Logger exit triggered, stopping components...', {\n params: { exitCode, timeoutMS: this.shutdownOptions?.timeoutMS },\n });\n\n // Stop all components with global timeout\n await this.stopAllComponents({\n ...this.shutdownOptions,\n });\n }\n\n // Proceed with exit\n return { action: 'proceed' as const };\n },\n );\n\n this.logger.debug('Logger exit hook enabled', {\n params: { timeoutMS: this.shutdownOptions?.timeoutMS },\n });\n }\n\n /**\n * Manually trigger a reload event.\n * @returns Result of broadcasting reload to components\n */\n public async triggerReload(): Promise<SignalBroadcastResult> {\n return this.handleReloadRequest();\n }\n\n /**\n * Manually trigger an info event.\n * @returns Result of broadcasting info to components\n */\n public async triggerInfo(): Promise<SignalBroadcastResult> {\n return this.handleInfoRequest();\n }\n\n /**\n * Manually trigger a debug event.\n * @returns Result of broadcasting debug to components\n */\n public async triggerDebug(): Promise<SignalBroadcastResult> {\n return this.handleDebugRequest();\n }\n\n // ============================================================================\n // Component Messaging\n // ============================================================================\n\n /**\n * Send a message to a specific component\n *\n * Delivers a message to the component's onMessage handler if implemented.\n * The 'from' parameter is automatically tracked based on calling context.\n *\n * @param componentName - Name of target component\n * @param payload - Message payload (any type)\n * @param options - Optional message options (timeout override)\n * @returns Result with sent status, data returned from handler, and any errors\n */\n public async sendMessageToComponent(\n componentName: string,\n payload: unknown,\n options?: SendMessageOptions,\n ): Promise<MessageResult> {\n return this.sendMessageInternal(componentName, payload, null, options);\n }\n\n /**\n * Broadcast a message to multiple components\n *\n * Sends the same message to multiple components (by default, all running components).\n * The 'from' parameter is automatically tracked based on calling context.\n *\n * @param payload - Message payload (any type)\n * @param options - Filtering options and message timeout override\n * @returns Array of results, one per component\n */\n public async broadcastMessage(\n payload: unknown,\n options?: BroadcastOptions,\n ): Promise<BroadcastResult[]> {\n return this.broadcastMessageInternal(payload, null, options);\n }\n\n // ============================================================================\n // Health Checks\n // ============================================================================\n\n /**\n * Check the health of a specific component\n *\n * Calls the component's healthCheck() method if implemented.\n * Times out after component's healthCheckTimeoutMS.\n *\n * @param name - Component name\n * @returns Health check result with status, message, details, and timing\n */\n public async checkComponentHealth(name: string): Promise<HealthCheckResult> {\n const startTime = Date.now();\n\n // Check if component exists\n const component = this.components.find((c) => c.getName() === name);\n\n if (!component) {\n return {\n name,\n healthy: false,\n message: 'Component not found',\n checkedAt: startTime,\n durationMS: 0,\n error: null,\n timedOut: false,\n code: 'not_found',\n };\n }\n\n // Check if component is running\n if (!this.isComponentRunning(name)) {\n const isStalled = this.stalledComponents.has(name);\n return {\n name,\n healthy: false,\n message: isStalled ? 'Component is stalled' : 'Component not running',\n checkedAt: startTime,\n durationMS: Date.now() - startTime,\n error: null,\n timedOut: false,\n code: isStalled ? 'stalled' : 'stopped',\n };\n }\n\n // Check if component implements healthCheck\n if (!component.healthCheck) {\n // No health check implemented - assume healthy\n return {\n name,\n healthy: true,\n message: 'No health check implemented',\n checkedAt: startTime,\n durationMS: Date.now() - startTime,\n error: null,\n timedOut: false,\n code: 'no_handler',\n };\n }\n\n this.lifecycleEvents.componentHealthCheckStarted(name);\n\n let timeoutHandle: NodeJS.Timeout | undefined;\n try {\n // Create timeout promise\n const timeoutMS = component.healthCheckTimeoutMS;\n const timeoutResult: ComponentHealthResult = {\n healthy: false,\n message: 'Health check timed out',\n };\n const timeoutPromise = new Promise<ComponentHealthResult>((resolve) => {\n timeoutHandle = setTimeout(() => {\n resolve(timeoutResult);\n }, timeoutMS);\n });\n\n // Race health check against timeout\n const healthCheckPromise = component.healthCheck();\n const result = await Promise.race([healthCheckPromise, timeoutPromise]);\n\n // Normalize boolean to ComponentHealthResult\n const isTimedOut = result === timeoutResult;\n if (isTimedOut) {\n this.logger.entity(name).warn('Health check timed out', {\n params: { timeoutMS },\n });\n // Prevent unhandled rejection if health check throws after timeout\n Promise.resolve(healthCheckPromise).catch(() => {\n // Intentionally ignore errors after timeout\n });\n }\n const healthResult: ComponentHealthResult =\n typeof result === 'boolean' ? { healthy: result } : result;\n\n const durationMS = Date.now() - startTime;\n this.lifecycleEvents.componentHealthCheckCompleted({\n name,\n healthy: healthResult.healthy,\n message: healthResult.message,\n details: healthResult.details,\n durationMS,\n timedOut: isTimedOut,\n });\n\n return {\n name,\n healthy: healthResult.healthy,\n message: healthResult.message,\n details: healthResult.details,\n checkedAt: startTime,\n durationMS,\n error: null,\n timedOut: isTimedOut,\n code: isTimedOut ? 'timeout' : 'ok',\n };\n } catch (error) {\n const durationMS = Date.now() - startTime;\n const err = error as Error;\n\n this.logger\n .entity(name)\n .error('Health check failed', { params: { error: err.message } });\n this.lifecycleEvents.componentHealthCheckFailed(name, err);\n\n return {\n name,\n healthy: false,\n message: 'Health check threw error',\n checkedAt: startTime,\n durationMS,\n error: err,\n timedOut: false,\n code: 'error',\n };\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n /**\n * Check the health of all running components\n *\n * Runs health checks on all running components in parallel.\n * Overall health is true only if ALL components are healthy.\n *\n * @returns Aggregate health report with individual component results\n */\n public async checkAllHealth(): Promise<HealthReport> {\n const startTime = Date.now();\n\n // Get all running components\n const runningComponents = this.components.filter((c) =>\n this.isComponentRunning(c.getName()),\n );\n\n // Check health of all running components in parallel\n const healthChecks = runningComponents.map((c) =>\n this.checkComponentHealth(c.getName()),\n );\n\n const results = await Promise.all(healthChecks);\n\n // Overall healthy only if all components are healthy\n const isOverallHealthy = results.every((r) => r.healthy);\n const hasTimeout = results.some((r) => r.timedOut);\n const hasError = results.some((r) => r.code === 'error');\n // \"no_handler\" is treated as healthy by design (implicit OK).\n const hasDegraded = results.some(\n (r) =>\n r.code === 'stopped' ||\n r.code === 'stalled' ||\n (r.code !== 'no_handler' && !r.healthy),\n );\n const code = hasError\n ? 'error'\n : hasTimeout\n ? 'timeout'\n : hasDegraded\n ? 'degraded'\n : 'ok';\n\n return {\n healthy: isOverallHealthy,\n components: results,\n checkedAt: startTime,\n durationMS: Date.now() - startTime,\n timedOut: hasTimeout,\n code,\n };\n }\n\n // ============================================================================\n // Shared Values (getValue Pattern)\n // ============================================================================\n\n /**\n * Request a value from a component by key\n *\n * Calls the component's getValue(key, from) method if implemented.\n * The 'from' parameter is automatically tracked based on calling context.\n *\n * @param componentName - Name of component to request value from\n * @param key - Value key to request\n * @returns Result with found status, value, and metadata\n */\n public getValue<T = unknown>(\n componentName: string,\n key: string,\n options?: GetValueOptions,\n ): ValueResult<T> {\n return this.getValueInternal<T>(componentName, key, null, options);\n }\n\n // ============================================================================\n // Internal Methods (Private - accessed via callbacks)\n // ============================================================================\n\n /**\n * Internal message sending with explicit 'from' parameter\n *\n * @param componentName - Target component name\n * @param payload - Message payload\n * @param from - Sender component name (null if external)\n */\n private async sendMessageInternal(\n componentName: string,\n payload: unknown,\n from: string | null,\n options?: SendMessageOptions,\n ): Promise<MessageResult> {\n // Check if shutting down\n if (this.isShuttingDown) {\n return {\n sent: false,\n componentFound: this.hasComponent(componentName),\n componentRunning: false,\n handlerImplemented: false,\n data: undefined,\n error: new Error('Cannot send message: shutdown in progress'),\n timedOut: false,\n code: 'error',\n };\n }\n\n // Find component\n const component = this.components.find(\n (c) => c.getName() === componentName,\n );\n\n if (!component) {\n return {\n sent: false,\n componentFound: false,\n componentRunning: false,\n handlerImplemented: false,\n data: undefined,\n error: null,\n timedOut: false,\n code: 'not_found',\n };\n }\n\n const isRunning = this.isComponentRunning(componentName);\n const isStalled = this.stalledComponents.has(componentName);\n const allowStopped = options?.includeStopped === true;\n const allowStalled = options?.includeStalled === true;\n const isStopped = !isRunning && !isStalled;\n\n // Check if running or explicitly allowed\n if (!isRunning) {\n if ((isStalled && allowStalled) || (isStopped && allowStopped)) {\n // Allowed to send to non-running component\n } else {\n return {\n sent: false,\n componentFound: true,\n componentRunning: false,\n handlerImplemented: false,\n data: undefined,\n error: null,\n timedOut: false,\n code: isStalled ? 'stalled' : 'stopped',\n };\n }\n }\n\n // Check if handler implemented\n if (!component.onMessage) {\n return {\n sent: false,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: false,\n data: undefined,\n error: null,\n timedOut: false,\n code: 'no_handler',\n };\n }\n\n // Send message\n this.lifecycleEvents.componentMessageSent({ componentName, from, payload });\n\n const timeoutMS = options?.timeout ?? this.messageTimeoutMS;\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutResult = { timedOut: true } as const;\n\n try {\n let result: unknown;\n try {\n result = component.onMessage(payload, from);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger\n .entity(componentName)\n .error('Message handler failed', { params: { error: err, from } });\n this.lifecycleEvents.componentMessageFailed(componentName, from, err, {\n timedOut: false,\n code: 'error',\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n data: undefined,\n });\n\n return {\n sent: true,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n data: undefined,\n error: err,\n timedOut: false,\n code: 'error',\n };\n }\n\n const handlerPromise = isPromise(result)\n ? result\n : Promise.resolve(result);\n\n const outcome =\n timeoutMS > 0\n ? await Promise.race([\n handlerPromise,\n new Promise<typeof timeoutResult>((resolve) => {\n timeoutHandle = setTimeout(() => {\n resolve(timeoutResult);\n }, timeoutMS);\n }),\n ])\n : await handlerPromise;\n\n if (outcome === timeoutResult) {\n this.logger.entity(componentName).warn('Message handler timed out', {\n params: { from, timeoutMS },\n });\n // Prevent unhandled rejection if handler throws after timeout\n Promise.resolve(handlerPromise).catch(() => {\n // Intentionally ignore errors after timeout\n });\n return {\n sent: true,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n data: undefined,\n error: null,\n timedOut: true,\n code: 'timeout',\n };\n }\n\n return {\n sent: true,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n data: outcome,\n error: null,\n timedOut: false,\n code: 'sent',\n };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.entity(componentName).error('Message handler failed', {\n params: { error: err, from, timeoutMS },\n });\n this.lifecycleEvents.componentMessageFailed(componentName, from, err, {\n timedOut: false,\n code: 'error',\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n data: undefined,\n });\n\n return {\n sent: true,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n data: undefined,\n error: err,\n timedOut: false,\n code: 'error',\n };\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n /**\n * Internal broadcast with explicit 'from' parameter\n *\n * @param payload - Message payload\n * @param from - Sender component name (null if external)\n * @param options - Filtering options\n */\n private async broadcastMessageInternal(\n payload: unknown,\n from: string | null,\n options?: BroadcastOptions,\n ): Promise<BroadcastResult[]> {\n this.lifecycleEvents.componentBroadcastStarted(from, payload);\n\n const results: BroadcastResult[] = [];\n\n // Determine which components to broadcast to\n let targetComponents = this.components;\n\n const hasExplicitTargets =\n options?.componentNames !== undefined &&\n options.componentNames.length > 0;\n\n // Filter by names if specified\n if (hasExplicitTargets && options.componentNames) {\n const names = options.componentNames;\n targetComponents = targetComponents.filter((c) =>\n names.includes(c.getName()),\n );\n }\n\n const allowStopped = options?.includeStopped === true;\n const allowStalled = options?.includeStalled === true;\n\n // Filter by running/stalled/stopped state unless explicitly included\n if (!allowStopped && !allowStalled && !hasExplicitTargets) {\n targetComponents = targetComponents.filter((c) =>\n this.isComponentRunning(c.getName()),\n );\n } else if (!hasExplicitTargets) {\n targetComponents = targetComponents.filter((c) => {\n const name = c.getName();\n const isRunning = this.isComponentRunning(name);\n\n if (isRunning) {\n return true;\n }\n\n const isStalled = this.stalledComponents.has(name);\n\n if (isStalled) {\n return allowStalled;\n }\n\n return allowStopped;\n });\n }\n\n // Send to each component\n for (const component of targetComponents) {\n const name = component.getName();\n const isRunning = this.isComponentRunning(name);\n const isStalled = this.stalledComponents.has(name);\n const isStopped = !isRunning && !isStalled;\n const allowNonRunning =\n (isStalled && allowStalled) || (isStopped && allowStopped);\n\n // Skip if not running and not explicitly allowed\n if (!isRunning && !allowNonRunning) {\n results.push({\n name,\n sent: false,\n running: false,\n data: undefined,\n error: null,\n timedOut: false,\n code: isStalled ? 'stalled' : 'stopped',\n });\n continue;\n }\n\n // Send message using internal method\n const messageResult = await this.sendMessageInternal(\n name,\n payload,\n from,\n options,\n );\n\n results.push({\n name,\n sent: messageResult.sent,\n running: messageResult.componentRunning,\n data: messageResult.data,\n error: messageResult.error,\n timedOut: messageResult.timedOut,\n code: messageResult.code === 'not_found' ? 'error' : messageResult.code,\n });\n }\n\n this.lifecycleEvents.componentBroadcastCompleted(\n from,\n results.length,\n results,\n );\n\n return results;\n }\n\n /**\n * Internal getValue with explicit 'from' parameter\n *\n * @param componentName - Target component name\n * @param key - Value key\n * @param from - Requester component name (null if external)\n */\n private getValueInternal<T = unknown>(\n componentName: string,\n key: string,\n from: string | null,\n options?: GetValueOptions,\n ): ValueResult<T> {\n this.lifecycleEvents.componentValueRequested(componentName, key, from);\n\n // Find component\n const component = this.components.find(\n (c) => c.getName() === componentName,\n );\n\n if (!component) {\n this.lifecycleEvents.componentValueReturned(componentName, key, from, {\n found: false,\n value: undefined,\n componentFound: false,\n componentRunning: false,\n handlerImplemented: false,\n requestedBy: from,\n code: 'not_found',\n });\n return {\n found: false,\n value: undefined,\n componentFound: false,\n componentRunning: false,\n handlerImplemented: false,\n requestedBy: from,\n code: 'not_found',\n };\n }\n\n // Check if running\n const isRunning = this.isComponentRunning(componentName);\n const isStalled = this.stalledComponents.has(componentName);\n const allowStopped = options?.includeStopped === true;\n const allowStalled = options?.includeStalled === true;\n const isStopped = !isRunning && !isStalled;\n\n if (\n !isRunning &&\n !((isStopped && allowStopped) || (isStalled && allowStalled))\n ) {\n const code = isStalled ? 'stalled' : 'stopped';\n this.lifecycleEvents.componentValueReturned(componentName, key, from, {\n found: false,\n value: undefined,\n componentFound: true,\n componentRunning: false,\n handlerImplemented: false,\n requestedBy: from,\n code,\n });\n return {\n found: false,\n value: undefined,\n componentFound: true,\n componentRunning: false,\n handlerImplemented: false,\n requestedBy: from,\n code,\n };\n }\n\n // Check if handler implemented\n if (!component.getValue) {\n this.lifecycleEvents.componentValueReturned(componentName, key, from, {\n found: false,\n value: undefined,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: false,\n requestedBy: from,\n code: 'no_handler',\n });\n return {\n found: false,\n value: undefined,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: false,\n requestedBy: from,\n code: 'no_handler',\n };\n }\n\n // Get value\n try {\n const componentResult = component.getValue(key, from);\n const wasFound = componentResult.found;\n const value = componentResult.value;\n\n this.lifecycleEvents.componentValueReturned(componentName, key, from, {\n found: wasFound,\n value,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n requestedBy: from,\n code: wasFound ? 'found' : 'not_found',\n });\n\n return {\n found: wasFound,\n value: value as T | undefined,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n requestedBy: from,\n code: wasFound ? 'found' : 'not_found',\n };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.entity(componentName).error('getValue handler failed', {\n params: { error: err, key, from },\n });\n\n this.lifecycleEvents.componentValueReturned(componentName, key, from, {\n found: false,\n value: undefined,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n requestedBy: from,\n code: 'error',\n });\n\n return {\n found: false,\n value: undefined,\n componentFound: true,\n componentRunning: isRunning,\n handlerImplemented: true,\n requestedBy: from,\n code: 'error',\n };\n }\n }\n\n // ============================================================================\n // Private Helper Methods\n // ============================================================================\n\n private updateStartedFlag(): void {\n this.isStarted =\n this.runningComponents.size > 0 || this.stalledComponents.size > 0;\n }\n\n /**\n * Internal method that handles component registration logic.\n * Used by both registerComponent and insertComponentAt.\n */\n private async registerComponentInternal(\n component: BaseComponent,\n position: InsertPosition,\n targetComponentName?: string,\n isInsertAction = false,\n _options?: RegisterOptions,\n ): Promise<InsertComponentAtResult> {\n const componentName = component.getName();\n const registrationIndexBefore = this.getComponentIndex(componentName);\n\n try {\n if (!this.isInsertPosition(position)) {\n this.logger.entity(componentName).warn('Invalid insertion position', {\n params: { position },\n });\n this.lifecycleEvents.componentRegistrationRejected({\n name: componentName,\n reason: 'invalid_position',\n message: `Invalid insert position: \"${String(position)}\". Expected one of: start, end, before, after.`,\n registrationIndexBefore,\n registrationIndexAfter: registrationIndexBefore,\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n manualPositionRespected: false,\n });\n\n return this.buildInsertResultFailure({\n componentName,\n position,\n targetComponentName,\n registrationIndexBefore,\n code: 'invalid_position',\n reason: `Invalid insert position: \"${String(position)}\". Expected one of: start, end, before, after.`,\n targetFound: undefined,\n });\n }\n\n // Block registration during shutdown\n if (this.isShuttingDown) {\n this.logger\n .entity(componentName)\n .warn('Cannot register component during shutdown');\n this.lifecycleEvents.componentRegistrationRejected({\n name: componentName,\n reason: 'shutdown_in_progress',\n message:\n 'Cannot register component while shutdown is in progress (isShuttingDown=true).',\n registrationIndexBefore,\n registrationIndexAfter: registrationIndexBefore,\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n manualPositionRespected: false,\n });\n\n return this.buildInsertResultFailure({\n componentName,\n position,\n targetComponentName,\n registrationIndexBefore,\n code: 'shutdown_in_progress',\n reason:\n 'Cannot register component while shutdown is in progress (isShuttingDown=true).',\n targetFound: undefined,\n });\n }\n\n // Block registration during startup if this component would be a dependency\n // for any already-registered component (would break dependency ordering)\n if (this.isRequiredDependencyDuringStartup(componentName)) {\n this.logger\n .entity(componentName)\n .warn(\n 'Cannot register component during startup - it is a required dependency for other components',\n );\n this.lifecycleEvents.componentRegistrationRejected({\n name: componentName,\n reason: 'startup_in_progress',\n message:\n 'Cannot register component during startup when it is a required dependency for other components.',\n registrationIndexBefore,\n registrationIndexAfter: registrationIndexBefore,\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n manualPositionRespected: false,\n });\n\n return this.buildInsertResultFailure({\n componentName,\n position,\n targetComponentName,\n registrationIndexBefore,\n code: 'startup_in_progress',\n reason:\n 'Cannot register component during startup when it is a required dependency for other components.',\n targetFound: undefined,\n });\n }\n\n // Check if component instance is already registered\n if (this.hasComponentInstance(component)) {\n this.logger\n .entity(componentName)\n .warn('Component instance already registered');\n this.lifecycleEvents.componentRegistrationRejected({\n name: componentName,\n reason: 'duplicate_instance',\n message: 'Component instance is already registered.',\n registrationIndexBefore,\n registrationIndexAfter: registrationIndexBefore,\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n manualPositionRespected: false,\n });\n\n return this.buildInsertResultFailure({\n componentName,\n position,\n targetComponentName,\n registrationIndexBefore,\n code: 'duplicate_instance',\n reason: 'Component instance is already registered.',\n targetFound: undefined,\n });\n }\n\n // Check if component name is already registered\n if (registrationIndexBefore !== null) {\n this.logger\n .entity(componentName)\n .warn('Component with this name already registered');\n this.lifecycleEvents.componentRegistrationRejected({\n name: componentName,\n reason: 'duplicate_name',\n message: `Component \"${componentName}\" is already registered.`,\n registrationIndexBefore,\n registrationIndexAfter: registrationIndexBefore,\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n manualPositionRespected: false,\n });\n\n return this.buildInsertResultFailure({\n componentName,\n position,\n targetComponentName,\n registrationIndexBefore,\n code: 'duplicate_name',\n reason: `Component \"${componentName}\" is already registered.`,\n targetFound: undefined,\n });\n }\n\n // Get the insertion index for the component\n const insertIndex = this.getInsertIndex(position, targetComponentName);\n if (insertIndex === null) {\n this.logger.entity(componentName).warn('Target component not found', {\n params: { target: targetComponentName },\n });\n this.lifecycleEvents.componentRegistrationRejected({\n name: componentName,\n reason: 'target_not_found',\n target: targetComponentName,\n message: `Target component \"${targetComponentName ?? ''}\" not found in registry.`,\n registrationIndexBefore,\n registrationIndexAfter: null,\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n manualPositionRespected: false,\n targetFound: false,\n });\n\n // Block registration during startup if this component would be a dependency\n // for any already-registered component (would break dependency ordering)\n let startupOrder: string[];\n\n try {\n startupOrder = this.getStartupOrderInternal();\n } catch (error) {\n // Defensive: This should never happen in normal operation since we validate\n // cycles before registration. However, if this.components somehow contains\n // a cycle (e.g., due to internal bugs or direct mutations), we must not\n // throw from an error handler. Return empty array to fail gracefully.\n this.logger.warn('Failed to compute startup order in error handler', {\n params: { error: error instanceof Error ? error.message : error },\n });\n\n startupOrder = [];\n }\n\n return {\n action: 'insert',\n success: false,\n registered: false,\n componentName,\n reason: `Target component \"${targetComponentName ?? ''}\" not found in registry.`,\n code: 'target_not_found',\n registrationIndexBefore: null,\n registrationIndexAfter: null,\n startupOrder,\n requestedPosition: { position, targetComponentName },\n manualPositionRespected: false,\n targetFound: false,\n duringStartup: this.isStarting,\n autoStartAttempted: false,\n startResult: undefined,\n };\n }\n\n // Compute dependency order *before* committing registration mutations.\n // This avoids leaving the registry/state maps inconsistent if a dependency\n // cycle is detected.\n const nextComponents = [...this.components];\n nextComponents.splice(insertIndex, 0, component);\n\n let startupOrder: string[];\n\n try {\n startupOrder = this.getStartupOrderInternal(nextComponents);\n } catch (error) {\n if (error instanceof DependencyCycleError) {\n this.logger\n .entity(componentName)\n .warn('Registration rejected due to dependency cycle', {\n params: { cycle: error.additionalInfo.cycle },\n });\n this.lifecycleEvents.componentRegistrationRejected({\n name: componentName,\n reason: 'dependency_cycle',\n cycle: error.additionalInfo.cycle,\n message: error.message,\n registrationIndexBefore,\n registrationIndexAfter: registrationIndexBefore,\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n manualPositionRespected: false,\n targetFound:\n position === 'before' || position === 'after' ? true : undefined,\n });\n\n return this.buildInsertResultFailure({\n componentName,\n position,\n targetComponentName,\n registrationIndexBefore,\n code: 'dependency_cycle',\n reason: error.message,\n error,\n targetFound:\n position === 'before' || position === 'after' ? true : undefined,\n });\n }\n throw error;\n }\n\n // Commit registration\n this.components.splice(insertIndex, 0, component);\n\n // Create callbacks for component-scoped lifecycle\n const internalCallbacks: LifecycleInternalCallbacks = {\n sendMessageInternal: (\n compName: string,\n payload: unknown,\n from: string | null,\n options?: SendMessageOptions,\n ) => this.sendMessageInternal(compName, payload, from, options),\n broadcastMessageInternal: (\n payload: unknown,\n from: string | null,\n opts?: BroadcastOptions,\n ) => this.broadcastMessageInternal(payload, from, opts),\n getValueInternal: <T = unknown>(\n compName: string,\n key: string,\n from: string | null,\n ) => this.getValueInternal<T>(compName, key, from),\n };\n\n // Assign lifecycle reference to component\n (component as unknown as { lifecycle: ComponentLifecycleRef }).lifecycle =\n new ComponentLifecycle(this, componentName, internalCallbacks);\n\n // Initialize state\n this.componentStates.set(componentName, 'registered');\n this.componentTimestamps.set(componentName, {\n startedAt: null,\n stoppedAt: null,\n });\n this.componentErrors.set(componentName, null);\n\n // Check if manual position was respected for logging\n const isManualPositionRespected = this.isManualPositionRespected({\n componentName,\n position,\n targetComponentName,\n startupOrder,\n });\n\n // Get the final registration index after insertion\n const registrationIndexAfter = this.getComponentIndex(componentName);\n const isTargetFound =\n position === 'before' || position === 'after'\n ? this.getComponentIndex(targetComponentName ?? '') !== null\n : undefined;\n\n if (isInsertAction) {\n this.logger.entity(componentName).info('Component inserted', {\n params: { position, index: registrationIndexAfter },\n });\n } else {\n this.logger.entity(componentName).info('Component registered', {\n params: { index: registrationIndexAfter },\n });\n }\n\n // Determine if auto-start will be attempted\n const shouldAutoStart = _options?.autoStart === true;\n let didAutoStartAttempt = false;\n\n // Handle AutoStart if requested and capture result\n let startResult: ComponentOperationResult | undefined;\n\n if (shouldAutoStart) {\n if (this.isStarted) {\n // Manager is already running - start the component directly\n this.logger\n .entity(componentName)\n .info('AutoStart: starting component (manager is running)');\n startResult = await this.startComponentInternal(componentName);\n didAutoStartAttempt = true;\n } else if (this.isStarting) {\n // Manager is currently starting - allow during bulk startup\n this.logger\n .entity(componentName)\n .info('AutoStart: starting component (during bulk startup)');\n startResult = await this.startComponentInternal(componentName, {\n allowDuringBulkStartup: true,\n });\n didAutoStartAttempt = true;\n } else {\n // Manager is not running - attempt to start just this component\n this.logger\n .entity(componentName)\n .info('AutoStart: starting component (manager not running)');\n startResult = await this.startComponentInternal(componentName);\n didAutoStartAttempt = true;\n }\n }\n\n const didAutoStartSucceed = didAutoStartAttempt\n ? startResult?.success === true\n : undefined;\n\n // Generate position description\n let positionDescription: string | undefined;\n\n if (registrationIndexAfter !== null) {\n const totalComponents = this.components.length;\n\n if (totalComponents === 1) {\n positionDescription = 'only component';\n } else if (registrationIndexAfter === 0) {\n const nextComponent = this.components[1]?.getName();\n positionDescription = nextComponent\n ? `at start, before ${nextComponent}`\n : 'at start';\n } else if (registrationIndexAfter === totalComponents - 1) {\n const prevComponent = this.components[totalComponents - 2]?.getName();\n positionDescription = prevComponent\n ? `at end, after ${prevComponent}`\n : 'at end';\n } else {\n const prevComponent =\n this.components[registrationIndexAfter - 1]?.getName();\n const nextComponent =\n this.components[registrationIndexAfter + 1]?.getName();\n if (prevComponent && nextComponent) {\n positionDescription = `after ${prevComponent}, before ${nextComponent}`;\n } else if (prevComponent) {\n positionDescription = `after ${prevComponent}`;\n } else if (nextComponent) {\n positionDescription = `before ${nextComponent}`;\n }\n }\n }\n\n const actualPosition =\n registrationIndexAfter !== null\n ? { index: registrationIndexAfter, description: positionDescription }\n : undefined;\n\n // Emit registration event\n this.lifecycleEvents.componentRegistered({\n name: componentName,\n index: registrationIndexAfter,\n action: isInsertAction ? 'insert' : 'register',\n registrationIndexBefore,\n registrationIndexAfter,\n startupOrder,\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n actualPosition,\n manualPositionRespected: isManualPositionRespected,\n targetFound: isTargetFound,\n duringStartup: this.isStarting,\n autoStartAttempted: didAutoStartAttempt,\n autoStartSucceeded: didAutoStartSucceed,\n });\n\n return {\n action: 'insert',\n success: true,\n registered: true,\n componentName,\n registrationIndexBefore: null,\n registrationIndexAfter,\n startupOrder,\n requestedPosition: { position, targetComponentName },\n actualPosition,\n manualPositionRespected: isManualPositionRespected,\n targetFound: isTargetFound,\n duringStartup: this.isStarting,\n autoStartAttempted: didAutoStartAttempt,\n autoStartSucceeded: didAutoStartSucceed,\n startResult,\n };\n } catch (error) {\n // Handle unexpected errors during registration\n const err = error as Error;\n const code: RegistrationFailureCode =\n err instanceof DependencyCycleError\n ? 'dependency_cycle'\n : 'unknown_error';\n\n this.logger\n .entity(componentName)\n .error('Registration failed with unexpected error', {\n params: { error: err },\n });\n this.lifecycleEvents.componentRegistrationRejected({\n name: componentName,\n reason: code,\n message: err.message,\n registrationIndexBefore,\n registrationIndexAfter: registrationIndexBefore,\n startupOrder: [],\n requestedPosition: isInsertAction\n ? { position, targetComponentName }\n : undefined,\n manualPositionRespected: false,\n targetFound:\n position === 'before' || position === 'after' ? false : undefined,\n ...(err instanceof DependencyCycleError\n ? { cycle: err.additionalInfo.cycle }\n : {}),\n });\n\n return {\n action: 'insert',\n success: false,\n registered: false,\n componentName,\n reason: err.message,\n code,\n error: err,\n registrationIndexBefore,\n registrationIndexAfter: registrationIndexBefore,\n startupOrder: [],\n requestedPosition: { position, targetComponentName },\n manualPositionRespected: false,\n targetFound:\n position === 'before' || position === 'after' ? false : undefined,\n duringStartup: this.isStarting,\n autoStartAttempted: false,\n startResult: undefined,\n };\n }\n }\n\n private async stopAllComponentsInternal(\n method: ShutdownMethod,\n options?: StopAllOptions,\n ): Promise<ShutdownResult> {\n const startTime = Date.now();\n const effectiveTimeout =\n options?.timeoutMS ?? this.shutdownOptions?.timeoutMS ?? 30000;\n const shouldRetryStalled = options?.retryStalled ?? true;\n const shouldHaltOnStall = options?.haltOnStall ?? true;\n\n // Reject if already shutting down\n if (this.isShuttingDown) {\n this.logger.warn(\n 'Cannot stop all components: shutdown already in progress',\n );\n\n return {\n success: false,\n stoppedComponents: [],\n stalledComponents: [],\n durationMS: 0,\n reason: 'Shutdown already in progress',\n code: 'already_in_progress',\n };\n }\n\n // Set shutting down flag and track how shutdown was triggered\n this.isShuttingDown = true;\n this.shutdownMethod = method;\n const isDuringStartup = this.isStarting;\n this.logger.info('Stopping all components', { params: { method } });\n this.lifecycleEvents.lifecycleManagerShutdownInitiated(\n method,\n isDuringStartup,\n );\n\n // Get shutdown order (reverse topological order)\n let shutdownOrder: string[];\n\n try {\n const startupOrder = this.getStartupOrderInternal();\n shutdownOrder = [...startupOrder].reverse();\n } catch (error) {\n // If we can't resolve order due to cycle, fall back to reverse registration order\n this.logger.warn(\n 'Could not resolve shutdown order, using registration order',\n {\n params: { error: (error as Error).message },\n },\n );\n shutdownOrder = this.components.map((c) => c.getName()).reverse();\n }\n\n const stalledComponentNames = new Set(this.stalledComponents.keys());\n\n // Filter to running components, plus stalled ones if retrying\n const runningComponentsToStop = shutdownOrder.filter(\n (name) =>\n this.isComponentRunning(name) ||\n (shouldRetryStalled && stalledComponentNames.has(name)),\n );\n\n const stoppedComponents: string[] = [];\n const stalledComponents: ComponentStallInfo[] = [];\n let hasTimedOut = false;\n let timeoutHandle: NodeJS.Timeout | undefined;\n\n try {\n // Start global timeout clock (halts further stop attempts after it fires)\n const timeoutPromise =\n effectiveTimeout > 0\n ? new Promise<'timeout'>((resolve) => {\n timeoutHandle = setTimeout(() => {\n hasTimedOut = true;\n\n this.logger.warn(\n 'Shutdown timeout exceeded, halting further stop attempts',\n {\n params: { timeoutMS: effectiveTimeout },\n },\n );\n\n resolve('timeout');\n }, effectiveTimeout);\n })\n : null;\n\n // Create shutdown operation\n const shutdownOperation = async () => {\n await this.runShutdownWarningPhase(runningComponentsToStop);\n\n // Stop each component in reverse dependency order\n for (const name of runningComponentsToStop) {\n if (hasTimedOut) {\n this.logger.warn(\n 'Shutdown timeout reached, stopping further component shutdown',\n {\n params: { timeoutMS: effectiveTimeout },\n },\n );\n break;\n }\n\n this.logger.entity(name).info('Stopping component');\n\n // Use internal method to bypass bulk operation checks.\n // - If running: normal stop flow\n // - If stalled and retryStalled: force-phase retry\n // - If stalled and no retry: report component_stalled\n // - Otherwise: component_not_running\n const isRunning = this.isComponentRunning(name);\n const isStalled = stalledComponentNames.has(name);\n\n const result: ComponentOperationResult = isRunning\n ? await this.stopComponentInternal(name)\n : shouldRetryStalled && isStalled\n ? await this.retryStalledComponent(name)\n : isStalled\n ? {\n success: false,\n componentName: name,\n reason: 'Component is stalled',\n code: 'component_stalled',\n status: this.getComponentStatus(name),\n }\n : {\n success: false,\n componentName: name,\n reason: 'Component not running',\n code: 'component_not_running',\n status: this.getComponentStatus(name),\n };\n\n if (result.success) {\n stoppedComponents.push(name);\n } else {\n // Component failed to stop - track as stalled but continue\n this.logger\n .entity(name)\n .error('Component failed to stop, continuing with others', {\n params: { error: result.error?.message },\n });\n\n const stallInfo = this.stalledComponents.get(name);\n if (stallInfo) {\n stalledComponents.push(stallInfo);\n }\n\n if (shouldHaltOnStall) {\n this.logger.warn(\n 'Halting shutdown after stall (haltOnStall=true)',\n { params: { stalledComponent: name } },\n );\n break;\n }\n }\n }\n };\n\n if (timeoutPromise) {\n await Promise.race([shutdownOperation(), timeoutPromise]);\n } else {\n await shutdownOperation();\n }\n\n const durationMS = Date.now() - startTime;\n const isSuccess = !hasTimedOut && stalledComponents.length === 0;\n\n this.logger[isSuccess ? 'success' : 'warn']('Shutdown completed', {\n params: {\n stopped: stoppedComponents.length,\n stalled: stalledComponents.length,\n durationMS,\n },\n });\n\n this.lifecycleEvents.lifecycleManagerShutdownCompleted({\n durationMS,\n stoppedComponents,\n stalledComponents,\n method,\n duringStartup: isDuringStartup,\n });\n\n const result: ShutdownResult = {\n success: isSuccess,\n stoppedComponents,\n stalledComponents,\n durationMS,\n timedOut: hasTimedOut || undefined,\n ...(hasTimedOut\n ? {\n code: 'shutdown_timeout' as const,\n reason: `Shutdown timeout exceeded (${effectiveTimeout}ms)`,\n }\n : {}),\n };\n\n // Store for getLastShutdownResult() - useful for debugging and metrics\n this.lastShutdownResult = result;\n\n return result;\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n\n // Reset state\n this.isShuttingDown = false;\n this.updateStartedFlag();\n }\n }\n\n /**\n * Retry shutdown for a stalled component.\n * Attempts the force phase directly to avoid re-running a failing stop().\n */\n private async retryStalledComponent(\n name: string,\n ): Promise<ComponentOperationResult> {\n const component = this.getComponent(name);\n\n if (!component) {\n return {\n success: false,\n componentName: name,\n reason: 'Component not found',\n code: 'component_not_found',\n };\n }\n\n if (!this.stalledComponents.has(name)) {\n if (this.isComponentRunning(name)) {\n return this.stopComponentInternal(name);\n }\n\n return {\n success: false,\n componentName: name,\n reason: 'Component not running',\n code: 'component_not_running',\n status: this.getComponentStatus(name),\n };\n }\n\n this.logger\n .entity(name)\n .warn('Retrying stalled component shutdown (force phase)');\n\n return this.shutdownComponentForce(name, component, {\n gracefulPhaseRan: false,\n gracefulTimedOut: false,\n gracefulError: undefined,\n startedAt: Date.now(),\n });\n }\n\n /**\n * Internal start component method - bypasses bulk operation checks\n * Used by both startComponent() and startAllComponents()\n */\n private async startComponentInternal(\n name: string,\n options?: StartComponentOptions,\n ): Promise<ComponentOperationResult> {\n // ALWAYS reject during shutdown (never bypass this check)\n if (this.isShuttingDown) {\n this.logger.entity(name).warn('Cannot start component during shutdown', {\n params: { isShuttingDown: this.isShuttingDown },\n });\n\n return {\n success: false,\n componentName: name,\n reason: 'Shutdown in progress',\n code: 'shutdown_in_progress',\n };\n }\n\n // Reject during bulk startup (unless allowDuringBulkStartup is enabled)\n const allowDuringBulkStartup = options?.allowDuringBulkStartup === true;\n if (!allowDuringBulkStartup && this.isStarting) {\n this.logger\n .entity(name)\n .warn('Cannot start component during bulk startup', {\n params: { isStarting: this.isStarting },\n });\n\n return {\n success: false,\n componentName: name,\n reason: 'Bulk startup in progress',\n code: 'startup_in_progress',\n };\n }\n\n const allowNonRunningDependencies =\n options?.allowNonRunningDependencies === true;\n\n const component = this.getComponent(name);\n\n if (!component) {\n return {\n success: false,\n componentName: name,\n reason: 'Component not found',\n code: 'component_not_found',\n };\n }\n\n // Check if component is stalled (unless explicitly forced)\n const shouldForceStalled = options?.forceStalled === true;\n if (!shouldForceStalled && this.stalledComponents.has(name)) {\n return {\n success: false,\n componentName: name,\n reason: 'Component is stalled',\n code: 'component_stalled',\n status: this.getComponentStatus(name),\n };\n }\n\n // Ensure dependencies are registered and running before starting.\n for (const dependencyName of component.getDependencies()) {\n const dependency = this.getComponent(dependencyName);\n if (!dependency) {\n return {\n success: false,\n componentName: name,\n reason: `Missing dependency \"${dependencyName}\"`,\n code: 'missing_dependency',\n status: this.getComponentStatus(name),\n };\n }\n\n if (!this.isComponentRunning(dependencyName)) {\n const isDependencyOptional = dependency.isOptional();\n\n // Check if we can skip this dependency\n if (allowNonRunningDependencies) {\n // Explicit override - allow skipping both optional and required dependencies\n this.logger\n .entity(name)\n .warn(\n `Starting with non-running dependency \"${dependencyName}\" (allowNonRunningDependencies=true)`,\n );\n continue;\n }\n\n if (isDependencyOptional) {\n // Optional dependencies never block startup\n this.logger\n .entity(name)\n .warn(\n `Starting with non-running optional dependency \"${dependencyName}\"`,\n );\n continue;\n }\n\n return {\n success: false,\n componentName: name,\n reason: `Dependency \"${dependencyName}\" is not running`,\n code: 'dependency_not_running',\n status: this.getComponentStatus(name),\n };\n }\n }\n\n const currentState = this.componentStates.get(name);\n if (currentState === 'starting') {\n return {\n success: false,\n componentName: name,\n reason: 'Component already starting',\n code: 'component_already_starting',\n status: this.getComponentStatus(name),\n };\n }\n\n // Check if already running\n if (this.isComponentRunning(name)) {\n return {\n success: false,\n componentName: name,\n reason: 'Component already running',\n code: 'component_already_running',\n status: this.getComponentStatus(name),\n };\n }\n\n // Set state to starting\n this.componentStates.set(name, 'starting');\n this.logger.entity(name).info('Starting component');\n this.lifecycleEvents.componentStarting(name);\n\n const timeoutMS = component.startupTimeoutMS;\n let timeoutHandle: NodeJS.Timeout | undefined;\n\n try {\n // Race against timeout\n const startPromise = component.start();\n\n if (timeoutMS > 0) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n // Call abort callback if implemented\n if (component.onStartupAborted) {\n try {\n component.onStartupAborted();\n } catch (error) {\n this.logger\n .entity(name)\n .warn('Error in onStartupAborted callback', {\n params: { error },\n });\n }\n }\n // Prevent unhandled rejection if start() throws after timeout\n Promise.resolve(startPromise).catch(() => {\n // Intentionally ignore errors after timeout\n });\n reject(\n new ComponentStartTimeoutError({\n componentName: name,\n timeoutMS,\n }),\n );\n }, timeoutMS);\n });\n\n await Promise.race([startPromise, timeoutPromise]);\n } else {\n await startPromise;\n }\n\n // Update state\n this.componentStates.set(name, 'running');\n this.runningComponents.add(name);\n this.stalledComponents.delete(name); // Clear stalled state if component was previously stalled\n this.updateStartedFlag();\n\n // Auto-attach signals if this is the first component and option is enabled\n if (\n this.attachSignalsOnStart &&\n this.runningComponents.size === 1 &&\n !this.processSignalManager\n ) {\n this.logger.info(\n 'Auto-attaching process signals on first component start',\n );\n this.attachSignals();\n }\n\n const timestamps = this.componentTimestamps.get(name) ?? {\n startedAt: null,\n stoppedAt: null,\n };\n timestamps.startedAt = Date.now();\n this.componentTimestamps.set(name, timestamps);\n\n this.logger.entity(name).success('Component started');\n const status = this.getComponentStatus(name);\n this.lifecycleEvents.componentStarted(name, status);\n\n return {\n success: true,\n componentName: name,\n status: this.getComponentStatus(name),\n };\n } catch (error) {\n const err = error as Error;\n\n // Store error\n this.componentErrors.set(name, err);\n\n // Check if it was a timeout\n if (\n err instanceof ComponentStartTimeoutError &&\n err.additionalInfo.componentName === name\n ) {\n this.componentStates.set(name, 'starting-timed-out'); // Timeout state (observability)\n this.logger.entity(name).error('Component startup timed out', {\n params: { error: err.message },\n });\n this.lifecycleEvents.componentStartTimeout(name, err, {\n timeoutMS,\n reason: err.message,\n });\n } else {\n this.componentStates.set(name, 'registered'); // Reset state\n this.logger.entity(name).error('Component failed to start', {\n params: { error: err.message },\n });\n this.lifecycleEvents.componentStartFailed(name, err, {\n reason: err.message,\n });\n }\n\n return {\n success: false,\n componentName: name,\n reason: err.message,\n code:\n err instanceof ComponentStartTimeoutError\n ? 'component_startup_timeout'\n : 'unknown_error',\n error: err,\n status: this.getComponentStatus(name),\n };\n } finally {\n // Ensure we always clean up the timeout handle, even if component.start()\n // rejects (non-timeout failure). Otherwise onStartupAborted() can fire\n // unexpectedly later and the timer handle leaks.\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n /**\n * Internal stop component method - bypasses bulk operation checks\n * Implements individual component graceful -> force shutdown (global warning handled elsewhere)\n */\n private async stopComponentInternal(\n name: string,\n options?: StopComponentOptions,\n ): Promise<ComponentOperationResult> {\n const component = this.getComponent(name);\n\n if (!component) {\n return {\n success: false,\n componentName: name,\n reason: 'Component not found',\n code: 'component_not_found',\n };\n }\n\n // Check if stalled\n if (this.stalledComponents.has(name)) {\n return {\n success: false,\n componentName: name,\n reason: 'Component is stalled',\n code: 'component_stalled',\n status: this.getComponentStatus(name),\n };\n }\n\n // Check if not running\n if (!this.isComponentRunning(name)) {\n return {\n success: false,\n componentName: name,\n reason: 'Component not running',\n code: 'component_not_running',\n status: this.getComponentStatus(name),\n };\n }\n\n // Check if already stopping to prevent concurrent stop operations\n const currentState = this.componentStates.get(name);\n if (currentState === 'stopping' || currentState === 'force-stopping') {\n return {\n success: false,\n componentName: name,\n reason: `Component is already ${currentState}`,\n code: 'component_already_stopping',\n status: this.getComponentStatus(name),\n };\n }\n\n // Handle forceImmediate option - skip all phases and go straight to force\n if (options?.forceImmediate) {\n return this.shutdownComponentForce(name, component, {\n gracefulPhaseRan: false,\n gracefulTimedOut: false,\n gracefulError: undefined,\n startedAt: Date.now(),\n });\n }\n\n // Run three-phase shutdown\n return this.shutdownComponent(name, component, options);\n }\n\n /**\n * Two-phase shutdown: graceful -> force (global warning handled by stopAllComponents)\n *\n * Phase 1: Graceful (always - calls stop())\n * Phase 2: Force (if Phase 1 failed - calls onShutdownForce())\n */\n private async shutdownComponent(\n name: string,\n component: BaseComponent,\n options?: StopComponentOptions,\n ): Promise<ComponentOperationResult> {\n const shutdownStartedAt = Date.now();\n\n // ============================================================================\n // Phase 1: Graceful (always)\n // ============================================================================\n const gracefulResult = await this.shutdownComponentGraceful(\n name,\n component,\n options,\n );\n\n if (gracefulResult.success) {\n return gracefulResult; // Graceful shutdown succeeded\n }\n\n // ============================================================================\n // Phase 2: Force (graceful failed)\n // ============================================================================\n this.logger\n .entity(name)\n .warn('Graceful shutdown failed, proceeding to force phase', {\n params: {\n reason: gracefulResult.reason,\n code: gracefulResult.code,\n },\n });\n\n return this.shutdownComponentForce(name, component, {\n gracefulPhaseRan: true,\n gracefulTimedOut: gracefulResult.code === 'component_shutdown_timeout',\n gracefulError: gracefulResult.error,\n startedAt: shutdownStartedAt,\n });\n }\n\n /**\n * Global warning phase (stopAllComponents only)\n * Calls onShutdownWarning() on running components with a global timeout\n */\n private async runShutdownWarningPhase(\n componentNames: string[],\n ): Promise<void> {\n const timeoutMS = this.shutdownWarningTimeoutMS;\n if (timeoutMS < 0 || componentNames.length === 0) {\n return;\n }\n\n // Only target running components that implement onShutdownWarning().\n const warningTargets: Array<{ name: string; component: BaseComponent }> =\n [];\n\n for (const name of componentNames) {\n const component = this.getComponent(name);\n\n if (component?.onShutdownWarning) {\n warningTargets.push({ name, component });\n }\n }\n\n if (warningTargets.length === 0) {\n return;\n }\n\n this.logger.info('Shutdown warning phase');\n this.lifecycleEvents.lifecycleManagerShutdownWarning(timeoutMS);\n\n if (timeoutMS === 0) {\n // Fire-and-forget: broadcast warnings without waiting for completion\n for (const { name, component } of warningTargets) {\n this.lifecycleEvents.componentShutdownWarning(name);\n Promise.resolve()\n .then(() => component.onShutdownWarning?.())\n .then(() => {\n this.lifecycleEvents.componentShutdownWarningCompleted(name);\n })\n .catch((error) => {\n this.logger.entity(name).warn('Shutdown warning phase failed', {\n params: { error: (error as Error).message },\n });\n });\n }\n\n // Flush microtask queue to ensure promises start executing before emitting completion\n await Promise.resolve();\n\n // Now that warnings are executing, emit global completion event\n this.lifecycleEvents.lifecycleManagerShutdownWarningCompleted(timeoutMS);\n\n return;\n }\n\n // Track completion so we can identify which components are still pending at timeout.\n const statuses = new Map<string, 'pending' | 'resolved' | 'rejected'>();\n const warningPromises: Promise<void>[] = [];\n\n for (const { name, component } of warningTargets) {\n statuses.set(name, 'pending');\n this.lifecycleEvents.componentShutdownWarning(name);\n\n const warningPromise = Promise.resolve().then(() =>\n component.onShutdownWarning?.(),\n );\n\n warningPromises.push(\n warningPromise\n .then(() => {\n statuses.set(name, 'resolved');\n this.lifecycleEvents.componentShutdownWarningCompleted(name);\n })\n .catch((error) => {\n statuses.set(name, 'rejected');\n this.logger.entity(name).warn('Shutdown warning phase failed', {\n params: { error: (error as Error).message },\n });\n }),\n );\n }\n\n // Race overall completion vs global timeout.\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutPromise = new Promise<'timeout'>((resolve) => {\n timeoutHandle = setTimeout(() => resolve('timeout'), timeoutMS);\n });\n\n try {\n const result = await Promise.race([\n Promise.allSettled(warningPromises).then(() => 'completed' as const),\n timeoutPromise,\n ]);\n\n if (result === 'timeout') {\n const pendingComponents = warningTargets.filter(\n ({ name }) => statuses.get(name) === 'pending',\n );\n\n for (const { name } of pendingComponents) {\n this.logger.entity(name).warn('Shutdown warning phase timed out', {\n params: { timeoutMS },\n });\n\n this.lifecycleEvents.componentShutdownWarningTimeout(name, timeoutMS);\n }\n\n // Global timeout: proceed to graceful shutdown regardless of pending warnings.\n this.logger.warn('Shutdown warning phase timed out', {\n params: { timeoutMS, pending: pendingComponents.length },\n });\n\n this.lifecycleEvents.lifecycleManagerShutdownWarningTimeout(\n timeoutMS,\n pendingComponents.map(({ name }) => name),\n );\n\n return;\n }\n\n this.lifecycleEvents.lifecycleManagerShutdownWarningCompleted(timeoutMS);\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n /**\n * Phase 2: Graceful shutdown\n * Calls stop() with timeout\n */\n private async shutdownComponentGraceful(\n name: string,\n component: BaseComponent,\n options?: StopComponentOptions,\n ): Promise<ComponentOperationResult> {\n // Set state to stopping\n this.componentStates.set(name, 'stopping');\n this.logger.entity(name).info('Graceful shutdown started');\n this.lifecycleEvents.componentStopping(name);\n\n // Use custom timeout if provided, otherwise use component's configured timeout\n const timeoutMS = options?.timeout ?? component.shutdownGracefulTimeoutMS;\n let timeoutHandle: NodeJS.Timeout | undefined;\n\n try {\n // Race against graceful timeout\n const stopPromise = component.stop();\n\n if (timeoutMS > 0) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n // Call abort callback if implemented\n if (component.onGracefulStopTimeout) {\n try {\n component.onGracefulStopTimeout();\n } catch (error) {\n this.logger\n .entity(name)\n .warn('Error in onGracefulStopTimeout callback', {\n params: { error },\n });\n }\n }\n\n // Prevent unhandled rejection if stop() throws after timeout\n Promise.resolve(stopPromise).catch(() => {\n // Intentionally ignore errors after timeout\n });\n reject(\n new ComponentStopTimeoutError({\n componentName: name,\n timeoutMS,\n }),\n );\n }, timeoutMS);\n });\n\n await Promise.race([stopPromise, timeoutPromise]);\n } else {\n await stopPromise;\n }\n\n // Update state - graceful succeeded\n this.componentStates.set(name, 'stopped');\n this.runningComponents.delete(name);\n this.stalledComponents.delete(name); // Clear stalled status on successful stop\n this.updateStartedFlag();\n\n // Auto-detach signals if this was the last component and option is enabled\n if (\n this.detachSignalsOnStop &&\n this.runningComponents.size === 0 &&\n this.processSignalManager\n ) {\n this.logger.info(\n 'Auto-detaching process signals on last component stop',\n );\n this.detachSignals();\n }\n\n const timestamps = this.componentTimestamps.get(name) ?? {\n startedAt: null,\n stoppedAt: null,\n };\n timestamps.stoppedAt = Date.now();\n this.componentTimestamps.set(name, timestamps);\n\n this.logger.entity(name).success('Component stopped gracefully');\n this.lifecycleEvents.componentStopped(\n name,\n this.getComponentStatus(name),\n );\n\n return {\n success: true,\n componentName: name,\n status: this.getComponentStatus(name),\n };\n } catch (error) {\n const err = error as Error;\n\n // Store error\n this.componentErrors.set(name, err);\n\n // Check if it was a timeout\n if (\n err instanceof ComponentStopTimeoutError &&\n err.additionalInfo.componentName === name\n ) {\n this.logger.entity(name).warn('Graceful shutdown timed out');\n this.lifecycleEvents.componentStopTimeout(name, err, {\n timeoutMS,\n reason: 'Graceful shutdown timed out',\n });\n\n return {\n success: false,\n componentName: name,\n reason: 'Graceful shutdown timed out',\n code: 'component_shutdown_timeout',\n error: err,\n status: this.getComponentStatus(name),\n };\n } else {\n // Error during graceful stop\n this.logger.entity(name).warn('Graceful shutdown threw error', {\n params: { error: err.message },\n });\n\n return {\n success: false,\n componentName: name,\n reason: err.message,\n code: 'unknown_error',\n error: err,\n status: this.getComponentStatus(name),\n };\n }\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n /**\n * Phase 3: Force shutdown\n * Calls onShutdownForce() with timeout, or marks as stalled if not implemented\n */\n private async shutdownComponentForce(\n name: string,\n component: BaseComponent,\n context: {\n gracefulPhaseRan: boolean;\n gracefulTimedOut: boolean;\n gracefulError?: Error;\n startedAt: number;\n },\n ): Promise<ComponentOperationResult> {\n this.componentStates.set(name, 'force-stopping');\n this.logger.entity(name).info('Force shutdown started', {\n params: {\n gracefulPhaseRan: context.gracefulPhaseRan,\n gracefulTimedOut: context.gracefulTimedOut,\n },\n });\n\n this.lifecycleEvents.componentShutdownForce({\n name,\n context: {\n gracefulPhaseRan: context.gracefulPhaseRan,\n gracefulTimedOut: context.gracefulTimedOut,\n },\n });\n\n const timeoutMS = component.shutdownForceTimeoutMS;\n let timeoutHandle: NodeJS.Timeout | undefined;\n\n // If component doesn't implement onShutdownForce, mark as stalled immediately\n if (!component.onShutdownForce) {\n const stallInfo: ComponentStallInfo = {\n name,\n phase: 'graceful', // Failed in graceful phase\n reason: context.gracefulTimedOut ? 'timeout' : 'error',\n startedAt: context.startedAt,\n stalledAt: Date.now(),\n error: context.gracefulError,\n };\n\n this.stalledComponents.set(name, stallInfo);\n this.componentStates.set(name, 'stalled');\n this.runningComponents.delete(name);\n this.updateStartedFlag();\n\n this.logger\n .entity(name)\n .error('Component stalled - graceful shutdown failed', {\n params: {\n reason: context.gracefulTimedOut ? 'timeout' : 'error',\n hasForceHandler: false,\n },\n });\n\n this.lifecycleEvents.componentStalled(name, stallInfo, {\n reason: stallInfo.reason,\n code: context.gracefulTimedOut\n ? 'component_shutdown_timeout'\n : 'unknown_error',\n });\n\n // Return the original graceful phase error\n return {\n success: false,\n componentName: name,\n reason: context.gracefulTimedOut\n ? 'Component stop timed out'\n : (context.gracefulError?.message ?? 'Graceful shutdown failed'),\n code: context.gracefulTimedOut\n ? 'component_shutdown_timeout'\n : 'unknown_error',\n error: context.gracefulError,\n status: this.getComponentStatus(name),\n };\n }\n\n try {\n const forcePromise = component.onShutdownForce();\n\n if (timeoutMS > 0) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n // Call abort callback if implemented\n if (component.onShutdownForceAborted) {\n try {\n component.onShutdownForceAborted();\n } catch (error) {\n this.logger\n .entity(name)\n .warn('Error in onShutdownForceAborted callback', {\n params: { error },\n });\n }\n }\n\n // Prevent unhandled rejection if onShutdownForce() throws after timeout\n Promise.resolve(forcePromise).catch(() => {\n // Intentionally ignore errors after timeout\n });\n reject(new Error('Force shutdown timed out'));\n }, timeoutMS);\n });\n\n await Promise.race([forcePromise, timeoutPromise]);\n } else {\n await forcePromise;\n }\n\n // Update state - force succeeded\n this.componentStates.set(name, 'stopped');\n this.runningComponents.delete(name);\n this.stalledComponents.delete(name); // Clear stalled status on successful force stop\n this.updateStartedFlag();\n\n // Auto-detach signals if this was the last component and option is enabled\n if (\n this.detachSignalsOnStop &&\n this.runningComponents.size === 0 &&\n this.processSignalManager\n ) {\n this.logger.info(\n 'Auto-detaching process signals on last component stop',\n );\n this.detachSignals();\n }\n\n const timestamps = this.componentTimestamps.get(name) ?? {\n startedAt: null,\n stoppedAt: null,\n };\n timestamps.stoppedAt = Date.now();\n this.componentTimestamps.set(name, timestamps);\n\n this.logger.entity(name).success('Component force stopped');\n this.lifecycleEvents.componentShutdownForceCompleted(name);\n this.lifecycleEvents.componentStopped(\n name,\n this.getComponentStatus(name),\n );\n\n return {\n success: true,\n componentName: name,\n status: this.getComponentStatus(name),\n };\n } catch (error) {\n const err = error as Error;\n\n // Determine if timeout or error\n const isTimeout = err.message === 'Force shutdown timed out';\n\n // Mark as stalled - force phase failed\n const stallInfo: ComponentStallInfo = {\n name,\n phase: 'force',\n reason: isTimeout\n ? 'timeout'\n : context.gracefulTimedOut\n ? 'both'\n : 'error',\n startedAt: context.startedAt,\n stalledAt: Date.now(),\n error: err,\n };\n this.stalledComponents.set(name, stallInfo);\n this.componentStates.set(name, 'stalled');\n this.runningComponents.delete(name);\n this.componentErrors.set(name, err);\n this.updateStartedFlag();\n\n if (isTimeout) {\n this.logger.entity(name).error('Force shutdown timed out - stalled', {\n params: { timeoutMS },\n });\n this.lifecycleEvents.componentShutdownForceTimeout(name, timeoutMS);\n } else {\n this.logger.entity(name).error('Force shutdown failed - stalled', {\n params: { error: err.message },\n });\n }\n\n this.lifecycleEvents.componentStalled(name, stallInfo, {\n reason: stallInfo.reason,\n code: isTimeout ? 'component_shutdown_timeout' : 'unknown_error',\n });\n\n return {\n success: false,\n componentName: name,\n reason: isTimeout ? 'Force shutdown timed out' : err.message,\n code: isTimeout ? 'component_shutdown_timeout' : 'unknown_error',\n error: err,\n status: this.getComponentStatus(name),\n };\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n // ============================================================================\n // Private Helper Methods\n // ============================================================================\n\n /**\n * Get a component by name\n */\n private getComponent(name: string): BaseComponent | undefined {\n return this.components.find((c) => c.getName() === name);\n }\n\n /**\n * Get all components that depend on the specified component (reverse lookup)\n * @param name - Component name to find dependents for\n * @returns Array of component names that depend on this component\n */\n private getDependents(name: string): string[] {\n const dependents: string[] = [];\n for (const component of this.components) {\n const dependencies = component.getDependencies();\n if (dependencies.includes(name)) {\n dependents.push(component.getName());\n }\n }\n return dependents;\n }\n\n /**\n * Get running components that depend on the specified component\n * @param name - Component name to check\n * @returns Array of running component names that depend on this component\n */\n private getRunningDependents(name: string): string[] {\n const dependents = this.getDependents(name);\n return dependents.filter((dep) => this.isComponentRunning(dep));\n }\n\n /**\n * Check if a component is a required dependency during startup\n * Used to prevent registering dependencies mid-startup which would break ordering\n * @param componentName - Component name to check\n * @returns true if this component would be a required dependency\n */\n private isRequiredDependencyDuringStartup(componentName: string): boolean {\n if (!this.isStarting) {\n return false;\n }\n\n // Check if any existing component lists this new component as a dependency\n return this.components.some((c) =>\n c.getDependencies().includes(componentName),\n );\n }\n\n /**\n * Check if a component instance is already registered\n */\n private hasComponentInstance(component: BaseComponent): boolean {\n return this.components.includes(component);\n }\n\n /**\n * Rollback startup by stopping all started components in reverse order\n * Used when a required component fails to start during startAllComponents()\n */\n private async rollbackStartup(startedComponents: string[]): Promise<void> {\n this.logger.warn('Rolling back startup, stopping started components', {\n params: { components: startedComponents },\n });\n\n // Stop components in reverse order\n const componentsToRollback = [...startedComponents].reverse();\n\n for (const name of componentsToRollback) {\n this.logger.entity(name).info('Rolling back component');\n this.lifecycleEvents.componentStartupRollback(name);\n\n // Use internal method to bypass bulk operation checks\n const result = await this.stopComponentInternal(name);\n if (!result.success) {\n this.logger\n .entity(name)\n .warn('Failed to stop component during rollback, continuing', {\n params: { error: result.error?.message },\n });\n }\n }\n\n this.logger.info('Rollback completed');\n }\n\n /**\n * Safe emit wrapper - prevents event handler errors from breaking lifecycle\n */\n private safeEmit<K extends LifecycleManagerEventName>(\n event: K,\n data: LifecycleManagerEventMap[K],\n ): void {\n try {\n this.emit(event, data);\n } catch (error) {\n this.logger.error('Event handler error', {\n params: { event, error },\n });\n }\n }\n\n private buildRegisterResultFailure(input: {\n componentName: string;\n registrationIndexBefore: number | null;\n code: RegistrationFailureCode;\n reason: string;\n error?: Error;\n }): RegisterComponentResult {\n let startupOrder: string[];\n\n try {\n startupOrder = this.getStartupOrderInternal();\n } catch (error) {\n // Defensive: This should never happen in normal operation since we validate\n // cycles before registration. However, if this.components somehow contains\n // a cycle (e.g., due to internal bugs or direct mutations), we must not\n // throw from an error handler. Return empty array to fail gracefully.\n this.logger.warn('Failed to compute startup order in error handler', {\n params: { error: error instanceof Error ? error.message : error },\n });\n\n startupOrder = [];\n }\n return {\n action: 'register',\n success: false,\n registered: false,\n componentName: input.componentName,\n reason: input.reason,\n code: input.code,\n error: input.error,\n registrationIndexBefore: input.registrationIndexBefore,\n registrationIndexAfter: input.registrationIndexBefore,\n startupOrder,\n };\n }\n\n private buildInsertResultFailure(input: {\n componentName: string;\n position: InsertPosition | (string & {});\n targetComponentName?: string;\n registrationIndexBefore: number | null;\n code: RegistrationFailureCode;\n reason: string;\n error?: Error;\n targetFound?: boolean;\n }): InsertComponentAtResult {\n let startupOrder: string[];\n\n try {\n startupOrder = this.getStartupOrderInternal();\n } catch (error) {\n // Defensive: This should never happen in normal operation since we validate\n // cycles before registration. However, if this.components somehow contains\n // a cycle (e.g., due to internal bugs or direct mutations), we must not\n // throw from an error handler. Return empty array to fail gracefully.\n this.logger.warn('Failed to compute startup order in error handler', {\n params: { error: error instanceof Error ? error.message : error },\n });\n startupOrder = [];\n }\n return {\n action: 'insert',\n success: false,\n registered: false,\n componentName: input.componentName,\n reason: input.reason,\n code: input.code,\n error: input.error,\n registrationIndexBefore: input.registrationIndexBefore,\n registrationIndexAfter: input.registrationIndexBefore,\n startupOrder,\n requestedPosition: {\n position: input.position,\n targetComponentName: input.targetComponentName,\n },\n manualPositionRespected: false,\n targetFound: input.targetFound,\n duringStartup: this.isStarting,\n autoStartAttempted: false,\n startResult: undefined,\n };\n }\n\n private getComponentIndex(name: string): number | null {\n const idx = this.components.findIndex((c) => c.getName() === name);\n return idx === -1 ? null : idx;\n }\n\n private isInsertPosition(value: unknown): value is InsertPosition {\n return (\n value === 'start' ||\n value === 'end' ||\n value === 'before' ||\n value === 'after'\n );\n }\n\n private getInsertIndex(\n position: InsertPosition,\n targetComponentName?: string,\n ): number | null {\n if (position === 'start') {\n return 0;\n } else if (position === 'end') {\n return this.components.length;\n } else if (position !== 'before' && position !== 'after') {\n return null;\n }\n\n const targetIdx = this.getComponentIndex(targetComponentName ?? '');\n if (targetIdx === null) {\n return null;\n }\n if (position === 'before') {\n return targetIdx;\n } else {\n return targetIdx + 1;\n }\n }\n\n private isManualPositionRespected(input: {\n componentName: string;\n position: InsertPosition;\n targetComponentName?: string;\n startupOrder: string[];\n }): boolean {\n const compIdx = input.startupOrder.indexOf(input.componentName);\n if (compIdx === -1) {\n return false;\n }\n\n if (input.position === 'start') {\n return compIdx === 0;\n } else if (input.position === 'end') {\n return compIdx === input.startupOrder.length - 1;\n } else if (input.position === 'before' || input.position === 'after') {\n const targetIdx = input.startupOrder.indexOf(\n input.targetComponentName ?? '',\n );\n if (targetIdx === -1) {\n return false;\n }\n if (input.position === 'before') {\n return compIdx < targetIdx;\n }\n return compIdx > targetIdx;\n }\n\n return false;\n }\n\n /**\n * Dependency-aware startup order.\n *\n * - Only registered components are included.\n * - Missing dependencies are ignored for ordering (they are validated at start time).\n * - Cycles throw DependencyCycleError (programmer error).\n */\n private getStartupOrderInternal(\n components: BaseComponent[] = this.components,\n ): string[] {\n const names = components.map((c) => c.getName());\n const regIndex = new Map<string, number>(\n names.map((name, idx) => [name, idx]),\n );\n\n const adjacency = new Map<string, Set<string>>();\n const inDegree = new Map<string, number>();\n\n for (const name of names) {\n adjacency.set(name, new Set());\n inDegree.set(name, 0);\n }\n\n // Build edges: dependency -> dependent (only when dependency is registered)\n for (const component of components) {\n const dependent = component.getName();\n for (const dep of component.getDependencies()) {\n if (!regIndex.has(dep)) {\n continue;\n }\n const neighbors = adjacency.get(dep);\n if (!neighbors) {\n continue;\n }\n if (neighbors.has(dependent)) {\n continue;\n }\n neighbors.add(dependent);\n inDegree.set(dependent, (inDegree.get(dependent) ?? 0) + 1);\n }\n }\n\n const available = new Set<string>();\n for (const name of names) {\n if ((inDegree.get(name) ?? 0) === 0) {\n available.add(name);\n }\n }\n\n const order: string[] = [];\n while (available.size > 0) {\n // Stable pick: lowest registration index\n const next = [...available].sort((a, b) => {\n return (regIndex.get(a) ?? 0) - (regIndex.get(b) ?? 0);\n })[0];\n\n available.delete(next);\n order.push(next);\n\n for (const neighbor of adjacency.get(next) ?? []) {\n const nextInDegree = (inDegree.get(neighbor) ?? 0) - 1;\n inDegree.set(neighbor, nextInDegree);\n if (nextInDegree === 0) {\n available.add(neighbor);\n }\n }\n }\n\n if (order.length !== names.length) {\n const remaining = names.filter((n) => !order.includes(n));\n const cycle = this.findDependencyCycle(adjacency);\n throw new DependencyCycleError({\n cycle: cycle.length > 0 ? cycle : remaining,\n });\n }\n\n return order;\n }\n\n /**\n * Find a single dependency cycle (for error reporting during registration)\n * Returns the first cycle found, or empty array if no cycle exists\n *\n * Performance note: This method exits early after finding the first cycle,\n * which is optimal for hot paths (registration, startup order resolution).\n * For comprehensive validation that needs ALL cycles, use findAllCircularCycles().\n */\n private findDependencyCycle(adjacency: Map<string, Set<string>>): string[] {\n const visited = new Set<string>();\n const inStack = new Set<string>();\n const path: string[] = [];\n\n const visit = (node: string): string[] | null => {\n visited.add(node);\n inStack.add(node);\n path.push(node);\n\n for (const neighbor of adjacency.get(node) ?? []) {\n if (!visited.has(neighbor)) {\n const result = visit(neighbor);\n if (result) {\n return result;\n }\n } else if (inStack.has(neighbor)) {\n const cycleStart = path.indexOf(neighbor);\n return cycleStart >= 0 ? path.slice(cycleStart) : [neighbor];\n }\n }\n\n inStack.delete(node);\n path.pop();\n return null;\n };\n\n for (const node of adjacency.keys()) {\n if (visited.has(node)) {\n continue;\n }\n const result = visit(node);\n if (result) {\n return result;\n }\n }\n\n return [];\n }\n\n /**\n * Find circular dependency cycles using Depth-First Search (DFS) with cycle detection.\n *\n * Algorithm: DFS with visited set and recursion stack tracking\n * - Uses 'visited' set to ensure each node is processed exactly once (prevents infinite loops)\n * - Uses 'inStack' set to track the current DFS recursion path\n * - When a node in the current path is encountered again, a cycle is detected\n * - Extracts the cycle from the path and continues searching for more cycles\n *\n * Time Complexity: O(V + E) where V = components, E = dependency edges\n * Space Complexity: O(V) for visited/inStack sets and recursion stack\n *\n * Performance note: This method finds a representative set of cycles while ensuring\n * each node is visited once (prevents infinite loops). For hot paths that only need\n * one cycle, use findDependencyCycle() which exits early.\n *\n * Returns an array of detected cycles, where each cycle is an array of component names.\n */\n private findAllCircularCycles(\n adjacency: Map<string, Set<string>>,\n ): string[][] {\n const cycles: string[][] = [];\n const visited = new Set<string>();\n const inStack = new Set<string>();\n const path: string[] = [];\n\n const visit = (node: string): void => {\n visited.add(node);\n inStack.add(node);\n path.push(node);\n\n for (const neighbor of adjacency.get(node) ?? []) {\n if (!visited.has(neighbor)) {\n // Continue DFS to unvisited neighbor\n visit(neighbor);\n } else if (inStack.has(neighbor)) {\n // Found a cycle - extract it from the path\n const cycleStart = path.indexOf(neighbor);\n if (cycleStart >= 0) {\n const cycle = path.slice(cycleStart);\n cycles.push(cycle);\n }\n }\n }\n\n inStack.delete(node);\n path.pop();\n };\n\n // Visit all nodes to find all cycles (including disconnected components)\n for (const node of adjacency.keys()) {\n if (!visited.has(node)) {\n visit(node);\n }\n }\n\n return cycles;\n }\n\n /**\n * Handle shutdown signal - initiates stopAllComponents().\n * Double signal protection: if already shutting down, log warning and ignore.\n */\n private handleShutdownRequest(method: ShutdownSignal): void {\n if (this.isShuttingDown) {\n this.logger.warn('Shutdown already in progress, ignoring signal', {\n params: { method },\n });\n return;\n }\n\n this.logger.info('Shutdown signal received', { params: { method } });\n this.lifecycleEvents.signalShutdown(method);\n\n // Initiate shutdown asynchronously (don't await in signal handler)\n void this.stopAllComponentsInternal(method, {\n ...this.shutdownOptions,\n });\n }\n\n /**\n * Handle reload request - calls custom callback or broadcasts to components.\n *\n * When called from signal handlers (source='signal'), the Promise is started\n * but not awaited due to Node.js signal handler constraints. Components are\n * still notified and the work completes, but return values are not accessible.\n *\n * When called from manual triggers (source='trigger'), the Promise is awaited\n * and results are returned for programmatic use.\n *\n * @param source - Whether triggered from signal manager or manual trigger\n */\n private async handleReloadRequest(\n source: 'signal' | 'trigger' = 'trigger',\n ): Promise<SignalBroadcastResult> {\n this.logger.info('Reload request received', { params: { source } });\n this.lifecycleEvents.signalReload();\n\n if (this.onReloadRequested) {\n // Call custom callback with broadcast function\n const broadcastFn = () => this.broadcastReload();\n const result = this.onReloadRequested(broadcastFn);\n\n if (isPromise(result)) {\n await result;\n }\n\n // Return empty result (custom callback handled it)\n return {\n signal: 'reload',\n results: [],\n timedOut: false,\n code: 'ok',\n };\n }\n\n // No custom callback - broadcast to all components\n return this.broadcastReload();\n }\n\n /**\n * Handle info request - calls custom callback or broadcasts to components.\n *\n * When called from signal handlers, the Promise executes but return values\n * are not accessible due to Node.js signal handler constraints.\n *\n * @param source - Whether triggered from signal manager or manual trigger\n */\n private async handleInfoRequest(\n source: 'signal' | 'trigger' = 'trigger',\n ): Promise<SignalBroadcastResult> {\n this.logger.info('Info request received', { params: { source } });\n this.lifecycleEvents.signalInfo();\n\n if (this.onInfoRequested) {\n // Call custom callback with broadcast function\n const broadcastFn = () => this.broadcastInfo();\n const result = this.onInfoRequested(broadcastFn);\n if (isPromise(result)) {\n await result;\n }\n\n // Return empty result (custom callback handled it)\n return {\n signal: 'info',\n results: [],\n timedOut: false,\n code: 'ok',\n };\n }\n\n // No custom callback - broadcast to all components\n return this.broadcastInfo();\n }\n\n /**\n * Handle debug request - calls custom callback or broadcasts to components.\n *\n * When called from signal handlers, the Promise executes but return values\n * are not accessible due to Node.js signal handler constraints.\n *\n * @param source - Whether triggered from signal manager or manual trigger\n */\n private async handleDebugRequest(\n source: 'signal' | 'trigger' = 'trigger',\n ): Promise<SignalBroadcastResult> {\n this.logger.info('Debug request received', { params: { source } });\n this.lifecycleEvents.signalDebug();\n\n if (this.onDebugRequested) {\n // Call custom callback with broadcast function\n const broadcastFn = () => this.broadcastDebug();\n const result = this.onDebugRequested(broadcastFn);\n if (isPromise(result)) {\n await result;\n }\n\n // Return empty result (custom callback handled it)\n return {\n signal: 'debug',\n results: [],\n timedOut: false,\n code: 'ok',\n };\n }\n\n // No custom callback - broadcast to all components\n return this.broadcastDebug();\n }\n\n /**\n * Broadcast reload signal to all running components.\n * Calls onReload() on components that implement it.\n * Continues on errors - collects all results.\n */\n private async broadcastReload(): Promise<SignalBroadcastResult> {\n const results: ComponentSignalResult[] = [];\n\n // Only call onReload() on running components\n const componentsToReload = this.components.filter((component) =>\n this.runningComponents.has(component.getName()),\n );\n\n if (this.isStarting) {\n this.logger.info(\n 'Reload during startup: only reloading already-started components',\n );\n }\n\n for (const component of componentsToReload) {\n const name = component.getName();\n\n if (!component.onReload) {\n // Component doesn't implement onReload\n results.push({\n name,\n called: false,\n error: null,\n timedOut: false,\n code: 'no_handler',\n });\n continue;\n }\n\n this.lifecycleEvents.componentReloadStarted(name);\n\n const timeoutMS = component.signalTimeoutMS;\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutResult = { timedOut: true } as const;\n\n try {\n const result = component.onReload();\n const handlerPromise: Promise<unknown> = isPromise(result)\n ? (result as Promise<unknown>)\n : Promise.resolve(result as unknown);\n\n const outcome: unknown =\n timeoutMS > 0\n ? await Promise.race([\n handlerPromise,\n new Promise<typeof timeoutResult>((resolve) => {\n timeoutHandle = setTimeout(() => {\n resolve(timeoutResult);\n }, timeoutMS);\n }),\n ])\n : await handlerPromise;\n\n if (outcome === timeoutResult) {\n this.logger.entity(name).warn('Reload handler timed out', {\n params: { timeoutMS },\n });\n // Prevent unhandled rejection if handler throws after timeout\n Promise.resolve(handlerPromise).catch(() => {\n // Intentionally ignore errors after timeout\n });\n results.push({\n name,\n called: true,\n error: null,\n timedOut: true,\n code: 'timeout',\n });\n } else {\n this.lifecycleEvents.componentReloadCompleted(name);\n results.push({\n name,\n called: true,\n error: null,\n timedOut: false,\n code: 'called',\n });\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger\n .entity(name)\n .error('Reload failed', { params: { error: err } });\n this.lifecycleEvents.componentReloadFailed(name, err);\n results.push({\n name,\n called: true,\n error: err,\n timedOut: false,\n code: 'error',\n });\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n const calledResults = results.filter((result) => result.called);\n const hasError = calledResults.some((result) => result.error);\n const isAllError =\n calledResults.length > 0 && calledResults.every((result) => result.error);\n const hasTimeout = calledResults.some((result) => result.timedOut);\n const isAllTimeout =\n calledResults.length > 0 &&\n calledResults.every((result) => result.timedOut);\n const code = hasError\n ? isAllError\n ? 'error'\n : 'partial_error'\n : hasTimeout\n ? isAllTimeout\n ? 'timeout'\n : 'partial_timeout'\n : 'ok';\n\n return {\n signal: 'reload',\n results,\n timedOut: hasTimeout,\n code,\n };\n }\n\n /**\n * Broadcast info signal to all running components.\n * Calls onInfo() on components that implement it.\n * Continues on errors - collects all results.\n */\n private async broadcastInfo(): Promise<SignalBroadcastResult> {\n const results: ComponentSignalResult[] = [];\n\n // Only call onInfo() on running components\n const componentsToNotify = this.components.filter((component) =>\n this.runningComponents.has(component.getName()),\n );\n\n if (this.isStarting) {\n this.logger.info(\n 'Info during startup: only notifying already-started components',\n );\n }\n\n for (const component of componentsToNotify) {\n const name = component.getName();\n\n if (!component.onInfo) {\n // Component doesn't implement onInfo\n results.push({\n name,\n called: false,\n error: null,\n timedOut: false,\n code: 'no_handler',\n });\n continue;\n }\n\n this.lifecycleEvents.componentInfoStarted(name);\n\n const timeoutMS = component.signalTimeoutMS;\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutResult = { timedOut: true } as const;\n\n try {\n const result = component.onInfo();\n const handlerPromise: Promise<unknown> = isPromise(result)\n ? (result as Promise<unknown>)\n : Promise.resolve(result as unknown);\n\n const outcome: unknown =\n timeoutMS > 0\n ? await Promise.race([\n handlerPromise,\n new Promise<typeof timeoutResult>((resolve) => {\n timeoutHandle = setTimeout(() => {\n resolve(timeoutResult);\n }, timeoutMS);\n }),\n ])\n : await handlerPromise;\n\n if (outcome === timeoutResult) {\n this.logger.entity(name).warn('Info handler timed out', {\n params: { timeoutMS },\n });\n // Prevent unhandled rejection if handler throws after timeout\n Promise.resolve(handlerPromise).catch(() => {\n // Intentionally ignore errors after timeout\n });\n results.push({\n name,\n called: true,\n error: null,\n timedOut: true,\n code: 'timeout',\n });\n } else {\n this.lifecycleEvents.componentInfoCompleted(name);\n results.push({\n name,\n called: true,\n error: null,\n timedOut: false,\n code: 'called',\n });\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger\n .entity(name)\n .error('Info handler failed', { params: { error: err } });\n this.lifecycleEvents.componentInfoFailed(name, err);\n results.push({\n name,\n called: true,\n error: err,\n timedOut: false,\n code: 'error',\n });\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n const calledResults = results.filter((result) => result.called);\n const hasError = calledResults.some((result) => result.error);\n const isAllError =\n calledResults.length > 0 && calledResults.every((result) => result.error);\n const hasTimeout = calledResults.some((result) => result.timedOut);\n const isAllTimeout =\n calledResults.length > 0 &&\n calledResults.every((result) => result.timedOut);\n const code = hasError\n ? isAllError\n ? 'error'\n : 'partial_error'\n : hasTimeout\n ? isAllTimeout\n ? 'timeout'\n : 'partial_timeout'\n : 'ok';\n\n return {\n signal: 'info',\n results,\n timedOut: hasTimeout,\n code,\n };\n }\n\n /**\n * Broadcast debug signal to all running components.\n * Calls onDebug() on components that implement it.\n * Continues on errors - collects all results.\n */\n private async broadcastDebug(): Promise<SignalBroadcastResult> {\n const results: ComponentSignalResult[] = [];\n\n // Only call onDebug() on running components\n const componentsToNotify = this.components.filter((component) =>\n this.runningComponents.has(component.getName()),\n );\n\n if (this.isStarting) {\n this.logger.info(\n 'Debug during startup: only notifying already-started components',\n );\n }\n\n for (const component of componentsToNotify) {\n const name = component.getName();\n\n if (!component.onDebug) {\n // Component doesn't implement onDebug\n results.push({\n name,\n called: false,\n error: null,\n timedOut: false,\n code: 'no_handler',\n });\n continue;\n }\n\n this.lifecycleEvents.componentDebugStarted(name);\n\n const timeoutMS = component.signalTimeoutMS;\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutResult = { timedOut: true } as const;\n\n try {\n const result = component.onDebug();\n const handlerPromise: Promise<unknown> = isPromise(result)\n ? (result as Promise<unknown>)\n : Promise.resolve(result as unknown);\n\n const outcome: unknown =\n timeoutMS > 0\n ? await Promise.race([\n handlerPromise,\n new Promise<typeof timeoutResult>((resolve) => {\n timeoutHandle = setTimeout(() => {\n resolve(timeoutResult);\n }, timeoutMS);\n }),\n ])\n : await handlerPromise;\n\n if (outcome === timeoutResult) {\n this.logger.entity(name).warn('Debug handler timed out', {\n params: { timeoutMS },\n });\n // Prevent unhandled rejection if handler throws after timeout\n Promise.resolve(handlerPromise).catch(() => {\n // Intentionally ignore errors after timeout\n });\n results.push({\n name,\n called: true,\n error: null,\n timedOut: true,\n code: 'timeout',\n });\n } else {\n this.lifecycleEvents.componentDebugCompleted(name);\n results.push({\n name,\n called: true,\n error: null,\n timedOut: false,\n code: 'called',\n });\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger\n .entity(name)\n .error('Debug handler failed', { params: { error: err } });\n this.lifecycleEvents.componentDebugFailed(name, err);\n results.push({\n name,\n called: true,\n error: err,\n timedOut: false,\n code: 'error',\n });\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n const calledResults = results.filter((result) => result.called);\n const hasError = calledResults.some((result) => result.error);\n const isAllError =\n calledResults.length > 0 && calledResults.every((result) => result.error);\n const hasTimeout = calledResults.some((result) => result.timedOut);\n const isAllTimeout =\n calledResults.length > 0 &&\n calledResults.every((result) => result.timedOut);\n const code = hasError\n ? isAllError\n ? 'error'\n : 'partial_error'\n : hasTimeout\n ? isAllTimeout\n ? 'timeout'\n : 'partial_timeout'\n : 'ok';\n\n return {\n signal: 'debug',\n results,\n timedOut: hasTimeout,\n code,\n };\n }\n}\n","import type { Logger } from '../logger';\nimport type { LoggerService } from '../logger/logger-service';\nimport type {\n ComponentOptions,\n ComponentHealthResult,\n ComponentLifecycleRef,\n ComponentValueResult,\n} from './types';\nimport { InvalidComponentNameError } from './errors';\nimport { finiteClampMin } from '../clamp';\n\n/**\n * Abstract base class for all lifecycle-managed components\n *\n * Components extend this class and implement the required start() and stop() methods.\n * They can optionally implement lifecycle hooks for shutdown phases, signal handling,\n * health checks, messaging, and value sharing.\n *\n * The component's lifecycle is managed by a LifecycleManager instance which:\n * - Calls start() during startup (with dependency ordering)\n * - Calls stop() and optional shutdown hooks during shutdown\n * - Provides messaging and value sharing between components\n * - Handles signals (SIGINT, SIGTERM, SIGHUP, etc.)\n *\n * @example\n * ```typescript\n * class DatabaseComponent extends BaseComponent {\n * private pool?: Pool;\n *\n * constructor(logger: Logger) {\n * super(logger, {\n * name: 'database',\n * dependencies: [],\n * startupTimeoutMS: 10000,\n * shutdownGracefulTimeoutMS: 5000,\n * });\n * }\n *\n * async start() {\n * this.logger.info('Connecting to database...');\n * this.pool = await createPool(config);\n * this.logger.success('Connected to database');\n * }\n *\n * async stop() {\n * this.logger.info('Closing database connections...');\n * await this.pool?.end();\n * this.logger.success('Database connections closed');\n * }\n *\n * // Optional: handle graceful shutdown warning\n * async onShutdownWarning() {\n * this.logger.info('Shutdown warning - stopping new connections');\n * this.pool?.stopAcceptingConnections();\n * }\n *\n * // Optional: handle reload signal\n * async onReload() {\n * this.logger.info('Reloading database configuration');\n * await this.reloadConfig();\n * }\n *\n * // Optional: health check\n * async healthCheck() {\n * const isHealthy = await this.pool?.ping();\n * return { healthy: isHealthy, message: 'Database connection active' };\n * }\n * }\n * ```\n */\nexport abstract class BaseComponent {\n /** Names of components this one depends on */\n public readonly dependencies: string[];\n\n /** If true, startup failure doesn't trigger rollback */\n public readonly optional: boolean;\n\n /** Time to wait for start() in milliseconds */\n public readonly startupTimeoutMS: number;\n\n /** Time to wait for graceful shutdown in milliseconds */\n public readonly shutdownGracefulTimeoutMS: number;\n\n /** Time to wait for force shutdown in milliseconds */\n public readonly shutdownForceTimeoutMS: number;\n\n /** Time to wait for healthCheck() in milliseconds */\n public readonly healthCheckTimeoutMS: number;\n\n /** Time to wait for onReload/onInfo/onDebug in milliseconds */\n public readonly signalTimeoutMS: number;\n\n /** Component logger (scoped to component name) */\n protected logger: LoggerService;\n\n /** Component name (kebab-case) */\n protected name: string;\n\n /** Reference to component-scoped lifecycle (set by manager when registered) */\n protected lifecycle!: ComponentLifecycleRef;\n\n /**\n * Create a new component\n *\n * @param rootLogger - Root logger instance (component will create scoped logger)\n * @param options - Component configuration\n * @throws {InvalidComponentNameError} If name doesn't match kebab-case pattern\n */\n constructor(rootLogger: Logger, options: ComponentOptions) {\n // Validate kebab-case name\n const kebabCaseRegex = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;\n if (!kebabCaseRegex.test(options.name)) {\n throw new InvalidComponentNameError({ name: options.name });\n }\n\n this.name = options.name;\n\n // Create component logger (component logs as its own service)\n this.logger = rootLogger.service(this.name);\n\n // Dependency configuration\n this.dependencies = options.dependencies ?? [];\n this.optional = options.optional ?? false;\n\n // Timeout configuration with defaults\n this.startupTimeoutMS = options.startupTimeoutMS ?? 30000;\n this.healthCheckTimeoutMS = options.healthCheckTimeoutMS ?? 5000;\n this.signalTimeoutMS = options.signalTimeoutMS ?? 5000;\n\n // Enforce minimums for shutdown timeouts (using finiteClampMin to handle edge cases)\n this.shutdownGracefulTimeoutMS = finiteClampMin(\n options.shutdownGracefulTimeoutMS,\n 1000, // Minimum 1 second\n 5000, // Default if undefined/null/non-finite\n );\n\n this.shutdownForceTimeoutMS = finiteClampMin(\n options.shutdownForceTimeoutMS,\n 500, // Minimum 500ms\n 2000, // Default if undefined/null/non-finite\n );\n }\n\n /**\n * Start the component\n *\n * Called by the LifecycleManager when starting components.\n * Should perform all initialization, connection setup, etc.\n * Dependencies are guaranteed to have started before this is called.\n *\n * Can be sync or async - manager will await if Promise is returned.\n *\n * @throws Should throw an error if startup fails\n */\n public abstract start(): Promise<void> | void;\n\n /**\n * Stop the component (graceful shutdown)\n *\n * Called by the LifecycleManager when stopping components.\n * Should perform graceful cleanup, close connections, save state, etc.\n * Dependents are guaranteed to have stopped before this is called.\n *\n * Can be sync or async - manager will await if Promise is returned.\n *\n * @throws Should throw an error if stop fails (will trigger force phase)\n */\n public abstract stop(): Promise<void> | void;\n\n /**\n * Called when start() times out\n *\n * Invoked when start() exceeds startupTimeoutMS before rollback begins.\n * Use this to set flags, abort pending work, or cleanup resources.\n * Must be synchronous and fast - manager won't wait for it to complete.\n */\n public onStartupAborted?(): void;\n\n /**\n * Called when stop() times out\n *\n * Invoked when stop() exceeds shutdownGracefulTimeoutMS before force shutdown begins.\n * Use this to set flags or prepare for more aggressive cleanup in onShutdownForce().\n * Must be synchronous and fast - manager won't wait for it to complete.\n */\n public onGracefulStopTimeout?(): void;\n\n /**\n * Called before graceful shutdown to warn component\n *\n * Optional lifecycle hook called before stopAllComponents() begins stopping components.\n * Use this to prepare for shutdown (stop accepting new work, drain queues, etc.)\n *\n * Can be sync or async - manager will await if Promise is returned.\n */\n public onShutdownWarning?(): Promise<void> | void;\n\n /**\n * Called for force shutdown if graceful shutdown times out or throws\n *\n * Optional lifecycle hook called after stop() fails.\n * Use this for more aggressive cleanup (kill connections, abandon work, etc.)\n *\n * Can be sync or async - manager will await if Promise is returned.\n */\n public onShutdownForce?(): Promise<void> | void;\n\n /**\n * Called when onShutdownForce() times out\n *\n * Invoked when onShutdownForce() exceeds shutdownForceTimeoutMS before component is marked stalled.\n * Must be synchronous and fast - manager won't wait for it to complete.\n */\n public onShutdownForceAborted?(): void;\n\n /**\n * Called when reload signal (SIGHUP, R key) is received\n *\n * Optional signal handler for runtime reload.\n * Use this to reload configuration, reconnect, etc. without full restart.\n *\n * Can be sync or async - manager will await if Promise is returned.\n * Errors are caught and logged but don't stop the broadcast.\n */\n public onReload?(): Promise<void> | void;\n\n /**\n * Called when info signal (SIGUSR1, I key) is received\n *\n * Optional signal handler for info requests.\n * Use this to log status, metrics, or other runtime information.\n *\n * Can be sync or async - manager will await if Promise is returned.\n * Errors are caught and logged but don't stop the broadcast.\n */\n public onInfo?(): Promise<void> | void;\n\n /**\n * Called when debug signal (SIGUSR2, D key) is received\n *\n * Optional signal handler for debug requests.\n * Use this to toggle debug mode, dump state, etc.\n *\n * Can be sync or async - manager will await if Promise is returned.\n * Errors are caught and logged but don't stop the broadcast.\n */\n public onDebug?(): Promise<void> | void;\n\n /**\n * Optional health check for runtime monitoring\n *\n * Return a simple boolean or a rich result with metadata.\n * Called by the manager when checking component health.\n * Only called on 'running' components.\n *\n * @returns boolean (healthy/unhealthy) or rich result with details\n *\n * @example\n * ```typescript\n * // Simple boolean\n * healthCheck() {\n * return this.isConnected;\n * }\n *\n * // Rich result with metadata\n * async healthCheck() {\n * const stats = await this.getStats();\n * return {\n * healthy: stats.errorRate < 0.05,\n * message: stats.errorRate < 0.05 ? 'Healthy' : 'High error rate',\n * details: { errorRate: stats.errorRate, requestsPerSec: stats.rps }\n * };\n * }\n * ```\n */\n public healthCheck?():\n | Promise<boolean | ComponentHealthResult>\n | boolean\n | ComponentHealthResult;\n\n /**\n * Optional message handler for arbitrary component messaging\n *\n * Receives messages from other components or external code.\n * Can return data which will be included in MessageResult.data.\n *\n * @param payload - The message content (any type)\n * @param from - Sender component name (null if external)\n * @returns Optional data to include in response\n *\n * @example\n * ```typescript\n * async onMessage(payload: unknown, from: string | null) {\n * const msg = payload as { action: string; data?: unknown };\n *\n * if (msg.action === 'reset') {\n * await this.reset();\n * return { success: true };\n * }\n *\n * if (msg.action === 'getStats') {\n * return { connections: this.pool.size, uptime: this.uptime };\n * }\n * }\n * ```\n */\n public onMessage?<TData = unknown>(\n payload: unknown,\n from: string | null,\n ): TData | Promise<TData>;\n\n /**\n * Optional value provider - return values on-demand for other components\n *\n * Called when other components or external code request a value by key.\n * Return a structured result indicating if the value was found.\n *\n * @param key - The value key being requested\n * @param from - Component name if another component requested, null if external\n * @returns Structured result with found status and value\n *\n * @example\n * ```typescript\n * getValue(key: string, from: string | null): ComponentValueResult {\n * if (key === 'pool') return { found: true, value: this.pool };\n * else if (key === 'config') return { found: true, value: this.config };\n * return { found: false, value: undefined }; // Key not found\n * }\n * ```\n */\n public getValue?<T = unknown>(\n key: string,\n from: string | null,\n ): ComponentValueResult<T>;\n\n /**\n * Get component name\n */\n public getName(): string {\n return this.name;\n }\n\n /**\n * Get component dependencies\n */\n public getDependencies(): string[] {\n return this.dependencies;\n }\n\n /**\n * Check if component is optional\n */\n public isOptional(): boolean {\n return this.optional;\n }\n}\n"],"mappings":"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","names":["stringWidth","import_string_width","stringWidth","availableWidth","import_string_width","stringWidth","availableWidth","callbacks","readline","durationMS","startupOrder","result"]}