@simplysm/sd-cli 14.0.10 → 14.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.
- package/README.md +58 -253
- package/dist/angular/client-transform-stylesheet.js +1 -1
- package/dist/angular/client-transform-stylesheet.js.map +1 -1
- package/dist/angular/vite-angular-plugin.d.ts +1 -1
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +60 -34
- package/dist/angular/vite-angular-plugin.js.map +1 -1
- package/dist/angular/vite-postcss-inline-plugin.d.ts +1 -1
- package/dist/angular/vite-postcss-inline-plugin.js +1 -1
- package/dist/capacitor/capacitor.d.ts +14 -2
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +131 -17
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/build.d.ts +3 -10
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +3 -10
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/check.js +3 -3
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/dev.d.ts +3 -9
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +3 -9
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/device.d.ts +13 -0
- package/dist/commands/device.d.ts.map +1 -0
- package/dist/commands/device.js +53 -0
- package/dist/commands/device.js.map +1 -0
- package/dist/commands/publish.d.ts +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +18 -26
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/replace-deps.d.ts +3 -3
- package/dist/commands/replace-deps.d.ts.map +1 -1
- package/dist/commands/replace-deps.js +1 -1
- package/dist/commands/typecheck.d.ts +4 -3
- package/dist/commands/typecheck.d.ts.map +1 -1
- package/dist/commands/typecheck.js +5 -11
- package/dist/commands/typecheck.js.map +1 -1
- package/dist/commands/watch.d.ts +9 -9
- package/dist/commands/watch.js +9 -9
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +42 -3
- package/dist/electron/electron.js.map +1 -1
- package/dist/engines/BaseEngine.d.ts +1 -1
- package/dist/engines/BaseEngine.d.ts.map +1 -1
- package/dist/engines/BaseEngine.js +3 -1
- package/dist/engines/BaseEngine.js.map +1 -1
- package/dist/engines/NgtscEngine.d.ts +7 -7
- package/dist/engines/NgtscEngine.d.ts.map +1 -1
- package/dist/engines/NgtscEngine.js +3 -3
- package/dist/engines/ServerEsbuildEngine.d.ts +7 -7
- package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
- package/dist/engines/ServerEsbuildEngine.js +3 -3
- package/dist/engines/TscEngine.d.ts +7 -7
- package/dist/engines/TscEngine.d.ts.map +1 -1
- package/dist/engines/TscEngine.js +3 -3
- package/dist/engines/ViteEngine.d.ts +1 -1
- package/dist/engines/ViteEngine.d.ts.map +1 -1
- package/dist/engines/ViteEngine.js +7 -12
- package/dist/engines/ViteEngine.js.map +1 -1
- package/dist/engines/index.d.ts +5 -5
- package/dist/engines/index.js +5 -5
- package/dist/engines/types.d.ts +20 -20
- package/dist/engines/types.d.ts.map +1 -1
- package/dist/infra/ResultCollector.d.ts +9 -9
- package/dist/infra/ResultCollector.js +8 -8
- package/dist/infra/SignalHandler.d.ts +7 -7
- package/dist/infra/SignalHandler.js +7 -7
- package/dist/infra/WorkerManager.d.ts +14 -14
- package/dist/infra/WorkerManager.js +14 -14
- package/dist/orchestrators/BuildOrchestrator.d.ts +25 -25
- package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +29 -29
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.d.ts +7 -7
- package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.js +35 -57
- package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
- package/dist/sd-cli-entry.d.ts +2 -2
- package/dist/sd-cli-entry.d.ts.map +1 -1
- package/dist/sd-cli-entry.js +45 -9
- package/dist/sd-cli-entry.js.map +1 -1
- package/dist/sd-cli.d.ts +3 -3
- package/dist/sd-cli.js +16 -16
- package/dist/sd-cli.js.map +1 -1
- package/dist/sd-config.types.d.ts +105 -105
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/utils/angular-compiler.js +5 -5
- package/dist/utils/angular-compiler.js.map +1 -1
- package/dist/utils/build-env.d.ts +1 -1
- package/dist/utils/build-env.js +1 -1
- package/dist/utils/concurrency.d.ts +7 -7
- package/dist/utils/concurrency.js +7 -7
- package/dist/utils/copy-public.d.ts +9 -9
- package/dist/utils/copy-public.js +17 -17
- package/dist/utils/copy-public.js.map +1 -1
- package/dist/utils/copy-src.d.ts +9 -9
- package/dist/utils/copy-src.js +11 -11
- package/dist/utils/copy-src.js.map +1 -1
- package/dist/utils/engine-stop.d.ts +8 -9
- package/dist/utils/engine-stop.d.ts.map +1 -1
- package/dist/utils/engine-stop.js +9 -10
- package/dist/utils/engine-stop.js.map +1 -1
- package/dist/utils/esbuild-config.d.ts +23 -23
- package/dist/utils/esbuild-config.d.ts.map +1 -1
- package/dist/utils/esbuild-config.js +25 -25
- package/dist/utils/esbuild-config.js.map +1 -1
- package/dist/utils/lint-with-program.d.ts +15 -15
- package/dist/utils/lint-with-program.d.ts.map +1 -1
- package/dist/utils/lint-with-program.js +29 -29
- package/dist/utils/lint-with-program.js.map +1 -1
- package/dist/utils/ngtsc-build-core.d.ts +8 -8
- package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
- package/dist/utils/ngtsc-build-core.js +14 -14
- package/dist/utils/ngtsc-build-core.js.map +1 -1
- package/dist/utils/output-path-rewriter.d.ts +14 -14
- package/dist/utils/output-path-rewriter.js +18 -18
- package/dist/utils/output-path-rewriter.js.map +1 -1
- package/dist/utils/output-utils.d.ts +6 -6
- package/dist/utils/output-utils.js +11 -11
- package/dist/utils/output-utils.js.map +1 -1
- package/dist/utils/package-utils.d.ts +21 -21
- package/dist/utils/package-utils.d.ts.map +1 -1
- package/dist/utils/package-utils.js +56 -45
- package/dist/utils/package-utils.js.map +1 -1
- package/dist/utils/replace-deps.d.ts +25 -25
- package/dist/utils/replace-deps.d.ts.map +1 -1
- package/dist/utils/replace-deps.js +84 -65
- package/dist/utils/replace-deps.js.map +1 -1
- package/dist/utils/sd-config.d.ts +3 -3
- package/dist/utils/sd-config.js +3 -3
- package/dist/utils/tsc-build.d.ts +13 -13
- package/dist/utils/tsc-build.d.ts.map +1 -1
- package/dist/utils/tsc-build.js +9 -9
- package/dist/utils/tsc-build.js.map +1 -1
- package/dist/utils/tsconfig.d.ts +11 -9
- package/dist/utils/tsconfig.d.ts.map +1 -1
- package/dist/utils/tsconfig.js +11 -9
- package/dist/utils/tsconfig.js.map +1 -1
- package/dist/utils/typecheck-non-package.d.ts +5 -6
- package/dist/utils/typecheck-non-package.d.ts.map +1 -1
- package/dist/utils/typecheck-non-package.js +7 -8
- package/dist/utils/typecheck-non-package.js.map +1 -1
- package/dist/utils/typecheck-serialization.d.ts +8 -8
- package/dist/utils/typecheck-serialization.d.ts.map +1 -1
- package/dist/utils/typecheck-serialization.js +12 -16
- package/dist/utils/typecheck-serialization.js.map +1 -1
- package/dist/utils/vite-config.d.ts +8 -5
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +36 -29
- package/dist/utils/vite-config.js.map +1 -1
- package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
- package/dist/utils/vite-scope-watch-plugin.js +1 -1
- package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
- package/dist/utils/worker-events.d.ts +12 -12
- package/dist/utils/worker-events.d.ts.map +1 -1
- package/dist/utils/worker-events.js +10 -10
- package/dist/utils/worker-events.js.map +1 -1
- package/dist/utils/worker-utils.d.ts +12 -13
- package/dist/utils/worker-utils.d.ts.map +1 -1
- package/dist/utils/worker-utils.js +12 -13
- package/dist/utils/worker-utils.js.map +1 -1
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +5 -7
- package/dist/vitest-plugin.js.map +1 -1
- package/dist/workers/client.worker.d.ts +4 -2
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +209 -1
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/library-build.worker.d.ts +1 -1
- package/dist/workers/library-build.worker.d.ts.map +1 -1
- package/dist/workers/library-build.worker.js +7 -7
- package/dist/workers/library-build.worker.js.map +1 -1
- package/dist/workers/lint.worker.d.ts +2 -2
- package/dist/workers/lint.worker.js +2 -2
- package/dist/workers/ngtsc-build.worker.js +30 -30
- package/dist/workers/ngtsc-build.worker.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts +17 -17
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +46 -46
- package/dist/workers/server-build.worker.js.map +1 -1
- package/dist/workers/server-runtime.worker.d.ts +7 -7
- package/dist/workers/server-runtime.worker.d.ts.map +1 -1
- package/dist/workers/server-runtime.worker.js +17 -17
- package/dist/workers/server-runtime.worker.js.map +1 -1
- package/docs/config.md +340 -0
- package/docs/publish-configuration-types.md +87 -0
- package/docs/pwa-configuration-types.md +55 -0
- package/docs/vitest-plugin.md +47 -0
- package/package.json +9 -7
- package/src/angular/client-transform-stylesheet.ts +1 -1
- package/src/angular/vite-angular-plugin.ts +70 -37
- package/src/angular/vite-postcss-inline-plugin.ts +1 -1
- package/src/capacitor/capacitor.ts +159 -23
- package/src/commands/build.ts +3 -10
- package/src/commands/check.ts +3 -3
- package/src/commands/dev.ts +3 -9
- package/src/commands/device.ts +65 -0
- package/src/commands/publish.ts +30 -26
- package/src/commands/replace-deps.ts +3 -3
- package/src/commands/typecheck.ts +7 -13
- package/src/commands/watch.ts +9 -9
- package/src/electron/electron.ts +49 -4
- package/src/engines/BaseEngine.ts +4 -1
- package/src/engines/NgtscEngine.ts +7 -7
- package/src/engines/ServerEsbuildEngine.ts +7 -7
- package/src/engines/TscEngine.ts +7 -7
- package/src/engines/ViteEngine.ts +8 -13
- package/src/engines/index.ts +5 -5
- package/src/engines/types.ts +20 -20
- package/src/infra/ResultCollector.ts +9 -9
- package/src/infra/SignalHandler.ts +7 -7
- package/src/infra/WorkerManager.ts +14 -14
- package/src/orchestrators/BuildOrchestrator.ts +37 -37
- package/src/orchestrators/DevWatchOrchestrator.ts +37 -61
- package/src/sd-cli-entry.ts +51 -9
- package/src/sd-cli.ts +16 -16
- package/src/sd-config.types.ts +107 -107
- package/src/utils/angular-compiler.ts +5 -5
- package/src/utils/build-env.ts +1 -1
- package/src/utils/concurrency.ts +7 -7
- package/src/utils/copy-public.ts +17 -17
- package/src/utils/copy-src.ts +11 -11
- package/src/utils/engine-stop.ts +9 -10
- package/src/utils/esbuild-config.ts +29 -29
- package/src/utils/lint-with-program.ts +34 -34
- package/src/utils/ngtsc-build-core.ts +17 -17
- package/src/utils/output-path-rewriter.ts +18 -18
- package/src/utils/output-utils.ts +11 -11
- package/src/utils/package-utils.ts +57 -45
- package/src/utils/replace-deps.ts +92 -67
- package/src/utils/sd-config.ts +3 -3
- package/src/utils/tsc-build.ts +18 -18
- package/src/utils/tsconfig.ts +11 -9
- package/src/utils/typecheck-non-package.ts +7 -8
- package/src/utils/typecheck-serialization.ts +13 -15
- package/src/utils/vite-config.ts +45 -35
- package/src/utils/vite-scope-watch-plugin.ts +6 -1
- package/src/utils/worker-events.ts +16 -16
- package/src/utils/worker-utils.ts +12 -13
- package/src/vitest-plugin.ts +5 -8
- package/src/workers/client.worker.ts +236 -2
- package/src/workers/library-build.worker.ts +8 -8
- package/src/workers/lint.worker.ts +2 -2
- package/src/workers/ngtsc-build.worker.ts +31 -31
- package/src/workers/server-build.worker.ts +60 -60
- package/src/workers/server-runtime.worker.ts +22 -22
- package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +1 -0
- package/tests/angular/vite-angular-plugin-hmr.spec.ts +78 -0
- package/tests/angular/vite-angular-plugin.spec.ts +67 -0
- package/tests/capacitor/capacitor-build.spec.ts +6 -4
- package/tests/capacitor/capacitor-icon.spec.ts +7 -5
- package/tests/capacitor/capacitor-init.spec.ts +120 -10
- package/tests/capacitor/capacitor-run.spec.ts +14 -17
- package/tests/capacitor/capacitor-workspace.spec.ts +5 -3
- package/tests/commands/check.spec.ts +2 -2
- package/tests/commands/device.spec.ts +147 -0
- package/tests/commands/publish.spec.ts +2 -2
- package/tests/commands/typecheck.spec.ts +8 -0
- package/tests/electron/electron.spec.ts +12 -10
- package/tests/engines/base-engine.spec.ts +37 -0
- package/tests/engines/vite-engine.spec.ts +115 -3
- package/tests/orchestrators/dev-watch-orchestrator.spec.ts +21 -93
- package/tests/utils/vite-config.spec.ts +144 -90
- package/tests/workers/client-worker.spec.ts +690 -0
- package/tests/workers/server-build-worker.spec.ts +3 -3
|
@@ -21,17 +21,16 @@ import { SignalHandler } from "../infra/SignalHandler";
|
|
|
21
21
|
import { createBuildEngine, type BuildEngine, type BuildPackageInfo, type ClientPackageInfo, type ServerPackageInfo } from "../engines/index";
|
|
22
22
|
import { watchCopySrcFiles } from "../utils/copy-src";
|
|
23
23
|
import { Capacitor } from "../capacitor/capacitor";
|
|
24
|
-
import { Electron } from "../electron/electron";
|
|
25
24
|
import type * as ServerRuntimeWorkerModule from "../workers/server-runtime.worker";
|
|
26
25
|
import type { ServerReadyEventData, ErrorEventData } from "../utils/worker-events";
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
|
-
* Orchestrator
|
|
28
|
+
* Orchestrator 모드
|
|
30
29
|
*/
|
|
31
30
|
export type OrchestratorMode = "watch" | "dev";
|
|
32
31
|
|
|
33
32
|
/**
|
|
34
|
-
* DevWatchOrchestrator
|
|
33
|
+
* DevWatchOrchestrator 옵션
|
|
35
34
|
*/
|
|
36
35
|
export interface DevWatchOrchestratorOptions {
|
|
37
36
|
mode: OrchestratorMode;
|
|
@@ -40,26 +39,26 @@ export interface DevWatchOrchestratorOptions {
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
/**
|
|
43
|
-
*
|
|
42
|
+
* watch/dev 모드 통합 Orchestrator
|
|
44
43
|
*
|
|
45
|
-
* - watch:
|
|
46
|
-
* - dev:
|
|
44
|
+
* - watch: 라이브러리(JS+DTS) + Scripts(watch hook) + copySrc + replaceDeps
|
|
45
|
+
* - dev: 서버(JS+런타임) + 클라이언트 준비(skip) + replaceDeps
|
|
47
46
|
*/
|
|
48
47
|
export class DevWatchOrchestrator {
|
|
49
48
|
private readonly _cwd: string;
|
|
50
49
|
private readonly _options: DevWatchOrchestratorOptions;
|
|
51
50
|
private readonly _logger;
|
|
52
51
|
|
|
53
|
-
//
|
|
52
|
+
// 인프라
|
|
54
53
|
private _resultCollector!: ResultCollector;
|
|
55
54
|
private _signalHandler!: SignalHandler;
|
|
56
55
|
private _rebuildManager!: RebuildManager;
|
|
57
56
|
|
|
58
|
-
//
|
|
57
|
+
// 엔진
|
|
59
58
|
private readonly _libraryEngines: BuildEngine[] = [];
|
|
60
59
|
private readonly _serverEngines = new Map<string, BuildEngine>();
|
|
61
60
|
|
|
62
|
-
//
|
|
61
|
+
// 패키지 정보
|
|
63
62
|
private _libraryPackages: BuildPackageInfo[] = [];
|
|
64
63
|
private _serverPackages: Array<{ name: string; dir: string; config: SdServerPackageConfig }> = [];
|
|
65
64
|
private _watchHookPackages: Array<{ name: string; dir: string; config: SdScriptsPackageConfig | SdBuildPackageConfig }> = [];
|
|
@@ -67,13 +66,13 @@ export class DevWatchOrchestrator {
|
|
|
67
66
|
private readonly _clientEngines = new Map<string, BuildEngine>();
|
|
68
67
|
private _serverClientsMap = new Map<string, string[]>();
|
|
69
68
|
|
|
70
|
-
//
|
|
69
|
+
// dev 모드: 런타임 워커
|
|
71
70
|
private _baseEnv: { VER: string; DEV: string } | undefined;
|
|
72
71
|
private readonly _serverRuntimeWorkers = new Map<string, WorkerProxy<typeof ServerRuntimeWorkerModule>>();
|
|
73
72
|
private _printServersTimer: ReturnType<typeof setTimeout> | undefined;
|
|
74
73
|
private _serverRestartTimer: ReturnType<typeof setTimeout> | undefined;
|
|
75
74
|
|
|
76
|
-
//
|
|
75
|
+
// 워처
|
|
77
76
|
private _copySrcWatchers: FsWatcher[] = [];
|
|
78
77
|
private readonly _watchHookWatchers: FsWatcher[] = [];
|
|
79
78
|
private readonly _watchHookChildren = new Map<string, ChildProcess>();
|
|
@@ -107,30 +106,30 @@ export class DevWatchOrchestrator {
|
|
|
107
106
|
throw err;
|
|
108
107
|
}
|
|
109
108
|
|
|
110
|
-
//
|
|
109
|
+
// config 패키지에서 pathMap 빌드 (tests 패키지는 watch/dev에서 제외)
|
|
111
110
|
this._pathMap = buildPathMapFromConfig(sdConfig.packages);
|
|
112
111
|
|
|
113
|
-
//
|
|
112
|
+
// 대상 유효성 검사
|
|
114
113
|
validateTargets(this._options.targets, sdConfig.packages);
|
|
115
114
|
|
|
116
|
-
//
|
|
115
|
+
// 엔진 생성을 위해 replaceDeps 저장
|
|
117
116
|
this._replaceDeps = sdConfig.replaceDeps;
|
|
118
117
|
|
|
119
|
-
//
|
|
118
|
+
// replaceDeps 설정이 있으면 watch 시작
|
|
120
119
|
if (sdConfig.replaceDeps != null) {
|
|
121
120
|
this._replaceDepWatcher = await watchReplaceDeps(this._cwd, sdConfig.replaceDeps);
|
|
122
121
|
}
|
|
123
122
|
|
|
124
|
-
//
|
|
123
|
+
// dev 모드용 VER, DEV 환경변수 준비
|
|
125
124
|
if (this._options.mode === "dev") {
|
|
126
125
|
const version = await getVersion(this._cwd);
|
|
127
126
|
this._baseEnv = { VER: version, DEV: "true" };
|
|
128
127
|
}
|
|
129
128
|
|
|
130
|
-
//
|
|
129
|
+
// 대상으로 필터링
|
|
131
130
|
const allPackages = filterPackagesByTargets(sdConfig.packages, this._options.targets);
|
|
132
131
|
|
|
133
|
-
//
|
|
132
|
+
// 모드에 따라 패키지 분류
|
|
134
133
|
if (this._options.mode === "watch") {
|
|
135
134
|
const classified = classifyWatchPackages(allPackages, this._cwd, this._pathMap);
|
|
136
135
|
this._libraryPackages = classified.libraryPackages;
|
|
@@ -142,7 +141,7 @@ export class DevWatchOrchestrator {
|
|
|
142
141
|
this._serverClientsMap = classified.serverClientsMap;
|
|
143
142
|
}
|
|
144
143
|
|
|
145
|
-
//
|
|
144
|
+
// 처리할 패키지가 있는지 확인
|
|
146
145
|
const totalPackages = this._libraryPackages.length + this._serverPackages.length + this._watchHookPackages.length + this._clientPackages.length;
|
|
147
146
|
if (totalPackages === 0) {
|
|
148
147
|
const modeLabel = this._options.mode === "watch" ? "워치" : "개발";
|
|
@@ -152,12 +151,12 @@ export class DevWatchOrchestrator {
|
|
|
152
151
|
|
|
153
152
|
this._hasPackages = true;
|
|
154
153
|
|
|
155
|
-
//
|
|
154
|
+
// 인프라 초기화
|
|
156
155
|
this._signalHandler = new SignalHandler();
|
|
157
156
|
this._resultCollector = new ResultCollector();
|
|
158
157
|
this._rebuildManager = new RebuildManager(this._logger);
|
|
159
158
|
|
|
160
|
-
//
|
|
159
|
+
// 배치 완료 핸들러
|
|
161
160
|
if (this._options.mode === "watch") {
|
|
162
161
|
this._rebuildManager.on("batchComplete", (_completedKeys) => {
|
|
163
162
|
printErrors(this._resultCollector.toMap());
|
|
@@ -168,7 +167,7 @@ export class DevWatchOrchestrator {
|
|
|
168
167
|
});
|
|
169
168
|
}
|
|
170
169
|
|
|
171
|
-
//
|
|
170
|
+
// 라이브러리 패키지용 BuildEngine 생성 (watch 모드 전용)
|
|
172
171
|
for (const pkg of this._libraryPackages) {
|
|
173
172
|
const engine = createBuildEngine(pkg, {
|
|
174
173
|
cwd: this._cwd,
|
|
@@ -179,7 +178,7 @@ export class DevWatchOrchestrator {
|
|
|
179
178
|
this._libraryEngines.push(engine);
|
|
180
179
|
}
|
|
181
180
|
|
|
182
|
-
//
|
|
181
|
+
// 서버 패키지용 BuildEngine 생성
|
|
183
182
|
for (const { name, dir, config } of this._serverPackages) {
|
|
184
183
|
const engineConfig = this._options.mode === "dev"
|
|
185
184
|
? { ...config, env: { ...this._baseEnv, ...config.env } }
|
|
@@ -197,7 +196,7 @@ export class DevWatchOrchestrator {
|
|
|
197
196
|
this._serverEngines.set(name, engine);
|
|
198
197
|
}
|
|
199
198
|
|
|
200
|
-
//
|
|
199
|
+
// 클라이언트 패키지용 BuildEngine 생성 (dev 모드 전용)
|
|
201
200
|
const resolvedReplaceDeps = this._replaceDepWatcher?.entries.map((e) => ({
|
|
202
201
|
packageName: e.targetName,
|
|
203
202
|
sourcePath: e.resolvedSourcePath,
|
|
@@ -250,16 +249,16 @@ export class DevWatchOrchestrator {
|
|
|
250
249
|
|
|
251
250
|
const shutdownTasks: Array<Promise<void>> = [];
|
|
252
251
|
|
|
253
|
-
//
|
|
252
|
+
// 모든 엔진 중지
|
|
254
253
|
shutdownTasks.push(...this._libraryEngines.map((e) => e.stop()));
|
|
255
254
|
shutdownTasks.push(...[...this._serverEngines.values()].map((e) => e.stop()));
|
|
256
255
|
shutdownTasks.push(...[...this._clientEngines.values()].map((e) => e.stop()));
|
|
257
256
|
|
|
258
|
-
//
|
|
257
|
+
// 워처 종료 (watch 모드)
|
|
259
258
|
shutdownTasks.push(...this._copySrcWatchers.map((w) => w.close()));
|
|
260
259
|
shutdownTasks.push(...this._watchHookWatchers.map((w) => w.close()));
|
|
261
260
|
|
|
262
|
-
//
|
|
261
|
+
// hook 자식 프로세스 종료
|
|
263
262
|
for (const child of this._watchHookChildren.values()) {
|
|
264
263
|
if (child.exitCode == null) {
|
|
265
264
|
child.kill();
|
|
@@ -267,7 +266,7 @@ export class DevWatchOrchestrator {
|
|
|
267
266
|
}
|
|
268
267
|
this._watchHookChildren.clear();
|
|
269
268
|
|
|
270
|
-
//
|
|
269
|
+
// 런타임 워커 종료 (dev 모드)
|
|
271
270
|
shutdownTasks.push(...[...this._serverRuntimeWorkers.values()].map((w) => w.terminate()));
|
|
272
271
|
|
|
273
272
|
await Promise.all(shutdownTasks);
|
|
@@ -278,7 +277,7 @@ export class DevWatchOrchestrator {
|
|
|
278
277
|
process.stdout.write("✔ 종료 완료\n");
|
|
279
278
|
}
|
|
280
279
|
|
|
281
|
-
// ---
|
|
280
|
+
// --- watch 모드 ---
|
|
282
281
|
|
|
283
282
|
private async _startWatchMode(): Promise<void> {
|
|
284
283
|
this._logger.debug("watch 모드 시작");
|
|
@@ -347,7 +346,7 @@ export class DevWatchOrchestrator {
|
|
|
347
346
|
});
|
|
348
347
|
}
|
|
349
348
|
|
|
350
|
-
// ---
|
|
349
|
+
// --- dev 모드 ---
|
|
351
350
|
|
|
352
351
|
private async _startDevMode(): Promise<void> {
|
|
353
352
|
// Start client and server engines in parallel
|
|
@@ -381,7 +380,7 @@ export class DevWatchOrchestrator {
|
|
|
381
380
|
}
|
|
382
381
|
});
|
|
383
382
|
|
|
384
|
-
//
|
|
383
|
+
// 독립 클라이언트 결과를 ResultCollector에 등록
|
|
385
384
|
for (const { name } of this._clientPackages) {
|
|
386
385
|
const isServerConnected = [...this._serverClientsMap.values()].some(
|
|
387
386
|
(clients) => clients.includes(name),
|
|
@@ -400,46 +399,23 @@ export class DevWatchOrchestrator {
|
|
|
400
399
|
}
|
|
401
400
|
}
|
|
402
401
|
|
|
403
|
-
//
|
|
402
|
+
// 클라이언트 패키지의 Capacitor 초기화 (디바이스 실행은 'device' 명령어가 담당)
|
|
404
403
|
for (const { name, config } of this._clientPackages) {
|
|
405
404
|
const port = this._getClientPort(name);
|
|
406
405
|
if (port == null) continue;
|
|
407
406
|
|
|
408
|
-
const devServerUrl = `http://localhost:${port}`;
|
|
409
407
|
const pkgDir = pathx.posixResolve(this._cwd, "packages", name);
|
|
410
408
|
|
|
411
409
|
if (config.capacitor != null) {
|
|
412
410
|
try {
|
|
413
411
|
const cap = await Capacitor.create(pkgDir, config.capacitor, config.exclude);
|
|
414
412
|
await cap.initialize();
|
|
415
|
-
await cap.run(devServerUrl);
|
|
416
413
|
} catch (err) {
|
|
417
414
|
this._logger.error(
|
|
418
|
-
`[${name}] Capacitor
|
|
415
|
+
`[${name}] Capacitor 초기화 실패: ${errNs.message(err)}`,
|
|
419
416
|
);
|
|
420
417
|
}
|
|
421
418
|
}
|
|
422
|
-
|
|
423
|
-
if (config.electron != null) {
|
|
424
|
-
void (async () => {
|
|
425
|
-
try {
|
|
426
|
-
const elc = await Electron.create(pkgDir, config.electron!, config.exclude);
|
|
427
|
-
await elc.initialize();
|
|
428
|
-
await elc.run(devServerUrl);
|
|
429
|
-
} catch (err) {
|
|
430
|
-
this._logger.error(
|
|
431
|
-
`[${name}] Electron 실행 실패: ${errNs.message(err)}`,
|
|
432
|
-
);
|
|
433
|
-
this._resultCollector.add({
|
|
434
|
-
name,
|
|
435
|
-
target: "client",
|
|
436
|
-
type: "build",
|
|
437
|
-
status: "error",
|
|
438
|
-
message: `Electron 실행 실패: ${errNs.message(err)}`,
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
})();
|
|
442
|
-
}
|
|
443
419
|
}
|
|
444
420
|
|
|
445
421
|
// Print initial results
|
|
@@ -498,13 +474,13 @@ export class DevWatchOrchestrator {
|
|
|
498
474
|
}, 300);
|
|
499
475
|
}
|
|
500
476
|
|
|
501
|
-
/**
|
|
477
|
+
/** 클라이언트 엔진에서 포트 가져오기 (ViteEngine.port에 대한 duck-typing) */
|
|
502
478
|
private _getClientPort(name: string): number | undefined {
|
|
503
479
|
const engine = this._clientEngines.get(name) as { port?: number } | undefined;
|
|
504
480
|
return engine?.port;
|
|
505
481
|
}
|
|
506
482
|
|
|
507
|
-
/**
|
|
483
|
+
/** 서버에 연결된 클라이언트들의 포트 수집 */
|
|
508
484
|
private _collectClientPorts(serverName: string): Record<string, number> {
|
|
509
485
|
const clientPorts: Record<string, number> = {};
|
|
510
486
|
const connectedClients = this._serverClientsMap.get(serverName) ?? [];
|
|
@@ -525,19 +501,19 @@ export class DevWatchOrchestrator {
|
|
|
525
501
|
): Promise<void> {
|
|
526
502
|
this._logger.debug(`[${serverName}] 서버 런타임 시작: ${mainJsPath}`);
|
|
527
503
|
|
|
528
|
-
//
|
|
504
|
+
// 기존 런타임 종료
|
|
529
505
|
const existingRuntime = this._serverRuntimeWorkers.get(serverName);
|
|
530
506
|
if (existingRuntime != null) {
|
|
531
507
|
this._logger.info(`[${serverName}] 서버 재시작 중...`);
|
|
532
508
|
await existingRuntime.terminate();
|
|
533
509
|
}
|
|
534
510
|
|
|
535
|
-
//
|
|
511
|
+
// 새 런타임 워커 생성 및 시작
|
|
536
512
|
const runtimeWorkerPath = import.meta.resolve("../workers/server-runtime.worker");
|
|
537
513
|
const runtimeWorker = Worker.create<typeof ServerRuntimeWorkerModule>(runtimeWorkerPath);
|
|
538
514
|
this._serverRuntimeWorkers.set(serverName, runtimeWorker);
|
|
539
515
|
|
|
540
|
-
//
|
|
516
|
+
// 런타임 이벤트 핸들러
|
|
541
517
|
runtimeWorker.on("serverReady", (readyData) => {
|
|
542
518
|
const readyEvent = readyData as ServerReadyEventData;
|
|
543
519
|
this._resultCollector.add({
|
package/src/sd-cli-entry.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
3
|
|
|
4
|
-
//
|
|
4
|
+
// 사이드 이펙트: Map/Array prototype 확장 (getOrCreate 등)
|
|
5
5
|
import "@simplysm/core-common";
|
|
6
6
|
import yargs, { type Argv } from "yargs";
|
|
7
7
|
import { hideBin } from "yargs/helpers";
|
|
@@ -23,7 +23,7 @@ EventEmitter.defaultMaxListeners = 100;
|
|
|
23
23
|
|
|
24
24
|
consola.options.reporters = [new SdCliReporter()];
|
|
25
25
|
|
|
26
|
-
const COMMAND_NAMES = ["check", "watch", "dev", "build", "publish", "replace-deps"];
|
|
26
|
+
const COMMAND_NAMES = ["check", "watch", "dev", "device", "build", "publish", "replace-deps"];
|
|
27
27
|
|
|
28
28
|
async function collectYargsHelp(argv: string[]): Promise<string> {
|
|
29
29
|
const lines: string[] = [];
|
|
@@ -34,7 +34,7 @@ async function collectYargsHelp(argv: string[]): Promise<string> {
|
|
|
34
34
|
try {
|
|
35
35
|
await createCliParser(argv).exitProcess(false).parse();
|
|
36
36
|
} catch {
|
|
37
|
-
// yargs
|
|
37
|
+
// yargs가 help 출력 후 throw할 수 있음
|
|
38
38
|
} finally {
|
|
39
39
|
|
|
40
40
|
console.log = orig;
|
|
@@ -43,11 +43,11 @@ async function collectYargsHelp(argv: string[]): Promise<string> {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
* @internal
|
|
46
|
+
* CLI 파서 생성
|
|
47
|
+
* @internal 테스트용으로 export
|
|
48
48
|
*/
|
|
49
49
|
export function createCliParser(argv: string[]): Argv {
|
|
50
|
-
//
|
|
50
|
+
// 최상위 --help/-h (서브커맨드 없이): 모든 명령어의 종합 도움말 표시
|
|
51
51
|
const hasHelp = argv.includes("--help") || argv.includes("-h");
|
|
52
52
|
const hasCommand = COMMAND_NAMES.some((cmd) => argv.includes(cmd));
|
|
53
53
|
if (hasHelp && !hasCommand) {
|
|
@@ -185,6 +185,41 @@ export function createCliParser(argv: string[]): Argv {
|
|
|
185
185
|
});
|
|
186
186
|
},
|
|
187
187
|
)
|
|
188
|
+
.command(
|
|
189
|
+
"device",
|
|
190
|
+
"Run native app on device/desktop",
|
|
191
|
+
(cmd) =>
|
|
192
|
+
cmd
|
|
193
|
+
.version(false)
|
|
194
|
+
.hide("help")
|
|
195
|
+
.options({
|
|
196
|
+
"package": {
|
|
197
|
+
type: "string",
|
|
198
|
+
alias: "p",
|
|
199
|
+
description: "Client package name to run",
|
|
200
|
+
demandOption: true,
|
|
201
|
+
},
|
|
202
|
+
"url": {
|
|
203
|
+
type: "string",
|
|
204
|
+
description: "Dev server URL (auto-detected from sd.config.ts if omitted)",
|
|
205
|
+
},
|
|
206
|
+
"opt": {
|
|
207
|
+
type: "string",
|
|
208
|
+
array: true,
|
|
209
|
+
alias: "o",
|
|
210
|
+
description: "Options to pass to sd.config.ts (e.g., -o key=value)",
|
|
211
|
+
default: [] as string[],
|
|
212
|
+
},
|
|
213
|
+
}),
|
|
214
|
+
async (args) => {
|
|
215
|
+
const { runDevice } = await import("./commands/device");
|
|
216
|
+
await runDevice({
|
|
217
|
+
package: args.package,
|
|
218
|
+
url: args.url,
|
|
219
|
+
options: args.opt,
|
|
220
|
+
});
|
|
221
|
+
},
|
|
222
|
+
)
|
|
188
223
|
.command(
|
|
189
224
|
"build [targets..]",
|
|
190
225
|
"Run production build",
|
|
@@ -278,11 +313,18 @@ export function createCliParser(argv: string[]): Argv {
|
|
|
278
313
|
},
|
|
279
314
|
)
|
|
280
315
|
.demandCommand(1, "Please specify a command.")
|
|
281
|
-
.strict()
|
|
316
|
+
.strict()
|
|
317
|
+
.fail((msg, err) => {
|
|
318
|
+
if (msg) {
|
|
319
|
+
consola.error(msg);
|
|
320
|
+
process.exit(1);
|
|
321
|
+
}
|
|
322
|
+
throw err;
|
|
323
|
+
});
|
|
282
324
|
}
|
|
283
325
|
|
|
284
|
-
//
|
|
285
|
-
//
|
|
326
|
+
// CLI로 직접 실행될 때만 파싱
|
|
327
|
+
// ESM에서 메인 모듈 판별: import.meta.url과 process.argv[1]을 정규화하여 비교
|
|
286
328
|
const cliEntryPath = process.argv.at(1);
|
|
287
329
|
if (
|
|
288
330
|
cliEntryPath != null &&
|
package/src/sd-cli.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* CLI
|
|
4
|
+
* CLI 런처
|
|
5
5
|
*
|
|
6
|
-
* .ts
|
|
7
|
-
* .js
|
|
6
|
+
* .ts 실행 (개발): CPU affinity 적용 후 sd-cli-entry를 직접 import
|
|
7
|
+
* .js 실행 (프로덕션): replaceDeps 실행 후 새 프로세스에서 sd-cli-entry 실행
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { cpx } from "@simplysm/core-node";
|
|
@@ -17,16 +17,16 @@ const __dirname = path.dirname(__filename);
|
|
|
17
17
|
const isDev = path.extname(__filename) === ".ts";
|
|
18
18
|
|
|
19
19
|
if (isDev) {
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
20
|
+
// 개발 모드 (.ts): affinity 적용 후 직접 실행
|
|
21
|
+
// import만으로는 메인 모듈 판별이 실패하므로 (process.argv[1] ≠ sd-cli-entry)
|
|
22
|
+
// createCliParser를 명시적으로 호출해야 한다.
|
|
23
23
|
configureAffinityAndPriority(process.pid);
|
|
24
24
|
const { createCliParser } = await import("./sd-cli-entry.js");
|
|
25
25
|
await createCliParser(process.argv.slice(2)).parse();
|
|
26
26
|
} else {
|
|
27
27
|
// Production mode (.js): two-stage execution
|
|
28
28
|
|
|
29
|
-
// Phase 1: replaceDeps (
|
|
29
|
+
// Phase 1: replaceDeps (인라인 — 설치된 버전으로 복사)
|
|
30
30
|
try {
|
|
31
31
|
const { loadSdConfig } = await import("./utils/sd-config.js");
|
|
32
32
|
const { setupReplaceDeps } = await import("./utils/replace-deps.js");
|
|
@@ -35,12 +35,12 @@ if (isDev) {
|
|
|
35
35
|
await setupReplaceDeps(process.cwd(), sdConfig.replaceDeps);
|
|
36
36
|
}
|
|
37
37
|
} catch {
|
|
38
|
-
//
|
|
38
|
+
// sd.config.ts가 없거나 replaceDeps가 설정되지 않으면 건너뜀
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
// Phase 2:
|
|
41
|
+
// Phase 2: 실제 CLI를 새 프로세스로 실행 (모듈 캐시 초기화)
|
|
42
42
|
const cliEntryFilePath = path.join(__dirname, "sd-cli-entry.js");
|
|
43
|
-
const subprocess = cpx.
|
|
43
|
+
const subprocess = cpx.spawn(
|
|
44
44
|
"node",
|
|
45
45
|
[
|
|
46
46
|
"--max-old-space-size=8192",
|
|
@@ -56,10 +56,10 @@ if (isDev) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
59
|
+
* CPU affinity 마스크 계산 (앞쪽 코어 제외)
|
|
60
60
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
61
|
+
* CPU 4개당 1개 코어를 제외하고, 나머지 코어의 비트를 ON으로 설정한다.
|
|
62
|
+
* 예시: 8코어 → 2개 제외 → 0xFC (코어 2~7)
|
|
63
63
|
*/
|
|
64
64
|
function calculateAffinityMask(cpuCount: number): string {
|
|
65
65
|
const exclude = cpuCount <= 1 ? 0 : Math.ceil(cpuCount / 4);
|
|
@@ -71,12 +71,12 @@ function calculateAffinityMask(cpuCount: number): string {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
74
|
+
* CPU affinity 및 우선순위 설정 (크로스 플랫폼)
|
|
75
75
|
*
|
|
76
76
|
* - Windows: PowerShell ProcessorAffinity + PriorityClass
|
|
77
77
|
* - Linux/WSL: taskset + renice
|
|
78
78
|
*
|
|
79
|
-
*
|
|
79
|
+
* 실패 시 경고만 출력하며, CLI 동작에는 영향을 주지 않는다.
|
|
80
80
|
*/
|
|
81
81
|
function configureAffinityAndPriority(pid: number): void {
|
|
82
82
|
const cpuCount = os.cpus().length;
|
|
@@ -94,7 +94,7 @@ function configureAffinityAndPriority(pid: number): void {
|
|
|
94
94
|
command = `taskset -p ${mask} ${pid} && renice +10 -p ${pid}`;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
cpx.
|
|
97
|
+
cpx.spawn(command, [], { shell: true }).catch((err: unknown) => {
|
|
98
98
|
// eslint-disable-next-line no-console
|
|
99
99
|
console.warn(
|
|
100
100
|
"Failed to configure CPU affinity/priority:",
|