@scpxl/nodejs-framework 1.0.17 → 1.0.20

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 (192) hide show
  1. package/README.md +29 -0
  2. package/dist/api-requester/api-requester.d.ts +27 -6
  3. package/dist/api-requester/api-requester.d.ts.map +1 -1
  4. package/dist/api-requester/api-requester.js +188 -26
  5. package/dist/api-requester/api-requester.js.map +2 -2
  6. package/dist/api-requester/index.d.ts +1 -0
  7. package/dist/api-requester/index.d.ts.map +1 -1
  8. package/dist/api-requester/index.js.map +1 -1
  9. package/dist/application/base-application.d.ts +15 -22
  10. package/dist/application/base-application.d.ts.map +1 -1
  11. package/dist/application/base-application.js +145 -111
  12. package/dist/application/base-application.js.map +2 -2
  13. package/dist/application/command-application.d.ts.map +1 -1
  14. package/dist/application/command-application.js +3 -4
  15. package/dist/application/command-application.js.map +2 -2
  16. package/dist/application/web-application.d.ts.map +1 -1
  17. package/dist/application/web-application.js +9 -2
  18. package/dist/application/web-application.js.map +2 -2
  19. package/dist/cache/manager.d.ts +87 -6
  20. package/dist/cache/manager.d.ts.map +1 -1
  21. package/dist/cache/manager.js +77 -30
  22. package/dist/cache/manager.js.map +2 -2
  23. package/dist/cluster/cluster-manager.d.ts.map +1 -1
  24. package/dist/cluster/cluster-manager.js +5 -8
  25. package/dist/cluster/cluster-manager.js.map +2 -2
  26. package/dist/config/env.d.ts +11 -0
  27. package/dist/config/env.d.ts.map +1 -0
  28. package/dist/config/env.js +103 -0
  29. package/dist/config/env.js.map +7 -0
  30. package/dist/config/index.d.ts +3 -0
  31. package/dist/config/index.d.ts.map +1 -0
  32. package/dist/config/index.js +3 -0
  33. package/dist/config/index.js.map +7 -0
  34. package/dist/config/schema.d.ts +408 -0
  35. package/dist/config/schema.d.ts.map +1 -0
  36. package/dist/config/schema.js +218 -0
  37. package/dist/config/schema.js.map +7 -0
  38. package/dist/database/dynamic-entity.d.ts.map +1 -1
  39. package/dist/database/dynamic-entity.js +6 -2
  40. package/dist/database/dynamic-entity.js.map +2 -2
  41. package/dist/database/instance.d.ts.map +1 -1
  42. package/dist/database/instance.js +0 -8
  43. package/dist/database/instance.js.map +2 -2
  44. package/dist/database/manager.d.ts.map +1 -1
  45. package/dist/database/manager.js +71 -9
  46. package/dist/database/manager.js.map +2 -2
  47. package/dist/error/error-reporter.d.ts +96 -0
  48. package/dist/error/error-reporter.d.ts.map +1 -0
  49. package/dist/error/error-reporter.js +228 -0
  50. package/dist/error/error-reporter.js.map +7 -0
  51. package/dist/error/error.interface.d.ts +126 -0
  52. package/dist/error/error.interface.d.ts.map +1 -0
  53. package/dist/error/error.interface.js +45 -0
  54. package/dist/error/error.interface.js.map +7 -0
  55. package/dist/error/framework-errors.d.ts +113 -0
  56. package/dist/error/framework-errors.d.ts.map +1 -0
  57. package/dist/error/framework-errors.js +176 -0
  58. package/dist/error/framework-errors.js.map +7 -0
  59. package/dist/error/index.d.ts +6 -0
  60. package/dist/error/index.d.ts.map +1 -0
  61. package/dist/error/index.js +34 -0
  62. package/dist/error/index.js.map +7 -0
  63. package/dist/event/manager.d.ts.map +1 -1
  64. package/dist/event/manager.js +2 -9
  65. package/dist/event/manager.js.map +2 -2
  66. package/dist/index.d.ts +5 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +5 -1
  69. package/dist/index.js.map +2 -2
  70. package/dist/lifecycle/exit.d.ts +2 -1
  71. package/dist/lifecycle/exit.d.ts.map +1 -1
  72. package/dist/lifecycle/exit.js +6 -0
  73. package/dist/lifecycle/exit.js.map +2 -2
  74. package/dist/lifecycle/index.d.ts +7 -0
  75. package/dist/lifecycle/index.d.ts.map +1 -0
  76. package/dist/lifecycle/index.js +12 -0
  77. package/dist/lifecycle/index.js.map +7 -0
  78. package/dist/lifecycle/lifecycle-manager.d.ts +55 -2
  79. package/dist/lifecycle/lifecycle-manager.d.ts.map +1 -1
  80. package/dist/lifecycle/lifecycle-manager.js +233 -7
  81. package/dist/lifecycle/lifecycle-manager.js.map +3 -3
  82. package/dist/lifecycle/shutdown-controller.d.ts +15 -0
  83. package/dist/lifecycle/shutdown-controller.d.ts.map +1 -0
  84. package/dist/lifecycle/shutdown-controller.js +38 -0
  85. package/dist/lifecycle/shutdown-controller.js.map +7 -0
  86. package/dist/lifecycle/types.d.ts +28 -0
  87. package/dist/lifecycle/types.d.ts.map +1 -0
  88. package/dist/lifecycle/types.js +13 -0
  89. package/dist/lifecycle/types.js.map +7 -0
  90. package/dist/logger/logger.d.ts +2 -1
  91. package/dist/logger/logger.d.ts.map +1 -1
  92. package/dist/logger/logger.js +35 -11
  93. package/dist/logger/logger.js.map +2 -2
  94. package/dist/performance/cache-performance.d.ts +6 -0
  95. package/dist/performance/cache-performance.d.ts.map +1 -1
  96. package/dist/performance/cache-performance.js +16 -0
  97. package/dist/performance/cache-performance.js.map +2 -2
  98. package/dist/performance/index.d.ts +1 -0
  99. package/dist/performance/index.d.ts.map +1 -1
  100. package/dist/performance/index.js +1 -0
  101. package/dist/performance/index.js.map +2 -2
  102. package/dist/performance/performance-monitor.d.ts.map +1 -1
  103. package/dist/performance/performance-monitor.js +47 -18
  104. package/dist/performance/performance-monitor.js.map +2 -2
  105. package/dist/performance/performance-monitor.plugin.d.ts +24 -0
  106. package/dist/performance/performance-monitor.plugin.d.ts.map +1 -0
  107. package/dist/performance/performance-monitor.plugin.js +89 -0
  108. package/dist/performance/performance-monitor.plugin.js.map +7 -0
  109. package/dist/performance/webserver-performance.js +1 -1
  110. package/dist/performance/webserver-performance.js.map +2 -2
  111. package/dist/queue/manager.d.ts.map +1 -1
  112. package/dist/queue/manager.js +3 -10
  113. package/dist/queue/manager.js.map +2 -2
  114. package/dist/queue/worker.d.ts.map +1 -1
  115. package/dist/queue/worker.js +2 -2
  116. package/dist/queue/worker.js.map +2 -2
  117. package/dist/redis/manager.d.ts.map +1 -1
  118. package/dist/redis/manager.js +228 -33
  119. package/dist/redis/manager.js.map +2 -2
  120. package/dist/request-context/index.d.ts +3 -0
  121. package/dist/request-context/index.d.ts.map +1 -0
  122. package/dist/request-context/index.js +25 -0
  123. package/dist/request-context/index.js.map +7 -0
  124. package/dist/request-context/request-context.d.ts +108 -0
  125. package/dist/request-context/request-context.d.ts.map +1 -0
  126. package/dist/request-context/request-context.interface.d.ts +46 -0
  127. package/dist/request-context/request-context.interface.d.ts.map +1 -0
  128. package/dist/request-context/request-context.interface.js +1 -0
  129. package/dist/request-context/request-context.interface.js.map +7 -0
  130. package/dist/request-context/request-context.js +79 -0
  131. package/dist/request-context/request-context.js.map +7 -0
  132. package/dist/services/aws/s3.js +4 -6
  133. package/dist/services/aws/s3.js.map +2 -2
  134. package/dist/util/file.d.ts +13 -0
  135. package/dist/util/file.d.ts.map +1 -1
  136. package/dist/util/file.js +46 -9
  137. package/dist/util/file.js.map +2 -2
  138. package/dist/util/helper.d.ts +16 -1
  139. package/dist/util/helper.d.ts.map +1 -1
  140. package/dist/util/helper.js +19 -43
  141. package/dist/util/helper.js.map +2 -2
  142. package/dist/util/index.d.ts +1 -0
  143. package/dist/util/index.d.ts.map +1 -1
  144. package/dist/util/index.js +18 -16
  145. package/dist/util/index.js.map +2 -2
  146. package/dist/util/loader.d.ts.map +1 -1
  147. package/dist/util/loader.js +13 -2
  148. package/dist/util/loader.js.map +2 -2
  149. package/dist/util/os.d.ts.map +1 -1
  150. package/dist/util/os.js +8 -14
  151. package/dist/util/os.js.map +2 -2
  152. package/dist/util/time.d.ts +8 -2
  153. package/dist/util/time.d.ts.map +1 -1
  154. package/dist/util/time.js +12 -7
  155. package/dist/util/time.js.map +2 -2
  156. package/dist/util/timing.d.ts +36 -0
  157. package/dist/util/timing.d.ts.map +1 -0
  158. package/dist/util/timing.interface.d.ts +47 -0
  159. package/dist/util/timing.interface.d.ts.map +1 -0
  160. package/dist/util/timing.interface.js +1 -0
  161. package/dist/util/timing.interface.js.map +7 -0
  162. package/dist/util/timing.js +98 -0
  163. package/dist/util/timing.js.map +7 -0
  164. package/dist/util/url.js +1 -1
  165. package/dist/util/url.js.map +2 -2
  166. package/dist/webserver/controller/base.d.ts +3 -1
  167. package/dist/webserver/controller/base.d.ts.map +1 -1
  168. package/dist/webserver/controller/base.interface.d.ts +2 -0
  169. package/dist/webserver/controller/base.interface.d.ts.map +1 -1
  170. package/dist/webserver/controller/base.js +4 -1
  171. package/dist/webserver/controller/base.js.map +2 -2
  172. package/dist/webserver/controller/health.d.ts +8 -1
  173. package/dist/webserver/controller/health.d.ts.map +1 -1
  174. package/dist/webserver/controller/health.js +36 -22
  175. package/dist/webserver/controller/health.js.map +2 -2
  176. package/dist/webserver/webserver.d.ts +16 -2
  177. package/dist/webserver/webserver.d.ts.map +1 -1
  178. package/dist/webserver/webserver.interface.d.ts +37 -0
  179. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  180. package/dist/webserver/webserver.interface.js.map +2 -2
  181. package/dist/webserver/webserver.js +117 -20
  182. package/dist/webserver/webserver.js.map +2 -2
  183. package/dist/websocket/controllers/server/system.d.ts.map +1 -1
  184. package/dist/websocket/controllers/server/system.js.map +2 -2
  185. package/dist/websocket/websocket-base.d.ts.map +1 -1
  186. package/dist/websocket/websocket-base.js +2 -3
  187. package/dist/websocket/websocket-base.js.map +2 -2
  188. package/dist/websocket/websocket-server.d.ts +1 -1
  189. package/dist/websocket/websocket-server.d.ts.map +1 -1
  190. package/dist/websocket/websocket-server.js +7 -31
  191. package/dist/websocket/websocket-server.js.map +2 -2
  192. package/package.json +51 -10
