@lark-apaas/coding-template-nestjs-react-fullstack 0.1.27-alpha.20260824122815 → 0.1.27
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 +1 -1
- package/template/package-lock.json +4385 -4385
- package/template/package.json +5 -5
- package/template/scripts/build.sh +0 -12
- package/template/scripts/dev.js +57 -415
- package/template/scripts/dev.sh +0 -2
- package/template/vite.config.ts +1 -1
- package/template/scripts/cache-generation-preflight.mjs +0 -1346
- package/template/scripts/cache-generation-prune.mjs +0 -174
- package/template/scripts/cache-runtime-coordinator.mjs +0 -482
- package/template/scripts/lib/preserve-dev-cache.cjs +0 -123
- package/template/scripts/patch-nest-cli-startup-instrumentation.mjs +0 -376
- package/template/scripts/patch-vite-dependency-graph-hash.mjs +0 -141
- package/template/scripts/server-cache-runtime.mjs +0 -865
- package/template/scripts/server-startup-runtime.mjs +0 -445
- package/template/scripts/vite-cache-runtime.mjs +0 -3098
- package/template/scripts/vite-runtime.config.mjs +0 -420
- package/template/scripts/workspace-client-runtime.mjs +0 -466
|
@@ -1,445 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import net from 'node:net';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
import { spawn } from 'node:child_process';
|
|
7
|
-
import { fileURLToPath } from 'node:url';
|
|
8
|
-
|
|
9
|
-
const projectRoot = path.resolve(
|
|
10
|
-
process.env.MIAODA_WORKSPACE_ROOT || process.cwd()
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
// The bundle orchestrator may be started directly by the image before the
|
|
14
|
-
// project npm task exists. Load the same project .env contract as dev.js so the
|
|
15
|
-
// later source service receives identical application configuration.
|
|
16
|
-
const projectEnvFile = path.join(projectRoot, '.env');
|
|
17
|
-
if (fs.existsSync(projectEnvFile)) {
|
|
18
|
-
for (const line of fs.readFileSync(projectEnvFile, 'utf8').split('\n')) {
|
|
19
|
-
const trimmed = line.trim();
|
|
20
|
-
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
21
|
-
const separator = trimmed.indexOf('=');
|
|
22
|
-
if (separator < 1) continue;
|
|
23
|
-
const key = trimmed.slice(0, separator).trim();
|
|
24
|
-
const value = trimmed.slice(separator + 1).trim();
|
|
25
|
-
if (!(key in process.env)) process.env[key] = value;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const scriptsRoot = path.dirname(fileURLToPath(import.meta.url));
|
|
29
|
-
const swcRuntimeConfigRelativePath = path.join(
|
|
30
|
-
'.miaoda-runtime',
|
|
31
|
-
'nest-cli.swc.json'
|
|
32
|
-
);
|
|
33
|
-
const workspaceReadyFile = path.resolve(
|
|
34
|
-
process.env.MIAODA_WORKSPACE_READY_FILE || '/tmp/event/WORKSPACE_READY'
|
|
35
|
-
);
|
|
36
|
-
const actionPluginReadyFile = path.resolve(
|
|
37
|
-
process.env.MIAODA_ACTION_PLUGIN_READY_FILE ||
|
|
38
|
-
'/tmp/event/MIAODA_ACTION_PLUGIN_READY.json'
|
|
39
|
-
);
|
|
40
|
-
const bundleFallbackFile = path.resolve(
|
|
41
|
-
process.env.MIAODA_NEST_BUNDLE_FALLBACK_FILE ||
|
|
42
|
-
'/tmp/event/MIAODA_NEST_BUNDLE_FALLBACK'
|
|
43
|
-
);
|
|
44
|
-
const serverHost = process.env.SERVER_HOST || '0.0.0.0';
|
|
45
|
-
const serverPort = Number(process.env.SERVER_PORT || 3000);
|
|
46
|
-
const requestedMode = process.env.MIAODA_NEST_START_MODE || 'workspace';
|
|
47
|
-
const skipActionPluginInit =
|
|
48
|
-
process.env.MIAODA_NEST_SKIP_ACTION_PLUGIN_INIT === 'true';
|
|
49
|
-
const expectedRestoreEpochMs =
|
|
50
|
-
process.env.MIAODA_PLATFORM_ENV_NOT_BEFORE_MS || '';
|
|
51
|
-
const supportedModes = new Set([
|
|
52
|
-
'bundle-handoff',
|
|
53
|
-
'workspace',
|
|
54
|
-
'swc',
|
|
55
|
-
]);
|
|
56
|
-
const runtimeStartedAtEpochMs = Date.now();
|
|
57
|
-
const startedAt = process.hrtime.bigint();
|
|
58
|
-
let stopping = false;
|
|
59
|
-
let serviceChild;
|
|
60
|
-
let compilerChild;
|
|
61
|
-
|
|
62
|
-
if (!supportedModes.has(requestedMode)) {
|
|
63
|
-
throw new Error(`MIAODA_NEST_START_MODE_INVALID: ${requestedMode}`);
|
|
64
|
-
}
|
|
65
|
-
if (
|
|
66
|
-
!Number.isSafeInteger(serverPort) ||
|
|
67
|
-
serverPort <= 0 ||
|
|
68
|
-
serverPort > 65_535
|
|
69
|
-
) {
|
|
70
|
-
throw new Error('MIAODA_NEST_SERVER_PORT_INVALID');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function durationMs(since = startedAt) {
|
|
74
|
-
return Number(process.hrtime.bigint() - since) / 1_000_000;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function emit(phase, since, details = {}) {
|
|
78
|
-
const atEpochMs = Date.now();
|
|
79
|
-
const phaseDurationMs = Number(durationMs(since).toFixed(3));
|
|
80
|
-
process.stdout.write(
|
|
81
|
-
`${JSON.stringify({
|
|
82
|
-
event: 'miaoda_workspace_runtime_phase',
|
|
83
|
-
runtime: 'nest',
|
|
84
|
-
mode: requestedMode,
|
|
85
|
-
phase,
|
|
86
|
-
atEpochMs,
|
|
87
|
-
phaseStartedAtEpochMs: Number((atEpochMs - phaseDurationMs).toFixed(3)),
|
|
88
|
-
runtimeStartedAtEpochMs,
|
|
89
|
-
durationMs: phaseDurationMs,
|
|
90
|
-
...details,
|
|
91
|
-
})}\n`
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function delay(ms) {
|
|
96
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function markBundleFallback(reason) {
|
|
100
|
-
fs.mkdirSync(path.dirname(bundleFallbackFile), { recursive: true });
|
|
101
|
-
const temporaryFile = `${bundleFallbackFile}.${process.pid}.tmp`;
|
|
102
|
-
fs.writeFileSync(
|
|
103
|
-
temporaryFile,
|
|
104
|
-
`${JSON.stringify({ schemaVersion: 1, reason, at: new Date().toISOString() })}\n`,
|
|
105
|
-
{ mode: 0o600 }
|
|
106
|
-
);
|
|
107
|
-
fs.renameSync(temporaryFile, bundleFallbackFile);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function childRunning(child) {
|
|
111
|
-
return Boolean(
|
|
112
|
-
child?.pid && child.exitCode === null && child.signalCode === null
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function terminate(child, signal = 'SIGTERM') {
|
|
117
|
-
if (!child?.pid) return;
|
|
118
|
-
try {
|
|
119
|
-
process.kill(-child.pid, signal);
|
|
120
|
-
} catch {
|
|
121
|
-
try {
|
|
122
|
-
child.kill(signal);
|
|
123
|
-
} catch {}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function workspaceDependenciesReady() {
|
|
128
|
-
try {
|
|
129
|
-
return (
|
|
130
|
-
fs.statSync(workspaceReadyFile).isFile() &&
|
|
131
|
-
fs.statSync(path.join(projectRoot, 'node_modules')).isDirectory()
|
|
132
|
-
);
|
|
133
|
-
} catch {
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async function waitForDependencies() {
|
|
139
|
-
const waitStartedAt = process.hrtime.bigint();
|
|
140
|
-
while (!stopping && !workspaceDependenciesReady()) await delay(100);
|
|
141
|
-
if (stopping) throw new Error('MIAODA_NEST_STARTUP_STOPPING');
|
|
142
|
-
emit('dependency_wait', waitStartedAt, { workspaceReadyFile });
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function actionPluginPreconditionReady() {
|
|
146
|
-
try {
|
|
147
|
-
const marker = JSON.parse(fs.readFileSync(actionPluginReadyFile, 'utf8'));
|
|
148
|
-
return (
|
|
149
|
-
marker?.schemaVersion === 1 &&
|
|
150
|
-
(!expectedRestoreEpochMs ||
|
|
151
|
-
String(marker.restoreEpochMs || '') === expectedRestoreEpochMs)
|
|
152
|
-
);
|
|
153
|
-
} catch {
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async function waitForActionPluginPrecondition() {
|
|
159
|
-
const waitStartedAt = process.hrtime.bigint();
|
|
160
|
-
while (!stopping && !actionPluginPreconditionReady()) await delay(100);
|
|
161
|
-
if (stopping) throw new Error('MIAODA_NEST_STARTUP_STOPPING');
|
|
162
|
-
emit('action_plugin_wait', waitStartedAt, {
|
|
163
|
-
actionPluginReadyFile,
|
|
164
|
-
ownership: 'shared-parent',
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function probeHost(host) {
|
|
169
|
-
if (!host || host === '0.0.0.0') return '127.0.0.1';
|
|
170
|
-
if (host === '::' || host === '[::]') return '::1';
|
|
171
|
-
return host.replace(/^\[|\]$/g, '');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async function waitForPort(child = serviceChild) {
|
|
175
|
-
const listenStartedAt = process.hrtime.bigint();
|
|
176
|
-
const deadline = Date.now() + 60_000;
|
|
177
|
-
const host = probeHost(serverHost);
|
|
178
|
-
while (!stopping && Date.now() < deadline) {
|
|
179
|
-
if (child && !childRunning(child)) {
|
|
180
|
-
throw new Error('MIAODA_NEST_PROCESS_EXITED_BEFORE_READY');
|
|
181
|
-
}
|
|
182
|
-
const connected = await new Promise(resolve => {
|
|
183
|
-
const socket = net.createConnection({ host, port: serverPort });
|
|
184
|
-
socket.once('connect', () => {
|
|
185
|
-
socket.destroy();
|
|
186
|
-
resolve(true);
|
|
187
|
-
});
|
|
188
|
-
socket.once('error', () => resolve(false));
|
|
189
|
-
});
|
|
190
|
-
if (connected) {
|
|
191
|
-
emit('listen_ready', listenStartedAt, {
|
|
192
|
-
host: serverHost,
|
|
193
|
-
port: serverPort,
|
|
194
|
-
});
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
await delay(100);
|
|
198
|
-
}
|
|
199
|
-
throw new Error('MIAODA_NEST_READY_TIMEOUT');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function spawnInherited(command, args, extraEnv = {}) {
|
|
203
|
-
return spawn(command, args, {
|
|
204
|
-
cwd: projectRoot,
|
|
205
|
-
detached: true,
|
|
206
|
-
stdio: 'inherit',
|
|
207
|
-
env: {
|
|
208
|
-
...process.env,
|
|
209
|
-
...extraEnv,
|
|
210
|
-
MIAODA_CACHE_BOOTSTRAP_ENABLED: 'false',
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async function runCommand(command, args, phase) {
|
|
216
|
-
const phaseStartedAt = process.hrtime.bigint();
|
|
217
|
-
compilerChild = spawnInherited(command, args);
|
|
218
|
-
const result = await new Promise((resolve, reject) => {
|
|
219
|
-
compilerChild.once('error', reject);
|
|
220
|
-
compilerChild.once('exit', (code, signal) => resolve({ code, signal }));
|
|
221
|
-
});
|
|
222
|
-
compilerChild = undefined;
|
|
223
|
-
emit(phase, phaseStartedAt, result);
|
|
224
|
-
if (result.code !== 0) {
|
|
225
|
-
throw new Error(
|
|
226
|
-
`MIAODA_NEST_COMMAND_FAILED: ${command} ${args.join(' ')} code=${result.code} signal=${result.signal}`
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
async function initializeActionPlugins() {
|
|
232
|
-
if (skipActionPluginInit) {
|
|
233
|
-
await waitForActionPluginPrecondition();
|
|
234
|
-
emit('action_plugin_init_skipped', process.hrtime.bigint(), {
|
|
235
|
-
reason: 'shared-parent-initialized',
|
|
236
|
-
});
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
if (actionPluginPreconditionReady()) {
|
|
240
|
-
emit('action_plugin_init_skipped', process.hrtime.bigint(), {
|
|
241
|
-
reason: 'shared-parent-initialized',
|
|
242
|
-
});
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
const cli = [
|
|
246
|
-
process.env.MIAODA_FULLSTACK_CLI_BIN,
|
|
247
|
-
path.join(
|
|
248
|
-
projectRoot,
|
|
249
|
-
'node_modules',
|
|
250
|
-
'@lark-apaas',
|
|
251
|
-
'fullstack-cli',
|
|
252
|
-
'bin',
|
|
253
|
-
'cli.js'
|
|
254
|
-
),
|
|
255
|
-
'/usr/lib/node_modules/@lark-apaas/fullstack-cli/bin/cli.js',
|
|
256
|
-
].find(candidate => candidate && fs.existsSync(candidate));
|
|
257
|
-
if (!cli) {
|
|
258
|
-
throw new Error('MIAODA_ACTION_PLUGIN_CLI_MISSING');
|
|
259
|
-
}
|
|
260
|
-
try {
|
|
261
|
-
await runCommand(
|
|
262
|
-
process.execPath,
|
|
263
|
-
[cli, 'action-plugin', 'init'],
|
|
264
|
-
'action_plugin_init'
|
|
265
|
-
);
|
|
266
|
-
} catch (error) {
|
|
267
|
-
// Match the original dev.js contract: plugin discovery failure is visible
|
|
268
|
-
// in logs but does not replace the Nest process with a platform failure.
|
|
269
|
-
process.stderr.write(
|
|
270
|
-
`${JSON.stringify({
|
|
271
|
-
event: 'miaoda_action_plugin_init_failed',
|
|
272
|
-
continueStartup: true,
|
|
273
|
-
error: error instanceof Error ? error.message : String(error),
|
|
274
|
-
})}\n`
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function spawnWorkspaceService() {
|
|
280
|
-
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
281
|
-
return spawnInherited(npmCommand, ['run', 'dev:server'], {
|
|
282
|
-
NODE_ENV: 'development',
|
|
283
|
-
MIAODA_NEST_CLI_INSTRUMENTATION: 'true',
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
function prepareSwcRuntimeConfig() {
|
|
288
|
-
const sourceConfigPath = path.join(projectRoot, 'nest-cli.json');
|
|
289
|
-
const runtimeConfigPath = path.join(
|
|
290
|
-
projectRoot,
|
|
291
|
-
swcRuntimeConfigRelativePath
|
|
292
|
-
);
|
|
293
|
-
const configuration = JSON.parse(fs.readFileSync(sourceConfigPath, 'utf8'));
|
|
294
|
-
const compilerOptions = configuration.compilerOptions || {};
|
|
295
|
-
const configuredBuilder = compilerOptions.builder;
|
|
296
|
-
const configuredSwcOptions =
|
|
297
|
-
configuredBuilder &&
|
|
298
|
-
typeof configuredBuilder === 'object' &&
|
|
299
|
-
configuredBuilder.type === 'swc'
|
|
300
|
-
? configuredBuilder.options || {}
|
|
301
|
-
: {};
|
|
302
|
-
configuration.compilerOptions = {
|
|
303
|
-
...compilerOptions,
|
|
304
|
-
builder: {
|
|
305
|
-
type: 'swc',
|
|
306
|
-
options: {
|
|
307
|
-
...configuredSwcOptions,
|
|
308
|
-
extensions: ['.ts'],
|
|
309
|
-
},
|
|
310
|
-
},
|
|
311
|
-
};
|
|
312
|
-
fs.mkdirSync(path.dirname(runtimeConfigPath), { recursive: true });
|
|
313
|
-
const temporaryPath = `${runtimeConfigPath}.${process.pid}.tmp`;
|
|
314
|
-
fs.writeFileSync(
|
|
315
|
-
temporaryPath,
|
|
316
|
-
`${JSON.stringify(configuration, null, 2)}\n`
|
|
317
|
-
);
|
|
318
|
-
fs.renameSync(temporaryPath, runtimeConfigPath);
|
|
319
|
-
return swcRuntimeConfigRelativePath;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
function spawnSwcService() {
|
|
323
|
-
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
324
|
-
const runtimeConfig = prepareSwcRuntimeConfig();
|
|
325
|
-
return spawnInherited(
|
|
326
|
-
npmCommand,
|
|
327
|
-
['run', 'dev:server', '--', '--config', runtimeConfig],
|
|
328
|
-
{
|
|
329
|
-
NODE_ENV: 'development',
|
|
330
|
-
MIAODA_NEST_CLI_INSTRUMENTATION: 'true',
|
|
331
|
-
}
|
|
332
|
-
);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
async function waitForServiceLifetime() {
|
|
336
|
-
if (!serviceChild) return { code: 1, signal: null };
|
|
337
|
-
return new Promise((resolve, reject) => {
|
|
338
|
-
serviceChild.once('error', reject);
|
|
339
|
-
serviceChild.once('exit', (code, signal) => resolve({ code, signal }));
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
async function runDependencyBackedMode(mode) {
|
|
344
|
-
await waitForDependencies();
|
|
345
|
-
await initializeActionPlugins();
|
|
346
|
-
if (mode === 'workspace') {
|
|
347
|
-
const spawnStartedAt = process.hrtime.bigint();
|
|
348
|
-
serviceChild = spawnWorkspaceService();
|
|
349
|
-
emit('process_spawn', spawnStartedAt, { pid: serviceChild.pid });
|
|
350
|
-
} else if (mode === 'swc') {
|
|
351
|
-
const spawnStartedAt = process.hrtime.bigint();
|
|
352
|
-
serviceChild = spawnSwcService();
|
|
353
|
-
emit('process_spawn', spawnStartedAt, {
|
|
354
|
-
pid: serviceChild.pid,
|
|
355
|
-
builder: 'swc',
|
|
356
|
-
config: swcRuntimeConfigRelativePath,
|
|
357
|
-
sourceExtensions: ['.ts'],
|
|
358
|
-
});
|
|
359
|
-
} else {
|
|
360
|
-
throw new Error(`MIAODA_NEST_DEPENDENCY_MODE_INVALID: ${mode}`);
|
|
361
|
-
}
|
|
362
|
-
await waitForPort();
|
|
363
|
-
emit('startup', startedAt, { pid: serviceChild.pid, port: serverPort });
|
|
364
|
-
return waitForServiceLifetime();
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
async function runBundleHandoff() {
|
|
368
|
-
const dependenciesReadyAtEntry = workspaceDependenciesReady();
|
|
369
|
-
// Once dependencies exist, never put the stale bundle back in front during
|
|
370
|
-
// a supervisor retry. This preserves the original Preview failure/retry UI
|
|
371
|
-
// when the complete workspace service fails after the transition window.
|
|
372
|
-
if (dependenciesReadyAtEntry) {
|
|
373
|
-
emit('bundle_skipped', process.hrtime.bigint(), {
|
|
374
|
-
reason: 'workspace-dependencies-ready',
|
|
375
|
-
});
|
|
376
|
-
return runDependencyBackedMode('workspace');
|
|
377
|
-
}
|
|
378
|
-
const runtime = path.join(scriptsRoot, 'server-cache-runtime.mjs');
|
|
379
|
-
if (!fs.existsSync(runtime)) {
|
|
380
|
-
markBundleFallback('runtime-missing');
|
|
381
|
-
process.stderr.write(
|
|
382
|
-
`${JSON.stringify({
|
|
383
|
-
event: 'miaoda_nest_bundle_unavailable',
|
|
384
|
-
reason: 'runtime-missing',
|
|
385
|
-
})}\n`
|
|
386
|
-
);
|
|
387
|
-
return runDependencyBackedMode('workspace');
|
|
388
|
-
}
|
|
389
|
-
const spawnStartedAt = process.hrtime.bigint();
|
|
390
|
-
serviceChild = spawnInherited(process.execPath, [runtime], {
|
|
391
|
-
MIAODA_NEST_SKIP_ACTION_PLUGIN_INIT: 'true',
|
|
392
|
-
});
|
|
393
|
-
emit('process_spawn', spawnStartedAt, {
|
|
394
|
-
pid: serviceChild.pid,
|
|
395
|
-
childRuntime: 'server-cache-runtime',
|
|
396
|
-
});
|
|
397
|
-
const exitPromise = new Promise((resolve, reject) => {
|
|
398
|
-
serviceChild.once('error', reject);
|
|
399
|
-
serviceChild.once('exit', (code, signal) => resolve({ code, signal }));
|
|
400
|
-
});
|
|
401
|
-
try {
|
|
402
|
-
await Promise.race([
|
|
403
|
-
waitForPort(),
|
|
404
|
-
exitPromise.then(exit => {
|
|
405
|
-
throw new Error(
|
|
406
|
-
`MIAODA_NEST_BUNDLE_EXITED_BEFORE_READY: code=${exit.code} signal=${exit.signal}`
|
|
407
|
-
);
|
|
408
|
-
}),
|
|
409
|
-
]);
|
|
410
|
-
emit('startup', startedAt, { pid: serviceChild.pid, port: serverPort });
|
|
411
|
-
return exitPromise;
|
|
412
|
-
} catch (error) {
|
|
413
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
414
|
-
markBundleFallback(reason);
|
|
415
|
-
process.stderr.write(
|
|
416
|
-
`${JSON.stringify({
|
|
417
|
-
event: 'miaoda_nest_bundle_fallback',
|
|
418
|
-
reason,
|
|
419
|
-
})}\n`
|
|
420
|
-
);
|
|
421
|
-
terminate(serviceChild);
|
|
422
|
-
return runDependencyBackedMode('workspace');
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
async function close(signal) {
|
|
427
|
-
if (stopping) return;
|
|
428
|
-
stopping = true;
|
|
429
|
-
terminate(compilerChild, signal);
|
|
430
|
-
terminate(serviceChild, signal);
|
|
431
|
-
setTimeout(() => {
|
|
432
|
-
terminate(compilerChild, 'SIGKILL');
|
|
433
|
-
terminate(serviceChild, 'SIGKILL');
|
|
434
|
-
}, 1_000).unref();
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
|
438
|
-
process.once(signal, () => void close(signal));
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
const exit =
|
|
442
|
-
requestedMode === 'bundle-handoff'
|
|
443
|
-
? await runBundleHandoff()
|
|
444
|
-
: await runDependencyBackedMode(requestedMode);
|
|
445
|
-
process.exit(exit?.code ?? (stopping ? 0 : 1));
|