@simplysm/sd-cli 13.0.75 → 13.0.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +341 -16
- package/dist/builders/DtsBuilder.js +2 -2
- package/dist/builders/DtsBuilder.js.map +1 -1
- package/dist/builders/LibraryBuilder.d.ts +3 -3
- package/dist/builders/LibraryBuilder.d.ts.map +1 -1
- package/dist/builders/LibraryBuilder.js +2 -2
- package/dist/builders/LibraryBuilder.js.map +1 -1
- package/dist/builders/types.d.ts +7 -1
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/capacitor/capacitor.d.ts +5 -0
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +59 -59
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/check.js +4 -4
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/device.js +3 -3
- package/dist/commands/device.js.map +1 -1
- package/dist/commands/lint.d.ts +2 -2
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +4 -98
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/publish.js +20 -20
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/replace-deps.js +1 -1
- package/dist/commands/replace-deps.js.map +1 -1
- package/dist/commands/typecheck.js +9 -9
- package/dist/commands/typecheck.js.map +1 -1
- package/dist/electron/electron.js +16 -16
- package/dist/electron/electron.js.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +6 -6
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevOrchestrator.d.ts +7 -6
- package/dist/orchestrators/DevOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/DevOrchestrator.js +157 -203
- package/dist/orchestrators/DevOrchestrator.js.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.js +3 -4
- package/dist/orchestrators/WatchOrchestrator.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 +9 -3
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/utils/copy-public.d.ts.map +1 -1
- package/dist/utils/copy-public.js +23 -27
- package/dist/utils/copy-public.js.map +1 -1
- package/dist/utils/copy-src.d.ts.map +1 -1
- package/dist/utils/copy-src.js +7 -7
- package/dist/utils/copy-src.js.map +1 -1
- package/dist/utils/esbuild-config.d.ts.map +1 -1
- package/dist/utils/esbuild-config.js +36 -42
- package/dist/utils/esbuild-config.js.map +1 -1
- package/dist/utils/replace-deps.js +7 -7
- package/dist/utils/replace-deps.js.map +1 -1
- package/dist/utils/sd-config.js +2 -2
- package/dist/utils/sd-config.js.map +1 -1
- package/dist/utils/template.js +7 -7
- package/dist/utils/template.js.map +1 -1
- package/dist/utils/tsconfig.d.ts +1 -2
- package/dist/utils/tsconfig.d.ts.map +1 -1
- package/dist/utils/tsconfig.js +5 -8
- package/dist/utils/tsconfig.js.map +1 -1
- package/dist/utils/typecheck-serialization.js +2 -2
- package/dist/utils/typecheck-serialization.js.map +1 -1
- package/dist/utils/vite-config.d.ts +2 -0
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +36 -3
- package/dist/utils/vite-config.js.map +1 -1
- package/dist/utils/worker-events.d.ts +11 -1
- package/dist/utils/worker-events.d.ts.map +1 -1
- package/dist/utils/worker-events.js +3 -5
- package/dist/utils/worker-events.js.map +1 -1
- package/dist/utils/worker-utils.d.ts +2 -2
- package/dist/utils/worker-utils.d.ts.map +1 -1
- package/dist/utils/worker-utils.js +1 -1
- package/dist/utils/worker-utils.js.map +1 -1
- package/dist/workers/client.worker.d.ts +1 -1
- package/dist/workers/client.worker.js +3 -3
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/dts.worker.d.ts +1 -1
- package/dist/workers/dts.worker.d.ts.map +1 -1
- package/dist/workers/dts.worker.js +13 -28
- package/dist/workers/dts.worker.js.map +1 -1
- package/dist/workers/library.worker.d.ts +1 -1
- package/dist/workers/library.worker.js +4 -4
- package/dist/workers/library.worker.js.map +1 -1
- package/dist/workers/lint.worker.d.ts +1 -1
- package/dist/workers/server-runtime.worker.d.ts +1 -1
- package/dist/workers/server-runtime.worker.js +4 -4
- package/dist/workers/server-runtime.worker.js.map +1 -1
- package/dist/workers/server.worker.d.ts +1 -1
- package/dist/workers/server.worker.js +6 -6
- package/dist/workers/server.worker.js.map +1 -1
- package/package.json +4 -5
- package/src/builders/DtsBuilder.ts +2 -2
- package/src/builders/LibraryBuilder.ts +7 -10
- package/src/builders/types.ts +6 -1
- package/src/capacitor/capacitor.ts +61 -60
- package/src/commands/check.ts +4 -4
- package/src/commands/device.ts +3 -3
- package/src/commands/lint.ts +6 -117
- package/src/commands/publish.ts +20 -20
- package/src/commands/replace-deps.ts +1 -1
- package/src/commands/typecheck.ts +9 -9
- package/src/electron/electron.ts +16 -16
- package/src/orchestrators/BuildOrchestrator.ts +6 -6
- package/src/orchestrators/DevOrchestrator.ts +210 -256
- package/src/orchestrators/WatchOrchestrator.ts +8 -10
- package/src/sd-cli.ts +1 -1
- package/src/sd-config.types.ts +10 -3
- package/src/utils/copy-public.ts +22 -26
- package/src/utils/copy-src.ts +7 -7
- package/src/utils/esbuild-config.ts +51 -63
- package/src/utils/replace-deps.ts +7 -7
- package/src/utils/sd-config.ts +2 -2
- package/src/utils/template.ts +7 -7
- package/src/utils/tsconfig.ts +6 -10
- package/src/utils/typecheck-serialization.ts +2 -2
- package/src/utils/vite-config.ts +376 -341
- package/src/utils/worker-events.ts +13 -10
- package/src/utils/worker-utils.ts +45 -45
- package/src/workers/client.worker.ts +3 -3
- package/src/workers/dts.worker.ts +451 -467
- package/src/workers/library.worker.ts +4 -4
- package/src/workers/server-runtime.worker.ts +4 -4
- package/src/workers/server.worker.ts +572 -572
- package/templates/init/package.json.hbs +2 -3
- package/templates/init/packages/client-admin/package.json.hbs +5 -5
- package/templates/init/packages/client-admin/src/views/auth/LoginView.tsx +2 -2
- package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeDetail.tsx.hbs +86 -105
- package/templates/init/packages/client-admin/src/views/home/base/employee/EmployeeSheet.tsx.hbs +1 -1
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleDetail.tsx.hbs +4 -12
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionDetail.tsx.hbs +0 -2
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RolePermissionView.tsx +1 -1
- package/templates/init/packages/client-admin/src/views/home/base/role-permission/RoleSheet.tsx.hbs +1 -1
- package/templates/init/packages/client-admin/src/views/home/my-info/MyInfoDetail.tsx.hbs +36 -43
- package/templates/init/packages/db-main/package.json.hbs +2 -2
- package/templates/init/packages/server/package.json.hbs +4 -4
- package/templates/init/tests/e2e/package.json.hbs +1 -1
- package/tests/get-compiler-options-for-package.spec.ts +13 -72
- package/tests/get-package-source-files.spec.ts +0 -42
- package/tests/get-types-from-package-json.spec.ts +15 -30
- package/tests/infra/ResultCollector.spec.ts +0 -9
- package/tests/infra/WorkerManager.spec.ts +0 -34
- package/tests/load-ignore-patterns.spec.ts +15 -40
- package/tests/load-sd-config.spec.ts +16 -53
- package/tests/publish-config-narrowing.spec.ts +20 -0
- package/tests/run-lint.spec.ts +38 -87
- package/tests/run-typecheck.spec.ts +194 -303
- package/tests/run-watch.spec.ts +0 -34
- package/tests/sd-cli.spec.ts +0 -88
- package/tests/sd-public-dev-plugin-mime.spec.ts +19 -0
- package/dist/builders/index.d.ts +0 -5
- package/dist/builders/index.d.ts.map +0 -1
- package/dist/builders/index.js +0 -5
- package/dist/builders/index.js.map +0 -6
- package/dist/infra/index.d.ts +0 -4
- package/dist/infra/index.d.ts.map +0 -1
- package/dist/infra/index.js +0 -4
- package/dist/infra/index.js.map +0 -6
- package/dist/orchestrators/index.d.ts +0 -4
- package/dist/orchestrators/index.d.ts.map +0 -1
- package/dist/orchestrators/index.js +0 -4
- package/dist/orchestrators/index.js.map +0 -6
- package/src/builders/index.ts +0 -4
- package/src/infra/index.ts +0 -3
- package/src/orchestrators/index.ts +0 -3
- package/templates/init/stylelint.config.ts +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { Worker, type WorkerProxy } from "@simplysm/core-node";
|
|
3
|
-
import {
|
|
3
|
+
import { err as errNs } from "@simplysm/core-common";
|
|
4
4
|
import type { SdConfig, SdClientPackageConfig, SdServerPackageConfig } from "../sd-config.types";
|
|
5
5
|
import { consola } from "consola";
|
|
6
6
|
import { loadSdConfig } from "../utils/sd-config";
|
|
@@ -16,7 +16,6 @@ import { formatBuildMessages, printErrors, printServers } from "../utils/output-
|
|
|
16
16
|
import { RebuildManager } from "../utils/rebuild-manager";
|
|
17
17
|
import {
|
|
18
18
|
registerWorkerEventHandlers,
|
|
19
|
-
type BaseWorkerInfo,
|
|
20
19
|
type ServerReadyEventData,
|
|
21
20
|
type ServerBuildEventData,
|
|
22
21
|
type ErrorEventData,
|
|
@@ -45,6 +44,19 @@ interface ClientWorkerInfo {
|
|
|
45
44
|
buildResolver: (() => void) | undefined;
|
|
46
45
|
}
|
|
47
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Options for client worker setup
|
|
49
|
+
*/
|
|
50
|
+
interface ClientSetupOptions {
|
|
51
|
+
workers: ClientWorkerInfo[];
|
|
52
|
+
/** Called on serverReady event. If undefined, completeTask is called with running status. */
|
|
53
|
+
onServerReady?: (workerInfo: ClientWorkerInfo, port: number, completeTask: (result: BuildResult) => void) => void;
|
|
54
|
+
/** Called on error event (in addition to default error handling) */
|
|
55
|
+
onError?: (workerInfo: ClientWorkerInfo) => void;
|
|
56
|
+
/** Create the config to pass to worker.startWatch() */
|
|
57
|
+
createConfig: (workerInfo: ClientWorkerInfo) => SdClientPackageConfig;
|
|
58
|
+
}
|
|
59
|
+
|
|
48
60
|
//#endregion
|
|
49
61
|
|
|
50
62
|
//#region DevOrchestrator
|
|
@@ -130,7 +142,7 @@ export class DevOrchestrator {
|
|
|
130
142
|
this._sdConfig = await loadSdConfig({
|
|
131
143
|
cwd: this._cwd,
|
|
132
144
|
dev: true,
|
|
133
|
-
|
|
145
|
+
options: this._options.options,
|
|
134
146
|
});
|
|
135
147
|
this._logger.debug("sd.config.ts loaded successfully");
|
|
136
148
|
} catch (err) {
|
|
@@ -236,9 +248,54 @@ export class DevOrchestrator {
|
|
|
236
248
|
}));
|
|
237
249
|
|
|
238
250
|
// Setup and start workers for each section
|
|
239
|
-
const standaloneClientPromises = this.
|
|
240
|
-
|
|
241
|
-
|
|
251
|
+
const standaloneClientPromises = this._setupClientWorkers({
|
|
252
|
+
workers: this._standaloneClientWorkers,
|
|
253
|
+
createConfig: (workerInfo) => ({
|
|
254
|
+
...workerInfo.config,
|
|
255
|
+
env: { ...this._baseEnv, ...workerInfo.config.env },
|
|
256
|
+
}),
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Vite client ready promises (server waits for client ports before starting runtime)
|
|
260
|
+
const viteClientReadyPromises = new Map<string, { promise: Promise<void>; resolver: () => void }>();
|
|
261
|
+
for (const workerInfo of this._viteClientWorkers) {
|
|
262
|
+
let readyResolver!: () => void;
|
|
263
|
+
const readyPromise = new Promise<void>((resolve) => {
|
|
264
|
+
readyResolver = resolve;
|
|
265
|
+
});
|
|
266
|
+
viteClientReadyPromises.set(workerInfo.name, {
|
|
267
|
+
promise: readyPromise,
|
|
268
|
+
resolver: readyResolver,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const viteClientPromises = this._setupClientWorkers({
|
|
273
|
+
workers: this._viteClientWorkers,
|
|
274
|
+
onServerReady: (workerInfo, port, completeTask) => {
|
|
275
|
+
this._logger.debug(`[${workerInfo.name}] Vite serverReady (port: ${String(port)})`);
|
|
276
|
+
this._clientPorts[workerInfo.name] = port;
|
|
277
|
+
// Notify Vite server ready (server is waiting for proxy setup)
|
|
278
|
+
viteClientReadyPromises.get(workerInfo.name)?.resolver();
|
|
279
|
+
// Call completeTask for build completion (Vite doesn't emit build event)
|
|
280
|
+
completeTask({
|
|
281
|
+
name: workerInfo.name,
|
|
282
|
+
target: workerInfo.config.target,
|
|
283
|
+
type: "build",
|
|
284
|
+
status: "success",
|
|
285
|
+
});
|
|
286
|
+
},
|
|
287
|
+
onError: (workerInfo) => {
|
|
288
|
+
// Also resolve readyPromises on Vite client error
|
|
289
|
+
// (prevent server from hanging indefinitely in await Promise.all(clientReadyPromises))
|
|
290
|
+
viteClientReadyPromises.get(workerInfo.name)?.resolver();
|
|
291
|
+
},
|
|
292
|
+
createConfig: (workerInfo) => ({
|
|
293
|
+
...workerInfo.config,
|
|
294
|
+
server: 0, // Vite will automatically assign port
|
|
295
|
+
env: { ...this._baseEnv, ...workerInfo.config.env },
|
|
296
|
+
}),
|
|
297
|
+
});
|
|
298
|
+
|
|
242
299
|
const serverPromises = this._setupServers(
|
|
243
300
|
serverWorkerPath,
|
|
244
301
|
serverRuntimeWorkerPath,
|
|
@@ -295,7 +352,7 @@ export class DevOrchestrator {
|
|
|
295
352
|
target: "client",
|
|
296
353
|
type: "capacitor",
|
|
297
354
|
status: "error",
|
|
298
|
-
message:
|
|
355
|
+
message: errNs.message(err),
|
|
299
356
|
});
|
|
300
357
|
this._logger.fail(taskName);
|
|
301
358
|
}
|
|
@@ -308,11 +365,11 @@ export class DevOrchestrator {
|
|
|
308
365
|
}
|
|
309
366
|
|
|
310
367
|
/**
|
|
311
|
-
* Setup and start standalone
|
|
368
|
+
* Setup and start client workers (unified for standalone and server-connected clients)
|
|
312
369
|
*/
|
|
313
|
-
private
|
|
370
|
+
private _setupClientWorkers(opts: ClientSetupOptions): Array<{ name: string; promise: Promise<void> }> {
|
|
314
371
|
const buildPromises = new Map<string, Promise<void>>();
|
|
315
|
-
for (const workerInfo of
|
|
372
|
+
for (const workerInfo of opts.workers) {
|
|
316
373
|
buildPromises.set(
|
|
317
374
|
workerInfo.name,
|
|
318
375
|
new Promise<void>((resolve) => {
|
|
@@ -322,9 +379,9 @@ export class DevOrchestrator {
|
|
|
322
379
|
}
|
|
323
380
|
|
|
324
381
|
// Register event handlers
|
|
325
|
-
for (const workerInfo of
|
|
382
|
+
for (const workerInfo of opts.workers) {
|
|
326
383
|
const completeTask = registerWorkerEventHandlers(
|
|
327
|
-
workerInfo
|
|
384
|
+
workerInfo,
|
|
328
385
|
{
|
|
329
386
|
resultKey: `${workerInfo.name}:build`,
|
|
330
387
|
listrTitle: `${workerInfo.name} (client)`,
|
|
@@ -337,112 +394,25 @@ export class DevOrchestrator {
|
|
|
337
394
|
// serverReady (Vite dev server)
|
|
338
395
|
workerInfo.worker.on("serverReady", (data) => {
|
|
339
396
|
const event = data as ServerReadyEventData;
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
type: "server",
|
|
344
|
-
status: "running",
|
|
345
|
-
port: event.port,
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
// Print server URL when scope package rebuild is detected
|
|
350
|
-
workerInfo.worker.on("scopeRebuild", () => {
|
|
351
|
-
this._schedulePrintServers();
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
// Start worker
|
|
355
|
-
const pkgDir = path.join(this._cwd, "packages", workerInfo.name);
|
|
356
|
-
const clientConfig: SdClientPackageConfig = {
|
|
357
|
-
...workerInfo.config,
|
|
358
|
-
env: { ...this._baseEnv, ...workerInfo.config.env },
|
|
359
|
-
};
|
|
360
|
-
workerInfo.worker
|
|
361
|
-
.startWatch({
|
|
362
|
-
name: workerInfo.name,
|
|
363
|
-
config: clientConfig,
|
|
364
|
-
cwd: this._cwd,
|
|
365
|
-
pkgDir,
|
|
366
|
-
replaceDeps: this._sdConfig!.replaceDeps,
|
|
367
|
-
})
|
|
368
|
-
.catch((err: unknown) => {
|
|
397
|
+
if (opts.onServerReady != null) {
|
|
398
|
+
opts.onServerReady(workerInfo, event.port, completeTask);
|
|
399
|
+
} else {
|
|
369
400
|
completeTask({
|
|
370
401
|
name: workerInfo.name,
|
|
371
402
|
target: workerInfo.config.target,
|
|
372
|
-
type: "
|
|
373
|
-
status: "
|
|
374
|
-
|
|
403
|
+
type: "server",
|
|
404
|
+
status: "running",
|
|
405
|
+
port: event.port,
|
|
375
406
|
});
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return this._standaloneClientWorkers.map((workerInfo) => ({
|
|
380
|
-
name: `${workerInfo.name} (client)`,
|
|
381
|
-
promise: buildPromises.get(workerInfo.name) ?? Promise.resolve(),
|
|
382
|
-
}));
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Setup and start Vite client (server-connected) workers
|
|
387
|
-
*/
|
|
388
|
-
private _setupViteClients(): {
|
|
389
|
-
buildPromises: Array<{ name: string; promise: Promise<void> }>;
|
|
390
|
-
readyPromises: Map<string, { promise: Promise<void>; resolver: () => void }>;
|
|
391
|
-
} {
|
|
392
|
-
const buildPromiseMap = new Map<string, Promise<void>>();
|
|
393
|
-
const readyPromises = new Map<string, { promise: Promise<void>; resolver: () => void }>();
|
|
394
|
-
for (const workerInfo of this._viteClientWorkers) {
|
|
395
|
-
buildPromiseMap.set(
|
|
396
|
-
workerInfo.name,
|
|
397
|
-
new Promise<void>((resolve) => {
|
|
398
|
-
workerInfo.buildResolver = resolve;
|
|
399
|
-
}),
|
|
400
|
-
);
|
|
401
|
-
// Vite server ready promise (wait until server knows client port)
|
|
402
|
-
let readyResolver!: () => void;
|
|
403
|
-
const readyPromise = new Promise<void>((resolve) => {
|
|
404
|
-
readyResolver = resolve;
|
|
405
|
-
});
|
|
406
|
-
readyPromises.set(workerInfo.name, {
|
|
407
|
-
promise: readyPromise,
|
|
408
|
-
resolver: readyResolver,
|
|
407
|
+
}
|
|
409
408
|
});
|
|
410
|
-
}
|
|
411
409
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
{
|
|
417
|
-
resultKey: `${workerInfo.name}:build`,
|
|
418
|
-
listrTitle: `${workerInfo.name} (client)`,
|
|
419
|
-
resultType: "build",
|
|
420
|
-
},
|
|
421
|
-
this._results,
|
|
422
|
-
this._rebuildManager,
|
|
423
|
-
);
|
|
424
|
-
|
|
425
|
-
// serverReady - Store Vite port in clientPorts (URL is printed via server)
|
|
426
|
-
workerInfo.worker.on("serverReady", (data) => {
|
|
427
|
-
const event = data as ServerReadyEventData;
|
|
428
|
-
this._logger.debug(`[${workerInfo.name}] Vite serverReady (port: ${String(event.port)})`);
|
|
429
|
-
this._clientPorts[workerInfo.name] = event.port;
|
|
430
|
-
// Notify Vite server ready (server is waiting for proxy setup)
|
|
431
|
-
readyPromises.get(workerInfo.name)?.resolver();
|
|
432
|
-
// Call completeTask for build completion (Vite doesn't emit build event)
|
|
433
|
-
completeTask({
|
|
434
|
-
name: workerInfo.name,
|
|
435
|
-
target: workerInfo.config.target,
|
|
436
|
-
type: "build",
|
|
437
|
-
status: "success",
|
|
410
|
+
// Additional error handling (in addition to default from registerWorkerEventHandlers)
|
|
411
|
+
if (opts.onError != null) {
|
|
412
|
+
workerInfo.worker.on("error", () => {
|
|
413
|
+
opts.onError!(workerInfo);
|
|
438
414
|
});
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// Also resolve readyPromises on Vite client error
|
|
442
|
-
// (prevent server from hanging indefinitely in await Promise.all(clientReadyPromises))
|
|
443
|
-
workerInfo.worker.on("error", () => {
|
|
444
|
-
readyPromises.get(workerInfo.name)?.resolver();
|
|
445
|
-
});
|
|
415
|
+
}
|
|
446
416
|
|
|
447
417
|
// Print server URL when scope package rebuild is detected
|
|
448
418
|
workerInfo.worker.on("scopeRebuild", () => {
|
|
@@ -451,16 +421,11 @@ export class DevOrchestrator {
|
|
|
451
421
|
|
|
452
422
|
// Start worker
|
|
453
423
|
const pkgDir = path.join(this._cwd, "packages", workerInfo.name);
|
|
454
|
-
|
|
455
|
-
const viteConfig: SdClientPackageConfig = {
|
|
456
|
-
...workerInfo.config,
|
|
457
|
-
server: 0, // Vite will automatically assign port
|
|
458
|
-
env: { ...this._baseEnv, ...workerInfo.config.env },
|
|
459
|
-
};
|
|
424
|
+
const clientConfig = opts.createConfig(workerInfo);
|
|
460
425
|
workerInfo.worker
|
|
461
426
|
.startWatch({
|
|
462
427
|
name: workerInfo.name,
|
|
463
|
-
config:
|
|
428
|
+
config: clientConfig,
|
|
464
429
|
cwd: this._cwd,
|
|
465
430
|
pkgDir,
|
|
466
431
|
replaceDeps: this._sdConfig!.replaceDeps,
|
|
@@ -471,18 +436,15 @@ export class DevOrchestrator {
|
|
|
471
436
|
target: workerInfo.config.target,
|
|
472
437
|
type: "build",
|
|
473
438
|
status: "error",
|
|
474
|
-
message:
|
|
439
|
+
message: errNs.message(err),
|
|
475
440
|
});
|
|
476
441
|
});
|
|
477
442
|
}
|
|
478
443
|
|
|
479
|
-
return {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
})),
|
|
484
|
-
readyPromises,
|
|
485
|
-
};
|
|
444
|
+
return opts.workers.map((workerInfo) => ({
|
|
445
|
+
name: `${workerInfo.name} (client)`,
|
|
446
|
+
promise: buildPromises.get(workerInfo.name) ?? Promise.resolve(),
|
|
447
|
+
}));
|
|
486
448
|
}
|
|
487
449
|
|
|
488
450
|
/**
|
|
@@ -519,13 +481,28 @@ export class DevOrchestrator {
|
|
|
519
481
|
serverRuntimePromises.set(name, { promise, resolver });
|
|
520
482
|
}
|
|
521
483
|
|
|
484
|
+
// Track first build state per server
|
|
485
|
+
const isFirstBuild = new Map<string, boolean>(
|
|
486
|
+
this._serverPackages.map(({ name }) => [name, true])
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
// Helper to encapsulate result + promise resolution pattern
|
|
490
|
+
const resolveServerStep = (serverName: string, resultKey: string, result: BuildResult): void => {
|
|
491
|
+
this._results.set(resultKey, result);
|
|
492
|
+
if (isFirstBuild.get(serverName)) {
|
|
493
|
+
isFirstBuild.set(serverName, false);
|
|
494
|
+
serverRuntimePromises.get(serverName)?.resolver();
|
|
495
|
+
}
|
|
496
|
+
const updatedBuild = this._serverBuildWorkers.get(serverName)!;
|
|
497
|
+
updatedBuild.buildResolver();
|
|
498
|
+
};
|
|
499
|
+
|
|
522
500
|
// Register Server Build Worker event handlers
|
|
523
501
|
for (const { name } of this._serverPackages) {
|
|
524
502
|
const serverBuild = this._serverBuildWorkers.get(name)!;
|
|
525
|
-
let isFirstBuild = true;
|
|
526
503
|
|
|
527
504
|
serverBuild.worker.on("buildStart", () => {
|
|
528
|
-
if (!isFirstBuild) {
|
|
505
|
+
if (!isFirstBuild.get(name)) {
|
|
529
506
|
// Register with RebuildManager on rebuild
|
|
530
507
|
const resolver = this._rebuildManager.registerBuild(`${name}:server`, `${name} (server)`);
|
|
531
508
|
this._serverBuildWorkers.set(name, {
|
|
@@ -545,162 +522,47 @@ export class DevOrchestrator {
|
|
|
545
522
|
}
|
|
546
523
|
|
|
547
524
|
if (!event.success) {
|
|
548
|
-
|
|
525
|
+
resolveServerStep(name, `${name}:build`, {
|
|
549
526
|
name,
|
|
550
527
|
target: "server",
|
|
551
528
|
type: "build",
|
|
552
529
|
status: "error",
|
|
553
530
|
message: event.errors?.join("\n"),
|
|
554
531
|
});
|
|
555
|
-
|
|
556
|
-
if (isFirstBuild) {
|
|
557
|
-
isFirstBuild = false;
|
|
558
|
-
serverRuntimePromises.get(name)?.resolver();
|
|
559
|
-
}
|
|
560
|
-
this._serverBuildWorkers.get(name)!.buildResolver();
|
|
561
532
|
return;
|
|
562
533
|
}
|
|
563
534
|
|
|
564
535
|
// Start runtime worker on build success (separate async function to prevent error propagation)
|
|
565
|
-
void
|
|
566
|
-
|
|
536
|
+
void this._startServerRuntime(
|
|
537
|
+
name,
|
|
538
|
+
event.mainJsPath,
|
|
539
|
+
serverRuntimeWorkerPath,
|
|
540
|
+
serverRuntimePromises,
|
|
541
|
+
resolveServerStep,
|
|
542
|
+
viteClientReadyPromises,
|
|
543
|
+
).catch((err: unknown) => {
|
|
544
|
+
const message = errNs.message(err);
|
|
567
545
|
this._logger.error(`[${name}] Error starting Server Runtime:`, message);
|
|
568
546
|
|
|
569
|
-
|
|
547
|
+
resolveServerStep(name, `${name}:server`, {
|
|
570
548
|
name,
|
|
571
549
|
target: "server",
|
|
572
550
|
type: "server",
|
|
573
551
|
status: "error",
|
|
574
552
|
message,
|
|
575
553
|
});
|
|
576
|
-
|
|
577
|
-
if (isFirstBuild) {
|
|
578
|
-
isFirstBuild = false;
|
|
579
|
-
serverRuntimePromises.get(name)?.resolver();
|
|
580
|
-
}
|
|
581
|
-
const updatedBuild = this._serverBuildWorkers.get(name)!;
|
|
582
|
-
updatedBuild.buildResolver();
|
|
583
554
|
});
|
|
584
555
|
});
|
|
585
556
|
|
|
586
|
-
/**
|
|
587
|
-
* Start server runtime worker.
|
|
588
|
-
* Separated as a dedicated function to catch errors from async event handlers.
|
|
589
|
-
*/
|
|
590
|
-
const startServerRuntime = async (serverName: string, mainJsPath: string): Promise<void> => {
|
|
591
|
-
this._logger.debug(`[${serverName}] startServerRuntime: ${mainJsPath}`);
|
|
592
|
-
const updatedBuild = this._serverBuildWorkers.get(serverName)!;
|
|
593
|
-
updatedBuild.mainJsPath = mainJsPath;
|
|
594
|
-
|
|
595
|
-
// Terminate existing Server Runtime Worker
|
|
596
|
-
const existingRuntime = this._serverRuntimeWorkers.get(serverName);
|
|
597
|
-
if (existingRuntime != null) {
|
|
598
|
-
this._logger.info(`[${serverName}] Restarting server...`);
|
|
599
|
-
await existingRuntime.terminate();
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// Create and start new Server Runtime Worker
|
|
603
|
-
const runtimeWorker =
|
|
604
|
-
Worker.create<typeof ServerRuntimeWorkerModule>(serverRuntimeWorkerPath);
|
|
605
|
-
this._serverRuntimeWorkers.set(serverName, runtimeWorker);
|
|
606
|
-
|
|
607
|
-
// Wait for Vite servers of clients connected to this server to be ready
|
|
608
|
-
const connectedClients = this._serverClientsMap.get(serverName) ?? [];
|
|
609
|
-
const clientReadyPromises = connectedClients
|
|
610
|
-
.map((clientName) => viteClientReadyPromises.get(clientName)?.promise)
|
|
611
|
-
.filter((p): p is Promise<void> => p != null);
|
|
612
|
-
this._logger.debug(
|
|
613
|
-
`[${serverName}] Waiting for clients: ${String(clientReadyPromises.length)} total`,
|
|
614
|
-
);
|
|
615
|
-
if (clientReadyPromises.length > 0) {
|
|
616
|
-
await Promise.all(clientReadyPromises);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// Collect client ports for this server
|
|
620
|
-
const serverClientPorts: Record<string, number> = {};
|
|
621
|
-
for (const clientName of connectedClients) {
|
|
622
|
-
if (clientName in this._clientPorts) {
|
|
623
|
-
serverClientPorts[clientName] = this._clientPorts[clientName];
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
// Server Runtime event handlers
|
|
628
|
-
runtimeWorker.on("serverReady", (readyData) => {
|
|
629
|
-
const readyEvent = readyData as ServerReadyEventData;
|
|
630
|
-
this._results.set(`${serverName}:server`, {
|
|
631
|
-
name: serverName,
|
|
632
|
-
target: "server",
|
|
633
|
-
type: "server",
|
|
634
|
-
status: "running",
|
|
635
|
-
port: readyEvent.port,
|
|
636
|
-
});
|
|
637
|
-
|
|
638
|
-
if (isFirstBuild) {
|
|
639
|
-
isFirstBuild = false;
|
|
640
|
-
serverRuntimePromises.get(serverName)?.resolver();
|
|
641
|
-
}
|
|
642
|
-
updatedBuild.buildResolver();
|
|
643
|
-
});
|
|
644
|
-
|
|
645
|
-
runtimeWorker.on("error", (errorData) => {
|
|
646
|
-
const errorEvent = errorData as ErrorEventData;
|
|
647
|
-
this._results.set(`${serverName}:server`, {
|
|
648
|
-
name: serverName,
|
|
649
|
-
target: "server",
|
|
650
|
-
type: "server",
|
|
651
|
-
status: "error",
|
|
652
|
-
message: errorEvent.message,
|
|
653
|
-
});
|
|
654
|
-
|
|
655
|
-
if (isFirstBuild) {
|
|
656
|
-
isFirstBuild = false;
|
|
657
|
-
serverRuntimePromises.get(serverName)?.resolver();
|
|
658
|
-
}
|
|
659
|
-
updatedBuild.buildResolver();
|
|
660
|
-
});
|
|
661
|
-
|
|
662
|
-
// Start Server Runtime
|
|
663
|
-
// If worker crashes, it terminates without emitting "serverReady"/"error" events,
|
|
664
|
-
// so catch promise rejection to prevent hanging
|
|
665
|
-
runtimeWorker
|
|
666
|
-
.start({
|
|
667
|
-
mainJsPath,
|
|
668
|
-
clientPorts: serverClientPorts,
|
|
669
|
-
})
|
|
670
|
-
.catch((err: unknown) => {
|
|
671
|
-
const message = errorMessage(err);
|
|
672
|
-
this._logger.error(`[${serverName}] Server Runtime Worker crashed:`, message);
|
|
673
|
-
|
|
674
|
-
this._results.set(`${serverName}:server`, {
|
|
675
|
-
name: serverName,
|
|
676
|
-
target: "server",
|
|
677
|
-
type: "server",
|
|
678
|
-
status: "error",
|
|
679
|
-
message,
|
|
680
|
-
});
|
|
681
|
-
|
|
682
|
-
if (isFirstBuild) {
|
|
683
|
-
isFirstBuild = false;
|
|
684
|
-
serverRuntimePromises.get(serverName)?.resolver();
|
|
685
|
-
}
|
|
686
|
-
updatedBuild.buildResolver();
|
|
687
|
-
});
|
|
688
|
-
};
|
|
689
|
-
|
|
690
557
|
serverBuild.worker.on("error", (data) => {
|
|
691
558
|
const event = data as ErrorEventData;
|
|
692
|
-
|
|
559
|
+
resolveServerStep(name, `${name}:build`, {
|
|
693
560
|
name,
|
|
694
561
|
target: "server",
|
|
695
562
|
type: "build",
|
|
696
563
|
status: "error",
|
|
697
564
|
message: event.message,
|
|
698
565
|
});
|
|
699
|
-
if (isFirstBuild) {
|
|
700
|
-
isFirstBuild = false;
|
|
701
|
-
serverRuntimePromises.get(name)?.resolver();
|
|
702
|
-
}
|
|
703
|
-
this._serverBuildWorkers.get(name)!.buildResolver();
|
|
704
566
|
});
|
|
705
567
|
}
|
|
706
568
|
|
|
@@ -724,7 +586,7 @@ export class DevOrchestrator {
|
|
|
724
586
|
target: "server",
|
|
725
587
|
type: "build",
|
|
726
588
|
status: "error",
|
|
727
|
-
message:
|
|
589
|
+
message: errNs.message(err),
|
|
728
590
|
});
|
|
729
591
|
serverRuntimePromises.get(name)?.resolver();
|
|
730
592
|
serverBuild.buildResolver();
|
|
@@ -737,6 +599,98 @@ export class DevOrchestrator {
|
|
|
737
599
|
}));
|
|
738
600
|
}
|
|
739
601
|
|
|
602
|
+
/**
|
|
603
|
+
* Start server runtime worker.
|
|
604
|
+
* Separated as a dedicated method to catch errors from async event handlers.
|
|
605
|
+
*/
|
|
606
|
+
private async _startServerRuntime(
|
|
607
|
+
serverName: string,
|
|
608
|
+
mainJsPath: string,
|
|
609
|
+
serverRuntimeWorkerPath: string,
|
|
610
|
+
serverRuntimePromises: Map<string, { promise: Promise<void>; resolver: () => void }>,
|
|
611
|
+
resolveServerStep: (serverName: string, resultKey: string, result: BuildResult) => void,
|
|
612
|
+
viteClientReadyPromises: Map<string, { promise: Promise<void>; resolver: () => void }>,
|
|
613
|
+
): Promise<void> {
|
|
614
|
+
this._logger.debug(`[${serverName}] _startServerRuntime: ${mainJsPath}`);
|
|
615
|
+
const updatedBuild = this._serverBuildWorkers.get(serverName)!;
|
|
616
|
+
updatedBuild.mainJsPath = mainJsPath;
|
|
617
|
+
|
|
618
|
+
// Terminate existing Server Runtime Worker
|
|
619
|
+
const existingRuntime = this._serverRuntimeWorkers.get(serverName);
|
|
620
|
+
if (existingRuntime != null) {
|
|
621
|
+
this._logger.info(`[${serverName}] Restarting server...`);
|
|
622
|
+
await existingRuntime.terminate();
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Create and start new Server Runtime Worker
|
|
626
|
+
const runtimeWorker = Worker.create<typeof ServerRuntimeWorkerModule>(serverRuntimeWorkerPath);
|
|
627
|
+
this._serverRuntimeWorkers.set(serverName, runtimeWorker);
|
|
628
|
+
|
|
629
|
+
// Wait for Vite servers of clients connected to this server to be ready
|
|
630
|
+
const connectedClients = this._serverClientsMap.get(serverName) ?? [];
|
|
631
|
+
const clientReadyPromises = connectedClients
|
|
632
|
+
.map((clientName) => viteClientReadyPromises.get(clientName)?.promise)
|
|
633
|
+
.filter((p): p is Promise<void> => p != null);
|
|
634
|
+
this._logger.debug(
|
|
635
|
+
`[${serverName}] Waiting for clients: ${String(clientReadyPromises.length)} total`,
|
|
636
|
+
);
|
|
637
|
+
if (clientReadyPromises.length > 0) {
|
|
638
|
+
await Promise.all(clientReadyPromises);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// Collect client ports for this server
|
|
642
|
+
const serverClientPorts: Record<string, number> = {};
|
|
643
|
+
for (const clientName of connectedClients) {
|
|
644
|
+
if (clientName in this._clientPorts) {
|
|
645
|
+
serverClientPorts[clientName] = this._clientPorts[clientName];
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Server Runtime event handlers
|
|
650
|
+
runtimeWorker.on("serverReady", (readyData) => {
|
|
651
|
+
const readyEvent = readyData as ServerReadyEventData;
|
|
652
|
+
resolveServerStep(serverName, `${serverName}:server`, {
|
|
653
|
+
name: serverName,
|
|
654
|
+
target: "server",
|
|
655
|
+
type: "server",
|
|
656
|
+
status: "running",
|
|
657
|
+
port: readyEvent.port,
|
|
658
|
+
});
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
runtimeWorker.on("error", (errorData) => {
|
|
662
|
+
const errorEvent = errorData as ErrorEventData;
|
|
663
|
+
resolveServerStep(serverName, `${serverName}:server`, {
|
|
664
|
+
name: serverName,
|
|
665
|
+
target: "server",
|
|
666
|
+
type: "server",
|
|
667
|
+
status: "error",
|
|
668
|
+
message: errorEvent.message,
|
|
669
|
+
});
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
// Start Server Runtime
|
|
673
|
+
// If worker crashes, it terminates without emitting "serverReady"/"error" events,
|
|
674
|
+
// so catch promise rejection to prevent hanging
|
|
675
|
+
runtimeWorker
|
|
676
|
+
.start({
|
|
677
|
+
mainJsPath,
|
|
678
|
+
clientPorts: serverClientPorts,
|
|
679
|
+
})
|
|
680
|
+
.catch((err: unknown) => {
|
|
681
|
+
const message = errNs.message(err);
|
|
682
|
+
this._logger.error(`[${serverName}] Server Runtime Worker crashed:`, message);
|
|
683
|
+
|
|
684
|
+
resolveServerStep(serverName, `${serverName}:server`, {
|
|
685
|
+
name: serverName,
|
|
686
|
+
target: "server",
|
|
687
|
+
type: "server",
|
|
688
|
+
status: "error",
|
|
689
|
+
message,
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
|
|
740
694
|
/**
|
|
741
695
|
* Wait for termination signal
|
|
742
696
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { consola } from "consola";
|
|
3
|
-
import type { BuildTarget,
|
|
3
|
+
import type { BuildTarget, SdBuildPackageConfig, SdConfig } from "../sd-config.types";
|
|
4
4
|
import { loadSdConfig } from "../utils/sd-config";
|
|
5
5
|
import { filterPackagesByTargets } from "../utils/package-utils";
|
|
6
6
|
import { watchReplaceDeps, type WatchReplaceDepResult } from "../utils/replace-deps";
|
|
@@ -10,10 +10,9 @@ import { ResultCollector } from "../infra/ResultCollector";
|
|
|
10
10
|
import { SignalHandler } from "../infra/SignalHandler";
|
|
11
11
|
import { LibraryBuilder } from "../builders/LibraryBuilder";
|
|
12
12
|
import { DtsBuilder } from "../builders/DtsBuilder";
|
|
13
|
-
import type {
|
|
13
|
+
import type { BuildPackageInfo } from "../builders/types";
|
|
14
14
|
import { watchCopySrcFiles } from "../utils/copy-src";
|
|
15
15
|
import type { FsWatcher } from "@simplysm/core-node";
|
|
16
|
-
import type { SdBuildPackageConfig } from "../sd-config.types";
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Watch command options
|
|
@@ -40,7 +39,7 @@ export class WatchOrchestrator {
|
|
|
40
39
|
private _rebuildManager!: RebuildManager;
|
|
41
40
|
private _libraryBuilder!: LibraryBuilder;
|
|
42
41
|
private _dtsBuilder!: DtsBuilder;
|
|
43
|
-
private _packages:
|
|
42
|
+
private _packages: BuildPackageInfo[] = [];
|
|
44
43
|
private _copySrcWatchers: FsWatcher[] = [];
|
|
45
44
|
private _replaceDepWatcher: WatchReplaceDepResult | undefined;
|
|
46
45
|
|
|
@@ -64,7 +63,7 @@ export class WatchOrchestrator {
|
|
|
64
63
|
sdConfig = await loadSdConfig({
|
|
65
64
|
cwd: this._cwd,
|
|
66
65
|
dev: true,
|
|
67
|
-
|
|
66
|
+
options: this._options.options,
|
|
68
67
|
});
|
|
69
68
|
this._logger.debug("sd.config.ts loaded");
|
|
70
69
|
} catch (err) {
|
|
@@ -85,10 +84,10 @@ export class WatchOrchestrator {
|
|
|
85
84
|
const isLibraryTarget = (target: string): target is BuildTarget =>
|
|
86
85
|
target === "node" || target === "browser" || target === "neutral";
|
|
87
86
|
|
|
88
|
-
const libraryConfigs: Record<string,
|
|
87
|
+
const libraryConfigs: Record<string, SdBuildPackageConfig> = {};
|
|
89
88
|
for (const [name, config] of Object.entries(allPackages)) {
|
|
90
89
|
if (isLibraryTarget(config.target)) {
|
|
91
|
-
libraryConfigs[name] = config;
|
|
90
|
+
libraryConfigs[name] = config as SdBuildPackageConfig;
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
|
|
@@ -145,9 +144,8 @@ export class WatchOrchestrator {
|
|
|
145
144
|
|
|
146
145
|
// Start copySrc watch
|
|
147
146
|
for (const pkg of this._packages) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const watcher = await watchCopySrcFiles(pkg.dir, buildConfig.copySrc);
|
|
147
|
+
if (pkg.config.copySrc != null && pkg.config.copySrc.length > 0) {
|
|
148
|
+
const watcher = await watchCopySrcFiles(pkg.dir, pkg.config.copySrc);
|
|
151
149
|
this._copySrcWatchers.push(watcher);
|
|
152
150
|
}
|
|
153
151
|
}
|
package/src/sd-cli.ts
CHANGED
|
@@ -30,7 +30,7 @@ if (isDev) {
|
|
|
30
30
|
try {
|
|
31
31
|
const { loadSdConfig } = await import("./utils/sd-config.js");
|
|
32
32
|
const { setupReplaceDeps } = await import("./utils/replace-deps.js");
|
|
33
|
-
const sdConfig = await loadSdConfig({ cwd: process.cwd(), dev: false,
|
|
33
|
+
const sdConfig = await loadSdConfig({ cwd: process.cwd(), dev: false, options: [] });
|
|
34
34
|
if (sdConfig.replaceDeps != null) {
|
|
35
35
|
await setupReplaceDeps(process.cwd(), sdConfig.replaceDeps);
|
|
36
36
|
}
|