@simplysm/sd-cli 13.0.66 → 13.0.68

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 (133) hide show
  1. package/dist/builders/BaseBuilder.d.ts.map +1 -1
  2. package/dist/builders/BaseBuilder.js +2 -7
  3. package/dist/builders/BaseBuilder.js.map +1 -1
  4. package/dist/builders/DtsBuilder.d.ts.map +1 -1
  5. package/dist/builders/DtsBuilder.js +4 -3
  6. package/dist/builders/DtsBuilder.js.map +1 -1
  7. package/dist/builders/LibraryBuilder.d.ts.map +1 -1
  8. package/dist/builders/LibraryBuilder.js +2 -1
  9. package/dist/builders/LibraryBuilder.js.map +1 -1
  10. package/dist/capacitor/capacitor.js +2 -2
  11. package/dist/capacitor/capacitor.js.map +1 -1
  12. package/dist/commands/add-client.js +2 -2
  13. package/dist/commands/add-server.js +2 -2
  14. package/dist/commands/build.d.ts +2 -10
  15. package/dist/commands/build.d.ts.map +1 -1
  16. package/dist/commands/build.js +1 -5
  17. package/dist/commands/build.js.map +1 -1
  18. package/dist/commands/check.d.ts.map +1 -1
  19. package/dist/commands/check.js +26 -37
  20. package/dist/commands/check.js.map +1 -1
  21. package/dist/commands/dev.d.ts +2 -9
  22. package/dist/commands/dev.d.ts.map +1 -1
  23. package/dist/commands/dev.js +1 -5
  24. package/dist/commands/dev.js.map +1 -1
  25. package/dist/commands/init.js +5 -5
  26. package/dist/commands/publish.js +16 -16
  27. package/dist/commands/publish.js.map +1 -1
  28. package/dist/commands/typecheck.d.ts +0 -1
  29. package/dist/commands/typecheck.d.ts.map +1 -1
  30. package/dist/commands/typecheck.js +5 -5
  31. package/dist/commands/typecheck.js.map +1 -1
  32. package/dist/commands/watch.d.ts +2 -8
  33. package/dist/commands/watch.d.ts.map +1 -1
  34. package/dist/commands/watch.js +1 -5
  35. package/dist/commands/watch.js.map +1 -1
  36. package/dist/electron/electron.js +2 -2
  37. package/dist/electron/electron.js.map +1 -1
  38. package/dist/infra/ResultCollector.d.ts +0 -21
  39. package/dist/infra/ResultCollector.d.ts.map +1 -1
  40. package/dist/infra/ResultCollector.js +0 -31
  41. package/dist/infra/ResultCollector.js.map +1 -1
  42. package/dist/orchestrators/BuildOrchestrator.d.ts +0 -1
  43. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  44. package/dist/orchestrators/BuildOrchestrator.js +10 -19
  45. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  46. package/dist/orchestrators/DevOrchestrator.d.ts +12 -0
  47. package/dist/orchestrators/DevOrchestrator.d.ts.map +1 -1
  48. package/dist/orchestrators/DevOrchestrator.js +178 -167
  49. package/dist/orchestrators/DevOrchestrator.js.map +1 -1
  50. package/dist/sd-cli-entry.js +14 -14
  51. package/dist/sd-cli-entry.js.map +1 -1
  52. package/dist/sd-cli.js +8 -13
  53. package/dist/sd-cli.js.map +1 -1
  54. package/dist/utils/output-utils.d.ts +4 -7
  55. package/dist/utils/output-utils.d.ts.map +1 -1
  56. package/dist/utils/output-utils.js +13 -5
  57. package/dist/utils/output-utils.js.map +1 -1
  58. package/dist/utils/package-utils.d.ts +0 -11
  59. package/dist/utils/package-utils.d.ts.map +1 -1
  60. package/dist/utils/package-utils.js.map +1 -1
  61. package/dist/utils/replace-deps.d.ts.map +1 -1
  62. package/dist/utils/replace-deps.js +21 -48
  63. package/dist/utils/replace-deps.js.map +1 -1
  64. package/dist/utils/sd-config.d.ts +2 -6
  65. package/dist/utils/sd-config.d.ts.map +1 -1
  66. package/dist/utils/sd-config.js.map +1 -1
  67. package/dist/utils/vite-config.d.ts.map +1 -1
  68. package/dist/utils/vite-config.js +7 -1
  69. package/dist/utils/vite-config.js.map +1 -1
  70. package/dist/utils/worker-events.d.ts +5 -5
  71. package/dist/utils/worker-events.d.ts.map +1 -1
  72. package/dist/utils/worker-events.js +14 -17
  73. package/dist/utils/worker-events.js.map +1 -1
  74. package/dist/utils/worker-utils.d.ts +7 -0
  75. package/dist/utils/worker-utils.d.ts.map +1 -1
  76. package/dist/utils/worker-utils.js +10 -0
  77. package/dist/utils/worker-utils.js.map +1 -1
  78. package/dist/workers/client.worker.d.ts.map +1 -1
  79. package/dist/workers/client.worker.js +11 -9
  80. package/dist/workers/client.worker.js.map +1 -1
  81. package/dist/workers/dts.worker.d.ts +4 -4
  82. package/dist/workers/dts.worker.d.ts.map +1 -1
  83. package/dist/workers/dts.worker.js +10 -11
  84. package/dist/workers/dts.worker.js.map +1 -1
  85. package/dist/workers/library.worker.d.ts.map +1 -1
  86. package/dist/workers/library.worker.js +7 -9
  87. package/dist/workers/library.worker.js.map +1 -1
  88. package/dist/workers/server-runtime.worker.d.ts.map +1 -1
  89. package/dist/workers/server-runtime.worker.js +4 -3
  90. package/dist/workers/server-runtime.worker.js.map +1 -1
  91. package/dist/workers/server.worker.d.ts.map +1 -1
  92. package/dist/workers/server.worker.js +10 -13
  93. package/dist/workers/server.worker.js.map +1 -1
  94. package/package.json +5 -4
  95. package/src/builders/BaseBuilder.ts +2 -7
  96. package/src/builders/DtsBuilder.ts +4 -3
  97. package/src/builders/LibraryBuilder.ts +2 -1
  98. package/src/capacitor/capacitor.ts +2 -2
  99. package/src/commands/add-client.ts +2 -2
  100. package/src/commands/add-server.ts +2 -2
  101. package/src/commands/build.ts +2 -17
  102. package/src/commands/check.ts +31 -44
  103. package/src/commands/dev.ts +2 -16
  104. package/src/commands/init.ts +5 -5
  105. package/src/commands/publish.ts +16 -16
  106. package/src/commands/typecheck.ts +5 -5
  107. package/src/commands/watch.ts +2 -15
  108. package/src/electron/electron.ts +2 -2
  109. package/src/infra/ResultCollector.ts +0 -36
  110. package/src/orchestrators/BuildOrchestrator.ts +12 -21
  111. package/src/orchestrators/DevOrchestrator.ts +221 -201
  112. package/src/sd-cli-entry.ts +14 -14
  113. package/src/sd-cli.ts +9 -14
  114. package/src/utils/output-utils.ts +15 -11
  115. package/src/utils/package-utils.ts +0 -12
  116. package/src/utils/replace-deps.ts +61 -88
  117. package/src/utils/sd-config.ts +2 -6
  118. package/src/utils/vite-config.ts +9 -1
  119. package/src/utils/worker-events.ts +22 -25
  120. package/src/utils/worker-utils.ts +16 -0
  121. package/src/workers/client.worker.ts +12 -11
  122. package/src/workers/dts.worker.ts +13 -15
  123. package/src/workers/library.worker.ts +7 -10
  124. package/src/workers/server-runtime.worker.ts +4 -3
  125. package/src/workers/server.worker.ts +10 -14
  126. package/templates/add-client/__CLIENT__/package.json.hbs +1 -1
  127. package/templates/add-server/__SERVER__/package.json.hbs +2 -2
  128. package/templates/init/package.json.hbs +3 -3
  129. package/dist/utils/spawn.d.ts +0 -26
  130. package/dist/utils/spawn.d.ts.map +0 -1
  131. package/dist/utils/spawn.js +0 -50
  132. package/dist/utils/spawn.js.map +0 -6
  133. package/src/utils/spawn.ts +0 -80
