@simplysm/sd-cli 13.0.10 → 13.0.12

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 (154) hide show
  1. package/dist/builders/BaseBuilder.d.ts +15 -4
  2. package/dist/builders/BaseBuilder.d.ts.map +1 -1
  3. package/dist/builders/BaseBuilder.js +50 -0
  4. package/dist/builders/BaseBuilder.js.map +1 -1
  5. package/dist/builders/DtsBuilder.d.ts.map +1 -1
  6. package/dist/builders/DtsBuilder.js +2 -39
  7. package/dist/builders/DtsBuilder.js.map +1 -1
  8. package/dist/builders/LibraryBuilder.d.ts.map +1 -1
  9. package/dist/builders/LibraryBuilder.js +2 -39
  10. package/dist/builders/LibraryBuilder.js.map +1 -1
  11. package/dist/builders/types.d.ts +2 -2
  12. package/dist/builders/types.d.ts.map +1 -1
  13. package/dist/capacitor/capacitor.d.ts.map +1 -1
  14. package/dist/capacitor/capacitor.js +2 -1
  15. package/dist/capacitor/capacitor.js.map +1 -1
  16. package/dist/commands/add-client.d.ts.map +1 -1
  17. package/dist/commands/add-client.js +1 -9
  18. package/dist/commands/add-client.js.map +1 -1
  19. package/dist/commands/add-server.d.ts.map +1 -1
  20. package/dist/commands/add-server.js +1 -9
  21. package/dist/commands/add-server.js.map +1 -1
  22. package/dist/commands/build.d.ts +1 -2
  23. package/dist/commands/build.d.ts.map +1 -1
  24. package/dist/commands/build.js +12 -311
  25. package/dist/commands/build.js.map +1 -1
  26. package/dist/commands/dev.d.ts +1 -1
  27. package/dist/commands/dev.d.ts.map +1 -1
  28. package/dist/commands/dev.js +11 -432
  29. package/dist/commands/dev.js.map +1 -1
  30. package/dist/commands/device.d.ts.map +1 -1
  31. package/dist/commands/device.js +17 -32
  32. package/dist/commands/device.js.map +1 -1
  33. package/dist/commands/init.d.ts.map +1 -1
  34. package/dist/commands/init.js +1 -9
  35. package/dist/commands/init.js.map +1 -1
  36. package/dist/commands/lint.d.ts +1 -1
  37. package/dist/commands/lint.d.ts.map +1 -1
  38. package/dist/commands/lint.js +71 -118
  39. package/dist/commands/lint.js.map +2 -2
  40. package/dist/commands/publish.d.ts.map +1 -1
  41. package/dist/commands/publish.js +47 -69
  42. package/dist/commands/publish.js.map +1 -1
  43. package/dist/commands/typecheck.d.ts +1 -1
  44. package/dist/commands/typecheck.d.ts.map +1 -1
  45. package/dist/commands/typecheck.js +11 -24
  46. package/dist/commands/typecheck.js.map +1 -1
  47. package/dist/index.d.ts +1 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +4 -0
  50. package/dist/index.js.map +1 -1
  51. package/dist/infra/ResultCollector.d.ts +1 -1
  52. package/dist/infra/ResultCollector.d.ts.map +1 -1
  53. package/dist/infra/ResultCollector.js +1 -1
  54. package/dist/infra/ResultCollector.js.map +1 -1
  55. package/dist/orchestrators/BuildOrchestrator.d.ts +53 -0
  56. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -0
  57. package/dist/orchestrators/BuildOrchestrator.js +338 -0
  58. package/dist/orchestrators/BuildOrchestrator.js.map +6 -0
  59. package/dist/orchestrators/DevOrchestrator.d.ts +64 -0
  60. package/dist/orchestrators/DevOrchestrator.d.ts.map +1 -0
  61. package/dist/orchestrators/DevOrchestrator.js +524 -0
  62. package/dist/orchestrators/DevOrchestrator.js.map +6 -0
  63. package/dist/orchestrators/WatchOrchestrator.d.ts +1 -1
  64. package/dist/orchestrators/WatchOrchestrator.d.ts.map +1 -1
  65. package/dist/orchestrators/WatchOrchestrator.js +30 -21
  66. package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
  67. package/dist/orchestrators/index.d.ts +2 -0
  68. package/dist/orchestrators/index.d.ts.map +1 -1
  69. package/dist/orchestrators/index.js +4 -0
  70. package/dist/orchestrators/index.js.map +1 -1
  71. package/dist/sd-cli-entry.js +14 -14
  72. package/dist/sd-cli-entry.js.map +1 -1
  73. package/dist/sd-cli.js +6 -4
  74. package/dist/sd-cli.js.map +1 -1
  75. package/dist/utils/output-utils.d.ts +0 -1
  76. package/dist/utils/output-utils.d.ts.map +1 -1
  77. package/dist/utils/output-utils.js +1 -1
  78. package/dist/utils/output-utils.js.map +1 -1
  79. package/dist/utils/package-utils.d.ts +5 -1
  80. package/dist/utils/package-utils.d.ts.map +1 -1
  81. package/dist/utils/package-utils.js +12 -0
  82. package/dist/utils/package-utils.js.map +1 -1
  83. package/dist/utils/rebuild-manager.d.ts +15 -0
  84. package/dist/utils/rebuild-manager.d.ts.map +1 -0
  85. package/dist/utils/rebuild-manager.js +50 -0
  86. package/dist/utils/rebuild-manager.js.map +6 -0
  87. package/dist/utils/replace-deps.d.ts.map +1 -1
  88. package/dist/utils/replace-deps.js +7 -14
  89. package/dist/utils/replace-deps.js.map +1 -1
  90. package/dist/utils/vite-config.d.ts.map +1 -1
  91. package/dist/utils/vite-config.js +43 -5
  92. package/dist/utils/vite-config.js.map +1 -1
  93. package/dist/utils/worker-events.d.ts +5 -4
  94. package/dist/utils/worker-events.d.ts.map +1 -1
  95. package/dist/utils/worker-events.js +4 -0
  96. package/dist/utils/worker-events.js.map +1 -1
  97. package/dist/utils/worker-utils.d.ts +13 -0
  98. package/dist/utils/worker-utils.d.ts.map +1 -0
  99. package/dist/utils/worker-utils.js +15 -0
  100. package/dist/utils/worker-utils.js.map +6 -0
  101. package/dist/workers/client.worker.d.ts.map +1 -1
  102. package/dist/workers/client.worker.js +2 -14
  103. package/dist/workers/client.worker.js.map +1 -1
  104. package/dist/workers/library.worker.d.ts.map +1 -1
  105. package/dist/workers/library.worker.js +2 -14
  106. package/dist/workers/library.worker.js.map +1 -1
  107. package/dist/workers/server-runtime.worker.d.ts.map +1 -1
  108. package/dist/workers/server-runtime.worker.js +11 -11
  109. package/dist/workers/server-runtime.worker.js.map +1 -1
  110. package/dist/workers/server.worker.d.ts.map +1 -1
  111. package/dist/workers/server.worker.js +2 -14
  112. package/dist/workers/server.worker.js.map +1 -1
  113. package/package.json +4 -5
  114. package/src/builders/BaseBuilder.ts +71 -4
  115. package/src/builders/DtsBuilder.ts +2 -49
  116. package/src/builders/LibraryBuilder.ts +2 -51
  117. package/src/builders/types.ts +2 -2
  118. package/src/capacitor/capacitor.ts +2 -1
  119. package/src/commands/add-client.ts +1 -14
  120. package/src/commands/add-server.ts +1 -13
  121. package/src/commands/build.ts +13 -443
  122. package/src/commands/dev.ts +12 -582
  123. package/src/commands/device.ts +17 -34
  124. package/src/commands/init.ts +1 -13
  125. package/src/commands/lint.ts +85 -146
  126. package/src/commands/publish.ts +58 -76
  127. package/src/commands/typecheck.ts +13 -46
  128. package/src/index.ts +1 -0
  129. package/src/infra/ResultCollector.ts +2 -2
  130. package/src/orchestrators/BuildOrchestrator.ts +499 -0
  131. package/src/orchestrators/DevOrchestrator.ts +703 -0
  132. package/src/orchestrators/WatchOrchestrator.ts +42 -25
  133. package/src/orchestrators/index.ts +2 -0
  134. package/src/sd-cli-entry.ts +14 -14
  135. package/src/sd-cli.ts +6 -4
  136. package/src/utils/output-utils.ts +1 -2
  137. package/src/utils/package-utils.ts +16 -1
  138. package/src/utils/rebuild-manager.ts +65 -0
  139. package/src/utils/replace-deps.ts +26 -25
  140. package/src/utils/vite-config.ts +84 -6
  141. package/src/utils/worker-events.ts +13 -5
  142. package/src/utils/worker-utils.ts +26 -0
  143. package/src/workers/client.worker.ts +3 -19
  144. package/src/workers/library.worker.ts +2 -19
  145. package/src/workers/server-runtime.worker.ts +16 -17
  146. package/src/workers/server.worker.ts +2 -19
  147. package/templates/add-client/__CLIENT__/package.json.hbs +1 -1
  148. package/templates/add-server/__SERVER__/package.json.hbs +2 -2
  149. package/templates/init/package.json.hbs +3 -3
  150. package/dist/utils/listr-manager.d.ts +0 -37
  151. package/dist/utils/listr-manager.d.ts.map +0 -1
  152. package/dist/utils/listr-manager.js +0 -59
  153. package/dist/utils/listr-manager.js.map +0 -6
  154. package/src/utils/listr-manager.ts +0 -89