package/dist/index.d.ts CHANGED
@@ -5,12 +5,16 @@ export * from './application/index.js';
5
5
  export * from './auth/index.js';
6
6
  export * from './cache/index.js';
7
7
  export * from './command/index.js';
8
+ export * from './config/index.js';
8
9
  export * from './database/index.js';
10
+ export * from './error/index.js';
9
11
  export * from './event/index.js';
10
- export * from './redis/index.js';
12
+ export * from './lifecycle/index.js';
11
13
  export * from './logger/index.js';
12
14
  export * from './performance/index.js';
13
15
  export * from './queue/index.js';
16
+ export * from './redis/index.js';
17
+ export * from './request-context/index.js';
14
18
  export * from './services/index.js';
15
19
  export * from './util/index.js';
16
20
  export * from './webserver/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,SAAS,QAA2B,CAAC;AAE3C,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,CAAC;AAEhC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,SAAS,QAA2B,CAAC;AAE3C,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,CAAC;AAEhC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -7,12 +7,16 @@ export * from "./application/index.js";
7
7
  export * from "./auth/index.js";
8
8
  export * from "./cache/index.js";
9
9
  export * from "./command/index.js";
10
+ export * from "./config/index.js";
10
11
  export * from "./database/index.js";
12
+ export * from "./error/index.js";
11
13
  export * from "./event/index.js";
12
- export * from "./redis/index.js";
14
+ export * from "./lifecycle/index.js";
13
15
  export * from "./logger/index.js";
14
16
  export * from "./performance/index.js";
15
17
  export * from "./queue/index.js";
18
+ export * from "./redis/index.js";
19
+ export * from "./request-context/index.js";
16
20
  export * from "./services/index.js";
17
21
  export * from "./util/index.js";