@@ -1,5 +1,6 @@
1
1
  import path from "path";
2
2
  import { Worker, type WorkerProxy } from "@simplysm/core-node";
3
+ import { errorMessage } from "@simplysm/core-common";
3
4
  import type { SdConfig, SdClientPackageConfig, SdServerPackageConfig } from "../sd-config.types";
4
5
  import { consola } from "consola";
5
6
  import { loadSdConfig } from "../utils/sd-config";
@@ -9,8 +10,9 @@ import type * as ClientWorkerModule from "../workers/client.worker";
9
10
  import type * as ServerWorkerModule from "../workers/server.worker";
10
11
  import type * as ServerRuntimeWorkerModule from "../workers/server-runtime.worker";
11
12
  import { Capacitor } from "../capacitor/capacitor";
12
- import { filterPackagesByTargets, type PackageResult } from "../utils/package-utils";
13
- import { printErrors, printServers } from "../utils/output-utils";
13
+ import { filterPackagesByTargets } from "../utils/package-utils";
14
+ import type { BuildResult } from "../infra/ResultCollector";
15
+ import { formatBuildMessages, printErrors, printServers } from "../utils/output-utils";
14
16
  import { RebuildManager } from "../utils/rebuild-manager";
15
17
  import {
16
18
  registerWorkerEventHandlers,
@@ -89,7 +91,7 @@ export class DevOrchestrator {
89
91
  >();
90
92
 
91
93
  // State
92
- private readonly _results = new Map<string, PackageResult>();
94
+ private readonly _results = new Map<string, BuildResult>();
93
95
  private _clientPorts: Record<string, number> = {};
94
96
  private _rebuildManager!: RebuildManager;
95
97
  private _signalHandler!: SignalHandler;
@@ -233,69 +235,93 @@ export class DevOrchestrator {
233
235
  buildResolver: undefined,
234
236
  }));