@@ -6,6 +6,7 @@ import { consola } from "consola";
6
6
  import type { SdClientPackageConfig } from "../sd-config.types";
7
7
  import { parseRootTsconfig, getCompilerOptionsForPackage } from "../utils/tsconfig";
8
8
  import { createViteConfig } from "../utils/vite-config";
9
+ import { registerCleanupHandlers } from "../utils/worker-utils";
9
10
 
10
11
  //#region Types
11
12
 
@@ -97,25 +98,7 @@ async function cleanup(): Promise<void> {
97
98
  // 프로세스 종료 전 리소스 정리 (SIGTERM/SIGINT)
98
99
  // 주의: worker.terminate()는 이 핸들러들을 호출하지 않고 즉시 종료됨.
99
100
  // 그러나 watch 모드에서 정상 종료는 메인 프로세스의 SIGINT/SIGTERM을 통해 이루어지므로 문제없음.
100
- process.on("SIGTERM", () => {
101
- cleanup()
102
- .catch((err) => {
103
- logger.error("cleanup 실패", err);
104
- })
105
- .finally(() => {
106
- process.exit(0);
107
- });
108
- });
109
-
110
- process.on("SIGINT", () => {
111
- cleanup()
112
- .catch((err) => {
113
- logger.error("cleanup 실패", err);
114
- })
115
- .finally(() => {
116
- process.exit(0);
117
- });
118
- });
101
+ registerCleanupHandlers(cleanup, logger);
119
102
 
120
103
  //#endregion
121
104
 
@@ -208,6 +191,7 @@ async function startWatch(info: ClientWatchInfo): Promise<void> {
208
191
  // 실제 할당된 포트 반환 (config.server.port는 설정값이므로 httpServer에서 실제 포트를 가져옴)
209
192
  const address = viteServer.httpServer?.address();
210
193
  const actualPort = typeof address === "object" && address != null ? address.port : viteServer.config.server.port;
194
+
211
195
  sender.send("serverReady", { port: actualPort });
212
196
  } catch (err) {
213
197
  sender.send("error", {
@@ -5,6 +5,7 @@ import { consola } from "consola";
5
5
  import type { SdBuildPackageConfig } from "../sd-config.types";
6
6
  import { parseRootTsconfig, getPackageSourceFiles, getCompilerOptionsForPackage } from "../utils/tsconfig";
7
7
  import { createLibraryEsbuildOptions, getTypecheckEnvFromTarget } from "../utils/esbuild-config";
8
+ import { registerCleanupHandlers } from "../utils/worker-utils";
8
9
 
9
10
  //#region Types
10
11
 
@@ -90,25 +91,7 @@ async function cleanup(): Promise<void> {
90
91
  // 프로세스 종료 전 리소스 정리 (SIGTERM/SIGINT)
91
92
  // 주의: worker.terminate()는 이 핸들러들을 호출하지 않고 즉시 종료됨.
92
93
  // 그러나 watch 모드에서 정상 종료는 메인 프로세스의 SIGINT/SIGTERM을 통해 이루어지므로 문제없음.
93
- process.on("SIGTERM", () => {
94
- cleanup()
95
- .catch((err) => {
96
- logger.error("cleanup 실패", err);
97
- })
98
- .finally(() => {
99
- process.exit(0);
100
- });
101
- });
102
-
103
- process.on("SIGINT", () => {
104
- cleanup()
105
- .catch((err) => {
106
- logger.error("cleanup 실패", err);
107
- })
108
- .finally(() => {
109
- process.exit(0);
110
- });
111
- });
94
+ registerCleanupHandlers(cleanup, logger);
112
95
 
113
96
  //#endregion
114
97
 
@@ -2,6 +2,7 @@ import proxy from "@fastify/http-proxy";
2
2
  import { createWorker } from "@simplysm/core-node";
3
3
  import { consola } from "consola";
4
4
  import net from "net";
5
+ import { registerCleanupHandlers } from "../utils/worker-utils";
5
6
 
6
7
  //#region Types
7
8
 
@@ -53,26 +54,24 @@ async function cleanup(): Promise<void> {
53
54
  serverInstance = undefined;
54
55
  }
55
56
 
56
- process.on("SIGTERM", () => {
57
- cleanup()
58
- .catch((err) => {
59
- logger.error("cleanup 실패", err);
60
- })
61
- .finally(() => {
62
- process.exit(0);
63
- });
57
+ // 서버 listen() 이후 발생하는 런타임 에러를 잡아서 custom "error" 이벤트로 전송
58
+ // (이 핸들러가 없으면 worker가 crash만 하고, dev.ts의 buildResolver가 호출되지 않아 listr가 멈춤)
59
+ process.on("uncaughtException", (err) => {
60
+ logger.error("Server Runtime 미처리 오류", err);
61
+ sender.send("error", {
62
+ message: err instanceof Error ? err.message : String(err),
63
+ });
64
64
  });
65
65
 
66
- process.on("SIGINT", () => {
67
- cleanup()
68
- .catch((err) => {
69
- logger.error("cleanup 실패", err);
70
- })
71
- .finally(() => {
72
- process.exit(0);
73
- });
66
+ process.on("unhandledRejection", (reason) => {
67
+ logger.error("Server Runtime 미처리 Promise 거부", reason);
68
+ sender.send("error", {
69
+ message: reason instanceof Error ? reason.message : String(reason),
70
+ });
74
71
  });
75
72
 
73
+ registerCleanupHandlers(cleanup, logger);
74
+
76
75
  /**
77
76
  * 포트가 사용 가능한지 확인
78
77
  */
@@ -97,7 +96,7 @@ async function findAvailablePort(startPort: number, maxRetries = 20): Promise<nu
97
96
  return port;
98
97
  }
99
98
  }
100
- return startPort;
99
+ throw new Error(`포트 ${startPort}부터 ${startPort + maxRetries - 1}까지 사용 가능한 포트가 없습니다.`);
101
100
  }
102
101
 
103
102
  /**
@@ -10,6 +10,7 @@ import {
10
10
  collectUninstalledOptionalPeerDeps,
11
11
  collectNativeModuleExternals,
12
12
  } from "../utils/esbuild-config";
13
+ import { registerCleanupHandlers } from "../utils/worker-utils";
13
14
 
14
15
  //#region Types
15
16
 
@@ -251,25 +252,7 @@ function generateProductionFiles(info: ServerBuildInfo, externals: string[]): vo
251
252
  // 프로세스 종료 전 리소스 정리 (SIGTERM/SIGINT)
252
253
  // 주의: worker.terminate()는 이 핸들러들을 호출하지 않고 즉시 종료됨.
253
254
  // 그러나 watch 모드에서 정상 종료는 메인 프로세스의 SIGINT/SIGTERM을 통해 이루어지므로 문제없음.
254
- process.on("SIGTERM", () => {
255
- cleanup()
256
- .catch((err) => {
257
- logger.error("cleanup 실패", err);
258
- })
259
- .finally(() => {
260
- process.exit(0);
261
- });
262
- });
263
-
264
- process.on("SIGINT", () => {
265
- cleanup()
266
- .catch((err) => {
267
- logger.error("cleanup 실패", err);
268
- })
269
- .finally(() => {
270
- process.exit(0);
271
- });
272
- });
255
+ registerCleanupHandlers(cleanup, logger);
273
256
 
274
257
  //#endregion
275
258
 
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
7
- "@simplysm/solid": "~13.0.10",
7
+ "@simplysm/solid": "~13.0.12",
8
8
  {{#if router}}
9
9
  "@solidjs/router": "^0.15.4",
10
10
  {{/if}}
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
7
- "@simplysm/core-common": "~13.0.10",
8
- "@simplysm/service-server": "~13.0.10"
7
+ "@simplysm/core-common": "~13.0.12",
8
+ "@simplysm/service-server": "~13.0.12"
9
9
  }
10
10
  }
@@ -15,9 +15,9 @@
15
15
  "vitest": "vitest"
16
16
  },
17
17
  "devDependencies": {
18
- "@simplysm/sd-cli": "~13.0.10",
19
- "@simplysm/claude": "~13.0.10",
20
- "@simplysm/lint": "~13.0.10",
18
+ "@simplysm/sd-cli": "~13.0.12",
19
+ "@simplysm/claude": "~13.0.12",
20
+ "@simplysm/lint": "~13.0.12",
21
21
  "@types/node": "^20.19.33",
22
22
  "eslint": "^9.39.2",
23
23
  "prettier": "^3.8.1",
@@ -1,37 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import type { consola } from "consola";
3
- /**
4
- * RebuildListrManager 이벤트 타입
5
- */
6
- interface RebuildListrManagerEvents {
7
- batchComplete: [];
8
- }
9
- /**
10
- * 리빌드 시 Listr 실행을 관리하는 클래스
11
- *
12
- * 여러 Worker가 동시에 buildStart를 발생시킬 때, 한 번에 하나의 Listr만 실행되도록 보장합니다.
13
- * 실행 중에 들어온 빌드 요청은 pending에 모아두었다가 현재 배치가 완료되면 다음 배치로 실행합니다.
14
- *
15
- * EventEmitter를 확장하여 배치 완료 시 `batchComplete` 이벤트를 발생시킵니다.
16
- */
17
- export declare class RebuildListrManager extends EventEmitter<RebuildListrManagerEvents> {
18
- private readonly _logger;
19
- private _isRunning;
20
- private readonly _pendingBuilds;
21
- constructor(_logger: ReturnType<typeof consola.withTag>);
22
- /**
23
- * 빌드를 등록하고 resolver 함수를 반환합니다.
24
- *
25
- * @param key - 빌드를 식별하는 고유 키 (예: "core-common:build")
26
- * @param title - Listr에 표시할 제목 (예: "core-common (node)")
27
- * @returns 워커가 빌드 완료 시 호출할 resolver 함수
28
- */
29
- registerBuild(key: string, title: string): () => void;
30
- /**
31
- * pending에 있는 빌드들을 모아서 하나의 Listr로 실행합니다.
32
- * 실행 중에 들어온 새 빌드는 다음 배치로 넘어갑니다.
33
- */
34
- private _runBatch;
35
- }
36
- export {};
37
- //# sourceMappingURL=listr-manager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"listr-manager.d.ts","sourceRoot":"","sources":["../../src/utils/listr-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC;;GAEG;AACH,UAAU,yBAAyB;IACjC,aAAa,EAAE,EAAE,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,mBAAoB,SAAQ,YAAY,CAAC,yBAAyB,CAAC;IAIlE,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsF;gBAExF,OAAO,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,OAAO,CAAC;IAIxE;;;;;;OAMG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,IAAI;IAgBrD;;;OAGG;YACW,SAAS;CAkCxB"}
@@ -1,59 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import { Listr } from "listr2";
3
- class RebuildListrManager extends EventEmitter {
4
- constructor(_logger) {
5
- super();
6
- this._logger = _logger;
7
- }
8
- _isRunning = false;
9
- _pendingBuilds = /* @__PURE__ */ new Map();
10
- /**
11
- * 빌드를 등록하고 resolver 함수를 반환합니다.
12
- *
13
- * @param key - 빌드를 식별하는 고유 키 (예: "core-common:build")
14
- * @param title - Listr에 표시할 제목 (예: "core-common (node)")
15
- * @returns 워커가 빌드 완료 시 호출할 resolver 함수
16
- */
17
- registerBuild(key, title) {
18
- let resolver;
19
- const promise = new Promise((resolve) => {
20
- resolver = resolve;
21
- });
22
- this._pendingBuilds.set(key, { title, promise, resolver });
23
- if (!this._isRunning) {
24
- void Promise.resolve().then(() => void this._runBatch());
25
- }
26
- return resolver;
27
- }
28
- /**
29
- * pending에 있는 빌드들을 모아서 하나의 Listr로 실행합니다.
30
- * 실행 중에 들어온 새 빌드는 다음 배치로 넘어갑니다.
31
- */
32
- async _runBatch() {
33
- if (this._isRunning || this._pendingBuilds.size === 0) {
34
- return;
35
- }
36
- this._isRunning = true;
37
- const batchBuilds = new Map(this._pendingBuilds);
38
- this._pendingBuilds.clear();
39
- const tasks = Array.from(batchBuilds.entries()).map(([, { title, promise }]) => ({
40
- title,
41
- task: () => promise
42
- }));
43
- const listr = new Listr(tasks, { concurrent: true });
44
- try {
45
- await listr.run();
46
- this.emit("batchComplete");
47
- } catch (err) {
48
- this._logger.error("listr \uC2E4\uD589 \uC911 \uC624\uB958 \uBC1C\uC0DD", { error: String(err) });
49
- }
50
- this._isRunning = false;
51
- if (this._pendingBuilds.size > 0) {
52
- void this._runBatch();
53
- }
54
- }
55
- }
56
- export {
57
- RebuildListrManager
58
- };
59
- //# sourceMappingURL=listr-manager.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/utils/listr-manager.ts"],
4
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,aAAa;AAkBf,MAAM,4BAA4B,aAAwC;AAAA,EAI/E,YAA6B,SAA6C;AACxE,UAAM;AADqB;AAAA,EAE7B;AAAA,EALQ,aAAa;AAAA,EACJ,iBAAiB,oBAAI,IAA6E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAanH,cAAc,KAAa,OAA2B;AACpD,QAAI;AACJ,UAAM,UAAU,IAAI,QAAc,CAAC,YAAY;AAC7C,iBAAW;AAAA,IACb,CAAC;AAED,SAAK,eAAe,IAAI,KAAK,EAAE,OAAO,SAAS,SAAS,CAAC;AAGzD,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,QAAQ,QAAQ,EAAE,KAAK,MAAM,KAAK,KAAK,UAAU,CAAC;AAAA,IACzD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAA2B;AACvC,QAAI,KAAK,cAAc,KAAK,eAAe,SAAS,GAAG;AACrD;AAAA,IACF;AAEA,SAAK,aAAa;AAGlB,UAAM,cAAc,IAAI,IAAI,KAAK,cAAc;AAC/C,SAAK,eAAe,MAAM;AAG1B,UAAM,QAAQ,MAAM,KAAK,YAAY,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,OAAO,QAAQ,CAAC,OAAO;AAAA,MAC/E;AAAA,MACA,MAAM,MAAM;AAAA,IACd,EAAE;AAEF,UAAM,QAAQ,IAAI,MAAM,OAAO,EAAE,YAAY,KAAK,CAAC;AAEnD,QAAI;AACF,YAAM,MAAM,IAAI;AAEhB,WAAK,KAAK,eAAe;AAAA,IAC3B,SAAS,KAAK;AACZ,WAAK,QAAQ,MAAM,uDAAoB,EAAE,OAAO,OAAO,GAAG,EAAE,CAAC;AAAA,IAC/D;AAEA,SAAK,aAAa;AAGlB,QAAI,KAAK,eAAe,OAAO,GAAG;AAChC,WAAK,KAAK,UAAU;AAAA,IACtB;AAAA,EACF;AACF;",
5
- "names": []
6
- }
@@ -1,89 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import { Listr } from "listr2";
3
- import type { consola } from "consola";
4
-
5
- /**
6
- * RebuildListrManager 이벤트 타입
7
- */
8
- interface RebuildListrManagerEvents {
9
- batchComplete: [];
10
- }
11
-
12
- /**
13
- * 리빌드 시 Listr 실행을 관리하는 클래스
14
- *
15
- * 여러 Worker가 동시에 buildStart를 발생시킬 때, 한 번에 하나의 Listr만 실행되도록 보장합니다.
16
- * 실행 중에 들어온 빌드 요청은 pending에 모아두었다가 현재 배치가 완료되면 다음 배치로 실행합니다.
17
- *
18
- * EventEmitter를 확장하여 배치 완료 시 `batchComplete` 이벤트를 발생시킵니다.
19
- */
20
- export class RebuildListrManager extends EventEmitter<RebuildListrManagerEvents> {
21
- private _isRunning = false;
22
- private readonly _pendingBuilds = new Map<string, { title: string; promise: Promise<void>; resolver: () => void }>();
23
-
24
- constructor(private readonly _logger: ReturnType<typeof consola.withTag>) {
25
- super();
26
- }
27
-
28
- /**
29
- * 빌드를 등록하고 resolver 함수를 반환합니다.
30
- *
31
- * @param key - 빌드를 식별하는 고유 키 (예: "core-common:build")
32
- * @param title - Listr에 표시할 제목 (예: "core-common (node)")
33
- * @returns 워커가 빌드 완료 시 호출할 resolver 함수
34
- */
35
- registerBuild(key: string, title: string): () => void {
36
- let resolver!: () => void;
37
- const promise = new Promise<void>((resolve) => {
38
- resolver = resolve;
39
- });
40
-
41
- this._pendingBuilds.set(key, { title, promise, resolver });
42
-
43
- // Listr가 실행 중이 아니면 다음 tick에 배치 실행
44
- if (!this._isRunning) {
45
- void Promise.resolve().then(() => void this._runBatch());
46
- }
47
-
48
- return resolver;
49
- }
50
-
51
- /**
52
- * pending에 있는 빌드들을 모아서 하나의 Listr로 실행합니다.
53
- * 실행 중에 들어온 새 빌드는 다음 배치로 넘어갑니다.
54
- */
55
- private async _runBatch(): Promise<void> {
56
- if (this._isRunning || this._pendingBuilds.size === 0) {
57
- return;
58
- }
59
-
60
- this._isRunning = true;
61
-
62
- // 현재 pending을 스냅샷으로 가져옴
63
- const batchBuilds = new Map(this._pendingBuilds);
64
- this._pendingBuilds.clear();
65
-
66
- // Listr 태스크 생성
67
- const tasks = Array.from(batchBuilds.entries()).map(([, { title, promise }]) => ({
68
- title,
69
- task: () => promise,
70
- }));
71
-
72
- const listr = new Listr(tasks, { concurrent: true });
73
-
74
- try {
75
- await listr.run();
76
- // 배치 완료 이벤트 발생
77
- this.emit("batchComplete");
78
- } catch (err) {
79
- this._logger.error("listr 실행 중 오류 발생", { error: String(err) });
80
- }
81
-
82
- this._isRunning = false;
83
-
84
- // 실행 중 새로 들어온 pending이 있으면 다음 배치 실행
85
- if (this._pendingBuilds.size > 0) {
86
- void this._runBatch();
87
- }
88
- }
89
- }