18
22
  export * from "./webserver/index.js";
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import { fileURLToPath } from 'url';\nimport path from 'node:path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport { __dirname as baseDir };\n\nexport * from './api-requester/index.js';\nexport * from './application/index.js';\nexport * from './auth/index.js';\nexport * from './cache/index.js';\nexport * from './command/index.js';\nexport * from './database/index.js';\nexport * from './event/index.js';\nexport * from './redis/index.js';\nexport * from './logger/index.js';\nexport * from './performance/index.js';\nexport * from './queue/index.js';\nexport * from './services/index.js';\nexport * from './util/index.js';\nexport * from './webserver/index.js';\nexport * from './websocket/index.js';\n"],
5
- "mappings": "AAAA,SAAS,qBAAqB;AAC9B,OAAO,UAAU;AAEjB,MAAM,aAAa,cAAc,YAAY,GAAG;AAChD,MAAM,YAAY,KAAK,QAAQ,UAAU;AAIzC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
4
+ "sourcesContent": ["import { fileURLToPath } from 'url';\nimport path from 'node:path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport { __dirname as baseDir };\n\nexport * from './api-requester/index.js';\nexport * from './application/index.js';\nexport * from './auth/index.js';\nexport * from './cache/index.js';\nexport * from './command/index.js';\nexport * from './config/index.js';\nexport * from './database/index.js';\nexport * from './error/index.js';\nexport * from './event/index.js';\nexport * from './lifecycle/index.js';\nexport * from './logger/index.js';\nexport * from './performance/index.js';\nexport * from './queue/index.js';\nexport * from './redis/index.js';\nexport * from './request-context/index.js';\nexport * from './services/index.js';\nexport * from './util/index.js';\nexport * from './webserver/index.js';\nexport * from './websocket/index.js';\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAC9B,OAAO,UAAU;AAEjB,MAAM,aAAa,cAAc,YAAY,GAAG;AAChD,MAAM,YAAY,KAAK,QAAQ,UAAU;AAIzC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,6 @@
1
+ export type ExitCode = 0 | 1 | 2 | 130 | 137 | 143;
1
2
  export interface ExitOutcome {
2
- code: number;
3
+ code: ExitCode;
3
4
  reason: string;
4
5
  error?: unknown;
5
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"exit.d.ts","sourceRoot":"","sources":["../../src/lifecycle/exit.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,KAAK,WAAW,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;AAMlD,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,QAE/C;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,QAO/C"}
1
+ {"version":3,"file":"exit.d.ts","sourceRoot":"","sources":["../../src/lifecycle/exit.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,KAAK,WAAW,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;AAMlD,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,QAE/C;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,QAqB/C"}
@@ -8,6 +8,12 @@ function setExitHandler(next) {
8
8
  }
9
9
  __name(setExitHandler, "setExitHandler");
10
10
  function requestExit(outcome) {
11
+ const nodeEnv = process.env.NODE_ENV ?? "";
12
+ const isTestEnv = nodeEnv.toLowerCase() === "test" || "VITEST" in process.env || "VITEST_WORKER_ID" in process.env || process.argv.some((a) => a.includes("vitest")) || typeof globalThis.afterAll === "function";
13
+ if (isTestEnv) {
14
+ console.info(`[exit] (test env) code=${outcome.code} reason=${outcome.reason}`);
15
+ return;
16
+ }
11
17
  try {
12
18
  handler(outcome);
13
19
  } catch (err) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lifecycle/exit.ts"],
4
- "sourcesContent": ["export interface ExitOutcome {\n code: number;\n reason: string;\n error?: unknown;\n}\n\ntype ExitHandler = (outcome: ExitOutcome) => void;\n\nlet handler: ExitHandler = outcome => {\n process.exit(outcome.code);\n};\n\nexport function setExitHandler(next: ExitHandler) {\n handler = next;\n}\n\nexport function requestExit(outcome: ExitOutcome) {\n try {\n handler(outcome);\n } catch (err) {\n console.error('Exit handler failure', err);\n process.exit(outcome.code);\n }\n}\n"],
5
- "mappings": ";;AAQA,IAAI,UAAuB,oCAAW;AACpC,UAAQ,KAAK,QAAQ,IAAI;AAC3B,GAF2B;AAIpB,SAAS,eAAe,MAAmB;AAChD,YAAU;AACZ;AAFgB;AAIT,SAAS,YAAY,SAAsB;AAChD,MAAI;AACF,YAAQ,OAAO;AAAA,EACjB,SAAS,KAAK;AACZ,YAAQ,MAAM,wBAAwB,GAAG;AACzC,YAAQ,KAAK,QAAQ,IAAI;AAAA,EAC3B;AACF;AAPgB;",
4
+ "sourcesContent": ["export type ExitCode = 0 | 1 | 2 | 130 | 137 | 143;\n\nexport interface ExitOutcome {\n code: ExitCode;\n reason: string;\n error?: unknown;\n}\n\ntype ExitHandler = (outcome: ExitOutcome) => void;\n\nlet handler: ExitHandler = outcome => {\n process.exit(outcome.code);\n};\n\nexport function setExitHandler(next: ExitHandler) {\n handler = next;\n}\n\nexport function requestExit(outcome: ExitOutcome) {\n const nodeEnv = process.env.NODE_ENV ?? '';\n const isTestEnv =\n nodeEnv.toLowerCase() === 'test' ||\n 'VITEST' in process.env ||\n 'VITEST_WORKER_ID' in process.env ||\n process.argv.some(a => a.includes('vitest')) ||\n typeof (globalThis as any).afterAll === 'function';\n\n if (isTestEnv) {\n // Suppress real process exit during tests; vitest intercepts and would throw otherwise.\n console.info(`[exit] (test env) code=${outcome.code} reason=${outcome.reason}`);\n return;\n }\n\n try {\n handler(outcome);\n } catch (err) {\n console.error('Exit handler failure', err);\n process.exit(outcome.code);\n }\n}\n"],
5
+ "mappings": ";;AAUA,IAAI,UAAuB,oCAAW;AACpC,UAAQ,KAAK,QAAQ,IAAI;AAC3B,GAF2B;AAIpB,SAAS,eAAe,MAAmB;AAChD,YAAU;AACZ;AAFgB;AAIT,SAAS,YAAY,SAAsB;AAChD,QAAM,UAAU,QAAQ,IAAI,YAAY;AACxC,QAAM,YACJ,QAAQ,YAAY,MAAM,UAC1B,YAAY,QAAQ,OACpB,sBAAsB,QAAQ,OAC9B,QAAQ,KAAK,KAAK,OAAK,EAAE,SAAS,QAAQ,CAAC,KAC3C,OAAQ,WAAmB,aAAa;AAE1C,MAAI,WAAW;AAEb,YAAQ,KAAK,0BAA0B,QAAQ,IAAI,WAAW,QAAQ,MAAM,EAAE;AAC9E;AAAA,EACF;AAEA,MAAI;AACF,YAAQ,OAAO;AAAA,EACjB,SAAS,KAAK;AACZ,YAAQ,MAAM,wBAAwB,GAAG;AACzC,YAAQ,KAAK,QAAQ,IAAI;AAAA,EAC3B;AACF;AArBgB;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,7 @@
1
+ export { LifecycleManager } from './lifecycle-manager.js';
2
+ export { ShutdownController } from './shutdown-controller.js';
3
+ export { requestExit, setExitHandler } from './exit.js';
4
+ export type { ExitCode, ExitOutcome } from './exit.js';
5
+ export type { Disposable, LifecycleHook, LifecycleConfig } from './types.js';
6
+ export { LifecyclePhase } from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lifecycle/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGxD,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEvD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { LifecycleManager } from "./lifecycle-manager.js";
2
+ import { ShutdownController } from "./shutdown-controller.js";
3
+ import { requestExit, setExitHandler } from "./exit.js";
4
+ import { LifecyclePhase } from "./types.js";
5
+ export {
6
+ LifecycleManager,
7
+ LifecyclePhase,
8
+ ShutdownController,
9
+ requestExit,
10
+ setExitHandler
11
+ };
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lifecycle/index.ts"],
4
+ "sourcesContent": ["// Main lifecycle management\nexport { LifecycleManager } from './lifecycle-manager.js';\nexport { ShutdownController } from './shutdown-controller.js';\n\n// Exit handling\nexport { requestExit, setExitHandler } from './exit.js';\n\n// Types and interfaces\nexport type { ExitCode, ExitOutcome } from './exit.js';\n\nexport type { Disposable, LifecycleHook, LifecycleConfig } from './types.js';\n\nexport { LifecyclePhase } from './types.js';\n"],
5
+ "mappings": "AACA,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,aAAa,sBAAsB;AAO5C,SAAS,sBAAsB;",
6
+ "names": []
7
+ }
@@ -1,13 +1,66 @@
1
+ import { type Disposable, type LifecycleConfig, type LifecycleHook, LifecyclePhase, type ReadinessCheck, type ReadinessCheckResult } from './types.js';
1
2
  export declare class LifecycleManager {
3
+ private _phase;
4
+ private config;
5
+ private initHooks;
6
+ private startHooks;
7
+ private readyHooks;
8
+ private beforeShutdownHooks;
2
9
  private shutdownHooks;
10
+ private disposables;
3
11
  private intervals;
4
12
  private timeouts;
5
- private shuttingDown;
6
- onShutdown(fn: () => void | Promise<void>): () => void;
13
+ private abortControllers;
14
+ private readinessChecks;
15
+ private _isReady;
16
+ constructor(config?: Partial<LifecycleConfig>);
17
+ get phase(): LifecyclePhase;
18
+ get isShuttingDown(): boolean;
19
+ get isReady(): boolean;
20
+ onInit(fn: LifecycleHook): () => void;
21
+ onStart(fn: LifecycleHook): () => void;
22
+ onReady(fn: LifecycleHook): () => void;
23
+ onBeforeShutdown(fn: LifecycleHook): () => void;
24
+ onShutdown(fn: LifecycleHook): () => void;
25
+ addReadinessCheck(name: string, check: ReadinessCheck): () => void;
26
+ trackDisposable(disposable: Disposable | {
27
+ dispose: Function;
28
+ }): Disposable;
7
29
  trackInterval(id: NodeJS.Timeout): NodeJS.Timeout;
8
30
  trackTimeout(id: NodeJS.Timeout): NodeJS.Timeout;
31
+ /**
32
+ * Track an AbortController for automatic cleanup on shutdown.
33
+ * When the lifecycle manager shuts down, it will call abort() on all tracked controllers.
34
+ * @param controller - The AbortController to track
35
+ * @returns The same AbortController for chaining
36
+ */
37
+ trackAbortController(controller: AbortController): AbortController;
38
+ /**
39
+ * Create and track a new AbortController.
40
+ * Convenience method that creates a new controller and automatically tracks it.
41
+ * @returns A new tracked AbortController
42
+ */
43
+ createAbortController(): AbortController;
44
+ initialize(): Promise<{
45
+ errors: unknown[];
46
+ }>;
47
+ start(): Promise<{
48
+ errors: unknown[];
49
+ }>;
50
+ ready(): Promise<{
51
+ errors: unknown[];
52
+ }>;
9
53
  shutdown(): Promise<{
10
54
  errors: unknown[];
55
+ timedOut: boolean;
56
+ }>;
57
+ private performShutdown;
58
+ private executeHooks;
59
+ private waitForReadiness;
60
+ private executeReadinessChecks;
61
+ getReadinessStatus(): Promise<{
62
+ ready: boolean;
63
+ checks: ReadinessCheckResult[];
11
64
  }>;
12
65
  }
13
66
  //# sourceMappingURL=lifecycle-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-manager.d.ts","sourceRoot":"","sources":["../../src/lifecycle/lifecycle-manager.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,YAAY,CAAS;IAE7B,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO;IAKhC,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO;IAKzB,QAAQ,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;CA0BjD"}
1
+ {"version":3,"file":"lifecycle-manager.d.ts","sourceRoot":"","sources":["../../src/lifecycle/lifecycle-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAC;AAEpB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,MAAM,CAAkB;IAEhC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,aAAa,CAAuB;IAE5C,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,gBAAgB,CAA8B;IAEtD,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM;IAYjD,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,MAAM,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,IAAI;IAQrC,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,IAAI;IAQtC,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,IAAI;IAQtC,gBAAgB,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,IAAI;IAQ/C,UAAU,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,IAAI;IAQzC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,IAAI;IAOlE,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAA;KAAE,GAAG,UAAU;IAM3E,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO;IAKjD,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO;IAKhD;;;;;OAKG;IACH,oBAAoB,CAAC,UAAU,EAAE,eAAe,GAAG,eAAe;IAKlE;;;;OAIG;IACH,qBAAqB,IAAI,eAAe;IAKlC,UAAU,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAU5C,KAAK,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAUvC,KAAK,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAkBvC,QAAQ,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;YAgCrD,eAAe;YA4Cf,YAAY;YAYZ,gBAAgB;YAmChB,sBAAsB;IAiC9B,kBAAkB,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,oBAAoB,EAAE,CAAA;KAAE,CAAC;CAKxF"}
@@ -1,13 +1,73 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ import {
4
+ LifecyclePhase
5
+ } from "./types.js";
3
6
  class LifecycleManager {
4
7
  static {
5
8
  __name(this, "LifecycleManager");
6
9
  }
10
+ _phase = LifecyclePhase.CREATED;
11
+ config;
12
+ initHooks = [];
13
+ startHooks = [];
14
+ readyHooks = [];
15
+ beforeShutdownHooks = [];
7
16
  shutdownHooks = [];
17
+ disposables = /* @__PURE__ */ new Set();
8
18
  intervals = /* @__PURE__ */ new Set();
9
19
  timeouts = /* @__PURE__ */ new Set();
10
- shuttingDown = false;
20
+ abortControllers = /* @__PURE__ */ new Set();
21
+ readinessChecks = /* @__PURE__ */ new Map();
22
+ _isReady = false;
23
+ constructor(config = {}) {
24
+ this.config = {
25
+ gracefulShutdown: {
26
+ timeoutMs: config.gracefulShutdown?.timeoutMs ?? 1e4
27
+ },
28
+ readiness: {
29
+ timeoutMs: config.readiness?.timeoutMs ?? 3e4,
30
+ checkIntervalMs: config.readiness?.checkIntervalMs ?? 100
31
+ }
32
+ };
33
+ }
34
+ get phase() {
35
+ return this._phase;
36
+ }
37
+ get isShuttingDown() {
38
+ return this._phase === LifecyclePhase.STOPPING || this._phase === LifecyclePhase.STOPPED;
39
+ }
40
+ get isReady() {
41
+ return this._isReady && this._phase === LifecyclePhase.RUNNING;
42
+ }
43
+ onInit(fn) {
44
+ this.initHooks.push(fn);
45
+ return () => {
46
+ const i = this.initHooks.indexOf(fn);
47
+ if (i >= 0) this.initHooks.splice(i, 1);
48
+ };
49
+ }
50
+ onStart(fn) {
51
+ this.startHooks.push(fn);
52
+ return () => {
53
+ const i = this.startHooks.indexOf(fn);
54
+ if (i >= 0) this.startHooks.splice(i, 1);
55
+ };
56
+ }
57
+ onReady(fn) {
58
+ this.readyHooks.push(fn);
59
+ return () => {
60
+ const i = this.readyHooks.indexOf(fn);
61
+ if (i >= 0) this.readyHooks.splice(i, 1);
62
+ };
63
+ }
64
+ onBeforeShutdown(fn) {
65
+ this.beforeShutdownHooks.push(fn);
66
+ return () => {
67
+ const i = this.beforeShutdownHooks.indexOf(fn);
68
+ if (i >= 0) this.beforeShutdownHooks.splice(i, 1);
69
+ };
70
+ }
11
71
  onShutdown(fn) {
12
72
  this.shutdownHooks.push(fn);
13
73
  return () => {
@@ -15,6 +75,17 @@ class LifecycleManager {
15
75
  if (i >= 0) this.shutdownHooks.splice(i, 1);
16
76
  };
17
77
  }
78
+ addReadinessCheck(name, check) {
79
+ this.readinessChecks.set(name, check);
80
+ return () => {
81
+ this.readinessChecks.delete(name);
82
+ };
83
+ }
84
+ trackDisposable(disposable) {
85
+ const d = "dispose" in disposable ? { dispose: /* @__PURE__ */ __name(() => disposable.dispose(), "dispose") } : disposable;
86
+ this.disposables.add(d);
87
+ return d;
88
+ }
18
89
  trackInterval(id) {
19
90
  this.intervals.add(id);
20
91
  return id;
@@ -23,11 +94,95 @@ class LifecycleManager {
23
94
  this.timeouts.add(id);
24
95
  return id;
25
96
  }
26
- async shutdown() {
27
- if (this.shuttingDown) {
97
+ /**
98
+ * Track an AbortController for automatic cleanup on shutdown.
99
+ * When the lifecycle manager shuts down, it will call abort() on all tracked controllers.
100
+ * @param controller - The AbortController to track
101
+ * @returns The same AbortController for chaining
102
+ */
103
+ trackAbortController(controller) {
104
+ this.abortControllers.add(controller);
105
+ return controller;
106
+ }
107
+ /**
108
+ * Create and track a new AbortController.
109
+ * Convenience method that creates a new controller and automatically tracks it.
110
+ * @returns A new tracked AbortController
111
+ */
112
+ createAbortController() {
113
+ const controller = new AbortController();
114
+ return this.trackAbortController(controller);
115
+ }
116
+ async initialize() {
117
+ if (this._phase !== LifecyclePhase.CREATED) {
118
+ return { errors: [] };
119
+ }
120
+ this._phase = LifecyclePhase.INITIALIZING;
121
+ const errors = await this.executeHooks(this.initHooks, "init");
122
+ return { errors };
123
+ }
124
+ async start() {
125
+ if (this._phase !== LifecyclePhase.INITIALIZING) {
126
+ return { errors: [] };
127
+ }
128
+ this._phase = LifecyclePhase.STARTING;
129
+ const errors = await this.executeHooks(this.startHooks, "start");
130
+ return { errors };
131
+ }
132
+ async ready() {
133
+ if (this._phase !== LifecyclePhase.STARTING) {
28
134
  return { errors: [] };
29
135
  }
30
- this.shuttingDown = true;
136
+ this._phase = LifecyclePhase.RUNNING;
137
+ const errors = await this.executeHooks(this.readyHooks, "ready");
138
+ const readinessResult = await this.waitForReadiness();
139
+ if (readinessResult.errors.length > 0) {
140
+ errors.push(...readinessResult.errors);
141
+ }
142
+ this._isReady = readinessResult.ready;
143
+ return { errors };
144
+ }
145
+ async shutdown() {
146
+ if (this.isShuttingDown) {
147
+ return { errors: [], timedOut: false };
148
+ }
149
+ this._phase = LifecyclePhase.STOPPING;
150
+ const timeoutMs = this.config.gracefulShutdown.timeoutMs;
151
+ if (timeoutMs > 0) {
152
+ let completed = false;
153
+ let timedOut = false;
154
+ const shutdownPromise = this.performShutdown().then((result3) => {
155
+ completed = true;
156
+ return result3;
157
+ });
158
+ const timeoutPromise = new Promise((resolve) => {
159
+ setTimeout(() => {
160
+ if (!completed) {
161
+ timedOut = true;
162
+ resolve({ errors: ["Shutdown timeout exceeded"] });
163
+ }
164
+ }, timeoutMs);
165
+ });
166
+ const result2 = await Promise.race([shutdownPromise, timeoutPromise]);
167
+ this._phase = LifecyclePhase.STOPPED;
168
+ return { errors: result2.errors, timedOut };
169
+ }
170
+ const result = await this.performShutdown();
171
+ this._phase = LifecyclePhase.STOPPED;
172
+ return { errors: result.errors, timedOut: false };
173
+ }
174
+ async performShutdown() {
175
+ const errors = [];
176
+ const beforeShutdownErrors = await this.executeHooks(this.beforeShutdownHooks, "before-shutdown");
177
+ errors.push(...beforeShutdownErrors);
178
+ for (const controller of this.abortControllers) {
179
+ try {
180
+ controller.abort();
181
+ } catch (e) {
182
+ errors.push(e);
183
+ }
184
+ }
185
+ this.abortControllers.clear();
31
186
  for (const id of this.intervals) {
32
187
  clearInterval(id);
33
188
  }
@@ -36,16 +191,87 @@ class LifecycleManager {
36
191
  }
37
192
  this.intervals.clear();
38
193
  this.timeouts.clear();
194
+ for (const disposable of this.disposables) {
195
+ try {
196
+ await disposable.dispose();
197
+ } catch (e) {
198
+ errors.push(e);
199
+ }
200
+ }
201
+ this.disposables.clear();
202
+ const shutdownErrors = await this.executeHooks([...this.shutdownHooks].reverse(), "shutdown");
203
+ errors.push(...shutdownErrors);
204
+ return { errors };
205
+ }
206
+ async executeHooks(hooks, _phase) {
39
207
  const errors = [];
40
- for (let i = this.shutdownHooks.length - 1; i >= 0; i--) {
41
- const hook = this.shutdownHooks[i];
208
+ for (const hook of hooks) {
42
209
  try {
43
210
  await hook();
44
211
  } catch (e) {
45
212
  errors.push(e);
46
213
  }
47
214
  }
48
- return { errors };
215
+ return errors;
216
+ }
217
+ async waitForReadiness() {
218
+ if (this.readinessChecks.size === 0) {
219
+ return { ready: true, errors: [] };
220
+ }
221
+ const timeoutMs = this.config.readiness?.timeoutMs ?? 3e4;
222
+ const checkIntervalMs = this.config.readiness?.checkIntervalMs ?? 100;
223
+ const startTime = Date.now();
224
+ const errors = [];
225
+ while (Date.now() - startTime < timeoutMs) {
226
+ const results = await this.executeReadinessChecks();
227
+ const allReady = results.every((r) => r.ready);
228
+ if (allReady) {
229
+ return { ready: true, errors };
230
+ }
231
+ for (const result of results) {
232
+ if (!result.ready && result.error) {
233
+ const errorMessage = result.error.message;
234
+ if (!errors.some((e) => e?.message === errorMessage)) {
235
+ errors.push(result.error);
236
+ }
237
+ }
238
+ }
239
+ await new Promise((resolve) => setTimeout(resolve, checkIntervalMs));
240
+ }
241
+ return { ready: false, errors: [...errors, new Error("Readiness check timeout exceeded")] };
242
+ }
243
+ async executeReadinessChecks() {
244
+ const checkEntries = Array.from(this.readinessChecks.entries());
245
+ const settledResults = await Promise.allSettled(
246
+ checkEntries.map(async ([name, check]) => {
247
+ try {
248
+ const result = await check();
249
+ return { name, ready: result };
250
+ } catch (error) {
251
+ return { name, ready: false, error };
252
+ }
253
+ })
254
+ );
255
+ return settledResults.map((settledResult, index) => {
256
+ const checkEntry = checkEntries.at(index);
257
+ if (!checkEntry) {
258
+ throw new Error(`Missing check entry at index ${index}`);
259
+ }
260
+ const [name] = checkEntry;
261
+ if (settledResult.status === "fulfilled") {
262
+ return settledResult.value;
263
+ }
264
+ return {
265
+ name,
266
+ ready: false,
267
+ error: settledResult.reason
268
+ };
269
+ });
270
+ }
271
+ async getReadinessStatus() {
272
+ const checks = await this.executeReadinessChecks();
273
+ const ready = this._isReady && this._phase === LifecyclePhase.RUNNING && checks.every((c) => c.ready);
274
+ return { ready, checks };
49
275
  }
50
276
  }
51
277
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lifecycle/lifecycle-manager.ts"],
4
- "sourcesContent": ["export class LifecycleManager {\n private shutdownHooks: Array<() => void | Promise<void>> = [];\n private intervals = new Set<NodeJS.Timeout>();\n private timeouts = new Set<NodeJS.Timeout>();\n private shuttingDown = false;\n\n onShutdown(fn: () => void | Promise<void>) {\n this.shutdownHooks.push(fn);\n return () => {\n const i = this.shutdownHooks.indexOf(fn);\n if (i >= 0) this.shutdownHooks.splice(i, 1);\n };\n }\n\n trackInterval(id: NodeJS.Timeout) {\n this.intervals.add(id);\n return id;\n }\n\n trackTimeout(id: NodeJS.Timeout) {\n this.timeouts.add(id);\n return id;\n }\n\n async shutdown(): Promise<{ errors: unknown[] }> {\n if (this.shuttingDown) {\n return { errors: [] };\n }\n this.shuttingDown = true;\n\n for (const id of this.intervals) {\n clearInterval(id);\n }\n for (const id of this.timeouts) {\n clearTimeout(id);\n }\n this.intervals.clear();\n this.timeouts.clear();\n\n const errors: unknown[] = [];\n for (let i = this.shutdownHooks.length - 1; i >= 0; i--) {\n const hook = this.shutdownHooks[i];\n try {\n await hook();\n } catch (e) {\n errors.push(e);\n }\n }\n return { errors };\n }\n}\n"],
5
- "mappings": ";;AAAO,MAAM,iBAAiB;AAAA,EAA9B,OAA8B;AAAA;AAAA;AAAA,EACpB,gBAAmD,CAAC;AAAA,EACpD,YAAY,oBAAI,IAAoB;AAAA,EACpC,WAAW,oBAAI,IAAoB;AAAA,EACnC,eAAe;AAAA,EAEvB,WAAW,IAAgC;AACzC,SAAK,cAAc,KAAK,EAAE;AAC1B,WAAO,MAAM;AACX,YAAM,IAAI,KAAK,cAAc,QAAQ,EAAE;AACvC,UAAI,KAAK,EAAG,MAAK,cAAc,OAAO,GAAG,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,cAAc,IAAoB;AAChC,SAAK,UAAU,IAAI,EAAE;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,aAAa,IAAoB;AAC/B,SAAK,SAAS,IAAI,EAAE;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAA2C;AAC/C,QAAI,KAAK,cAAc;AACrB,aAAO,EAAE,QAAQ,CAAC,EAAE;AAAA,IACtB;AACA,SAAK,eAAe;AAEpB,eAAW,MAAM,KAAK,WAAW;AAC/B,oBAAc,EAAE;AAAA,IAClB;AACA,eAAW,MAAM,KAAK,UAAU;AAC9B,mBAAa,EAAE;AAAA,IACjB;AACA,SAAK,UAAU,MAAM;AACrB,SAAK,SAAS,MAAM;AAEpB,UAAM,SAAoB,CAAC;AAC3B,aAAS,IAAI,KAAK,cAAc,SAAS,GAAG,KAAK,GAAG,KAAK;AACvD,YAAM,OAAO,KAAK,cAAc,CAAC;AACjC,UAAI;AACF,cAAM,KAAK;AAAA,MACb,SAAS,GAAG;AACV,eAAO,KAAK,CAAC;AAAA,MACf;AAAA,IACF;AACA,WAAO,EAAE,OAAO;AAAA,EAClB;AACF;",
6
- "names": []
4
+ "sourcesContent": ["import {\n type Disposable,\n type LifecycleConfig,\n type LifecycleHook,\n LifecyclePhase,\n type ReadinessCheck,\n type ReadinessCheckResult,\n} from './types.js';\n\nexport class LifecycleManager {\n private _phase: LifecyclePhase = LifecyclePhase.CREATED;\n private config: LifecycleConfig;\n\n private initHooks: LifecycleHook[] = [];\n private startHooks: LifecycleHook[] = [];\n private readyHooks: LifecycleHook[] = [];\n private beforeShutdownHooks: LifecycleHook[] = [];\n private shutdownHooks: LifecycleHook[] = [];\n\n private disposables = new Set<Disposable>();\n private intervals = new Set<NodeJS.Timeout>();\n private timeouts = new Set<NodeJS.Timeout>();\n private abortControllers = new Set<AbortController>();\n\n private readinessChecks = new Map<string, ReadinessCheck>();\n private _isReady = false;\n\n constructor(config: Partial<LifecycleConfig> = {}) {\n this.config = {\n gracefulShutdown: {\n timeoutMs: config.gracefulShutdown?.timeoutMs ?? 10000,\n },\n readiness: {\n timeoutMs: config.readiness?.timeoutMs ?? 30000,\n checkIntervalMs: config.readiness?.checkIntervalMs ?? 100,\n },\n };\n }\n\n get phase(): LifecyclePhase {\n return this._phase;\n }\n\n get isShuttingDown(): boolean {\n return this._phase === LifecyclePhase.STOPPING || this._phase === LifecyclePhase.STOPPED;\n }\n\n get isReady(): boolean {\n return this._isReady && this._phase === LifecyclePhase.RUNNING;\n }\n\n onInit(fn: LifecycleHook): () => void {\n this.initHooks.push(fn);\n return () => {\n const i = this.initHooks.indexOf(fn);\n if (i >= 0) this.initHooks.splice(i, 1);\n };\n }\n\n onStart(fn: LifecycleHook): () => void {\n this.startHooks.push(fn);\n return () => {\n const i = this.startHooks.indexOf(fn);\n if (i >= 0) this.startHooks.splice(i, 1);\n };\n }\n\n onReady(fn: LifecycleHook): () => void {\n this.readyHooks.push(fn);\n return () => {\n const i = this.readyHooks.indexOf(fn);\n if (i >= 0) this.readyHooks.splice(i, 1);\n };\n }\n\n onBeforeShutdown(fn: LifecycleHook): () => void {\n this.beforeShutdownHooks.push(fn);\n return () => {\n const i = this.beforeShutdownHooks.indexOf(fn);\n if (i >= 0) this.beforeShutdownHooks.splice(i, 1);\n };\n }\n\n onShutdown(fn: LifecycleHook): () => void {\n this.shutdownHooks.push(fn);\n return () => {\n const i = this.shutdownHooks.indexOf(fn);\n if (i >= 0) this.shutdownHooks.splice(i, 1);\n };\n }\n\n addReadinessCheck(name: string, check: ReadinessCheck): () => void {\n this.readinessChecks.set(name, check);\n return () => {\n this.readinessChecks.delete(name);\n };\n }\n\n trackDisposable(disposable: Disposable | { dispose: Function }): Disposable {\n const d: Disposable = 'dispose' in disposable ? { dispose: () => (disposable as any).dispose() } : disposable;\n this.disposables.add(d);\n return d;\n }\n\n trackInterval(id: NodeJS.Timeout): NodeJS.Timeout {\n this.intervals.add(id);\n return id;\n }\n\n trackTimeout(id: NodeJS.Timeout): NodeJS.Timeout {\n this.timeouts.add(id);\n return id;\n }\n\n /**\n * Track an AbortController for automatic cleanup on shutdown.\n * When the lifecycle manager shuts down, it will call abort() on all tracked controllers.\n * @param controller - The AbortController to track\n * @returns The same AbortController for chaining\n */\n trackAbortController(controller: AbortController): AbortController {\n this.abortControllers.add(controller);\n return controller;\n }\n\n /**\n * Create and track a new AbortController.\n * Convenience method that creates a new controller and automatically tracks it.\n * @returns A new tracked AbortController\n */\n createAbortController(): AbortController {\n const controller = new AbortController();\n return this.trackAbortController(controller);\n }\n\n async initialize(): Promise<{ errors: unknown[] }> {\n if (this._phase !== LifecyclePhase.CREATED) {\n return { errors: [] };\n }\n this._phase = LifecyclePhase.INITIALIZING;\n\n const errors = await this.executeHooks(this.initHooks, 'init');\n return { errors };\n }\n\n async start(): Promise<{ errors: unknown[] }> {\n if (this._phase !== LifecyclePhase.INITIALIZING) {\n return { errors: [] };\n }\n this._phase = LifecyclePhase.STARTING;\n\n const errors = await this.executeHooks(this.startHooks, 'start');\n return { errors };\n }\n\n async ready(): Promise<{ errors: unknown[] }> {\n if (this._phase !== LifecyclePhase.STARTING) {\n return { errors: [] };\n }\n this._phase = LifecyclePhase.RUNNING;\n\n const errors = await this.executeHooks(this.readyHooks, 'ready');\n\n // Wait for readiness checks to pass\n const readinessResult = await this.waitForReadiness();\n if (readinessResult.errors.length > 0) {\n errors.push(...readinessResult.errors);\n }\n this._isReady = readinessResult.ready;\n\n return { errors };\n }\n\n async shutdown(): Promise<{ errors: unknown[]; timedOut: boolean }> {\n if (this.isShuttingDown) {\n return { errors: [], timedOut: false };\n }\n this._phase = LifecyclePhase.STOPPING;\n\n const timeoutMs = this.config.gracefulShutdown.timeoutMs;\n if (timeoutMs > 0) {\n let completed = false;\n let timedOut = false;\n const shutdownPromise = this.performShutdown().then(result => {\n completed = true;\n return result;\n });\n const timeoutPromise = new Promise<{ errors: unknown[] }>(resolve => {\n setTimeout(() => {\n if (!completed) {\n timedOut = true;\n resolve({ errors: ['Shutdown timeout exceeded'] });\n }\n }, timeoutMs);\n });\n const result = await Promise.race([shutdownPromise, timeoutPromise]);\n this._phase = LifecyclePhase.STOPPED;\n return { errors: result.errors, timedOut };\n }\n\n const result = await this.performShutdown();\n this._phase = LifecyclePhase.STOPPED;\n return { errors: result.errors, timedOut: false };\n }\n\n private async performShutdown(): Promise<{ errors: unknown[] }> {\n const errors: unknown[] = [];\n\n // Execute before-shutdown hooks in registration order (FIFO)\n const beforeShutdownErrors = await this.executeHooks(this.beforeShutdownHooks, 'before-shutdown');\n errors.push(...beforeShutdownErrors);\n\n // Abort all tracked AbortControllers\n for (const controller of this.abortControllers) {\n try {\n controller.abort();\n } catch (e) {\n errors.push(e);\n }\n }\n this.abortControllers.clear();\n\n // Clear intervals and timeouts\n for (const id of this.intervals) {\n clearInterval(id);\n }\n for (const id of this.timeouts) {\n clearTimeout(id);\n }\n this.intervals.clear();\n this.timeouts.clear();\n\n // Dispose of tracked disposables\n for (const disposable of this.disposables) {\n try {\n await disposable.dispose();\n } catch (e) {\n errors.push(e);\n }\n }\n this.disposables.clear();\n\n // Execute shutdown hooks in reverse registration order (LIFO)\n const shutdownErrors = await this.executeHooks([...this.shutdownHooks].reverse(), 'shutdown');\n errors.push(...shutdownErrors);\n\n return { errors };\n }\n\n private async executeHooks(hooks: LifecycleHook[], _phase: string): Promise<unknown[]> {\n const errors: unknown[] = [];\n for (const hook of hooks) {\n try {\n await hook();\n } catch (e) {\n errors.push(e);\n }\n }\n return errors;\n }\n\n private async waitForReadiness(): Promise<{ ready: boolean; errors: unknown[] }> {\n if (this.readinessChecks.size === 0) {\n return { ready: true, errors: [] };\n }\n\n const timeoutMs = this.config.readiness?.timeoutMs ?? 30000;\n const checkIntervalMs = this.config.readiness?.checkIntervalMs ?? 100;\n const startTime = Date.now();\n const errors: unknown[] = [];\n\n while (Date.now() - startTime < timeoutMs) {\n const results = await this.executeReadinessChecks();\n const allReady = results.every(r => r.ready);\n\n if (allReady) {\n return { ready: true, errors };\n }\n\n // Collect unique errors from failed checks\n for (const result of results) {\n if (!result.ready && result.error) {\n const errorMessage = result.error.message;\n if (!errors.some(e => (e as Error)?.message === errorMessage)) {\n errors.push(result.error);\n }\n }\n }\n\n // Wait before next check\n await new Promise(resolve => setTimeout(resolve, checkIntervalMs));\n }\n\n return { ready: false, errors: [...errors, new Error('Readiness check timeout exceeded')] };\n }\n\n private async executeReadinessChecks(): Promise<ReadinessCheckResult[]> {\n const checkEntries = Array.from(this.readinessChecks.entries());\n\n const settledResults = await Promise.allSettled(\n checkEntries.map(async ([name, check]) => {\n try {\n const result = await check();\n return { name, ready: result };\n } catch (error) {\n return { name, ready: false, error: error as Error };\n }\n }),\n );\n\n return settledResults.map((settledResult, index) => {\n const checkEntry = checkEntries.at(index);\n if (!checkEntry) {\n throw new Error(`Missing check entry at index ${index}`);\n }\n const [name] = checkEntry;\n\n if (settledResult.status === 'fulfilled') {\n return settledResult.value;\n }\n\n return {\n name,\n ready: false,\n error: settledResult.reason as Error,\n };\n });\n }\n\n async getReadinessStatus(): Promise<{ ready: boolean; checks: ReadinessCheckResult[] }> {\n const checks = await this.executeReadinessChecks();\n const ready = this._isReady && this._phase === LifecyclePhase.RUNNING && checks.every(c => c.ready);\n return { ready, checks };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["result"]
7
7
  }
@@ -0,0 +1,15 @@
1
+ import type { LifecycleManager } from './lifecycle-manager.js';
2
+ import type { LifecycleHook } from './types.js';
3
+ export declare class ShutdownController {
4
+ private lifecycle;
5
+ private _isShuttingDown;
6
+ private _hasInitiated;
7
+ constructor(lifecycle: LifecycleManager);
8
+ get isShuttingDown(): boolean;
9
+ register(fn: LifecycleHook): () => void;
10
+ initiate(_reason: string, _signal?: string): Promise<{
11
+ errors: unknown[];
12
+ timedOut: boolean;
13
+ }>;
14
+ }
15
+ //# sourceMappingURL=shutdown-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown-controller.d.ts","sourceRoot":"","sources":["../../src/lifecycle/shutdown-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,kBAAkB;IAIjB,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAAS;gBAEV,SAAS,EAAE,gBAAgB;IAE/C,IAAI,cAAc,IAAI,OAAO,CAO5B;IAED,QAAQ,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,IAAI;IAIjC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;CAerG"}
@@ -0,0 +1,38 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ class ShutdownController {
4
+ constructor(lifecycle) {
5
+ this.lifecycle = lifecycle;
6
+ }
7
+ static {
8
+ __name(this, "ShutdownController");
9
+ }
10
+ _isShuttingDown = false;
11
+ _hasInitiated = false;
12
+ get isShuttingDown() {
13
+ if (this._hasInitiated) {
14
+ return this._isShuttingDown;
15
+ }
16
+ return this._isShuttingDown || this.lifecycle.isShuttingDown;
17
+ }
18
+ register(fn) {
19
+ return this.lifecycle.onShutdown(fn);
20
+ }
21
+ async initiate(_reason, _signal) {
22
+ if (this._isShuttingDown) {
23
+ return { errors: [], timedOut: false };
24
+ }
25
+ this._isShuttingDown = true;
26
+ this._hasInitiated = true;
27
+ try {
28
+ const result = await this.lifecycle.shutdown();
29
+ return result;
30
+ } finally {
31
+ this._isShuttingDown = false;
32
+ }
33
+ }
34
+ }
35
+ export {
36
+ ShutdownController
37
+ };
38
+ //# sourceMappingURL=shutdown-controller.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lifecycle/shutdown-controller.ts"],
4
+ "sourcesContent": ["import type { LifecycleManager } from './lifecycle-manager.js';\nimport type { LifecycleHook } from './types.js';\n\nexport class ShutdownController {\n private _isShuttingDown = false;\n private _hasInitiated = false;\n\n constructor(private lifecycle: LifecycleManager) {}\n\n get isShuttingDown(): boolean {\n if (this._hasInitiated) {\n // If we've initiated shutdown, only check our own flag\n return this._isShuttingDown;\n }\n // Otherwise, check both our flag and lifecycle state\n return this._isShuttingDown || this.lifecycle.isShuttingDown;\n }\n\n register(fn: LifecycleHook): () => void {\n return this.lifecycle.onShutdown(fn);\n }\n\n async initiate(_reason: string, _signal?: string): Promise<{ errors: unknown[]; timedOut: boolean }> {\n if (this._isShuttingDown) {\n return { errors: [], timedOut: false };\n }\n\n this._isShuttingDown = true;\n this._hasInitiated = true;\n\n try {\n const result = await this.lifecycle.shutdown();\n return result;\n } finally {\n this._isShuttingDown = false;\n }\n }\n}\n"],
5
+ "mappings": ";;AAGO,MAAM,mBAAmB;AAAA,EAI9B,YAAoB,WAA6B;AAA7B;AAAA,EAA8B;AAAA,EAPpD,OAGgC;AAAA;AAAA;AAAA,EACtB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAIxB,IAAI,iBAA0B;AAC5B,QAAI,KAAK,eAAe;AAEtB,aAAO,KAAK;AAAA,IACd;AAEA,WAAO,KAAK,mBAAmB,KAAK,UAAU;AAAA,EAChD;AAAA,EAEA,SAAS,IAA+B;AACtC,WAAO,KAAK,UAAU,WAAW,EAAE;AAAA,EACrC;AAAA,EAEA,MAAM,SAAS,SAAiB,SAAqE;AACnG,QAAI,KAAK,iBAAiB;AACxB,aAAO,EAAE,QAAQ,CAAC,GAAG,UAAU,MAAM;AAAA,IACvC;AAEA,SAAK,kBAAkB;AACvB,SAAK,gBAAgB;AAErB,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,UAAU,SAAS;AAC7C,aAAO;AAAA,IACT,UAAE;AACA,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,28 @@
1
+ export interface Disposable {
2
+ dispose(): Promise<void> | void;
3
+ }
4
+ export declare enum LifecyclePhase {
5
+ CREATED = "created",
6
+ INITIALIZING = "initializing",
7
+ STARTING = "starting",
8
+ RUNNING = "running",
9
+ STOPPING = "stopping",
10
+ STOPPED = "stopped"
11
+ }
12
+ export type LifecycleHook = () => Promise<void> | void;
13
+ export type ReadinessCheck = () => Promise<boolean> | boolean;
14
+ export interface ReadinessCheckResult {
15
+ name: string;
16
+ ready: boolean;
17
+ error?: Error;
18
+ }
19
+ export interface LifecycleConfig {
20
+ gracefulShutdown: {
21
+ timeoutMs: number;
22
+ };
23
+ readiness?: {
24
+ timeoutMs?: number;
25
+ checkIntervalMs?: number;
26
+ };
27
+ }
28
+ //# sourceMappingURL=types.d.ts.map