235
237
 
236
- // Standalone client 빌드 Promise 미리 생성
237
- const standaloneClientBuildPromises = new Map<string, Promise<void>>();
238
- for (const workerInfo of this._standaloneClientWorkers) {
239
- standaloneClientBuildPromises.set(
240
- workerInfo.name,
241
- new Promise<void>((resolve) => {
242
- workerInfo.buildResolver = resolve;
243
- }),
244
- );
238
+ // 섹션별 setup 워커 시작
239
+ const standaloneClientPromises = this._setupStandaloneClients();
240
+ const { buildPromises: viteClientPromises, readyPromises: viteClientReadyPromises } =
241
+ this._setupViteClients();
242
+ const serverPromises = this._setupServers(
243
+ serverWorkerPath,
244
+ serverRuntimeWorkerPath,
245
+ viteClientReadyPromises,
246
+ );
247
+
248
+ // 초기 빌드 완료까지 대기 (병렬 실행)
249
+ this._logger.debug("초기 빌드 시작 (Promise.allSettled)");
250
+ const initialBuildPromises: Array<{ name: string; promise: Promise<void> }> = [
251
+ ...standaloneClientPromises,
252
+ ...viteClientPromises,
253
+ ...serverPromises,
254
+ ];
255
+
256
+ const initialResults = await Promise.allSettled(
257
+ initialBuildPromises.map((item) => item.promise),
258
+ );
259
+
260
+ initialResults.forEach((result, index) => {
261
+ const taskName = initialBuildPromises[index].name;
262
+ if (result.status === "rejected") {
263
+ this._logger.debug(`[${taskName}] 초기 빌드 실패:`, result.reason);
264
+ } else {
265
+ this._logger.debug(`[${taskName}] 초기 빌드 완료`);
266
+ }
267
+ });
268
+
269
+ // Capacitor 초기화 (client 타겟 중 capacitor 설정이 있는 패키지)
270
+ const capacitorPackages: Array<[string, SdClientPackageConfig]> = [];
271
+ for (const { name, config } of this._clientPackages) {
272
+ if (config.capacitor != null) {
273
+ capacitorPackages.push([name, config]);
274
+ }
245
275
  }
246
276
 
247
- // Vite client 빌드 Promise 미리 생성 (서버 연결 클라이언트)
248
- const viteClientBuildPromises = new Map<string, Promise<void>>();
249
- const viteClientReadyPromises = new Map<
250
- string,
251
- { promise: Promise<void>; resolver: () => void }
252
- >();
253
- for (const workerInfo of this._viteClientWorkers) {
254
- viteClientBuildPromises.set(
277
+ if (capacitorPackages.length > 0) {
278
+ for (const [name, config] of capacitorPackages) {
279
+ const taskName = `${name} (capacitor)`;
280
+ this._logger.start(taskName);
281
+ const pkgDir = path.join(this._cwd, "packages", name);
282
+ try {
283
+ const cap = await Capacitor.create(pkgDir, config.capacitor!);
284
+ await cap.initialize();
285
+ this._results.set(`${name}:capacitor`, {
286
+ name,
287
+ target: "client",
288
+ type: "capacitor",
289
+ status: "success",
290
+ });
291
+ this._logger.success(taskName);
292
+ } catch (err) {
293
+ this._results.set(`${name}:capacitor`, {
294
+ name,
295
+ target: "client",
296
+ type: "capacitor",
297
+ status: "error",
298
+ message: errorMessage(err),
299
+ });
300
+ this._logger.fail(taskName);
301
+ }
302
+ }
303
+ }
304
+
305
+ // 초기 빌드 결과 출력
306
+ printErrors(this._results);
307
+ printServers(this._results, this._serverClientsMap);
308
+ }
309
+
310
+ /**
311
+ * Standalone client Worker 설정 및 시작
312
+ */
313
+ private _setupStandaloneClients(): Array<{ name: string; promise: Promise<void> }> {
314
+ const buildPromises = new Map<string, Promise<void>>();
315
+ for (const workerInfo of this._standaloneClientWorkers) {
316
+ buildPromises.set(
255
317
  workerInfo.name,
256
318
  new Promise<void>((resolve) => {
257
319
  workerInfo.buildResolver = resolve;
258
320
  }),
259
321
  );
260
- // Vite 서버 준비 완료 Promise (서버가 클라이언트 포트를 알 때까지 대기)
261
- let readyResolver!: () => void;
262
- const readyPromise = new Promise<void>((resolve) => {
263
- readyResolver = resolve;
264
- });
265
- viteClientReadyPromises.set(workerInfo.name, {
266
- promise: readyPromise,
267
- resolver: readyResolver,
268
- });
269
322
  }
270
323
 
271
- // Server Build Worker 및 Promise 생성
272
- for (const { name } of this._serverPackages) {
273
- let resolver!: () => void;
274
- const promise = new Promise<void>((resolve) => {
275
- resolver = resolve;
276
- });
277
- this._serverBuildWorkers.set(name, {
278
- worker: Worker.create<typeof ServerWorkerModule>(serverWorkerPath),
279
- buildPromise: promise,
280
- buildResolver: resolver,
281
- });
282
- }
283
-
284
- // Server Runtime Promise (초기 서버 시작 완료 대기용)
285
- const serverRuntimePromises = new Map<
286
- string,
287
- { promise: Promise<void>; resolver: () => void }
288
- >();
289
- for (const { name } of this._serverPackages) {
290
- let resolver!: () => void;
291
- const promise = new Promise<void>((resolve) => {
292
- resolver = resolve;
293
- });
294
- serverRuntimePromises.set(name, { promise, resolver });
295
- }
296
-
297
- // Standalone client 이벤트 핸들러 등록 및 completeTask 함수 저장
298
- const clientCompleteTasks = new Map<string, (result: PackageResult) => void>();
324
+ // 이벤트 핸들러 등록
299
325
  for (const workerInfo of this._standaloneClientWorkers) {
300
326
  const completeTask = registerWorkerEventHandlers(
301
327
  workerInfo as unknown as BaseWorkerInfo,
@@ -307,7 +333,6 @@ export class DevOrchestrator {
307
333
  this._results,
308
334
  this._rebuildManager,
309
335
  );
310
- clientCompleteTasks.set(workerInfo.name, completeTask);
311
336
 
312
337
  // serverReady (Vite dev server)
313
338
  workerInfo.worker.on("serverReady", (data) => {
@@ -325,9 +350,66 @@ export class DevOrchestrator {
325
350
  workerInfo.worker.on("scopeRebuild", () => {
326
351
  this._schedulePrintServers();
327
352
  });
353
+
354
+ // 워커 시작
355
+ const pkgDir = path.join(this._cwd, "packages", workerInfo.name);
356
+ const clientConfig: SdClientPackageConfig = {
357
+ ...workerInfo.config,
358
+ env: { ...this._baseEnv, ...workerInfo.config.env },
359
+ };
360
+ workerInfo.worker
361
+ .startWatch({
362
+ name: workerInfo.name,
363
+ config: clientConfig,
364
+ cwd: this._cwd,
365
+ pkgDir,
366
+ replaceDeps: this._sdConfig!.replaceDeps,
367
+ })
368
+ .catch((err: unknown) => {
369
+ completeTask({
370
+ name: workerInfo.name,
371
+ target: workerInfo.config.target,
372
+ type: "build",
373
+ status: "error",
374
+ message: errorMessage(err),
375
+ });
376
+ });
328
377
  }
329
378
 
330
- // Vite client (서버 연결) 이벤트 핸들러 등록
379
+ return this._standaloneClientWorkers.map((workerInfo) => ({
380
+ name: `${workerInfo.name} (client)`,
381
+ promise: buildPromises.get(workerInfo.name) ?? Promise.resolve(),
382
+ }));
383
+ }
384
+
385
+ /**
386
+ * Vite client (서버 연결) Worker 설정 및 시작
387
+ */
388
+ private _setupViteClients(): {
389
+ buildPromises: Array<{ name: string; promise: Promise<void> }>;
390
+ readyPromises: Map<string, { promise: Promise<void>; resolver: () => void }>;
391
+ } {
392
+ const buildPromiseMap = new Map<string, Promise<void>>();
393
+ const readyPromises = new Map<string, { promise: Promise<void>; resolver: () => void }>();
394
+ for (const workerInfo of this._viteClientWorkers) {
395
+ buildPromiseMap.set(
396
+ workerInfo.name,
397
+ new Promise<void>((resolve) => {
398
+ workerInfo.buildResolver = resolve;
399
+ }),
400
+ );
401
+ // Vite 서버 준비 완료 Promise (서버가 클라이언트 포트를 알 때까지 대기)
402
+ let readyResolver!: () => void;
403
+ const readyPromise = new Promise<void>((resolve) => {
404
+ readyResolver = resolve;
405
+ });
406
+ readyPromises.set(workerInfo.name, {
407
+ promise: readyPromise,
408
+ resolver: readyResolver,
409
+ });
410
+ }
411
+
412
+ // 이벤트 핸들러 등록
331
413
  for (const workerInfo of this._viteClientWorkers) {
332
414
  const completeTask = registerWorkerEventHandlers(
333
415
  workerInfo as unknown as BaseWorkerInfo,
@@ -339,7 +421,6 @@ export class DevOrchestrator {
339
421
  this._results,
340
422
  this._rebuildManager,
341
423
  );
342
- clientCompleteTasks.set(workerInfo.name, completeTask);
343
424
 
344
425
  // serverReady - Vite 포트를 clientPorts에 저장 (URL은 서버를 통해 출력)
345
426
  workerInfo.worker.on("serverReady", (data) => {
@@ -347,7 +428,7 @@ export class DevOrchestrator {
347
428
  this._logger.debug(`[${workerInfo.name}] Vite serverReady (port: ${String(event.port)})`);
348
429
  this._clientPorts[workerInfo.name] = event.port;
349
430
  // Vite 서버 준비 완료 알림 (서버가 프록시 설정을 위해 대기 중)
350
- viteClientReadyPromises.get(workerInfo.name)?.resolver();
431
+ readyPromises.get(workerInfo.name)?.resolver();
351
432
  // 빌드 완료를 위해 completeTask 호출 (Vite는 build 이벤트를 발생시키지 않음)
352
433
  completeTask({
353
434
  name: workerInfo.name,
@@ -357,16 +438,85 @@ export class DevOrchestrator {
357
438
  });
358
439
  });
359
440
 
360
- // Vite client error 시에도 viteClientReadyPromises resolve
441
+ // Vite client error 시에도 readyPromises resolve
361
442
  // (서버가 await Promise.all(clientReadyPromises)에서 무한 대기하지 않도록)
362
443
  workerInfo.worker.on("error", () => {
363
- viteClientReadyPromises.get(workerInfo.name)?.resolver();
444
+ readyPromises.get(workerInfo.name)?.resolver();
364
445
  });
365
446
 
366
447
  // scope 패키지 리빌드 감지 시 서버 URL 출력
367
448
  workerInfo.worker.on("scopeRebuild", () => {
368
449
  this._schedulePrintServers();
369
450
  });
451
+
452
+ // 워커 시작
453
+ const pkgDir = path.join(this._cwd, "packages", workerInfo.name);
454
+ // Vite가 자동으로 포트를 할당하도록 설정
455
+ const viteConfig: SdClientPackageConfig = {
456
+ ...workerInfo.config,
457
+ server: 0, // Vite가 자동으로 포트 할당
458
+ env: { ...this._baseEnv, ...workerInfo.config.env },
459
+ };
460
+ workerInfo.worker
461
+ .startWatch({
462
+ name: workerInfo.name,
463
+ config: viteConfig,
464
+ cwd: this._cwd,
465
+ pkgDir,
466
+ replaceDeps: this._sdConfig!.replaceDeps,
467
+ })
468
+ .catch((err: unknown) => {
469
+ completeTask({
470
+ name: workerInfo.name,
471
+ target: workerInfo.config.target,
472
+ type: "build",
473
+ status: "error",
474
+ message: errorMessage(err),
475
+ });
476
+ });
477
+ }
478
+
479
+ return {
480
+ buildPromises: this._viteClientWorkers.map((workerInfo) => ({
481
+ name: `${workerInfo.name} (client)`,
482
+ promise: buildPromiseMap.get(workerInfo.name) ?? Promise.resolve(),
483
+ })),
484
+ readyPromises,
485
+ };
486
+ }
487
+
488
+ /**
489
+ * Server Build/Runtime Worker 설정 및 시작
490
+ */
491
+ private _setupServers(
492
+ serverWorkerPath: string,
493
+ serverRuntimeWorkerPath: string,
494
+ viteClientReadyPromises: Map<string, { promise: Promise<void>; resolver: () => void }>,
495
+ ): Array<{ name: string; promise: Promise<void> }> {
496
+ // Server Build Worker 및 Promise 생성
497
+ for (const { name } of this._serverPackages) {
498
+ let resolver!: () => void;
499
+ const promise = new Promise<void>((resolve) => {
500
+ resolver = resolve;
501
+ });
502
+ this._serverBuildWorkers.set(name, {
503
+ worker: Worker.create<typeof ServerWorkerModule>(serverWorkerPath),
504
+ buildPromise: promise,
505
+ buildResolver: resolver,
506
+ });
507
+ }
508
+
509
+ // Server Runtime Promise (초기 서버 시작 완료 대기용)
510
+ const serverRuntimePromises = new Map<
511
+ string,
512
+ { promise: Promise<void>; resolver: () => void }
513
+ >();
514
+ for (const { name } of this._serverPackages) {
515
+ let resolver!: () => void;
516
+ const promise = new Promise<void>((resolve) => {
517
+ resolver = resolve;
518
+ });
519
+ serverRuntimePromises.set(name, { promise, resolver });
370
520
  }
371
521
 
372
522
  // Server Build Worker 이벤트 핸들러 등록
@@ -391,13 +541,7 @@ export class DevOrchestrator {
391
541
 
392
542
  // warnings 출력
393
543
  if (event.warnings != null && event.warnings.length > 0) {
394
- const warnLines: string[] = [`${name} (server)`];
395
- for (const warning of event.warnings) {
396
- for (const line of warning.split("\n")) {
397
- warnLines.push(` → ${line}`);
398
- }
399
- }
400
- this._logger.warn(warnLines.join("\n"));
544
+ this._logger.warn(formatBuildMessages(name, "server", event.warnings));
401
545
  }
402
546
 
403
547
  if (!event.success) {
@@ -419,7 +563,7 @@ export class DevOrchestrator {
419
563
 
420
564
  // 빌드 성공 시 런타임 워커 시작 (async 로직은 별도 함수로 분리하여 에러 전파 방지)
421
565
  void startServerRuntime(name, event.mainJsPath).catch((err: unknown) => {
422
- const message = err instanceof Error ? err.message : String(err);
566
+ const message = errorMessage(err);
423
567
  this._logger.error(`[${name}] Server Runtime 시작 중 오류:`, message);
424
568
 
425
569
  this._results.set(`${name}:server`, {
@@ -524,7 +668,7 @@ export class DevOrchestrator {
524
668
  clientPorts: serverClientPorts,
525
669
  })
526
670
  .catch((err: unknown) => {
527
- const message = err instanceof Error ? err.message : String(err);
671
+ const message = errorMessage(err);
528
672
  this._logger.error(`[${serverName}] Server Runtime Worker 크래시:`, message);
529
673
 
530
674
  this._results.set(`${serverName}:server`, {
@@ -560,62 +704,6 @@ export class DevOrchestrator {
560
704
  });
561
705
  }
562
706
 
563
- // Standalone client 워커 시작
564
- for (const workerInfo of this._standaloneClientWorkers) {
565
- const pkgDir = path.join(this._cwd, "packages", workerInfo.name);
566
- const completeTask = clientCompleteTasks.get(workerInfo.name)!;
567
- const clientConfig: SdClientPackageConfig = {
568
- ...workerInfo.config,
569
- env: { ...this._baseEnv, ...workerInfo.config.env },
570
- };
571
- workerInfo.worker
572
- .startWatch({
573
- name: workerInfo.name,
574
- config: clientConfig,
575
- cwd: this._cwd,
576
- pkgDir,
577
- replaceDeps: this._sdConfig!.replaceDeps,
578
- })
579
- .catch((err: unknown) => {
580
- completeTask({
581
- name: workerInfo.name,
582
- target: workerInfo.config.target,
583
- type: "build",
584
- status: "error",
585
- message: err instanceof Error ? err.message : String(err),
586
- });
587
- });
588
- }
589
-
590
- // Vite client 워커 시작 (서버 연결) - Vite 자동 포트 사용
591
- for (const workerInfo of this._viteClientWorkers) {
592
- const pkgDir = path.join(this._cwd, "packages", workerInfo.name);
593
- const completeTask = clientCompleteTasks.get(workerInfo.name)!;
594
- // Vite가 자동으로 포트를 할당하도록 설정
595
- const viteConfig: SdClientPackageConfig = {
596
- ...workerInfo.config,
597
- server: 0, // Vite가 자동으로 포트 할당
598
- env: { ...this._baseEnv, ...workerInfo.config.env },
599
- };
600
- workerInfo.worker
601
- .startWatch({
602
- name: workerInfo.name,
603
- config: viteConfig,
604
- cwd: this._cwd,
605
- pkgDir,
606
- replaceDeps: this._sdConfig!.replaceDeps,
607
- })
608
- .catch((err: unknown) => {
609
- completeTask({
610
- name: workerInfo.name,
611
- target: workerInfo.config.target,
612
- type: "build",
613
- status: "error",
614
- message: err instanceof Error ? err.message : String(err),
615
- });
616
- });
617
- }
618
-
619
707
  // Server Build 워커 시작
620
708
  for (const { name, config } of this._serverPackages) {
621
709
  const pkgDir = path.join(this._cwd, "packages", name);
@@ -636,85 +724,17 @@ export class DevOrchestrator {
636
724
  target: "server",
637
725
  type: "build",
638
726
  status: "error",
639
- message: err instanceof Error ? err.message : String(err),
727
+ message: errorMessage(err),
640
728
  });
641
729
  serverRuntimePromises.get(name)?.resolver();
642
730
  serverBuild.buildResolver();
643
731
  });
644
732
  }
645
733
 
646
- // 초기 빌드 완료까지 대기 (병렬 실행)
647
- this._logger.debug("초기 빌드 시작 (Promise.allSettled)");
648
- const initialBuildPromises: Array<{ name: string; promise: Promise<void> }> = [
649
- // Standalone client
650
- ...this._standaloneClientWorkers.map((workerInfo) => ({
651
- name: `${workerInfo.name} (client)`,
652
- promise: standaloneClientBuildPromises.get(workerInfo.name) ?? Promise.resolve(),
653
- })),
654
- // Vite client (서버 연결)
655
- ...this._viteClientWorkers.map((workerInfo) => ({
656
- name: `${workerInfo.name} (client)`,
657
- promise: viteClientBuildPromises.get(workerInfo.name) ?? Promise.resolve(),
658
- })),
659
- // Server 빌드 + 런타임 시작
660
- ...this._serverPackages.map(({ name }) => ({
661
- name: `${name} (server)`,
662
- promise: serverRuntimePromises.get(name)?.promise ?? Promise.resolve(),
663
- })),
664
- ];
665
-
666
- const initialResults = await Promise.allSettled(
667
- initialBuildPromises.map((item) => item.promise),
668
- );
669
-
670
- initialResults.forEach((result, index) => {
671
- const taskName = initialBuildPromises[index].name;
672
- if (result.status === "rejected") {
673
- this._logger.debug(`[${taskName}] 초기 빌드 실패:`, result.reason);
674
- } else {
675
- this._logger.debug(`[${taskName}] 초기 빌드 완료`);
676
- }
677
- });
678
-
679
- // Capacitor 초기화 (client 타겟 중 capacitor 설정이 있는 패키지)
680
- const capacitorPackages: Array<[string, SdClientPackageConfig]> = [];
681
- for (const { name, config } of this._clientPackages) {
682
- if (config.capacitor != null) {
683
- capacitorPackages.push([name, config]);
684
- }
685
- }
686
-
687
- if (capacitorPackages.length > 0) {
688
- for (const [name, config] of capacitorPackages) {
689
- const taskName = `${name} (capacitor)`;
690
- this._logger.start(taskName);
691
- const pkgDir = path.join(this._cwd, "packages", name);
692
- try {
693
- const cap = await Capacitor.create(pkgDir, config.capacitor!);
694
- await cap.initialize();
695
- this._results.set(`${name}:capacitor`, {
696
- name,
697
- target: "client",
698
- type: "capacitor",
699
- status: "success",
700
- });
701
- this._logger.success(taskName);
702
- } catch (err) {
703
- this._results.set(`${name}:capacitor`, {
704
- name,
705
- target: "client",
706
- type: "capacitor",
707
- status: "error",
708
- message: err instanceof Error ? err.message : String(err),
709
- });
710
- this._logger.fail(taskName);
711
- }
712
- }
713
- }
714
-
715
- // 초기 빌드 결과 출력
716
- printErrors(this._results);
717
- printServers(this._results, this._serverClientsMap);
734
+ return this._serverPackages.map(({ name }) => ({
735
+ name: `${name} (server)`,
736
+ promise: serverRuntimePromises.get(name)?.promise ?? Promise.resolve(),
737
+ }));
718
738
  }
719
739
 
720
740
  /**
@@ -86,7 +86,7 @@ export function createCliParser(argv: string[]): Argv {
86
86
  default: [],
87
87
  })
88
88
  .options({
89
- configOpt: {
89
+ opt: {
90
90
  type: "string",
91
91
  array: true,
92
92
  alias: "o",
@@ -97,7 +97,7 @@ export function createCliParser(argv: string[]): Argv {
97
97
  async (args) => {
98
98
  await runTypecheck({
99
99
  targets: args.targets,
100
- options: args.configOpt,
100
+ options: args.opt,
101
101
  });
102
102
  },
103
103
  )
@@ -142,7 +142,7 @@ export function createCliParser(argv: string[]): Argv {
142
142
  default: [],
143
143
  })
144
144
  .options({
145
- configOpt: {
145
+ opt: {
146
146
  type: "string",
147
147
  array: true,
148
148
  alias: "o",
@@ -153,7 +153,7 @@ export function createCliParser(argv: string[]): Argv {
153
153
  async (args) => {
154
154
  await runWatch({
155
155
  targets: args.targets,
156
- options: args.configOpt,
156
+ options: args.opt,
157
157
  });
158
158
  },
159
159
  )
@@ -171,7 +171,7 @@ export function createCliParser(argv: string[]): Argv {
171
171
  default: [],
172
172
  })
173
173
  .options({
174
- configOpt: {
174
+ opt: {
175
175
  type: "string",
176
176
  array: true,
177
177
  alias: "o",
@@ -182,7 +182,7 @@ export function createCliParser(argv: string[]): Argv {
182
182
  async (args) => {
183
183
  await runDev({
184
184
  targets: args.targets,
185
- options: args.configOpt,
185
+ options: args.opt,
186
186
  });
187
187
  },
188
188
  )
@@ -200,7 +200,7 @@ export function createCliParser(argv: string[]): Argv {
200
200
  default: [],
201
201
  })
202
202
  .options({
203
- configOpt: {
203
+ opt: {
204
204
  type: "string",
205
205
  array: true,
206
206
  alias: "o",
@@ -211,7 +211,7 @@ export function createCliParser(argv: string[]): Argv {
211
211
  async (args) => {
212
212
  await runBuild({
213
213
  targets: args.targets,
214
- options: args.configOpt,
214
+ options: args.opt,
215
215
  });
216
216
  },
217
217
  )
@@ -234,7 +234,7 @@ export function createCliParser(argv: string[]): Argv {
234
234
  alias: "u",
235
235
  describe: "개발 서버 URL (미지정 시 sd.config.ts의 server 설정 사용)",
236
236
  },
237
- configOpt: {
237
+ opt: {
238
238
  type: "string",
239
239
  array: true,
240
240
  alias: "o",
@@ -246,7 +246,7 @@ export function createCliParser(argv: string[]): Argv {
246
246
  await runDevice({
247
247
  package: args.package,
248
248
  url: args.url,
249
- options: args.configOpt,
249
+ options: args.opt,
250
250
  });
251
251
  },
252
252
  )
@@ -307,7 +307,7 @@ export function createCliParser(argv: string[]): Argv {
307
307
  describe: "실제 배포 없이 시뮬레이션",
308
308
  default: false,
309
309
  },
310
- "configOpt": {
310
+ "opt": {
311
311
  type: "string",
312
312
  array: true,
313
313
  alias: "o",
@@ -320,7 +320,7 @@ export function createCliParser(argv: string[]): Argv {
320
320
  targets: args.targets,
321
321
  noBuild: !args.build,
322
322
  dryRun: args.dryRun,
323
- options: args.configOpt,
323
+ options: args.opt,
324
324
  });
325
325
  },
326
326
  )
@@ -332,7 +332,7 @@ export function createCliParser(argv: string[]): Argv {
332
332
  .version(false)
333
333
  .hide("help")
334
334
  .options({
335
- configOpt: {
335
+ opt: {
336
336
  type: "string",
337
337
  array: true,
338
338
  alias: "o",
@@ -342,7 +342,7 @@ export function createCliParser(argv: string[]): Argv {
342
342
  }),
343
343
  async (args) => {
344
344
  await runReplaceDeps({
345
- options: args.configOpt,
345
+ options: args.opt,
346
346
  });
347
347
  },
348
348
  )