@simplysm/sd-cli 14.0.30 → 14.0.32
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/dist/{utils → angular}/angular-build-pipeline.d.ts +0 -2
- package/dist/angular/angular-build-pipeline.d.ts.map +1 -0
- package/dist/{utils → angular}/angular-build-pipeline.js +3 -6
- package/dist/angular/angular-build-pipeline.js.map +1 -0
- package/dist/{utils → angular}/angular-build.d.ts +1 -1
- package/dist/angular/angular-build.d.ts.map +1 -0
- package/dist/{utils → angular}/angular-build.js +1 -1
- package/dist/angular/angular-build.js.map +1 -0
- package/dist/{utils → angular}/angular-compiler.d.ts +0 -3
- package/dist/angular/angular-compiler.d.ts.map +1 -0
- package/dist/{utils → angular}/angular-compiler.js +1 -45
- package/dist/angular/angular-compiler.js.map +1 -0
- package/dist/angular/client-transform-stylesheet.js +1 -1
- package/dist/angular/client-transform-stylesheet.js.map +1 -1
- package/dist/{utils → angular}/ngtsc-build-core.d.ts +3 -3
- package/dist/angular/ngtsc-build-core.d.ts.map +1 -0
- package/dist/angular/ngtsc-build-core.js.map +1 -0
- package/dist/angular/scss-compiler.d.ts.map +1 -0
- package/dist/angular/scss-compiler.js.map +1 -0
- package/dist/angular/vite-angular-plugin.d.ts +2 -10
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +20 -286
- package/dist/angular/vite-angular-plugin.js.map +1 -1
- package/dist/capacitor/capacitor-build.d.ts +14 -0
- package/dist/capacitor/capacitor-build.d.ts.map +1 -0
- package/dist/capacitor/capacitor-build.js +105 -0
- package/dist/capacitor/capacitor-build.js.map +1 -0
- package/dist/capacitor/capacitor-config-writer.d.ts +11 -0
- package/dist/capacitor/capacitor-config-writer.d.ts.map +1 -0
- package/dist/capacitor/capacitor-config-writer.js +54 -0
- package/dist/capacitor/capacitor-config-writer.js.map +1 -0
- package/dist/capacitor/capacitor-icon.d.ts +5 -0
- package/dist/capacitor/capacitor-icon.d.ts.map +1 -0
- package/dist/capacitor/capacitor-icon.js +58 -0
- package/dist/capacitor/capacitor-icon.js.map +1 -0
- package/dist/capacitor/capacitor-npm-config.d.ts +11 -0
- package/dist/capacitor/capacitor-npm-config.d.ts.map +1 -0
- package/dist/capacitor/capacitor-npm-config.js +145 -0
- package/dist/capacitor/capacitor-npm-config.js.map +1 -0
- package/dist/capacitor/capacitor.d.ts +0 -45
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +15 -354
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/check.js +2 -2
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/dev.d.ts +3 -3
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +3 -3
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/lint.d.ts +1 -1
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +1 -1
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/publish/deployment-phase.d.ts +12 -0
- package/dist/commands/publish/deployment-phase.d.ts.map +1 -0
- package/dist/commands/publish/deployment-phase.js +94 -0
- package/dist/commands/publish/deployment-phase.js.map +1 -0
- package/dist/commands/publish/env-utils.d.ts +10 -0
- package/dist/commands/publish/env-utils.d.ts.map +1 -0
- package/dist/commands/publish/env-utils.js +41 -0
- package/dist/commands/publish/env-utils.js.map +1 -0
- package/dist/commands/publish/git-phase.d.ts +12 -0
- package/dist/commands/publish/git-phase.d.ts.map +1 -0
- package/dist/commands/publish/git-phase.js +79 -0
- package/dist/commands/publish/git-phase.js.map +1 -0
- package/dist/commands/{publish.d.ts → publish/index.d.ts} +1 -1
- package/dist/commands/publish/index.d.ts.map +1 -0
- package/dist/commands/publish/index.js +211 -0
- package/dist/commands/publish/index.js.map +1 -0
- package/dist/commands/publish/local-publisher.d.ts +6 -0
- package/dist/commands/publish/local-publisher.d.ts.map +1 -0
- package/dist/commands/publish/local-publisher.js +16 -0
- package/dist/commands/publish/local-publisher.js.map +1 -0
- package/dist/commands/publish/npm-publisher.d.ts +6 -0
- package/dist/commands/publish/npm-publisher.d.ts.map +1 -0
- package/dist/commands/publish/npm-publisher.js +21 -0
- package/dist/commands/publish/npm-publisher.js.map +1 -0
- package/dist/commands/publish/post-publish-phase.d.ts +8 -0
- package/dist/commands/publish/post-publish-phase.d.ts.map +1 -0
- package/dist/commands/publish/post-publish-phase.js +34 -0
- package/dist/commands/publish/post-publish-phase.js.map +1 -0
- package/dist/commands/publish/storage-publisher.d.ts +18 -0
- package/dist/commands/publish/storage-publisher.d.ts.map +1 -0
- package/dist/commands/publish/storage-publisher.js +173 -0
- package/dist/commands/publish/storage-publisher.js.map +1 -0
- package/dist/commands/publish/version-upgrade.d.ts +28 -0
- package/dist/commands/publish/version-upgrade.d.ts.map +1 -0
- package/dist/commands/publish/version-upgrade.js +96 -0
- package/dist/commands/publish/version-upgrade.js.map +1 -0
- package/dist/commands/replace-deps.js +1 -1
- package/dist/commands/replace-deps.js.map +1 -1
- package/dist/commands/watch.d.ts +3 -4
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +3 -4
- package/dist/commands/watch.js.map +1 -1
- package/dist/deps/replace-deps/collect-deps.d.ts +6 -0
- package/dist/deps/replace-deps/collect-deps.d.ts.map +1 -0
- package/dist/deps/replace-deps/collect-deps.js +71 -0
- package/dist/deps/replace-deps/collect-deps.js.map +1 -0
- package/dist/{utils/replace-deps.d.ts → deps/replace-deps/replace-deps-resolve.d.ts} +7 -24
- package/dist/deps/replace-deps/replace-deps-resolve.d.ts.map +1 -0
- package/dist/{utils/replace-deps.js → deps/replace-deps/replace-deps-resolve.js} +4 -152
- package/dist/deps/replace-deps/replace-deps-resolve.js.map +1 -0
- package/dist/deps/replace-deps/replace-deps.d.ts +36 -0
- package/dist/deps/replace-deps/replace-deps.d.ts.map +1 -0
- package/dist/deps/replace-deps/replace-deps.js +155 -0
- package/dist/deps/replace-deps/replace-deps.js.map +1 -0
- package/dist/{utils → deps/server-externals}/server-production-files.d.ts +1 -1
- package/dist/deps/server-externals/server-production-files.d.ts.map +1 -0
- package/dist/{utils → deps/server-externals}/server-production-files.js +1 -1
- package/dist/deps/server-externals/server-production-files.js.map +1 -0
- package/dist/dev-server/dev-http-server.d.ts +23 -0
- package/dist/dev-server/dev-http-server.d.ts.map +1 -0
- package/dist/dev-server/dev-http-server.js +116 -0
- package/dist/dev-server/dev-http-server.js.map +1 -0
- package/dist/dev-server/hmr-client-script.d.ts +13 -0
- package/dist/dev-server/hmr-client-script.d.ts.map +1 -0
- package/dist/dev-server/hmr-client-script.js +73 -0
- package/dist/dev-server/hmr-client-script.js.map +1 -0
- package/dist/dev-server/hmr-service.d.ts +23 -0
- package/dist/dev-server/hmr-service.d.ts.map +1 -0
- package/dist/dev-server/hmr-service.js +139 -0
- package/dist/dev-server/hmr-service.js.map +1 -0
- package/dist/electron/electron.d.ts +5 -0
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +17 -24
- package/dist/electron/electron.js.map +1 -1
- package/dist/engines/BaseEngine.d.ts +18 -4
- package/dist/engines/BaseEngine.d.ts.map +1 -1
- package/dist/engines/BaseEngine.js +45 -66
- package/dist/engines/BaseEngine.js.map +1 -1
- package/dist/engines/{ViteEngine.d.ts → EsbuildClientEngine.d.ts} +11 -18
- package/dist/engines/EsbuildClientEngine.d.ts.map +1 -0
- package/dist/engines/{ViteEngine.js → EsbuildClientEngine.js} +28 -55
- package/dist/engines/EsbuildClientEngine.js.map +1 -0
- package/dist/engines/NgtscEngine.d.ts +2 -2
- package/dist/engines/NgtscEngine.d.ts.map +1 -1
- package/dist/engines/NgtscEngine.js +1 -9
- package/dist/engines/NgtscEngine.js.map +1 -1
- package/dist/engines/ServerEsbuildEngine.d.ts +2 -2
- package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
- package/dist/engines/ServerEsbuildEngine.js +1 -9
- package/dist/engines/ServerEsbuildEngine.js.map +1 -1
- package/dist/engines/TscEngine.d.ts +2 -2
- package/dist/engines/TscEngine.d.ts.map +1 -1
- package/dist/engines/TscEngine.js +1 -9
- package/dist/engines/TscEngine.js.map +1 -1
- package/dist/engines/index.d.ts +15 -5
- package/dist/engines/index.d.ts.map +1 -1
- package/dist/engines/index.js +21 -5
- package/dist/engines/index.js.map +1 -1
- package/dist/engines/types.d.ts +3 -3
- package/dist/engines/types.d.ts.map +1 -1
- package/dist/esbuild/esbuild-client-config.d.ts +38 -0
- package/dist/esbuild/esbuild-client-config.d.ts.map +1 -0
- package/dist/esbuild/esbuild-client-config.js +171 -0
- package/dist/esbuild/esbuild-client-config.js.map +1 -0
- package/dist/esbuild/esbuild-config.d.ts.map +1 -0
- package/dist/{utils → esbuild}/esbuild-config.js +1 -0
- package/dist/esbuild/esbuild-config.js.map +1 -0
- package/dist/esbuild/esbuild-index-html.d.ts +39 -0
- package/dist/esbuild/esbuild-index-html.d.ts.map +1 -0
- package/dist/esbuild/esbuild-index-html.js +68 -0
- package/dist/esbuild/esbuild-index-html.js.map +1 -0
- package/dist/esbuild/esbuild-pwa.d.ts +21 -0
- package/dist/esbuild/esbuild-pwa.d.ts.map +1 -0
- package/dist/esbuild/esbuild-pwa.js +105 -0
- package/dist/esbuild/esbuild-pwa.js.map +1 -0
- package/dist/esbuild/esbuild-scss-plugin.d.ts +6 -0
- package/dist/esbuild/esbuild-scss-plugin.d.ts.map +1 -0
- package/dist/esbuild/esbuild-scss-plugin.js +41 -0
- package/dist/esbuild/esbuild-scss-plugin.js.map +1 -0
- package/dist/lint/lint-core.d.ts.map +1 -0
- package/dist/lint/lint-core.js.map +1 -0
- package/dist/lint/lint-utils.d.ts.map +1 -0
- package/dist/lint/lint-utils.js.map +1 -0
- package/dist/lint/lint-with-program.d.ts.map +1 -0
- package/dist/lint/lint-with-program.js.map +1 -0
- package/dist/orchestrators/BaseOrchestrator.d.ts +44 -0
- package/dist/orchestrators/BaseOrchestrator.d.ts.map +1 -0
- package/dist/orchestrators/BaseOrchestrator.js +92 -0
- package/dist/orchestrators/BaseOrchestrator.js.map +1 -0
- package/dist/orchestrators/BuildOrchestrator.d.ts +45 -3
- package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +170 -143
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevOrchestrator.d.ts +39 -0
- package/dist/orchestrators/DevOrchestrator.d.ts.map +1 -0
- package/dist/orchestrators/DevOrchestrator.js +249 -0
- package/dist/orchestrators/DevOrchestrator.js.map +1 -0
- package/dist/orchestrators/ServerRuntimeManager.d.ts +22 -0
- package/dist/orchestrators/ServerRuntimeManager.d.ts.map +1 -0
- package/dist/orchestrators/ServerRuntimeManager.js +66 -0
- package/dist/orchestrators/ServerRuntimeManager.js.map +1 -0
- package/dist/orchestrators/TypecheckOrchestrator.d.ts +17 -2
- package/dist/orchestrators/TypecheckOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/TypecheckOrchestrator.js +122 -108
- package/dist/orchestrators/TypecheckOrchestrator.js.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.d.ts +33 -0
- package/dist/orchestrators/WatchOrchestrator.d.ts.map +1 -0
- package/dist/orchestrators/WatchOrchestrator.js +158 -0
- package/dist/orchestrators/WatchOrchestrator.js.map +1 -0
- package/dist/orchestrators/types.d.ts +17 -0
- package/dist/orchestrators/types.d.ts.map +1 -0
- package/dist/orchestrators/types.js +2 -0
- package/dist/orchestrators/types.js.map +1 -0
- package/dist/runtime/ResultCollector.d.ts.map +1 -0
- package/dist/runtime/ResultCollector.js.map +1 -0
- package/dist/runtime/SignalHandler.d.ts.map +1 -0
- package/dist/runtime/SignalHandler.js.map +1 -0
- package/dist/{utils → runtime}/engine-stop.d.ts +1 -1
- package/dist/runtime/engine-stop.d.ts.map +1 -0
- package/dist/{utils → runtime}/engine-stop.js +1 -1
- package/dist/runtime/engine-stop.js.map +1 -0
- package/dist/runtime/engine-watch-events.d.ts +43 -0
- package/dist/runtime/engine-watch-events.d.ts.map +1 -0
- package/dist/runtime/engine-watch-events.js +72 -0
- package/dist/runtime/engine-watch-events.js.map +1 -0
- package/dist/{utils → runtime}/rebuild-manager.d.ts +1 -0
- package/dist/runtime/rebuild-manager.d.ts.map +1 -0
- package/dist/{utils → runtime}/rebuild-manager.js +8 -1
- package/dist/runtime/rebuild-manager.js.map +1 -0
- package/dist/runtime/worker-events.d.ts +22 -0
- package/dist/runtime/worker-events.d.ts.map +1 -0
- package/dist/runtime/worker-events.js +2 -0
- package/dist/runtime/worker-events.js.map +1 -0
- package/dist/runtime/worker-utils.d.ts.map +1 -0
- package/dist/runtime/worker-utils.js.map +1 -0
- package/dist/sd-cli-entry.d.ts.map +1 -1
- package/dist/sd-cli-entry.js +61 -54
- package/dist/sd-cli-entry.js.map +1 -1
- package/dist/sd-cli.js +1 -1
- package/dist/sd-cli.js.map +1 -1
- package/dist/sd-config.types.d.ts +6 -15
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/typecheck/typecheck-non-package.d.ts.map +1 -0
- package/dist/{utils → typecheck}/typecheck-non-package.js +1 -1
- package/dist/typecheck/typecheck-non-package.js.map +1 -0
- package/dist/typecheck/typecheck-serialization.d.ts.map +1 -0
- package/dist/typecheck/typecheck-serialization.js.map +1 -0
- package/dist/utils/diagnostic-utils.d.ts +5 -0
- package/dist/utils/diagnostic-utils.d.ts.map +1 -1
- package/dist/utils/diagnostic-utils.js +15 -0
- package/dist/utils/diagnostic-utils.js.map +1 -1
- package/dist/utils/orchestrator-utils.d.ts +1 -5
- package/dist/utils/orchestrator-utils.d.ts.map +1 -1
- package/dist/utils/orchestrator-utils.js +2 -5
- package/dist/utils/orchestrator-utils.js.map +1 -1
- package/dist/utils/output-utils.d.ts +1 -1
- package/dist/utils/output-utils.d.ts.map +1 -1
- package/dist/utils/package-classify.d.ts +54 -0
- package/dist/utils/package-classify.d.ts.map +1 -0
- package/dist/utils/package-classify.js +134 -0
- package/dist/utils/package-classify.js.map +1 -0
- package/dist/utils/package-utils.d.ts +1 -58
- package/dist/utils/package-utils.d.ts.map +1 -1
- package/dist/utils/package-utils.js +0 -193
- package/dist/utils/package-utils.js.map +1 -1
- package/dist/utils/tsc-build.d.ts +1 -1
- package/dist/utils/tsc-build.d.ts.map +1 -1
- package/dist/utils/tsc-build.js +1 -1
- package/dist/utils/tsc-build.js.map +1 -1
- package/dist/workers/build-change-filter.d.ts +8 -0
- package/dist/workers/build-change-filter.d.ts.map +1 -0
- package/dist/workers/build-change-filter.js +16 -0
- package/dist/workers/build-change-filter.js.map +1 -0
- package/dist/workers/build-watch-paths.d.ts +20 -0
- package/dist/workers/build-watch-paths.d.ts.map +1 -0
- package/dist/workers/build-watch-paths.js +29 -0
- package/dist/workers/build-watch-paths.js.map +1 -0
- package/dist/workers/client.worker.d.ts +11 -18
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +218 -289
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/library-build.worker.d.ts +2 -2
- package/dist/workers/library-build.worker.d.ts.map +1 -1
- package/dist/workers/library-build.worker.js +13 -24
- package/dist/workers/library-build.worker.js.map +1 -1
- package/dist/workers/lint.worker.d.ts +1 -1
- package/dist/workers/lint.worker.d.ts.map +1 -1
- package/dist/workers/lint.worker.js +1 -1
- package/dist/workers/lint.worker.js.map +1 -1
- package/dist/workers/ngtsc-build.worker.d.ts +1 -1
- package/dist/workers/ngtsc-build.worker.d.ts.map +1 -1
- package/dist/workers/ngtsc-build.worker.js +19 -35
- package/dist/workers/ngtsc-build.worker.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts +2 -2
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +36 -137
- package/dist/workers/server-build.worker.js.map +1 -1
- package/dist/workers/server-esbuild-context.d.ts +47 -0
- package/dist/workers/server-esbuild-context.d.ts.map +1 -0
- package/dist/workers/server-esbuild-context.js +92 -0
- package/dist/workers/server-esbuild-context.js.map +1 -0
- package/dist/workers/server-runtime.worker.d.ts.map +1 -1
- package/dist/workers/server-runtime.worker.js +3 -1
- package/dist/workers/server-runtime.worker.js.map +1 -1
- package/dist/workers/server-watch-manager.d.ts +44 -0
- package/dist/workers/server-watch-manager.d.ts.map +1 -0
- package/dist/workers/server-watch-manager.js +87 -0
- package/dist/workers/server-watch-manager.js.map +1 -0
- package/dist/workers/shared-worker-lifecycle.d.ts +14 -0
- package/dist/workers/shared-worker-lifecycle.d.ts.map +1 -0
- package/dist/workers/shared-worker-lifecycle.js +17 -0
- package/dist/workers/shared-worker-lifecycle.js.map +1 -0
- package/package.json +9 -9
- package/src/{utils → angular}/angular-build-pipeline.ts +3 -8
- package/src/{utils → angular}/angular-build.ts +1 -1
- package/src/{utils → angular}/angular-compiler.ts +1 -64
- package/src/angular/client-transform-stylesheet.ts +1 -1
- package/src/{utils → angular}/ngtsc-build-core.ts +3 -3
- package/src/angular/vite-angular-plugin.ts +22 -355
- package/src/capacitor/capacitor-build.ts +142 -0
- package/src/capacitor/capacitor-config-writer.ts +66 -0
- package/src/capacitor/capacitor-icon.ts +75 -0
- package/src/capacitor/capacitor-npm-config.ts +192 -0
- package/src/capacitor/capacitor.ts +32 -441
- package/src/commands/check.ts +2 -2
- package/src/commands/dev.ts +6 -6
- package/src/commands/lint.ts +1 -1
- package/src/commands/publish/deployment-phase.ts +125 -0
- package/src/commands/publish/env-utils.ts +44 -0
- package/src/commands/publish/git-phase.ts +99 -0
- package/src/commands/publish/index.ts +266 -0
- package/src/commands/publish/local-publisher.ts +23 -0
- package/src/commands/publish/npm-publisher.ts +30 -0
- package/src/commands/publish/post-publish-phase.ts +43 -0
- package/src/commands/publish/storage-publisher.ts +208 -0
- package/src/commands/publish/version-upgrade.ts +132 -0
- package/src/commands/replace-deps.ts +1 -1
- package/src/commands/watch.ts +6 -7
- package/src/deps/replace-deps/collect-deps.ts +92 -0
- package/src/{utils/replace-deps.ts → deps/replace-deps/replace-deps-resolve.ts} +4 -188
- package/src/deps/replace-deps/replace-deps.ts +193 -0
- package/src/{utils → deps/server-externals}/server-production-files.ts +2 -2
- package/src/dev-server/dev-http-server.ts +149 -0
- package/src/dev-server/hmr-client-script.ts +74 -0
- package/src/dev-server/hmr-service.ts +178 -0
- package/src/electron/electron.ts +21 -28
- package/src/engines/BaseEngine.ts +64 -83
- package/src/engines/{ViteEngine.ts → EsbuildClientEngine.ts} +33 -72
- package/src/engines/NgtscEngine.ts +3 -11
- package/src/engines/ServerEsbuildEngine.ts +3 -11
- package/src/engines/TscEngine.ts +3 -11
- package/src/engines/index.ts +29 -9
- package/src/engines/types.ts +3 -3
- package/src/esbuild/esbuild-client-config.ts +230 -0
- package/src/{utils → esbuild}/esbuild-config.ts +1 -0
- package/src/esbuild/esbuild-index-html.ts +119 -0
- package/src/esbuild/esbuild-pwa.ts +139 -0
- package/src/esbuild/esbuild-scss-plugin.ts +48 -0
- package/src/orchestrators/BaseOrchestrator.ts +118 -0
- package/src/orchestrators/BuildOrchestrator.ts +234 -171
- package/src/orchestrators/DevOrchestrator.ts +315 -0
- package/src/orchestrators/ServerRuntimeManager.ts +85 -0
- package/src/orchestrators/TypecheckOrchestrator.ts +166 -117
- package/src/orchestrators/WatchOrchestrator.ts +203 -0
- package/src/orchestrators/types.ts +18 -0
- package/src/{utils → runtime}/engine-stop.ts +1 -1
- package/src/runtime/engine-watch-events.ts +121 -0
- package/src/{utils → runtime}/rebuild-manager.ts +8 -1
- package/src/runtime/worker-events.ts +25 -0
- package/src/sd-cli-entry.ts +69 -54
- package/src/sd-cli.ts +1 -1
- package/src/sd-config.types.ts +6 -16
- package/src/{utils → typecheck}/typecheck-non-package.ts +1 -1
- package/src/utils/diagnostic-utils.ts +15 -0
- package/src/utils/orchestrator-utils.ts +2 -6
- package/src/utils/output-utils.ts +1 -1
- package/src/utils/package-classify.ts +182 -0
- package/src/utils/package-utils.ts +0 -257
- package/src/utils/tsc-build.ts +1 -1
- package/src/workers/build-change-filter.ts +27 -0
- package/src/workers/build-watch-paths.ts +54 -0
- package/src/workers/client.worker.ts +258 -328
- package/src/workers/library-build.worker.ts +15 -34
- package/src/workers/lint.worker.ts +1 -1
- package/src/workers/ngtsc-build.worker.ts +19 -46
- package/src/workers/server-build.worker.ts +38 -168
- package/src/workers/server-esbuild-context.ts +122 -0
- package/src/workers/server-runtime.worker.ts +4 -1
- package/src/workers/server-watch-manager.ts +124 -0
- package/src/workers/shared-worker-lifecycle.ts +24 -0
- package/tests/angular/angular-build-pipeline.spec.ts +2 -2
- package/tests/angular/angular-compiler-aot.acc.spec.ts +68 -0
- package/tests/angular/angular-compiler-aot.spec.ts +80 -0
- package/tests/angular/angular-compiler-hmr-removal.verify.md +16 -0
- package/tests/angular/vite-angular-plugin-legacy-watch.spec.ts +0 -17
- package/tests/angular/vite-angular-plugin-vitest.spec.ts +1 -6
- package/tests/angular/vite-angular-plugin-vitest.verify.md +20 -0
- package/tests/angular/vite-angular-plugin.spec.ts +4 -178
- package/tests/capacitor/capacitor-android.spec.ts +1 -0
- package/tests/capacitor/capacitor-build.spec.ts +1 -0
- package/tests/capacitor/capacitor-config-writer.acc.spec.ts +108 -0
- package/tests/capacitor/capacitor-config-writer.spec.ts +95 -0
- package/tests/capacitor/capacitor-icon.spec.ts +1 -0
- package/tests/capacitor/capacitor-init.spec.ts +1 -0
- package/tests/capacitor/capacitor-npm-config.acc.spec.ts +236 -0
- package/tests/capacitor/capacitor-npm-config.spec.ts +132 -0
- package/tests/capacitor/capacitor-run.spec.ts +1 -0
- package/tests/capacitor/capacitor-workspace.spec.ts +1 -0
- package/tests/commands/check.spec.ts +2 -2
- package/tests/commands/deployment-phase.acc.spec.ts +142 -0
- package/tests/commands/git-phase.acc.spec.ts +158 -0
- package/tests/commands/lint.spec.ts +1 -1
- package/tests/commands/post-publish-phase.acc.spec.ts +82 -0
- package/tests/commands/publish-npm-local-split.verify.md +9 -0
- package/tests/commands/publish-responsibility-split.verify.md +13 -0
- package/tests/commands/publish-storage-split.verify.md +8 -0
- package/tests/commands/publish.spec.ts +1 -1
- package/tests/commands/typecheck.spec.ts +18 -18
- package/tests/deps/deps-directory-separation.verify.md +15 -0
- package/tests/engines/base-engine.spec.ts +65 -6
- package/tests/engines/engine-adapter-isolation.spec.ts +11 -18
- package/tests/engines/engine-selection.spec.ts +38 -5
- package/tests/engines/engine-typecheck-selection.acc.spec.ts +85 -0
- package/tests/engines/engine-typecheck-selection.verify.md +8 -0
- package/tests/engines/esbuild-client-engine.acc.spec.ts +161 -0
- package/tests/engines/esbuild-client-engine.spec.ts +320 -0
- package/tests/engines/esbuild-client-engine.verify.md +15 -0
- package/tests/engines/normalize-result.verify.md +9 -0
- package/tests/engines/vite-dependency-cleanup.verify.md +24 -0
- package/tests/orchestrators/build-orchestrator.spec.ts +3 -3
- package/tests/orchestrators/dev-orchestrator.spec.ts +799 -0
- package/tests/orchestrators/orchestrator-baseenv.verify.md +10 -0
- package/tests/orchestrators/orchestrator-diagnostic-formatting.verify.md +10 -0
- package/tests/orchestrators/orchestrator-initializemode-signature.verify.md +9 -0
- package/tests/orchestrators/typecheck-orchestrator.spec.ts +11 -11
- package/tests/orchestrators/watch-orchestrator.spec.ts +511 -0
- package/tests/{infra → runtime}/result-collector.spec.ts +1 -1
- package/tests/{infra → runtime}/signal-handler.spec.ts +1 -1
- package/tests/sd-cli-entry.spec.ts +9 -0
- package/tests/utils/angular-build.spec.ts +15 -20
- package/tests/utils/angular-compiler-emit.spec.ts +2 -2
- package/tests/utils/angular-compiler.spec.ts +2 -2
- package/tests/utils/angular-source-file-cache.spec.ts +2 -2
- package/tests/utils/concurrency.spec.ts +2 -10
- package/tests/utils/dev-http-server.acc.spec.ts +206 -0
- package/tests/utils/dev-http-server.spec.ts +181 -0
- package/tests/utils/dev-http-server.verify.md +8 -0
- package/tests/utils/diagnostic-utils.spec.ts +42 -1
- package/tests/utils/engine-stop.spec.ts +1 -1
- package/tests/utils/engine-watch-events.acc.spec.ts +217 -0
- package/tests/utils/engine-watch-events.spec.ts +141 -0
- package/tests/utils/engine-watch-events.verify.md +17 -0
- package/tests/utils/esbuild-client-config.acc.spec.ts +443 -0
- package/tests/utils/esbuild-client-config.spec.ts +590 -0
- package/tests/utils/esbuild-client-config.verify.md +26 -0
- package/tests/utils/esbuild-config.spec.ts +11 -1
- package/tests/utils/esbuild-index-html.acc.spec.ts +166 -0
- package/tests/utils/esbuild-index-html.spec.ts +194 -0
- package/tests/utils/esbuild-index-html.verify.md +10 -0
- package/tests/utils/esbuild-pwa.acc.spec.ts +203 -0
- package/tests/utils/esbuild-pwa.spec.ts +189 -0
- package/tests/utils/esbuild-pwa.verify.md +9 -0
- package/tests/utils/esbuild-scss-plugin.acc.spec.ts +111 -0
- package/tests/utils/esbuild-scss-plugin.spec.ts +150 -0
- package/tests/utils/esbuild-scss-plugin.verify.md +8 -0
- package/tests/utils/external-modules.spec.ts +1 -1
- package/tests/utils/hmr-client-script.acc.spec.ts +128 -0
- package/tests/utils/hmr-client-script.spec.ts +44 -0
- package/tests/utils/hmr-service-dispatcher.acc.spec.ts +217 -0
- package/tests/utils/hmr-service-dispatcher.spec.ts +143 -0
- package/tests/utils/hmr-service.acc.spec.ts +139 -0
- package/tests/utils/hmr-service.spec.ts +131 -0
- package/tests/utils/hmr-service.verify.md +17 -0
- package/tests/utils/lint-core.spec.ts +2 -1
- package/tests/utils/lint-utils.spec.ts +1 -1
- package/tests/utils/lint-with-program.spec.ts +1 -1
- package/tests/utils/ngtsc-build-core-write-emit.spec.ts +19 -19
- package/tests/utils/ngtsc-build-core.spec.ts +4 -4
- package/tests/utils/orchestrator-utils.spec.ts +2 -2
- package/tests/utils/output-utils.spec.ts +1 -1
- package/tests/utils/package-utils.spec.ts +1 -1
- package/tests/utils/rebuild-manager.spec.ts +20 -7
- package/tests/utils/replace-deps-split.verify.md +15 -0
- package/tests/utils/replace-deps-watch.acc.spec.ts +131 -0
- package/tests/utils/replace-deps-watch.spec.ts +91 -0
- package/tests/utils/replace-deps-watch.verify.md +9 -0
- package/tests/utils/replace-deps.spec.ts +1 -1
- package/tests/utils/scss-compiler.spec.ts +1 -1
- package/tests/utils/tsc-build.spec.ts +1 -1
- package/tests/utils/typecheck-non-package.spec.ts +2 -2
- package/tests/utils/worker-utils.spec.ts +2 -1
- package/tests/workers/build-change-filter.acc.spec.ts +78 -0
- package/tests/workers/build-change-filter.spec.ts +39 -0
- package/tests/workers/build-watch-paths-library.verify.md +10 -0
- package/tests/workers/build-watch-paths-ngtsc-server.verify.md +12 -0
- package/tests/workers/build-watch-paths.acc.spec.ts +101 -0
- package/tests/workers/build-watch-paths.spec.ts +121 -0
- package/tests/workers/client-worker-browser-support.verify.md +7 -0
- package/tests/workers/client-worker-onend-sync.verify.md +7 -0
- package/tests/workers/client-worker.acc.spec.ts +185 -0
- package/tests/workers/client-worker.spec.ts +91 -178
- package/tests/workers/library-build-lint.spec.ts +3 -3
- package/tests/workers/library-build-worker.spec.ts +10 -11
- package/tests/workers/ngtsc-build-lint.spec.ts +4 -4
- package/tests/workers/ngtsc-build-worker.spec.ts +2 -2
- package/tests/workers/server-build-lint.spec.ts +4 -4
- package/tests/workers/server-build-worker.spec.ts +14 -15
- package/tests/workers/server-esbuild-context-integration.verify.md +10 -0
- package/tests/workers/server-esbuild-context.acc.spec.ts +98 -0
- package/tests/workers/server-esbuild-context.spec.ts +198 -0
- package/tests/workers/server-runtime-worker.spec.ts +4 -3
- package/tests/workers/server-watch-manager.acc.spec.ts +162 -0
- package/tests/workers/server-watch-manager.spec.ts +199 -0
- package/tests/workers/shared-worker-lifecycle.acc.spec.ts +27 -0
- package/tests/workers/shared-worker-lifecycle.spec.ts +47 -0
- package/dist/angular/vite-postcss-inline-plugin.d.ts +0 -18
- package/dist/angular/vite-postcss-inline-plugin.d.ts.map +0 -1
- package/dist/angular/vite-postcss-inline-plugin.js +0 -108
- package/dist/angular/vite-postcss-inline-plugin.js.map +0 -1
- package/dist/commands/publish.d.ts.map +0 -1
- package/dist/commands/publish.js +0 -689
- package/dist/commands/publish.js.map +0 -1
- package/dist/engines/ViteEngine.d.ts.map +0 -1
- package/dist/engines/ViteEngine.js.map +0 -1
- package/dist/infra/ResultCollector.d.ts.map +0 -1
- package/dist/infra/ResultCollector.js.map +0 -1
- package/dist/infra/SignalHandler.d.ts.map +0 -1
- package/dist/infra/SignalHandler.js.map +0 -1
- package/dist/orchestrators/DevWatchOrchestrator.d.ts +0 -63
- package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +0 -1
- package/dist/orchestrators/DevWatchOrchestrator.js +0 -478
- package/dist/orchestrators/DevWatchOrchestrator.js.map +0 -1
- package/dist/utils/angular-build-pipeline.d.ts.map +0 -1
- package/dist/utils/angular-build-pipeline.js.map +0 -1
- package/dist/utils/angular-build.d.ts.map +0 -1
- package/dist/utils/angular-build.js.map +0 -1
- package/dist/utils/angular-compiler.d.ts.map +0 -1
- package/dist/utils/angular-compiler.js.map +0 -1
- package/dist/utils/engine-stop.d.ts.map +0 -1
- package/dist/utils/engine-stop.js.map +0 -1
- package/dist/utils/esbuild-config.d.ts.map +0 -1
- package/dist/utils/esbuild-config.js.map +0 -1
- package/dist/utils/hmr-candidates.d.ts +0 -15
- package/dist/utils/hmr-candidates.d.ts.map +0 -1
- package/dist/utils/hmr-candidates.js +0 -234
- package/dist/utils/hmr-candidates.js.map +0 -1
- package/dist/utils/lint-core.d.ts.map +0 -1
- package/dist/utils/lint-core.js.map +0 -1
- package/dist/utils/lint-utils.d.ts.map +0 -1
- package/dist/utils/lint-utils.js.map +0 -1
- package/dist/utils/lint-with-program.d.ts.map +0 -1
- package/dist/utils/lint-with-program.js.map +0 -1
- package/dist/utils/ngtsc-build-core.d.ts.map +0 -1
- package/dist/utils/ngtsc-build-core.js.map +0 -1
- package/dist/utils/rebuild-manager.d.ts.map +0 -1
- package/dist/utils/rebuild-manager.js.map +0 -1
- package/dist/utils/replace-deps.d.ts.map +0 -1
- package/dist/utils/replace-deps.js.map +0 -1
- package/dist/utils/scss-compiler.d.ts.map +0 -1
- package/dist/utils/scss-compiler.js.map +0 -1
- package/dist/utils/server-production-files.d.ts.map +0 -1
- package/dist/utils/server-production-files.js.map +0 -1
- package/dist/utils/typecheck-non-package.d.ts.map +0 -1
- package/dist/utils/typecheck-non-package.js.map +0 -1
- package/dist/utils/typecheck-serialization.d.ts.map +0 -1
- package/dist/utils/typecheck-serialization.js.map +0 -1
- package/dist/utils/vite-config.d.ts +0 -50
- package/dist/utils/vite-config.d.ts.map +0 -1
- package/dist/utils/vite-config.js +0 -242
- package/dist/utils/vite-config.js.map +0 -1
- package/dist/utils/vite-pwa-plugin.d.ts +0 -9
- package/dist/utils/vite-pwa-plugin.d.ts.map +0 -1
- package/dist/utils/vite-pwa-plugin.js +0 -139
- package/dist/utils/vite-pwa-plugin.js.map +0 -1
- package/dist/utils/vite-scope-watch-plugin.d.ts +0 -24
- package/dist/utils/vite-scope-watch-plugin.d.ts.map +0 -1
- package/dist/utils/vite-scope-watch-plugin.js +0 -51
- package/dist/utils/vite-scope-watch-plugin.js.map +0 -1
- package/dist/utils/worker-events.d.ts +0 -66
- package/dist/utils/worker-events.d.ts.map +0 -1
- package/dist/utils/worker-events.js +0 -55
- package/dist/utils/worker-events.js.map +0 -1
- package/dist/utils/worker-utils.d.ts.map +0 -1
- package/dist/utils/worker-utils.js.map +0 -1
- package/src/angular/vite-postcss-inline-plugin.ts +0 -139
- package/src/commands/publish.ts +0 -850
- package/src/orchestrators/DevWatchOrchestrator.ts +0 -594
- package/src/utils/hmr-candidates.ts +0 -327
- package/src/utils/vite-config.ts +0 -318
- package/src/utils/vite-pwa-plugin.ts +0 -168
- package/src/utils/vite-scope-watch-plugin.ts +0 -77
- package/src/utils/worker-events.ts +0 -128
- package/tests/angular/angular-compiler-hmr.spec.ts +0 -152
- package/tests/angular/hmr-candidates.spec.ts +0 -158
- package/tests/angular/linker-disk-cache.spec.ts +0 -171
- package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +0 -333
- package/tests/angular/vite-angular-plugin-hmr.spec.ts +0 -320
- package/tests/angular/vite-angular-plugin-scss-hmr.spec.ts +0 -95
- package/tests/angular/vite-postcss-inline-plugin.spec.ts +0 -60
- package/tests/engines/vite-engine.spec.ts +0 -409
- package/tests/orchestrators/dev-watch-orchestrator.spec.ts +0 -1542
- package/tests/utils/vite-config.spec.ts +0 -780
- package/tests/utils/vite-pwa-plugin.spec.ts +0 -401
- package/tests/utils/vite-scope-watch-plugin.spec.ts +0 -218
- package/tests/utils/worker-events.spec.ts +0 -147
- package/tests/workers/client-worker-legacy.spec.ts +0 -659
- /package/dist/{utils → angular}/ngtsc-build-core.js +0 -0
- /package/dist/{utils → angular}/scss-compiler.d.ts +0 -0
- /package/dist/{utils → angular}/scss-compiler.js +0 -0
- /package/dist/{utils → esbuild}/esbuild-config.d.ts +0 -0
- /package/dist/{utils → lint}/lint-core.d.ts +0 -0
- /package/dist/{utils → lint}/lint-core.js +0 -0
- /package/dist/{utils → lint}/lint-utils.d.ts +0 -0
- /package/dist/{utils → lint}/lint-utils.js +0 -0
- /package/dist/{utils → lint}/lint-with-program.d.ts +0 -0
- /package/dist/{utils → lint}/lint-with-program.js +0 -0
- /package/dist/{infra → runtime}/ResultCollector.d.ts +0 -0
- /package/dist/{infra → runtime}/ResultCollector.js +0 -0
- /package/dist/{infra → runtime}/SignalHandler.d.ts +0 -0
- /package/dist/{infra → runtime}/SignalHandler.js +0 -0
- /package/dist/{utils → runtime}/worker-utils.d.ts +0 -0
- /package/dist/{utils → runtime}/worker-utils.js +0 -0
- /package/dist/{utils → typecheck}/typecheck-non-package.d.ts +0 -0
- /package/dist/{utils → typecheck}/typecheck-serialization.d.ts +0 -0
- /package/dist/{utils → typecheck}/typecheck-serialization.js +0 -0
- /package/src/{utils → angular}/scss-compiler.ts +0 -0
- /package/src/{utils → lint}/lint-core.ts +0 -0
- /package/src/{utils → lint}/lint-utils.ts +0 -0
- /package/src/{utils → lint}/lint-with-program.ts +0 -0
- /package/src/{infra → runtime}/ResultCollector.ts +0 -0
- /package/src/{infra → runtime}/SignalHandler.ts +0 -0
- /package/src/{utils → runtime}/worker-utils.ts +0 -0
- /package/src/{utils → typecheck}/typecheck-serialization.ts +0 -0
|
@@ -1,1542 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
|
|
3
|
-
// --- Mock factories (vi.mock is hoisted) ---
|
|
4
|
-
|
|
5
|
-
vi.mock("../../src/utils/sd-config", () => ({
|
|
6
|
-
loadSdConfig: vi.fn(),
|
|
7
|
-
}));
|
|
8
|
-
|
|
9
|
-
vi.mock("../../src/utils/build-env", () => ({
|
|
10
|
-
getVersion: vi.fn(),
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
vi.mock("../../src/utils/replace-deps", () => ({
|
|
14
|
-
watchReplaceDeps: vi.fn(),
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
vi.mock("../../src/utils/output-utils", async (importOriginal) => {
|
|
18
|
-
const actual = await importOriginal<typeof import("../../src/utils/output-utils")>();
|
|
19
|
-
return {
|
|
20
|
-
...actual,
|
|
21
|
-
printErrors: vi.fn(),
|
|
22
|
-
printServers: vi.fn(),
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
vi.mock("../../src/infra/SignalHandler", () => ({
|
|
27
|
-
SignalHandler: vi.fn().mockImplementation(function (this: any) {
|
|
28
|
-
this.waitForTermination = vi.fn().mockResolvedValue(undefined);
|
|
29
|
-
this.isTerminated = vi.fn().mockReturnValue(false);
|
|
30
|
-
this.requestTermination = vi.fn();
|
|
31
|
-
}),
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
vi.mock("../../src/utils/copy-src", () => ({
|
|
35
|
-
watchCopySrcFiles: vi.fn().mockResolvedValue({
|
|
36
|
-
close: vi.fn().mockResolvedValue(undefined),
|
|
37
|
-
}),
|
|
38
|
-
}));
|
|
39
|
-
|
|
40
|
-
// Engine mock — tracks created engines and the package they were created for
|
|
41
|
-
const mockBuildEngines: Array<{
|
|
42
|
-
run: ReturnType<typeof vi.fn>;
|
|
43
|
-
startWatch: ReturnType<typeof vi.fn>;
|
|
44
|
-
stop: ReturnType<typeof vi.fn>;
|
|
45
|
-
_pkgName: string;
|
|
46
|
-
}> = [];
|
|
47
|
-
|
|
48
|
-
vi.mock("../../src/engines/index", () => ({
|
|
49
|
-
createBuildEngine: vi.fn((pkg: any, options: any) => {
|
|
50
|
-
const engine = {
|
|
51
|
-
run: vi.fn().mockResolvedValue({
|
|
52
|
-
success: true,
|
|
53
|
-
build: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
54
|
-
}),
|
|
55
|
-
startWatch: vi.fn().mockImplementation(() => {
|
|
56
|
-
const resolve = options.rebuildManager.registerBuild(
|
|
57
|
-
`${pkg.name}:build`,
|
|
58
|
-
`${pkg.name} (${pkg.config.target})`,
|
|
59
|
-
);
|
|
60
|
-
options.resultCollector.add({
|
|
61
|
-
name: pkg.name,
|
|
62
|
-
target: pkg.config.target,
|
|
63
|
-
type: "build",
|
|
64
|
-
status: "success",
|
|
65
|
-
});
|
|
66
|
-
resolve();
|
|
67
|
-
}),
|
|
68
|
-
stop: vi.fn().mockResolvedValue(undefined),
|
|
69
|
-
_pkgName: pkg.name,
|
|
70
|
-
};
|
|
71
|
-
mockBuildEngines.push(engine);
|
|
72
|
-
return engine;
|
|
73
|
-
}),
|
|
74
|
-
}));
|
|
75
|
-
|
|
76
|
-
vi.mock("@simplysm/core-node", () => ({
|
|
77
|
-
FsWatcher: {
|
|
78
|
-
watch: vi.fn().mockResolvedValue({
|
|
79
|
-
onChange: vi.fn(),
|
|
80
|
-
close: vi.fn().mockResolvedValue(undefined),
|
|
81
|
-
}),
|
|
82
|
-
},
|
|
83
|
-
Worker: {
|
|
84
|
-
create: vi.fn(),
|
|
85
|
-
},
|
|
86
|
-
pathx: {
|
|
87
|
-
posix: vi.fn((p: string) => p.replace(/\\/g, "/")),
|
|
88
|
-
posixResolve: vi.fn((...args: string[]) => args.join("/").replace(/\\/g, "/")),
|
|
89
|
-
isChildPath: vi.fn((child: string, parent: string) => child.startsWith(parent + "/")),
|
|
90
|
-
filterByTargets: vi.fn((files: string[], targets: string[]) => targets.length === 0 ? files : files),
|
|
91
|
-
},
|
|
92
|
-
}));
|
|
93
|
-
|
|
94
|
-
vi.mock("child_process", () => ({
|
|
95
|
-
spawn: vi.fn(() => ({
|
|
96
|
-
on: vi.fn(),
|
|
97
|
-
kill: vi.fn(),
|
|
98
|
-
exitCode: 0,
|
|
99
|
-
})),
|
|
100
|
-
}));
|
|
101
|
-
|
|
102
|
-
// Capacitor mock
|
|
103
|
-
const mockCapacitorInstance = {
|
|
104
|
-
initialize: vi.fn().mockResolvedValue(undefined),
|
|
105
|
-
build: vi.fn().mockResolvedValue(undefined),
|
|
106
|
-
run: vi.fn().mockResolvedValue(undefined),
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
vi.mock("../../src/capacitor/capacitor", () => ({
|
|
110
|
-
Capacitor: {
|
|
111
|
-
create: vi.fn().mockResolvedValue(mockCapacitorInstance),
|
|
112
|
-
},
|
|
113
|
-
}));
|
|
114
|
-
|
|
115
|
-
// Electron mock
|
|
116
|
-
const mockElectronInstance = {
|
|
117
|
-
initialize: vi.fn().mockResolvedValue(undefined),
|
|
118
|
-
build: vi.fn().mockResolvedValue(undefined),
|
|
119
|
-
run: vi.fn().mockResolvedValue(undefined),
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
vi.mock("../../src/electron/electron", () => ({
|
|
123
|
-
Electron: {
|
|
124
|
-
create: vi.fn().mockResolvedValue(mockElectronInstance),
|
|
125
|
-
},
|
|
126
|
-
}));
|
|
127
|
-
|
|
128
|
-
// --- Dynamic imports after mocking ---
|
|
129
|
-
|
|
130
|
-
const { DevWatchOrchestrator } = await import("../../src/orchestrators/DevWatchOrchestrator");
|
|
131
|
-
const { loadSdConfig } = await import("../../src/utils/sd-config");
|
|
132
|
-
const { watchReplaceDeps } = await import("../../src/utils/replace-deps");
|
|
133
|
-
const { printErrors, printServers: _printServers } = await import("../../src/utils/output-utils");
|
|
134
|
-
const { createBuildEngine } = await import("../../src/engines/index");
|
|
135
|
-
const { watchCopySrcFiles } = await import("../../src/utils/copy-src");
|
|
136
|
-
const { FsWatcher, Worker } = await import("@simplysm/core-node");
|
|
137
|
-
const { spawn } = await import("child_process");
|
|
138
|
-
const { getVersion } = await import("../../src/utils/build-env");
|
|
139
|
-
|
|
140
|
-
const { Capacitor } = await import("../../src/capacitor/capacitor");
|
|
141
|
-
const { Electron } = await import("../../src/electron/electron");
|
|
142
|
-
|
|
143
|
-
import type { SdConfig } from "../../src/sd-config.types";
|
|
144
|
-
|
|
145
|
-
// --- Runtime worker mock helper ---
|
|
146
|
-
|
|
147
|
-
interface MockRuntimeProxy {
|
|
148
|
-
on: ReturnType<typeof vi.fn>;
|
|
149
|
-
start: ReturnType<typeof vi.fn>;
|
|
150
|
-
terminate: ReturnType<typeof vi.fn>;
|
|
151
|
-
emit: (event: string, data?: unknown) => void;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function createMockRuntimeProxy(): MockRuntimeProxy {
|
|
155
|
-
const handlers = new Map<string, (data: unknown) => void>();
|
|
156
|
-
return {
|
|
157
|
-
on: vi.fn((event: string, handler: (data: unknown) => void) => {
|
|
158
|
-
handlers.set(event, handler);
|
|
159
|
-
}),
|
|
160
|
-
start: vi.fn().mockResolvedValue(undefined),
|
|
161
|
-
terminate: vi.fn().mockResolvedValue(undefined),
|
|
162
|
-
emit(event: string, data?: unknown) {
|
|
163
|
-
handlers.get(event)?.(data);
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
let mockRuntimeProxies: MockRuntimeProxy[];
|
|
169
|
-
|
|
170
|
-
// Capture infra objects from engine options for tests that need direct access
|
|
171
|
-
let capturedRebuildManager: any;
|
|
172
|
-
let capturedResultCollector: any;
|
|
173
|
-
|
|
174
|
-
// --- Helpers ---
|
|
175
|
-
|
|
176
|
-
function createConfig(overrides: Partial<SdConfig> = {}): SdConfig {
|
|
177
|
-
return { packages: {}, ...overrides };
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function setupDefaults(config: SdConfig): void {
|
|
181
|
-
vi.mocked(loadSdConfig).mockResolvedValue(config);
|
|
182
|
-
vi.mocked(watchReplaceDeps).mockResolvedValue({ entries: [], dispose: vi.fn() });
|
|
183
|
-
vi.mocked(getVersion).mockResolvedValue("1.0.0");
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// --- Tests ---
|
|
187
|
-
|
|
188
|
-
describe("DevWatchOrchestrator", () => {
|
|
189
|
-
beforeEach(() => {
|
|
190
|
-
vi.clearAllMocks();
|
|
191
|
-
mockBuildEngines.length = 0;
|
|
192
|
-
mockRuntimeProxies = [];
|
|
193
|
-
capturedRebuildManager = undefined;
|
|
194
|
-
capturedResultCollector = undefined;
|
|
195
|
-
vi.spyOn(process, "cwd").mockReturnValue("/test-root");
|
|
196
|
-
vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
|
197
|
-
vi.mocked(Worker.create).mockImplementation(() => {
|
|
198
|
-
const proxy = createMockRuntimeProxy();
|
|
199
|
-
mockRuntimeProxies.push(proxy);
|
|
200
|
-
return proxy as any;
|
|
201
|
-
});
|
|
202
|
-
// Reset Capacitor/Electron instance mocks
|
|
203
|
-
mockCapacitorInstance.initialize.mockResolvedValue(undefined);
|
|
204
|
-
mockCapacitorInstance.build.mockResolvedValue(undefined);
|
|
205
|
-
mockCapacitorInstance.run.mockResolvedValue(undefined);
|
|
206
|
-
mockElectronInstance.initialize.mockResolvedValue(undefined);
|
|
207
|
-
mockElectronInstance.build.mockResolvedValue(undefined);
|
|
208
|
-
mockElectronInstance.run.mockResolvedValue(undefined);
|
|
209
|
-
vi.mocked(Capacitor.create).mockResolvedValue(mockCapacitorInstance as any);
|
|
210
|
-
vi.mocked(Electron.create).mockResolvedValue(mockElectronInstance as any);
|
|
211
|
-
// Restore default mock implementations that may have been overridden
|
|
212
|
-
vi.mocked(createBuildEngine).mockImplementation((pkg: any, options: any) => {
|
|
213
|
-
capturedRebuildManager = options.rebuildManager;
|
|
214
|
-
capturedResultCollector = options.resultCollector;
|
|
215
|
-
const engine = {
|
|
216
|
-
run: vi.fn().mockResolvedValue({
|
|
217
|
-
success: true,
|
|
218
|
-
build: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
219
|
-
}),
|
|
220
|
-
startWatch: vi.fn().mockImplementation(() => {
|
|
221
|
-
const resolve = options.rebuildManager.registerBuild(
|
|
222
|
-
`${pkg.name}:build`,
|
|
223
|
-
`${pkg.name} (${pkg.config.target})`,
|
|
224
|
-
);
|
|
225
|
-
options.resultCollector.add({
|
|
226
|
-
name: pkg.name,
|
|
227
|
-
target: pkg.config.target,
|
|
228
|
-
type: "build",
|
|
229
|
-
status: "success",
|
|
230
|
-
});
|
|
231
|
-
resolve();
|
|
232
|
-
}),
|
|
233
|
-
stop: vi.fn().mockResolvedValue(undefined),
|
|
234
|
-
_pkgName: pkg.name,
|
|
235
|
-
};
|
|
236
|
-
mockBuildEngines.push(engine);
|
|
237
|
-
return engine as any;
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
describe("Slice 1: watch mode", () => {
|
|
242
|
-
// --- Unit Tests ---
|
|
243
|
-
|
|
244
|
-
it("creates BuildEngine for library packages with correct output flags", async () => {
|
|
245
|
-
setupDefaults(createConfig({
|
|
246
|
-
packages: { "core-common": { target: "node" }, "core-browser": { target: "browser" } },
|
|
247
|
-
}));
|
|
248
|
-
|
|
249
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
250
|
-
await orchestrator.initialize();
|
|
251
|
-
|
|
252
|
-
expect(mockBuildEngines).toHaveLength(2);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it("does not create BuildEngine for server packages in watch mode", async () => {
|
|
256
|
-
setupDefaults(createConfig({
|
|
257
|
-
packages: { "service-server": { target: "server" } },
|
|
258
|
-
}));
|
|
259
|
-
|
|
260
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
261
|
-
await orchestrator.initialize();
|
|
262
|
-
|
|
263
|
-
expect(mockBuildEngines).toHaveLength(0);
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it("outputs warning when no watchable packages exist", async () => {
|
|
267
|
-
setupDefaults(createConfig({
|
|
268
|
-
packages: { "sd-scripts": { target: "scripts" } },
|
|
269
|
-
}));
|
|
270
|
-
|
|
271
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
272
|
-
await orchestrator.initialize();
|
|
273
|
-
|
|
274
|
-
expect(mockBuildEngines).toHaveLength(0);
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
// --- Acceptance: Scenario 1 — watch 모드는 Library + Scripts만 대상 (server 제외) ---
|
|
278
|
-
it("processes Library and Scripts packages in watch mode, excludes server", async () => {
|
|
279
|
-
setupDefaults(createConfig({
|
|
280
|
-
packages: {
|
|
281
|
-
"core-common": { target: "node" },
|
|
282
|
-
"service-server": { target: "server" },
|
|
283
|
-
"sd-scripts": { target: "scripts", watch: { target: ["dist/**/*.js"], cmd: "node" } },
|
|
284
|
-
},
|
|
285
|
-
}));
|
|
286
|
-
|
|
287
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
288
|
-
await orchestrator.initialize();
|
|
289
|
-
await orchestrator.start();
|
|
290
|
-
|
|
291
|
-
// Library only = 1 engine (server excluded)
|
|
292
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
293
|
-
expect(mockBuildEngines[0]._pkgName).toBe("core-common");
|
|
294
|
-
|
|
295
|
-
// Library engine: startWatch with js+dts
|
|
296
|
-
const libraryEngine = mockBuildEngines.find((e) => e._pkgName === "core-common")!;
|
|
297
|
-
expect(libraryEngine.startWatch).toHaveBeenCalledWith({ js: true, dts: true, lint: false });
|
|
298
|
-
|
|
299
|
-
// Scripts+watch: spawn called for hook
|
|
300
|
-
expect(spawn).toHaveBeenCalled();
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// --- Acceptance: Scenario 2 — 통합 Orchestrator가 공통 인프라를 사용한다 ---
|
|
304
|
-
it("uses ResultCollector and RebuildManager for build lifecycle", async () => {
|
|
305
|
-
setupDefaults(createConfig({
|
|
306
|
-
packages: { "core-common": { target: "node" } },
|
|
307
|
-
}));
|
|
308
|
-
|
|
309
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
310
|
-
await orchestrator.initialize();
|
|
311
|
-
await orchestrator.start();
|
|
312
|
-
|
|
313
|
-
// 실제 인프라가 동작하여 batchComplete 후 printErrors가 호출됨
|
|
314
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
315
|
-
expect(printErrors).toHaveBeenCalled();
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
// --- Acceptance: Scenario 3 — Library 패키지 watch ---
|
|
319
|
-
it("starts library engine with js+dts output", async () => {
|
|
320
|
-
setupDefaults(createConfig({
|
|
321
|
-
packages: {
|
|
322
|
-
"core-common": { target: "node" },
|
|
323
|
-
"core-browser": { target: "browser" },
|
|
324
|
-
"storage": { target: "neutral" },
|
|
325
|
-
},
|
|
326
|
-
}));
|
|
327
|
-
|
|
328
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
329
|
-
await orchestrator.initialize();
|
|
330
|
-
await orchestrator.start();
|
|
331
|
-
|
|
332
|
-
for (const engine of mockBuildEngines) {
|
|
333
|
-
expect(engine.startWatch).toHaveBeenCalledWith({ js: true, dts: true, lint: false });
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
// --- Acceptance: Scenario 4 — Server 패키지는 watch에서 제외 ---
|
|
338
|
-
it("excludes server packages from watch mode entirely", async () => {
|
|
339
|
-
setupDefaults(createConfig({
|
|
340
|
-
packages: {
|
|
341
|
-
"core-common": { target: "node" },
|
|
342
|
-
"service-server": { target: "server" },
|
|
343
|
-
},
|
|
344
|
-
}));
|
|
345
|
-
|
|
346
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
347
|
-
await orchestrator.initialize();
|
|
348
|
-
await orchestrator.start();
|
|
349
|
-
|
|
350
|
-
// Only library engine created, no server engine
|
|
351
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
352
|
-
expect(mockBuildEngines[0]._pkgName).toBe("core-common");
|
|
353
|
-
expect(Worker.create).not.toHaveBeenCalled();
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
// --- Acceptance: Scenario 5 — Scripts+watch 패키지 hook 실행 ---
|
|
357
|
-
it("runs initial hook and starts file watcher for scripts+watch packages", async () => {
|
|
358
|
-
setupDefaults(createConfig({
|
|
359
|
-
packages: {
|
|
360
|
-
"sd-scripts": {
|
|
361
|
-
target: "scripts",
|
|
362
|
-
watch: { target: ["dist/**/*.js"], cmd: "node", args: ["run-task.js"] },
|
|
363
|
-
},
|
|
364
|
-
},
|
|
365
|
-
}));
|
|
366
|
-
|
|
367
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
368
|
-
await orchestrator.initialize();
|
|
369
|
-
await orchestrator.start();
|
|
370
|
-
|
|
371
|
-
expect(spawn).toHaveBeenCalledWith("node", ["run-task.js"], expect.objectContaining({ shell: true }));
|
|
372
|
-
expect(FsWatcher.watch).toHaveBeenCalled();
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
// Unit: file change re-runs hook
|
|
376
|
-
it("re-runs watch hook when watched files change", async () => {
|
|
377
|
-
let onChangeCallback: (...args: any[]) => void = () => {};
|
|
378
|
-
vi.mocked(FsWatcher.watch).mockResolvedValue({
|
|
379
|
-
onChange: vi.fn((_opts: any, cb: any) => { onChangeCallback = cb; }),
|
|
380
|
-
close: vi.fn().mockResolvedValue(undefined),
|
|
381
|
-
} as any);
|
|
382
|
-
|
|
383
|
-
setupDefaults(createConfig({
|
|
384
|
-
packages: {
|
|
385
|
-
"sd-scripts": {
|
|
386
|
-
target: "scripts",
|
|
387
|
-
watch: { target: ["dist/**/*.js"], cmd: "node", args: ["run-task.js"] },
|
|
388
|
-
},
|
|
389
|
-
},
|
|
390
|
-
}));
|
|
391
|
-
|
|
392
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
393
|
-
await orchestrator.initialize();
|
|
394
|
-
await orchestrator.start();
|
|
395
|
-
|
|
396
|
-
expect(spawn).toHaveBeenCalledTimes(1);
|
|
397
|
-
onChangeCallback();
|
|
398
|
-
expect(spawn).toHaveBeenCalledTimes(2);
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
// --- Acceptance: Scenario 6 — watch에서 copySrc 파일 감시 ---
|
|
402
|
-
it("starts copySrc watcher when library package has copySrc config", async () => {
|
|
403
|
-
setupDefaults(createConfig({
|
|
404
|
-
packages: {
|
|
405
|
-
"core-common": { target: "node", copySrc: ["**/*.json"] },
|
|
406
|
-
},
|
|
407
|
-
}));
|
|
408
|
-
|
|
409
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
410
|
-
await orchestrator.initialize();
|
|
411
|
-
await orchestrator.start();
|
|
412
|
-
|
|
413
|
-
expect(watchCopySrcFiles).toHaveBeenCalledWith(
|
|
414
|
-
expect.stringContaining("core-common"),
|
|
415
|
-
["**/*.json"],
|
|
416
|
-
);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
// Unit: no copySrc watcher when config absent
|
|
420
|
-
it("does not start copySrc watcher when config is absent", async () => {
|
|
421
|
-
setupDefaults(createConfig({
|
|
422
|
-
packages: { "core-common": { target: "node" } },
|
|
423
|
-
}));
|
|
424
|
-
|
|
425
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
426
|
-
await orchestrator.initialize();
|
|
427
|
-
await orchestrator.start();
|
|
428
|
-
|
|
429
|
-
expect(watchCopySrcFiles).not.toHaveBeenCalled();
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
// --- Acceptance: Library 패키지에 watch hook 설정 시 빌드 엔진 + hook 동시 실행 ---
|
|
433
|
-
it("runs both build engine and watch hook for library package with watch config", async () => {
|
|
434
|
-
setupDefaults(createConfig({
|
|
435
|
-
packages: {
|
|
436
|
-
"core-common": {
|
|
437
|
-
target: "node",
|
|
438
|
-
watch: { target: ["scripts/**/*.mjs"], cmd: "node", args: ["sync.mjs"] },
|
|
439
|
-
},
|
|
440
|
-
},
|
|
441
|
-
}));
|
|
442
|
-
|
|
443
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
444
|
-
await orchestrator.initialize();
|
|
445
|
-
await orchestrator.start();
|
|
446
|
-
|
|
447
|
-
// Build engine created and started
|
|
448
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
449
|
-
const libraryEngine = mockBuildEngines.find((e) => e._pkgName === "core-common")!;
|
|
450
|
-
expect(libraryEngine.startWatch).toHaveBeenCalledWith({ js: true, dts: true, lint: false });
|
|
451
|
-
|
|
452
|
-
// Watch hook also executed
|
|
453
|
-
expect(spawn).toHaveBeenCalledWith("node", ["sync.mjs"], expect.objectContaining({ shell: true }));
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
// --- Unit: Library 패키지에 watch hook 없으면 hook 미실행 ---
|
|
457
|
-
it("does not run watch hook for library package without watch config", async () => {
|
|
458
|
-
setupDefaults(createConfig({
|
|
459
|
-
packages: { "core-common": { target: "node" } },
|
|
460
|
-
}));
|
|
461
|
-
|
|
462
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
463
|
-
await orchestrator.initialize();
|
|
464
|
-
await orchestrator.start();
|
|
465
|
-
|
|
466
|
-
// Build engine created
|
|
467
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
468
|
-
// No hook
|
|
469
|
-
expect(spawn).not.toHaveBeenCalled();
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
// --- Acceptance: Scenario 7 — watch에서 replaceDeps 감시 ---
|
|
473
|
-
it("starts replaceDeps watcher when config exists", async () => {
|
|
474
|
-
const replaceDeps = { "@simplysm/*": "packages/*/src" };
|
|
475
|
-
setupDefaults(createConfig({
|
|
476
|
-
packages: { "core-common": { target: "node" } },
|
|
477
|
-
replaceDeps,
|
|
478
|
-
}));
|
|
479
|
-
|
|
480
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
481
|
-
await orchestrator.initialize();
|
|
482
|
-
|
|
483
|
-
expect(watchReplaceDeps).toHaveBeenCalledWith("/test-root", replaceDeps);
|
|
484
|
-
});
|
|
485
|
-
|
|
486
|
-
// Unit: no replaceDeps watcher when config absent
|
|
487
|
-
it("does not start replaceDeps watcher when config is absent", async () => {
|
|
488
|
-
setupDefaults(createConfig({
|
|
489
|
-
packages: { "core-common": { target: "node" } },
|
|
490
|
-
}));
|
|
491
|
-
|
|
492
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
493
|
-
await orchestrator.initialize();
|
|
494
|
-
|
|
495
|
-
expect(watchReplaceDeps).not.toHaveBeenCalled();
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
// --- Shutdown tests ---
|
|
499
|
-
|
|
500
|
-
it("stops all engines, closes watchers, and disposes replaceDeps on shutdown", async () => {
|
|
501
|
-
const mockDispose = vi.fn();
|
|
502
|
-
vi.mocked(watchReplaceDeps).mockResolvedValue({ entries: [], dispose: mockDispose });
|
|
503
|
-
|
|
504
|
-
const mockCopySrcWatcher = { close: vi.fn().mockResolvedValue(undefined) };
|
|
505
|
-
vi.mocked(watchCopySrcFiles).mockResolvedValue(mockCopySrcWatcher as any);
|
|
506
|
-
|
|
507
|
-
setupDefaults(createConfig({
|
|
508
|
-
packages: {
|
|
509
|
-
"core-common": { target: "node", copySrc: ["**/*.json"] },
|
|
510
|
-
},
|
|
511
|
-
replaceDeps: { "@simplysm/*": "packages/*/src" },
|
|
512
|
-
}));
|
|
513
|
-
vi.mocked(watchReplaceDeps).mockResolvedValue({ entries: [], dispose: mockDispose });
|
|
514
|
-
|
|
515
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
516
|
-
await orchestrator.initialize();
|
|
517
|
-
await orchestrator.start();
|
|
518
|
-
await orchestrator.shutdown();
|
|
519
|
-
|
|
520
|
-
for (const engine of mockBuildEngines) {
|
|
521
|
-
expect(engine.stop).toHaveBeenCalledOnce();
|
|
522
|
-
}
|
|
523
|
-
expect(mockCopySrcWatcher.close).toHaveBeenCalledOnce();
|
|
524
|
-
expect(mockDispose).toHaveBeenCalledOnce();
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
// --- batchComplete handler ---
|
|
528
|
-
|
|
529
|
-
it("triggers printErrors on batchComplete", async () => {
|
|
530
|
-
setupDefaults(createConfig({
|
|
531
|
-
packages: { "core-common": { target: "node" } },
|
|
532
|
-
}));
|
|
533
|
-
|
|
534
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
535
|
-
await orchestrator.initialize();
|
|
536
|
-
await orchestrator.start();
|
|
537
|
-
|
|
538
|
-
// engine의 startWatch가 registerBuild + resolve를 호출 → batchComplete 자연 발생
|
|
539
|
-
// microtask 대기 (RebuildManager 내부 Promise.resolve().then 처리)
|
|
540
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
541
|
-
expect(printErrors).toHaveBeenCalled();
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
// --- awaitTermination ---
|
|
545
|
-
|
|
546
|
-
it("delegates awaitTermination to SignalHandler", async () => {
|
|
547
|
-
setupDefaults(createConfig({
|
|
548
|
-
packages: { "core-common": { target: "node" } },
|
|
549
|
-
}));
|
|
550
|
-
|
|
551
|
-
const { SignalHandler } = await import("../../src/infra/SignalHandler");
|
|
552
|
-
|
|
553
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
554
|
-
await orchestrator.initialize();
|
|
555
|
-
await orchestrator.awaitTermination();
|
|
556
|
-
|
|
557
|
-
const signalInstance = vi.mocked(SignalHandler).mock.instances[0];
|
|
558
|
-
expect(signalInstance.waitForTermination).toHaveBeenCalled();
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
// --- targets filter ---
|
|
562
|
-
|
|
563
|
-
it("filters packages by targets so only targeted packages get engines", async () => {
|
|
564
|
-
setupDefaults(createConfig({
|
|
565
|
-
packages: { "core-common": { target: "node" }, "storage": { target: "node" } },
|
|
566
|
-
}));
|
|
567
|
-
|
|
568
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: ["core-common"], options: [] });
|
|
569
|
-
await orchestrator.initialize();
|
|
570
|
-
|
|
571
|
-
// 실제 filterPackagesByTargets가 동작하여 core-common만 엔진 생성
|
|
572
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
573
|
-
expect(mockBuildEngines[0]._pkgName).toBe("core-common");
|
|
574
|
-
});
|
|
575
|
-
});
|
|
576
|
-
|
|
577
|
-
describe("Slice 2: dev mode", () => {
|
|
578
|
-
// Helper: override engine mock to add build result to resultCollector
|
|
579
|
-
function setupEngineWithResult(status: "success" | "error" = "success"): void {
|
|
580
|
-
vi.mocked(createBuildEngine).mockImplementation((pkg: any, options: any) => {
|
|
581
|
-
capturedRebuildManager = options.rebuildManager;
|
|
582
|
-
capturedResultCollector = options.resultCollector;
|
|
583
|
-
const engine = {
|
|
584
|
-
run: vi.fn().mockResolvedValue({ success: true, build: { success: true, errors: [], warnings: [], diagnostics: [] } }),
|
|
585
|
-
startWatch: vi.fn().mockImplementation(() => {
|
|
586
|
-
const resolve = options.rebuildManager.registerBuild(
|
|
587
|
-
`${pkg.name}:build`,
|
|
588
|
-
`${pkg.name} (${pkg.config.target})`,
|
|
589
|
-
);
|
|
590
|
-
options.resultCollector.add({
|
|
591
|
-
name: pkg.name, target: pkg.config.target, type: "build", status,
|
|
592
|
-
});
|
|
593
|
-
resolve();
|
|
594
|
-
}),
|
|
595
|
-
stop: vi.fn().mockResolvedValue(undefined),
|
|
596
|
-
_pkgName: pkg.name,
|
|
597
|
-
};
|
|
598
|
-
mockBuildEngines.push(engine);
|
|
599
|
-
return engine as any;
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// --- Acceptance: dev 명령어가 통합 Orchestrator를 사용한다 ---
|
|
604
|
-
it("creates engine for server packages and starts runtime in dev mode", async () => {
|
|
605
|
-
setupDefaults(createConfig({
|
|
606
|
-
packages: { "service-server": { target: "server" } },
|
|
607
|
-
}));
|
|
608
|
-
setupEngineWithResult("success");
|
|
609
|
-
|
|
610
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
611
|
-
await orchestrator.initialize();
|
|
612
|
-
await orchestrator.start();
|
|
613
|
-
|
|
614
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
615
|
-
expect(mockBuildEngines[0]._pkgName).toBe("service-server");
|
|
616
|
-
expect(mockBuildEngines[0].startWatch).toHaveBeenCalledWith({ js: true, dts: false, lint: false });
|
|
617
|
-
// Runtime starts during start() after all engines ready
|
|
618
|
-
expect(Worker.create).toHaveBeenCalled();
|
|
619
|
-
expect(mockRuntimeProxies[0].start).toHaveBeenCalled();
|
|
620
|
-
});
|
|
621
|
-
|
|
622
|
-
// --- Acceptance: Server 패키지 dev 모드 실행 ---
|
|
623
|
-
it("passes merged env (VER+DEV+config.env) to engine and runtime", async () => {
|
|
624
|
-
setupDefaults(createConfig({
|
|
625
|
-
packages: {
|
|
626
|
-
"service-server": { target: "server", env: { DB_HOST: "localhost" } },
|
|
627
|
-
},
|
|
628
|
-
}));
|
|
629
|
-
setupEngineWithResult("success");
|
|
630
|
-
|
|
631
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
632
|
-
await orchestrator.initialize();
|
|
633
|
-
await orchestrator.start();
|
|
634
|
-
|
|
635
|
-
const serverCall = vi.mocked(createBuildEngine).mock.calls.find(
|
|
636
|
-
(c: any[]) => c[0].name === "service-server",
|
|
637
|
-
);
|
|
638
|
-
expect((serverCall![0] as any).config.env).toEqual(
|
|
639
|
-
expect.objectContaining({ VER: "1.0.0", DEV: "true", DB_HOST: "localhost" }),
|
|
640
|
-
);
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
// --- Acceptance: Server 리빌드 실패 시 runtime 미재시작 ---
|
|
644
|
-
it("does not start runtime when build fails", async () => {
|
|
645
|
-
setupDefaults(createConfig({
|
|
646
|
-
packages: { "service-server": { target: "server" } },
|
|
647
|
-
}));
|
|
648
|
-
setupEngineWithResult("error");
|
|
649
|
-
|
|
650
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
651
|
-
await orchestrator.initialize();
|
|
652
|
-
await orchestrator.start();
|
|
653
|
-
|
|
654
|
-
expect(Worker.create).not.toHaveBeenCalled();
|
|
655
|
-
expect(printErrors).toHaveBeenCalled();
|
|
656
|
-
});
|
|
657
|
-
|
|
658
|
-
// --- Acceptance: Library 패키지가 dev에서 제외된다 ---
|
|
659
|
-
it("excludes library packages from dev mode", async () => {
|
|
660
|
-
setupDefaults(createConfig({
|
|
661
|
-
packages: {
|
|
662
|
-
"core-common": { target: "node" },
|
|
663
|
-
"service-server": { target: "server" },
|
|
664
|
-
},
|
|
665
|
-
}));
|
|
666
|
-
setupEngineWithResult("success");
|
|
667
|
-
|
|
668
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
669
|
-
await orchestrator.initialize();
|
|
670
|
-
await orchestrator.start();
|
|
671
|
-
|
|
672
|
-
// Only server engine created
|
|
673
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
674
|
-
expect(mockBuildEngines[0]._pkgName).toBe("service-server");
|
|
675
|
-
});
|
|
676
|
-
|
|
677
|
-
// --- Acceptance: client target 패키지를 분류한다 ---
|
|
678
|
-
it("creates engine for client packages in dev mode", async () => {
|
|
679
|
-
setupDefaults(createConfig({
|
|
680
|
-
packages: {
|
|
681
|
-
"service-server": { target: "server" },
|
|
682
|
-
"my-client": { target: "client", server: "service-server" },
|
|
683
|
-
},
|
|
684
|
-
}));
|
|
685
|
-
setupEngineWithResult("success");
|
|
686
|
-
|
|
687
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
688
|
-
await orchestrator.initialize();
|
|
689
|
-
|
|
690
|
-
// Server + Client engines created
|
|
691
|
-
expect(mockBuildEngines).toHaveLength(2);
|
|
692
|
-
expect(mockBuildEngines.find((e) => e._pkgName === "my-client")).toBeDefined();
|
|
693
|
-
});
|
|
694
|
-
|
|
695
|
-
// --- Acceptance: server가 string이고 해당 서버가 dev 대상 → 서버 연결 클라이언트 ---
|
|
696
|
-
it("maps client to server when config.server is a string and server is a dev target", async () => {
|
|
697
|
-
setupDefaults(createConfig({
|
|
698
|
-
packages: {
|
|
699
|
-
"service-server": { target: "server" },
|
|
700
|
-
"my-client": { target: "client", server: "service-server" },
|
|
701
|
-
},
|
|
702
|
-
}));
|
|
703
|
-
setupEngineWithResult("success");
|
|
704
|
-
|
|
705
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
706
|
-
await orchestrator.initialize();
|
|
707
|
-
|
|
708
|
-
// Client engine created (not skipped)
|
|
709
|
-
const clientEngineCall = vi.mocked(createBuildEngine).mock.calls.find(
|
|
710
|
-
(c: any[]) => c[0].name === "my-client",
|
|
711
|
-
);
|
|
712
|
-
expect(clientEngineCall).toBeDefined();
|
|
713
|
-
});
|
|
714
|
-
|
|
715
|
-
// --- Acceptance: server가 string이지만 서버가 dev 대상 아닌 경우 → 경고 후 독립 전환 ---
|
|
716
|
-
it("warns and treats as standalone when config.server names a non-dev-target server", async () => {
|
|
717
|
-
setupDefaults(createConfig({
|
|
718
|
-
packages: {
|
|
719
|
-
"my-client": { target: "client", server: "non-existent-server" },
|
|
720
|
-
},
|
|
721
|
-
}));
|
|
722
|
-
setupEngineWithResult("success");
|
|
723
|
-
|
|
724
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
725
|
-
await orchestrator.initialize();
|
|
726
|
-
|
|
727
|
-
// Client engine still created
|
|
728
|
-
expect(mockBuildEngines.find((e) => e._pkgName === "my-client")).toBeDefined();
|
|
729
|
-
// Warning about non-target server
|
|
730
|
-
expect(process.stdout.write).toHaveBeenCalledWith(
|
|
731
|
-
expect.stringContaining("non-existent-server"),
|
|
732
|
-
);
|
|
733
|
-
});
|
|
734
|
-
|
|
735
|
-
// --- Acceptance: client 패키지가 0개 → 기존 동작 유지 ---
|
|
736
|
-
it("operates normally with server only when no client packages exist", async () => {
|
|
737
|
-
setupDefaults(createConfig({
|
|
738
|
-
packages: {
|
|
739
|
-
"service-server": { target: "server" },
|
|
740
|
-
},
|
|
741
|
-
}));
|
|
742
|
-
setupEngineWithResult("success");
|
|
743
|
-
|
|
744
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
745
|
-
await orchestrator.initialize();
|
|
746
|
-
await orchestrator.start();
|
|
747
|
-
|
|
748
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
749
|
-
expect(mockBuildEngines[0]._pkgName).toBe("service-server");
|
|
750
|
-
});
|
|
751
|
-
|
|
752
|
-
// --- Unit: server가 number인 경우 독립 클라이언트 ---
|
|
753
|
-
it("creates engine for standalone client with config.server as number", async () => {
|
|
754
|
-
setupDefaults(createConfig({
|
|
755
|
-
packages: {
|
|
756
|
-
"standalone": { target: "client", server: 4200 },
|
|
757
|
-
},
|
|
758
|
-
}));
|
|
759
|
-
setupEngineWithResult("success");
|
|
760
|
-
|
|
761
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
762
|
-
await orchestrator.initialize();
|
|
763
|
-
|
|
764
|
-
expect(mockBuildEngines.find((e) => e._pkgName === "standalone")).toBeDefined();
|
|
765
|
-
});
|
|
766
|
-
|
|
767
|
-
// --- Unit: client only (no server) still initializes ---
|
|
768
|
-
it("initializes when only client packages exist (no server)", async () => {
|
|
769
|
-
setupDefaults(createConfig({
|
|
770
|
-
packages: {
|
|
771
|
-
"my-client": { target: "client", server: 4200 },
|
|
772
|
-
},
|
|
773
|
-
}));
|
|
774
|
-
setupEngineWithResult("success");
|
|
775
|
-
|
|
776
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
777
|
-
await orchestrator.initialize();
|
|
778
|
-
|
|
779
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
// --- Acceptance: Server batchComplete 시 runtime 시작 ---
|
|
783
|
-
it("starts runtime during start() after all engines ready", async () => {
|
|
784
|
-
setupDefaults(createConfig({
|
|
785
|
-
packages: { "service-server": { target: "server" } },
|
|
786
|
-
}));
|
|
787
|
-
setupEngineWithResult("success");
|
|
788
|
-
|
|
789
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
790
|
-
await orchestrator.initialize();
|
|
791
|
-
await orchestrator.start();
|
|
792
|
-
|
|
793
|
-
// Runtime starts during start(), not via batchComplete
|
|
794
|
-
expect(mockRuntimeProxies).toHaveLength(1);
|
|
795
|
-
expect(mockRuntimeProxies[0].start).toHaveBeenCalled();
|
|
796
|
-
});
|
|
797
|
-
|
|
798
|
-
// --- Acceptance: SIGINT/SIGTERM 시 graceful shutdown (dev mode) ---
|
|
799
|
-
it("stops engines and terminates runtime workers on shutdown", async () => {
|
|
800
|
-
setupDefaults(createConfig({
|
|
801
|
-
packages: { "service-server": { target: "server" } },
|
|
802
|
-
}));
|
|
803
|
-
setupEngineWithResult("success");
|
|
804
|
-
|
|
805
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
806
|
-
await orchestrator.initialize();
|
|
807
|
-
await orchestrator.start();
|
|
808
|
-
|
|
809
|
-
// Runtime is now started during start()
|
|
810
|
-
expect(mockRuntimeProxies).toHaveLength(1);
|
|
811
|
-
|
|
812
|
-
await orchestrator.shutdown();
|
|
813
|
-
|
|
814
|
-
expect(mockBuildEngines[0].stop).toHaveBeenCalledOnce();
|
|
815
|
-
expect(mockRuntimeProxies[0].terminate).toHaveBeenCalled();
|
|
816
|
-
});
|
|
817
|
-
|
|
818
|
-
// --- Acceptance: dev에서 replaceDeps 감시 ---
|
|
819
|
-
it("starts replaceDeps watcher in dev mode", async () => {
|
|
820
|
-
const replaceDeps = { "@simplysm/*": "packages/*/src" };
|
|
821
|
-
setupDefaults(createConfig({
|
|
822
|
-
packages: { "service-server": { target: "server" } },
|
|
823
|
-
replaceDeps,
|
|
824
|
-
}));
|
|
825
|
-
setupEngineWithResult("success");
|
|
826
|
-
|
|
827
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
828
|
-
await orchestrator.initialize();
|
|
829
|
-
|
|
830
|
-
expect(watchReplaceDeps).toHaveBeenCalledWith("/test-root", replaceDeps);
|
|
831
|
-
});
|
|
832
|
-
|
|
833
|
-
// Unit: no server packages in dev mode — does not create runtime proxies
|
|
834
|
-
it("does not create runtime proxies when no server packages in dev mode", async () => {
|
|
835
|
-
setupDefaults(createConfig({
|
|
836
|
-
packages: { "core-common": { target: "node" } },
|
|
837
|
-
}));
|
|
838
|
-
|
|
839
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
840
|
-
await orchestrator.initialize();
|
|
841
|
-
|
|
842
|
-
expect(mockBuildEngines).toHaveLength(0);
|
|
843
|
-
});
|
|
844
|
-
|
|
845
|
-
// Unit: multiple server packages
|
|
846
|
-
it("creates engines for multiple server packages (runtimes start during start())", async () => {
|
|
847
|
-
setupDefaults(createConfig({
|
|
848
|
-
packages: {
|
|
849
|
-
"service-server": { target: "server" },
|
|
850
|
-
"api-server": { target: "server" },
|
|
851
|
-
},
|
|
852
|
-
}));
|
|
853
|
-
setupEngineWithResult("success");
|
|
854
|
-
|
|
855
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
856
|
-
await orchestrator.initialize();
|
|
857
|
-
await orchestrator.start();
|
|
858
|
-
|
|
859
|
-
expect(mockBuildEngines).toHaveLength(2);
|
|
860
|
-
// Runtimes start during start() after all engines ready
|
|
861
|
-
expect(Worker.create).toHaveBeenCalledTimes(2);
|
|
862
|
-
});
|
|
863
|
-
|
|
864
|
-
// Unit: skips start when no packages
|
|
865
|
-
it("skips start when no server packages found", async () => {
|
|
866
|
-
setupDefaults(createConfig({
|
|
867
|
-
packages: { "core-common": { target: "node" } },
|
|
868
|
-
}));
|
|
869
|
-
|
|
870
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
871
|
-
await orchestrator.initialize();
|
|
872
|
-
await orchestrator.start();
|
|
873
|
-
|
|
874
|
-
expect(mockBuildEngines).toHaveLength(0);
|
|
875
|
-
});
|
|
876
|
-
|
|
877
|
-
// Unit: disposes replaceDeps on dev shutdown
|
|
878
|
-
it("disposes replaceDeps watcher on dev shutdown", async () => {
|
|
879
|
-
const mockDispose = vi.fn();
|
|
880
|
-
vi.mocked(watchReplaceDeps).mockResolvedValue({ entries: [], dispose: mockDispose } as any);
|
|
881
|
-
|
|
882
|
-
setupDefaults(createConfig({
|
|
883
|
-
packages: { "service-server": { target: "server" } },
|
|
884
|
-
replaceDeps: { "@simplysm/*": "packages/*/src" },
|
|
885
|
-
}));
|
|
886
|
-
vi.mocked(watchReplaceDeps).mockResolvedValue({ entries: [], dispose: mockDispose } as any);
|
|
887
|
-
setupEngineWithResult("success");
|
|
888
|
-
|
|
889
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
890
|
-
await orchestrator.initialize();
|
|
891
|
-
await orchestrator.start();
|
|
892
|
-
await orchestrator.shutdown();
|
|
893
|
-
|
|
894
|
-
expect(mockDispose).toHaveBeenCalledOnce();
|
|
895
|
-
});
|
|
896
|
-
});
|
|
897
|
-
|
|
898
|
-
describe("Slice 4: dev mode client integration", () => {
|
|
899
|
-
// Helper: engine mock with ViteEngine-like port behavior for clients
|
|
900
|
-
function setupEngineWithClientPort(
|
|
901
|
-
serverStatus: "success" | "error" = "success",
|
|
902
|
-
clientPort: number | null = 54321,
|
|
903
|
-
): void {
|
|
904
|
-
vi.mocked(createBuildEngine).mockImplementation((pkg: any, options: any) => {
|
|
905
|
-
capturedRebuildManager = options.rebuildManager;
|
|
906
|
-
capturedResultCollector = options.resultCollector;
|
|
907
|
-
const isClient = pkg.config.target === "client";
|
|
908
|
-
const engine: any = {
|
|
909
|
-
run: vi.fn().mockResolvedValue({ success: true, build: { success: true, errors: [], warnings: [], diagnostics: [] } }),
|
|
910
|
-
startWatch: vi.fn().mockImplementation(() => {
|
|
911
|
-
if (isClient) {
|
|
912
|
-
// Client: simulate Vite serverReady
|
|
913
|
-
if (clientPort != null) {
|
|
914
|
-
engine.port = clientPort;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
const resolve = options.rebuildManager.registerBuild(
|
|
918
|
-
`${pkg.name}:build`,
|
|
919
|
-
`${pkg.name} (${pkg.config.target})`,
|
|
920
|
-
);
|
|
921
|
-
options.resultCollector.add({
|
|
922
|
-
name: pkg.name,
|
|
923
|
-
target: isClient ? "client" : "server",
|
|
924
|
-
type: "build",
|
|
925
|
-
status: isClient ? "success" : serverStatus,
|
|
926
|
-
});
|
|
927
|
-
resolve();
|
|
928
|
-
}),
|
|
929
|
-
stop: vi.fn().mockResolvedValue(undefined),
|
|
930
|
-
_pkgName: pkg.name,
|
|
931
|
-
port: undefined,
|
|
932
|
-
};
|
|
933
|
-
mockBuildEngines.push(engine);
|
|
934
|
-
return engine;
|
|
935
|
-
});
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
// --- Acceptance: 서버 연결 클라이언트의 Vite dev server 시작 ---
|
|
939
|
-
it("starts client engines with startWatch({ js: true, dts: false })", async () => {
|
|
940
|
-
setupDefaults(createConfig({
|
|
941
|
-
packages: {
|
|
942
|
-
"service-server": { target: "server" },
|
|
943
|
-
"my-client": { target: "client", server: "service-server" },
|
|
944
|
-
},
|
|
945
|
-
}));
|
|
946
|
-
setupEngineWithClientPort("success");
|
|
947
|
-
|
|
948
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
949
|
-
await orchestrator.initialize();
|
|
950
|
-
await orchestrator.start();
|
|
951
|
-
|
|
952
|
-
const clientEngine = mockBuildEngines.find((e) => e._pkgName === "my-client")!;
|
|
953
|
-
expect(clientEngine.startWatch).toHaveBeenCalledWith({ js: true, dts: false, lint: false });
|
|
954
|
-
});
|
|
955
|
-
|
|
956
|
-
// --- Acceptance: batchComplete 시 서버 시작 → clientPorts 전달 ---
|
|
957
|
-
it("passes clientPorts to server runtime for connected clients", async () => {
|
|
958
|
-
setupDefaults(createConfig({
|
|
959
|
-
packages: {
|
|
960
|
-
"service-server": { target: "server" },
|
|
961
|
-
"my-client": { target: "client", server: "service-server" },
|
|
962
|
-
},
|
|
963
|
-
}));
|
|
964
|
-
setupEngineWithClientPort("success", 54321);
|
|
965
|
-
|
|
966
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
967
|
-
await orchestrator.initialize();
|
|
968
|
-
await orchestrator.start();
|
|
969
|
-
|
|
970
|
-
// Runtime starts during start() with client ports available
|
|
971
|
-
expect(Worker.create).toHaveBeenCalled();
|
|
972
|
-
expect(mockRuntimeProxies[0].start).toHaveBeenCalledWith(
|
|
973
|
-
expect.objectContaining({
|
|
974
|
-
clientPorts: { "my-client": 54321 },
|
|
975
|
-
}),
|
|
976
|
-
);
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
// --- Acceptance: 독립 클라이언트는 서버 시작 대기에 영향 없음 ---
|
|
980
|
-
it("does not include standalone client ports in server runtime clientPorts", async () => {
|
|
981
|
-
setupDefaults(createConfig({
|
|
982
|
-
packages: {
|
|
983
|
-
"service-server": { target: "server" },
|
|
984
|
-
"standalone": { target: "client", server: 4200 },
|
|
985
|
-
},
|
|
986
|
-
}));
|
|
987
|
-
setupEngineWithClientPort("success", 4200);
|
|
988
|
-
|
|
989
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
990
|
-
await orchestrator.initialize();
|
|
991
|
-
await orchestrator.start();
|
|
992
|
-
|
|
993
|
-
// Runtime starts during start(), standalone client ports excluded
|
|
994
|
-
expect(mockRuntimeProxies[0].start).toHaveBeenCalledWith(
|
|
995
|
-
expect.objectContaining({
|
|
996
|
-
clientPorts: {},
|
|
997
|
-
}),
|
|
998
|
-
);
|
|
999
|
-
});
|
|
1000
|
-
|
|
1001
|
-
// --- Acceptance: 독립 클라이언트 URL 출력 (ResultCollector 등록) ---
|
|
1002
|
-
it("registers standalone client as running server in ResultCollector", async () => {
|
|
1003
|
-
setupDefaults(createConfig({
|
|
1004
|
-
packages: {
|
|
1005
|
-
"standalone": { target: "client", server: 4200 },
|
|
1006
|
-
},
|
|
1007
|
-
}));
|
|
1008
|
-
setupEngineWithClientPort("success", 4200);
|
|
1009
|
-
|
|
1010
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1011
|
-
await orchestrator.initialize();
|
|
1012
|
-
await orchestrator.start();
|
|
1013
|
-
|
|
1014
|
-
// 실제 ResultCollector에 독립 클라이언트가 server로 등록되었는지 확인
|
|
1015
|
-
const serverResult = capturedResultCollector.get("standalone:server");
|
|
1016
|
-
expect(serverResult).toEqual(
|
|
1017
|
-
expect.objectContaining({
|
|
1018
|
-
name: "standalone",
|
|
1019
|
-
target: "client",
|
|
1020
|
-
type: "server",
|
|
1021
|
-
status: "running",
|
|
1022
|
-
port: 4200,
|
|
1023
|
-
}),
|
|
1024
|
-
);
|
|
1025
|
-
});
|
|
1026
|
-
|
|
1027
|
-
// --- Acceptance: 클라이언트 Vite 서버 실패 시 프록시 없이 서버 시작 ---
|
|
1028
|
-
it("starts server without proxy when client port is unavailable", async () => {
|
|
1029
|
-
setupDefaults(createConfig({
|
|
1030
|
-
packages: {
|
|
1031
|
-
"service-server": { target: "server" },
|
|
1032
|
-
"my-client": { target: "client", server: "service-server" },
|
|
1033
|
-
},
|
|
1034
|
-
}));
|
|
1035
|
-
setupEngineWithClientPort("success", null);
|
|
1036
|
-
|
|
1037
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1038
|
-
await orchestrator.initialize();
|
|
1039
|
-
await orchestrator.start();
|
|
1040
|
-
|
|
1041
|
-
// Runtime starts during start() but client port unavailable → empty clientPorts
|
|
1042
|
-
expect(mockRuntimeProxies[0].start).toHaveBeenCalledWith(
|
|
1043
|
-
expect.objectContaining({
|
|
1044
|
-
clientPorts: {},
|
|
1045
|
-
}),
|
|
1046
|
-
);
|
|
1047
|
-
});
|
|
1048
|
-
|
|
1049
|
-
// --- Acceptance: printServers는 start()에서 직접 호출되지 않는다 (serverReady 이벤트 경로만 사용) ---
|
|
1050
|
-
it("does not call printServers directly during start()", async () => {
|
|
1051
|
-
setupDefaults(createConfig({
|
|
1052
|
-
packages: {
|
|
1053
|
-
"service-server": { target: "server" },
|
|
1054
|
-
"my-client": { target: "client", server: "service-server" },
|
|
1055
|
-
},
|
|
1056
|
-
}));
|
|
1057
|
-
setupEngineWithClientPort("success", 54321);
|
|
1058
|
-
|
|
1059
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1060
|
-
await orchestrator.initialize();
|
|
1061
|
-
await orchestrator.start();
|
|
1062
|
-
|
|
1063
|
-
// printServers should NOT be called directly during start()
|
|
1064
|
-
// It should only be called via serverReady → _schedulePrintServers()
|
|
1065
|
-
expect(_printServers).not.toHaveBeenCalled();
|
|
1066
|
-
});
|
|
1067
|
-
|
|
1068
|
-
// --- Acceptance: 서버 rebuild 시 프록시 재등록 ---
|
|
1069
|
-
it("passes clientPorts on server rebuild restart", async () => {
|
|
1070
|
-
setupDefaults(createConfig({
|
|
1071
|
-
packages: {
|
|
1072
|
-
"service-server": { target: "server" },
|
|
1073
|
-
"my-client": { target: "client", server: "service-server" },
|
|
1074
|
-
},
|
|
1075
|
-
}));
|
|
1076
|
-
setupEngineWithClientPort("success", 54321);
|
|
1077
|
-
|
|
1078
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1079
|
-
await orchestrator.initialize();
|
|
1080
|
-
await orchestrator.start();
|
|
1081
|
-
|
|
1082
|
-
// First runtime created during start() with clientPorts
|
|
1083
|
-
expect(mockRuntimeProxies).toHaveLength(1);
|
|
1084
|
-
expect(mockRuntimeProxies[0].start).toHaveBeenCalledWith(
|
|
1085
|
-
expect.objectContaining({
|
|
1086
|
-
clientPorts: { "my-client": 54321 },
|
|
1087
|
-
}),
|
|
1088
|
-
);
|
|
1089
|
-
|
|
1090
|
-
// Trigger batchComplete (rebuild after initial build) via real RebuildManager
|
|
1091
|
-
const resolve = capturedRebuildManager.registerBuild("service-server:build", "service-server (server)");
|
|
1092
|
-
resolve();
|
|
1093
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
1094
|
-
|
|
1095
|
-
// Second runtime start (rebuild) should also have clientPorts
|
|
1096
|
-
expect(mockRuntimeProxies).toHaveLength(2);
|
|
1097
|
-
expect(mockRuntimeProxies[0].terminate).toHaveBeenCalled();
|
|
1098
|
-
expect(mockRuntimeProxies[1].start).toHaveBeenCalledWith(
|
|
1099
|
-
expect.objectContaining({
|
|
1100
|
-
clientPorts: { "my-client": 54321 },
|
|
1101
|
-
}),
|
|
1102
|
-
);
|
|
1103
|
-
});
|
|
1104
|
-
|
|
1105
|
-
// --- Unit: shutdown stops client engines ---
|
|
1106
|
-
it("stops client engines on shutdown", async () => {
|
|
1107
|
-
setupDefaults(createConfig({
|
|
1108
|
-
packages: {
|
|
1109
|
-
"service-server": { target: "server" },
|
|
1110
|
-
"my-client": { target: "client", server: "service-server" },
|
|
1111
|
-
},
|
|
1112
|
-
}));
|
|
1113
|
-
setupEngineWithClientPort("success", 54321);
|
|
1114
|
-
|
|
1115
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1116
|
-
await orchestrator.initialize();
|
|
1117
|
-
await orchestrator.start();
|
|
1118
|
-
await orchestrator.shutdown();
|
|
1119
|
-
|
|
1120
|
-
const clientEngine = mockBuildEngines.find((e) => e._pkgName === "my-client")!;
|
|
1121
|
-
expect(clientEngine.stop).toHaveBeenCalledOnce();
|
|
1122
|
-
});
|
|
1123
|
-
|
|
1124
|
-
// --- Acceptance: Scenario "DevWatchOrchestrator가 env와 configs를 ViteEngine에 전달" + "dev 모드의 baseEnv" ---
|
|
1125
|
-
it("passes merged baseEnv + config.env to client engine config", async () => {
|
|
1126
|
-
setupDefaults(createConfig({
|
|
1127
|
-
packages: {
|
|
1128
|
-
"my-client": { target: "client", server: 4200, env: { API_URL: "http://example.com" } },
|
|
1129
|
-
},
|
|
1130
|
-
}));
|
|
1131
|
-
setupEngineWithClientPort("success", 4200);
|
|
1132
|
-
|
|
1133
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1134
|
-
await orchestrator.initialize();
|
|
1135
|
-
|
|
1136
|
-
const clientCall = vi.mocked(createBuildEngine).mock.calls.find(
|
|
1137
|
-
(c: any[]) => c[0].name === "my-client",
|
|
1138
|
-
);
|
|
1139
|
-
const clientConfig = clientCall?.[0] as any;
|
|
1140
|
-
expect(clientConfig.config.env).toEqual(
|
|
1141
|
-
expect.objectContaining({
|
|
1142
|
-
VER: expect.any(String),
|
|
1143
|
-
DEV: "true",
|
|
1144
|
-
API_URL: "http://example.com",
|
|
1145
|
-
}),
|
|
1146
|
-
);
|
|
1147
|
-
});
|
|
1148
|
-
});
|
|
1149
|
-
|
|
1150
|
-
describe("tests packages exclusion", () => {
|
|
1151
|
-
// tests 패키지는 watch/dev에서 제외되고, sd.config.ts 패키지만 처리된다
|
|
1152
|
-
it("only processes sd.config.ts packages, excludes tests packages", async () => {
|
|
1153
|
-
setupDefaults(createConfig({
|
|
1154
|
-
packages: { "core-common": { target: "node" } },
|
|
1155
|
-
}));
|
|
1156
|
-
|
|
1157
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
1158
|
-
await orchestrator.initialize();
|
|
1159
|
-
await orchestrator.start();
|
|
1160
|
-
|
|
1161
|
-
// Only config package should have BuildEngine created
|
|
1162
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
1163
|
-
expect(mockBuildEngines[0]._pkgName).toBe("core-common");
|
|
1164
|
-
});
|
|
1165
|
-
|
|
1166
|
-
// sd.config.ts 패키지는 기존 packages/ 경로 유지
|
|
1167
|
-
it("preserves packages/ path for sd.config.ts packages", async () => {
|
|
1168
|
-
setupDefaults(createConfig({
|
|
1169
|
-
packages: { "core-common": { target: "neutral" } },
|
|
1170
|
-
}));
|
|
1171
|
-
|
|
1172
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
1173
|
-
await orchestrator.initialize();
|
|
1174
|
-
|
|
1175
|
-
const coreCall = vi.mocked(createBuildEngine).mock.calls.find(
|
|
1176
|
-
(c: any[]) => c[0].name === "core-common",
|
|
1177
|
-
);
|
|
1178
|
-
expect(coreCall![0]).toEqual(expect.objectContaining({
|
|
1179
|
-
dir: "/test-root/packages/core-common",
|
|
1180
|
-
}));
|
|
1181
|
-
});
|
|
1182
|
-
|
|
1183
|
-
// buildPathMapFromConfig 결과가 dir에 반영된다
|
|
1184
|
-
it("builds pathMap from config and reflects in engine dir", async () => {
|
|
1185
|
-
setupDefaults(createConfig({
|
|
1186
|
-
packages: { "core-common": { target: "node" } },
|
|
1187
|
-
}));
|
|
1188
|
-
|
|
1189
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
1190
|
-
await orchestrator.initialize();
|
|
1191
|
-
|
|
1192
|
-
// 실제 buildPathMapFromConfig가 "packages/core-common"을 반환하고
|
|
1193
|
-
// orchestrator가 cwd + pathMap 값으로 dir을 구성
|
|
1194
|
-
const coreEngine = vi.mocked(createBuildEngine).mock.calls.find(
|
|
1195
|
-
(c: any[]) => c[0].name === "core-common",
|
|
1196
|
-
);
|
|
1197
|
-
expect(coreEngine![0]).toEqual(expect.objectContaining({
|
|
1198
|
-
dir: "/test-root/packages/core-common",
|
|
1199
|
-
}));
|
|
1200
|
-
});
|
|
1201
|
-
});
|
|
1202
|
-
|
|
1203
|
-
describe("target validation", () => {
|
|
1204
|
-
it("initializes without error for valid target in watch mode", async () => {
|
|
1205
|
-
setupDefaults(createConfig({
|
|
1206
|
-
packages: { "core-common": { target: "node" } },
|
|
1207
|
-
}));
|
|
1208
|
-
|
|
1209
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: ["core-common"], options: [] });
|
|
1210
|
-
await orchestrator.initialize();
|
|
1211
|
-
|
|
1212
|
-
// 실제 validateTargets가 에러 없이 통과하고 엔진이 생성됨
|
|
1213
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
1214
|
-
expect(mockBuildEngines[0]._pkgName).toBe("core-common");
|
|
1215
|
-
});
|
|
1216
|
-
|
|
1217
|
-
it("initializes without error for valid target in dev mode", async () => {
|
|
1218
|
-
setupDefaults(createConfig({
|
|
1219
|
-
packages: { "service-server": { target: "server" } },
|
|
1220
|
-
}));
|
|
1221
|
-
|
|
1222
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: ["service-server"], options: [] });
|
|
1223
|
-
await orchestrator.initialize();
|
|
1224
|
-
|
|
1225
|
-
// 실제 validateTargets가 에러 없이 통과하고 엔진이 생성됨
|
|
1226
|
-
expect(mockBuildEngines).toHaveLength(1);
|
|
1227
|
-
expect(mockBuildEngines[0]._pkgName).toBe("service-server");
|
|
1228
|
-
});
|
|
1229
|
-
|
|
1230
|
-
it("throws for unknown target in watch mode", async () => {
|
|
1231
|
-
setupDefaults(createConfig({
|
|
1232
|
-
packages: { "core-common": { target: "node" } },
|
|
1233
|
-
}));
|
|
1234
|
-
|
|
1235
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: ["nonexistent"], options: [] });
|
|
1236
|
-
await expect(orchestrator.initialize()).rejects.toThrow("Unknown target: nonexistent");
|
|
1237
|
-
});
|
|
1238
|
-
|
|
1239
|
-
it("throws for unknown target in dev mode", async () => {
|
|
1240
|
-
setupDefaults(createConfig({
|
|
1241
|
-
packages: { "service-server": { target: "server" } },
|
|
1242
|
-
}));
|
|
1243
|
-
|
|
1244
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: ["nonexistent"], options: [] });
|
|
1245
|
-
await expect(orchestrator.initialize()).rejects.toThrow("Unknown target: nonexistent");
|
|
1246
|
-
});
|
|
1247
|
-
});
|
|
1248
|
-
|
|
1249
|
-
describe("Slice 3: native device run integration", () => {
|
|
1250
|
-
// Helper: setup engine with port so dev server URL can be constructed
|
|
1251
|
-
function setupEngineWithPort(port: number): void {
|
|
1252
|
-
vi.mocked(createBuildEngine).mockImplementation((pkg: any, options: any) => {
|
|
1253
|
-
capturedRebuildManager = options.rebuildManager;
|
|
1254
|
-
capturedResultCollector = options.resultCollector;
|
|
1255
|
-
const engine = {
|
|
1256
|
-
run: vi.fn().mockResolvedValue({
|
|
1257
|
-
success: true,
|
|
1258
|
-
build: { success: true, errors: [], warnings: [], diagnostics: [] },
|
|
1259
|
-
}),
|
|
1260
|
-
startWatch: vi.fn().mockImplementation(() => {
|
|
1261
|
-
// Simulate server ready with port
|
|
1262
|
-
(engine as any).port = port;
|
|
1263
|
-
const resolve = options.rebuildManager.registerBuild(
|
|
1264
|
-
`${pkg.name}:build`,
|
|
1265
|
-
`${pkg.name} (${pkg.config.target})`,
|
|
1266
|
-
);
|
|
1267
|
-
options.resultCollector.add({
|
|
1268
|
-
name: pkg.name,
|
|
1269
|
-
target: pkg.config.target === "client" ? "client" : "server",
|
|
1270
|
-
type: "build",
|
|
1271
|
-
status: "success",
|
|
1272
|
-
});
|
|
1273
|
-
resolve();
|
|
1274
|
-
}),
|
|
1275
|
-
stop: vi.fn().mockResolvedValue(undefined),
|
|
1276
|
-
port: undefined as number | undefined,
|
|
1277
|
-
_pkgName: pkg.name,
|
|
1278
|
-
};
|
|
1279
|
-
mockBuildEngines.push(engine);
|
|
1280
|
-
return engine as any;
|
|
1281
|
-
});
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
|
-
// Acceptance: Scenario "Capacitor 초기화만 수행 (run 미호출)"
|
|
1285
|
-
it("runs Capacitor.create + initialize but NOT run in dev mode", async () => {
|
|
1286
|
-
setupDefaults(createConfig({
|
|
1287
|
-
packages: {
|
|
1288
|
-
"my-client": {
|
|
1289
|
-
target: "client",
|
|
1290
|
-
server: 4200,
|
|
1291
|
-
capacitor: { appId: "com.test.app", appName: "TestApp" },
|
|
1292
|
-
},
|
|
1293
|
-
},
|
|
1294
|
-
}));
|
|
1295
|
-
setupEngineWithPort(4200);
|
|
1296
|
-
|
|
1297
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1298
|
-
await orchestrator.initialize();
|
|
1299
|
-
await orchestrator.start();
|
|
1300
|
-
|
|
1301
|
-
expect(Capacitor.create).toHaveBeenCalledWith(
|
|
1302
|
-
expect.stringContaining("my-client"),
|
|
1303
|
-
{ appId: "com.test.app", appName: "TestApp" },
|
|
1304
|
-
undefined,
|
|
1305
|
-
);
|
|
1306
|
-
expect(mockCapacitorInstance.initialize).toHaveBeenCalled();
|
|
1307
|
-
expect(mockCapacitorInstance.run).not.toHaveBeenCalled();
|
|
1308
|
-
});
|
|
1309
|
-
|
|
1310
|
-
// Acceptance: Scenario "dev 모드에서 Electron 미처리"
|
|
1311
|
-
it("does not run Electron in dev mode even when electron config exists", async () => {
|
|
1312
|
-
setupDefaults(createConfig({
|
|
1313
|
-
packages: {
|
|
1314
|
-
"my-client": {
|
|
1315
|
-
target: "client",
|
|
1316
|
-
server: 4200,
|
|
1317
|
-
electron: { appId: "com.test.electron" },
|
|
1318
|
-
},
|
|
1319
|
-
},
|
|
1320
|
-
}));
|
|
1321
|
-
setupEngineWithPort(4200);
|
|
1322
|
-
|
|
1323
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1324
|
-
await orchestrator.initialize();
|
|
1325
|
-
await orchestrator.start();
|
|
1326
|
-
|
|
1327
|
-
expect(Electron.create).not.toHaveBeenCalled();
|
|
1328
|
-
expect(mockElectronInstance.initialize).not.toHaveBeenCalled();
|
|
1329
|
-
expect(mockElectronInstance.run).not.toHaveBeenCalled();
|
|
1330
|
-
});
|
|
1331
|
-
|
|
1332
|
-
// Acceptance: Scenario "Capacitor + Electron 동시 설정 시 Capacitor만 초기화"
|
|
1333
|
-
it("initializes Capacitor but ignores Electron when both are configured", async () => {
|
|
1334
|
-
setupDefaults(createConfig({
|
|
1335
|
-
packages: {
|
|
1336
|
-
"my-client": {
|
|
1337
|
-
target: "client",
|
|
1338
|
-
server: 4200,
|
|
1339
|
-
capacitor: { appId: "com.test.app", appName: "TestApp" },
|
|
1340
|
-
electron: { appId: "com.test.electron" },
|
|
1341
|
-
},
|
|
1342
|
-
},
|
|
1343
|
-
}));
|
|
1344
|
-
setupEngineWithPort(4200);
|
|
1345
|
-
|
|
1346
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1347
|
-
await orchestrator.initialize();
|
|
1348
|
-
await orchestrator.start();
|
|
1349
|
-
|
|
1350
|
-
expect(Capacitor.create).toHaveBeenCalled();
|
|
1351
|
-
expect(mockCapacitorInstance.initialize).toHaveBeenCalled();
|
|
1352
|
-
expect(mockCapacitorInstance.run).not.toHaveBeenCalled();
|
|
1353
|
-
expect(Electron.create).not.toHaveBeenCalled();
|
|
1354
|
-
});
|
|
1355
|
-
|
|
1356
|
-
// Acceptance: Scenario "네이티브 설정 없는 dev 모드"
|
|
1357
|
-
it("does not run native apps when no capacitor/electron configured", async () => {
|
|
1358
|
-
setupDefaults(createConfig({
|
|
1359
|
-
packages: {
|
|
1360
|
-
"my-client": { target: "client", server: 4200 },
|
|
1361
|
-
},
|
|
1362
|
-
}));
|
|
1363
|
-
setupEngineWithPort(4200);
|
|
1364
|
-
|
|
1365
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1366
|
-
await orchestrator.initialize();
|
|
1367
|
-
await orchestrator.start();
|
|
1368
|
-
|
|
1369
|
-
expect(Capacitor.create).not.toHaveBeenCalled();
|
|
1370
|
-
expect(Electron.create).not.toHaveBeenCalled();
|
|
1371
|
-
});
|
|
1372
|
-
|
|
1373
|
-
// Acceptance: Scenario "dev 모드 종료 시 Capacitor 초기화 후 정상 종료"
|
|
1374
|
-
// Capacitor.initialize()만 호출되므로 별도 정리 불필요.
|
|
1375
|
-
it("shutdown completes when Capacitor was initialized", async () => {
|
|
1376
|
-
setupDefaults(createConfig({
|
|
1377
|
-
packages: {
|
|
1378
|
-
"my-client": {
|
|
1379
|
-
target: "client",
|
|
1380
|
-
server: 4200,
|
|
1381
|
-
capacitor: { appId: "com.test.app", appName: "TestApp" },
|
|
1382
|
-
},
|
|
1383
|
-
},
|
|
1384
|
-
}));
|
|
1385
|
-
setupEngineWithPort(4200);
|
|
1386
|
-
|
|
1387
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1388
|
-
await orchestrator.initialize();
|
|
1389
|
-
await orchestrator.start();
|
|
1390
|
-
await orchestrator.shutdown();
|
|
1391
|
-
|
|
1392
|
-
// Verify shutdown doesn't throw and engines are stopped
|
|
1393
|
-
for (const engine of mockBuildEngines) {
|
|
1394
|
-
expect(engine.stop).toHaveBeenCalled();
|
|
1395
|
-
}
|
|
1396
|
-
});
|
|
1397
|
-
|
|
1398
|
-
// Unit: Capacitor.initialize 에러는 로그만 남기고 크래시하지 않음
|
|
1399
|
-
it("logs error but does not crash when Capacitor.initialize throws", async () => {
|
|
1400
|
-
setupDefaults(createConfig({
|
|
1401
|
-
packages: {
|
|
1402
|
-
"my-client": {
|
|
1403
|
-
target: "client",
|
|
1404
|
-
server: 4200,
|
|
1405
|
-
capacitor: { appId: "com.test.app", appName: "TestApp" },
|
|
1406
|
-
},
|
|
1407
|
-
},
|
|
1408
|
-
}));
|
|
1409
|
-
setupEngineWithPort(4200);
|
|
1410
|
-
mockCapacitorInstance.initialize.mockRejectedValue(new Error("init failed"));
|
|
1411
|
-
|
|
1412
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1413
|
-
await orchestrator.initialize();
|
|
1414
|
-
// Should not throw
|
|
1415
|
-
await orchestrator.start();
|
|
1416
|
-
|
|
1417
|
-
expect(mockCapacitorInstance.initialize).toHaveBeenCalled();
|
|
1418
|
-
expect(mockCapacitorInstance.run).not.toHaveBeenCalled();
|
|
1419
|
-
});
|
|
1420
|
-
});
|
|
1421
|
-
|
|
1422
|
-
//#region Slice 4: watch/dev lint 활성화 (Feature 3.2)
|
|
1423
|
-
|
|
1424
|
-
describe("resource safety (DESIGN-001, DESIGN-002)", () => {
|
|
1425
|
-
// --- Acceptance: shutdown 시 타이머 정리 + replaceDepWatcher 해제 ---
|
|
1426
|
-
|
|
1427
|
-
it("clears pending timers on shutdown so no delayed restart fires", async () => {
|
|
1428
|
-
vi.useFakeTimers();
|
|
1429
|
-
try {
|
|
1430
|
-
setupDefaults(createConfig({
|
|
1431
|
-
packages: { "demo-server": { target: "server" } },
|
|
1432
|
-
}));
|
|
1433
|
-
// Engine with rebuildManager integration
|
|
1434
|
-
vi.mocked(createBuildEngine).mockImplementation((pkg: any, options: any) => {
|
|
1435
|
-
capturedRebuildManager = options.rebuildManager;
|
|
1436
|
-
capturedResultCollector = options.resultCollector;
|
|
1437
|
-
const engine = {
|
|
1438
|
-
run: vi.fn(),
|
|
1439
|
-
startWatch: vi.fn().mockImplementation(() => {
|
|
1440
|
-
const resolve = options.rebuildManager.registerBuild(
|
|
1441
|
-
`${pkg.name}:build`,
|
|
1442
|
-
`${pkg.name} (${pkg.config.target})`,
|
|
1443
|
-
);
|
|
1444
|
-
options.resultCollector.add({
|
|
1445
|
-
name: pkg.name, target: "server", type: "build", status: "success",
|
|
1446
|
-
});
|
|
1447
|
-
resolve();
|
|
1448
|
-
}),
|
|
1449
|
-
stop: vi.fn().mockResolvedValue(undefined),
|
|
1450
|
-
_pkgName: pkg.name,
|
|
1451
|
-
};
|
|
1452
|
-
mockBuildEngines.push(engine);
|
|
1453
|
-
return engine as any;
|
|
1454
|
-
});
|
|
1455
|
-
|
|
1456
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1457
|
-
await orchestrator.initialize();
|
|
1458
|
-
await orchestrator.start();
|
|
1459
|
-
|
|
1460
|
-
// Trigger batchComplete (rebuild) with a server build key → sets _serverRestartTimer
|
|
1461
|
-
const runtimeCountBefore = mockRuntimeProxies.length;
|
|
1462
|
-
const resolve = capturedRebuildManager.registerBuild("demo-server:build", "demo-server (server)");
|
|
1463
|
-
resolve();
|
|
1464
|
-
// Allow microtask for _runBatch to execute
|
|
1465
|
-
await vi.advanceTimersByTimeAsync(0);
|
|
1466
|
-
|
|
1467
|
-
// shutdown before restart timer fires
|
|
1468
|
-
await orchestrator.shutdown();
|
|
1469
|
-
|
|
1470
|
-
// Advance past timer (100ms restart + 300ms print)
|
|
1471
|
-
vi.advanceTimersByTime(500);
|
|
1472
|
-
|
|
1473
|
-
// No new runtime workers created after shutdown
|
|
1474
|
-
expect(mockRuntimeProxies.length).toBe(runtimeCountBefore);
|
|
1475
|
-
} finally {
|
|
1476
|
-
vi.useRealTimers();
|
|
1477
|
-
}
|
|
1478
|
-
});
|
|
1479
|
-
|
|
1480
|
-
it("disposes replaceDepWatcher even when initialize fails after watchReplaceDeps", async () => {
|
|
1481
|
-
const mockDispose = vi.fn();
|
|
1482
|
-
vi.mocked(watchReplaceDeps).mockResolvedValue({ entries: [], dispose: mockDispose } as any);
|
|
1483
|
-
|
|
1484
|
-
setupDefaults(createConfig({
|
|
1485
|
-
packages: { "demo-server": { target: "server" } },
|
|
1486
|
-
replaceDeps: { "@simplysm/*": "packages/*/src" },
|
|
1487
|
-
}));
|
|
1488
|
-
vi.mocked(watchReplaceDeps).mockResolvedValue({ entries: [], dispose: mockDispose } as any);
|
|
1489
|
-
// Make getVersion throw to simulate partial init failure after watchReplaceDeps
|
|
1490
|
-
vi.mocked(getVersion).mockRejectedValue(new Error("version fetch failed"));
|
|
1491
|
-
|
|
1492
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1493
|
-
await expect(orchestrator.initialize()).rejects.toThrow("version fetch failed");
|
|
1494
|
-
|
|
1495
|
-
await orchestrator.shutdown();
|
|
1496
|
-
|
|
1497
|
-
expect(mockDispose).toHaveBeenCalledOnce();
|
|
1498
|
-
});
|
|
1499
|
-
});
|
|
1500
|
-
|
|
1501
|
-
describe("lint activation", () => {
|
|
1502
|
-
// Scenario: watch 초기 빌드에서 lint 비활성화 (별도 실행으로 분리됨)
|
|
1503
|
-
it("passes lint:false to startWatch for library engines in watch mode", async () => {
|
|
1504
|
-
setupDefaults(createConfig({
|
|
1505
|
-
packages: {
|
|
1506
|
-
"core-common": { target: "node" },
|
|
1507
|
-
"core-browser": { target: "browser" },
|
|
1508
|
-
},
|
|
1509
|
-
}));
|
|
1510
|
-
|
|
1511
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "watch", targets: [], options: [] });
|
|
1512
|
-
await orchestrator.initialize();
|
|
1513
|
-
await orchestrator.start();
|
|
1514
|
-
|
|
1515
|
-
for (const engine of mockBuildEngines) {
|
|
1516
|
-
expect(engine.startWatch).toHaveBeenCalledWith({ js: true, dts: true, lint: false });
|
|
1517
|
-
}
|
|
1518
|
-
});
|
|
1519
|
-
|
|
1520
|
-
// Scenario: dev 초기 빌드에서 server/client lint 비활성화
|
|
1521
|
-
it("passes lint:false to startWatch for server and client engines in dev mode", async () => {
|
|
1522
|
-
setupDefaults(createConfig({
|
|
1523
|
-
packages: {
|
|
1524
|
-
"demo-server": { target: "server" },
|
|
1525
|
-
"my-client": { target: "client", server: "demo-server" } as any,
|
|
1526
|
-
},
|
|
1527
|
-
}));
|
|
1528
|
-
|
|
1529
|
-
const orchestrator = new DevWatchOrchestrator({ mode: "dev", targets: [], options: [] });
|
|
1530
|
-
await orchestrator.initialize();
|
|
1531
|
-
await orchestrator.start();
|
|
1532
|
-
|
|
1533
|
-
const serverEngine = mockBuildEngines.find((e) => e._pkgName === "demo-server")!;
|
|
1534
|
-
const clientEngine = mockBuildEngines.find((e) => e._pkgName === "my-client")!;
|
|
1535
|
-
|
|
1536
|
-
expect(serverEngine.startWatch).toHaveBeenCalledWith({ js: true, dts: false, lint: false });
|
|
1537
|
-
expect(clientEngine.startWatch).toHaveBeenCalledWith({ js: true, dts: false, lint: false });
|
|
1538
|
-
});
|
|
1539
|
-
});
|
|
1540
|
-
|
|
1541
|
-
//#endregion
|
|
1542
|
-
});
|