@lark-apaas/fullstack-cli 1.1.59-alpha.20260719171717 → 1.1.59-alpha.20260720184331
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/package.json
CHANGED
package/templates/scripts/dev.js
CHANGED
|
@@ -8,7 +8,9 @@ const readline = require('readline');
|
|
|
8
8
|
const {
|
|
9
9
|
applyPreviewArtifactHostOverrides,
|
|
10
10
|
buildListeningPortLookupArgs,
|
|
11
|
+
closePreviewPhaseReporterWithRetry,
|
|
11
12
|
createDeferredTypecheckGate,
|
|
13
|
+
createPreviewPhaseFrameDecoder,
|
|
12
14
|
createPreviewPhaseReporter,
|
|
13
15
|
normalizeTcpPort,
|
|
14
16
|
parseTscWatchSummary,
|
|
@@ -199,6 +201,7 @@ function startProcess({
|
|
|
199
201
|
args,
|
|
200
202
|
cleanupPort,
|
|
201
203
|
phaseDetail = {},
|
|
204
|
+
phaseChannel = false,
|
|
202
205
|
onReady,
|
|
203
206
|
onOutputLine,
|
|
204
207
|
}) {
|
|
@@ -236,12 +239,23 @@ function startProcess({
|
|
|
236
239
|
}
|
|
237
240
|
|
|
238
241
|
while (!stopping) {
|
|
242
|
+
const childEnv = { ...process.env };
|
|
243
|
+
// The parent is the only outbox writer. Child processes receive a narrow
|
|
244
|
+
// producer channel, never the filesystem destination.
|
|
245
|
+
delete childEnv.MIAODA_PREVIEW_PHASE_OUTBOX_ROOT;
|
|
246
|
+
if (phaseChannel) {
|
|
247
|
+
childEnv.MIAODA_PREVIEW_PHASE_FD = '3';
|
|
248
|
+
} else {
|
|
249
|
+
delete childEnv.MIAODA_PREVIEW_PHASE_FD;
|
|
250
|
+
}
|
|
239
251
|
const child = spawn(command, args, {
|
|
240
252
|
detached: true,
|
|
241
|
-
stdio:
|
|
253
|
+
stdio: phaseChannel
|
|
254
|
+
? ['ignore', 'pipe', 'pipe', 'pipe']
|
|
255
|
+
: ['ignore', 'pipe', 'pipe'],
|
|
242
256
|
shell: true,
|
|
243
257
|
cwd: PROJECT_ROOT,
|
|
244
|
-
env:
|
|
258
|
+
env: childEnv,
|
|
245
259
|
});
|
|
246
260
|
|
|
247
261
|
entry.pid = child.pid;
|
|
@@ -307,13 +321,24 @@ function startProcess({
|
|
|
307
321
|
|
|
308
322
|
// Pipe stdout and stderr through readline for timestamped logging
|
|
309
323
|
let typecheckSummaryReported = false;
|
|
310
|
-
|
|
324
|
+
let phaseReported = false;
|
|
325
|
+
const pipeLines = (stream, allowPhaseFallback = false) => {
|
|
311
326
|
const rl = readline.createInterface({
|
|
312
327
|
input: stream,
|
|
313
328
|
crlfDelay: Infinity,
|
|
314
329
|
});
|
|
315
330
|
rl.on('line', line => {
|
|
316
331
|
if (onOutputLine) onOutputLine(line);
|
|
332
|
+
const legacyPhaseCandidate =
|
|
333
|
+
allowPhaseFallback && line.startsWith('[MiaodaPreviewPhase] ');
|
|
334
|
+
if (legacyPhaseCandidate && !phaseReported) {
|
|
335
|
+
phaseReported = previewPhaseReporter.ingest(line, {
|
|
336
|
+
producer: 'vite_plugin',
|
|
337
|
+
allowed_phases: ['vite_http_listening'],
|
|
338
|
+
attempt,
|
|
339
|
+
allow_legacy_stdout: true,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
317
342
|
if (name === 'server-typecheck' && !typecheckSummaryReported) {
|
|
318
343
|
const summary = parseTscWatchSummary(line);
|
|
319
344
|
if (summary) {
|
|
@@ -334,11 +359,38 @@ function startProcess({
|
|
|
334
359
|
try {
|
|
335
360
|
fs.writeSync(logFd, msg);
|
|
336
361
|
} catch {}
|
|
337
|
-
|
|
362
|
+
// Phase fallbacks are normalized by the parent reporter before they
|
|
363
|
+
// enter the shared log. Keep the raw child claim quarantined in the
|
|
364
|
+
// component log so collectors never observe two representations.
|
|
365
|
+
if (!legacyPhaseCandidate) writeOutput(msg);
|
|
338
366
|
});
|
|
339
367
|
};
|
|
340
|
-
if (child.stdout) pipeLines(child.stdout);
|
|
368
|
+
if (child.stdout) pipeLines(child.stdout, phaseChannel);
|
|
341
369
|
if (child.stderr) pipeLines(child.stderr);
|
|
370
|
+
if (phaseChannel && child.stdio[3]) {
|
|
371
|
+
let oversizedPhaseFrameReported = false;
|
|
372
|
+
const phaseDecoder = createPreviewPhaseFrameDecoder({
|
|
373
|
+
max_bytes: 16 * 1024,
|
|
374
|
+
on_oversized_frame: () => {
|
|
375
|
+
if (oversizedPhaseFrameReported) return;
|
|
376
|
+
oversizedPhaseFrameReported = true;
|
|
377
|
+
logEvent(
|
|
378
|
+
'WARN',
|
|
379
|
+
name,
|
|
380
|
+
'Dropped an oversized preview phase producer frame'
|
|
381
|
+
);
|
|
382
|
+
},
|
|
383
|
+
on_frame: line => {
|
|
384
|
+
if (phaseReported) return;
|
|
385
|
+
phaseReported = previewPhaseReporter.ingest(line, {
|
|
386
|
+
producer: 'vite_plugin',
|
|
387
|
+
allowed_phases: ['vite_http_listening'],
|
|
388
|
+
attempt,
|
|
389
|
+
});
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
child.stdio[3].on('data', chunk => phaseDecoder.push(chunk));
|
|
393
|
+
}
|
|
342
394
|
|
|
343
395
|
// Wait for the direct child to exit.
|
|
344
396
|
// NOTE: must use 'exit', not 'close'. With shell:true, grandchild processes
|
|
@@ -468,6 +520,16 @@ async function cleanup() {
|
|
|
468
520
|
|
|
469
521
|
logEvent('INFO', 'main', 'All processes stopped');
|
|
470
522
|
|
|
523
|
+
const previewPhaseSealed =
|
|
524
|
+
await closePreviewPhaseReporterWithRetry(previewPhaseReporter);
|
|
525
|
+
if (!previewPhaseSealed) {
|
|
526
|
+
logEvent(
|
|
527
|
+
'ERROR',
|
|
528
|
+
'main',
|
|
529
|
+
'Preview phase outbox did not seal after bounded shutdown retries'
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
|
|
471
533
|
try {
|
|
472
534
|
fs.closeSync(devStdLogFd);
|
|
473
535
|
} catch {}
|
|
@@ -475,7 +537,7 @@ async function cleanup() {
|
|
|
475
537
|
fs.closeSync(devLogFd);
|
|
476
538
|
} catch {}
|
|
477
539
|
|
|
478
|
-
process.exit(0);
|
|
540
|
+
process.exit(previewPhaseSealed ? 0 : 1);
|
|
479
541
|
}
|
|
480
542
|
|
|
481
543
|
process.on('SIGTERM', cleanup);
|
|
@@ -644,6 +706,7 @@ async function main() {
|
|
|
644
706
|
command: 'npm',
|
|
645
707
|
args: ['run', 'dev:client'],
|
|
646
708
|
cleanupPort: CLIENT_DEV_PORT,
|
|
709
|
+
phaseChannel: true,
|
|
647
710
|
});
|
|
648
711
|
|
|
649
712
|
writeOutput(`📋 Dev processes running. Press Ctrl+C to stop.\n`);
|
|
@@ -657,7 +720,14 @@ async function main() {
|
|
|
657
720
|
}
|
|
658
721
|
}
|
|
659
722
|
|
|
660
|
-
main().catch(err => {
|
|
723
|
+
main().catch(async err => {
|
|
661
724
|
console.error('Fatal error:', err);
|
|
725
|
+
const previewPhaseSealed =
|
|
726
|
+
await closePreviewPhaseReporterWithRetry(previewPhaseReporter);
|
|
727
|
+
if (!previewPhaseSealed) {
|
|
728
|
+
console.error(
|
|
729
|
+
'Preview phase outbox did not seal after bounded fatal-exit retries'
|
|
730
|
+
);
|
|
731
|
+
}
|
|
662
732
|
process.exit(1);
|
|
663
733
|
});
|