@lunora/cli 1.0.0-alpha.70 → 1.0.0-alpha.71
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/index.d.mts
CHANGED
|
@@ -452,15 +452,33 @@ interface StudioServerHandle {
|
|
|
452
452
|
url: string;
|
|
453
453
|
}
|
|
454
454
|
/**
|
|
455
|
-
* How the dev child runs. `wrangler` is the classic `lunora dev` stack
|
|
456
|
-
*
|
|
457
|
-
* `@lunora/vite`: the
|
|
458
|
-
* inside the Vite dev server, so `lunora dev` runs the
|
|
459
|
-
* script and gets out of the way —
|
|
460
|
-
*
|
|
455
|
+
* How the dev child runs. `wrangler` is the classic `lunora dev` stack (wrangler
|
|
456
|
+
* worker + embedded studio + codegen watch) for a standalone class-C project.
|
|
457
|
+
* `vite` is a project on `@lunora/vite`: the plugin already runs the worker,
|
|
458
|
+
* studio, and codegen inside the Vite dev server, so `lunora dev` runs the
|
|
459
|
+
* project's own dev script and gets out of the way — this also covers class-B
|
|
460
|
+
* frameworks whose own dev server runs the worker in `workerd` (Astro 6 +
|
|
461
|
+
* `@astrojs/cloudflare`, which embeds `@cloudflare/vite-plugin` in `astro dev`:
|
|
462
|
+
* SSR + `/_lunora/*` + `ShardDO` in one process, HMR intact). `framework-worker`
|
|
463
|
+
* is a class-B framework whose dev server CANNOT host the `ShardDO` Durable
|
|
464
|
+
* Object (SvelteKit / Nuxt: their adapters use wrangler's `getPlatformProxy()`,
|
|
465
|
+
* which runs an empty-script Miniflare and does not emulate internal DOs); there
|
|
466
|
+
* `lunora dev` runs the framework's own dev server (front door, HMR, and — via
|
|
467
|
+
* its `@lunora/vite` plugin — studio + codegen) AND a second `wrangler dev`
|
|
468
|
+
* sidecar that owns the real `ShardDO` in `workerd`, wired via the committed
|
|
469
|
+
* `wrangler.dev.jsonc`.
|
|
470
|
+
*/
|
|
471
|
+
type DevFlavor = "framework-worker" | "vite" | "wrangler";
|
|
472
|
+
/**
|
|
473
|
+
* Detect the dev flavor.
|
|
474
|
+
*
|
|
475
|
+
* A SvelteKit / Nuxt project needs the two-process `framework-worker` stack even
|
|
476
|
+
* though it also declares `@lunora/vite` (which its framework dev server uses for
|
|
477
|
+
* codegen/studio) — so the framework check comes FIRST. Everything else on
|
|
478
|
+
* `@lunora/vite` (class-A frameworks + Astro + standalone Vite) delegates to the
|
|
479
|
+
* project's own dev server (`vite`); a project without `@lunora/vite` is the
|
|
480
|
+
* classic standalone `wrangler` stack.
|
|
461
481
|
*/
|
|
462
|
-
type DevFlavor = "vite" | "wrangler";
|
|
463
|
-
/** Detect the dev flavor: a declared `@lunora/vite` dependency means Vite owns the dev server. */
|
|
464
482
|
/** A running worker child the orchestrator controls: send signals, await its exit. */
|
|
465
483
|
interface WorkerProcess {
|
|
466
484
|
/** Resolves with the worker's exit code (1 if it failed to start). */
|
|
@@ -543,11 +561,22 @@ interface DevCommandPlan {
|
|
|
543
561
|
ipv4LoopbackForced: boolean;
|
|
544
562
|
/** The remote-binding decision: which D1/KV/R2 bindings hit the deployed worker. */
|
|
545
563
|
remote: DevRemotePlan;
|
|
564
|
+
/**
|
|
565
|
+
* The `wrangler dev` sidecar for the `framework-worker` flavor (SvelteKit /
|
|
566
|
+
* Nuxt): a second child that owns the real `ShardDO` in `workerd`, wired via
|
|
567
|
+
* the committed `wrangler.dev.jsonc`. `undefined` for every other flavor —
|
|
568
|
+
* only the two-process class-B stack has a sidecar. When present, `wrangler`
|
|
569
|
+
* (above) is the framework's own dev server (the front door / HMR) and this
|
|
570
|
+
* is the Lunora realtime plane.
|
|
571
|
+
*/
|
|
572
|
+
sidecar?: SpawnDescriptor & {
|
|
573
|
+
tag: string;
|
|
574
|
+
};
|
|
546
575
|
studioEnabled: boolean;
|
|
547
576
|
studioPort: number;
|
|
548
577
|
workerOrigin: string;
|
|
549
578
|
workerPort: number;
|
|
550
|
-
/** The
|
|
579
|
+
/** The primary child `lunora dev` spawns: `wrangler dev` (wrangler flavor) or the framework/`vite dev` server (vite / framework-worker). */
|
|
551
580
|
wrangler: SpawnDescriptor & {
|
|
552
581
|
tag: string;
|
|
553
582
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -452,15 +452,33 @@ interface StudioServerHandle {
|
|
|
452
452
|
url: string;
|
|
453
453
|
}
|
|
454
454
|
/**
|
|
455
|
-
* How the dev child runs. `wrangler` is the classic `lunora dev` stack
|
|
456
|
-
*
|
|
457
|
-
* `@lunora/vite`: the
|
|
458
|
-
* inside the Vite dev server, so `lunora dev` runs the
|
|
459
|
-
* script and gets out of the way —
|
|
460
|
-
*
|
|
455
|
+
* How the dev child runs. `wrangler` is the classic `lunora dev` stack (wrangler
|
|
456
|
+
* worker + embedded studio + codegen watch) for a standalone class-C project.
|
|
457
|
+
* `vite` is a project on `@lunora/vite`: the plugin already runs the worker,
|
|
458
|
+
* studio, and codegen inside the Vite dev server, so `lunora dev` runs the
|
|
459
|
+
* project's own dev script and gets out of the way — this also covers class-B
|
|
460
|
+
* frameworks whose own dev server runs the worker in `workerd` (Astro 6 +
|
|
461
|
+
* `@astrojs/cloudflare`, which embeds `@cloudflare/vite-plugin` in `astro dev`:
|
|
462
|
+
* SSR + `/_lunora/*` + `ShardDO` in one process, HMR intact). `framework-worker`
|
|
463
|
+
* is a class-B framework whose dev server CANNOT host the `ShardDO` Durable
|
|
464
|
+
* Object (SvelteKit / Nuxt: their adapters use wrangler's `getPlatformProxy()`,
|
|
465
|
+
* which runs an empty-script Miniflare and does not emulate internal DOs); there
|
|
466
|
+
* `lunora dev` runs the framework's own dev server (front door, HMR, and — via
|
|
467
|
+
* its `@lunora/vite` plugin — studio + codegen) AND a second `wrangler dev`
|
|
468
|
+
* sidecar that owns the real `ShardDO` in `workerd`, wired via the committed
|
|
469
|
+
* `wrangler.dev.jsonc`.
|
|
470
|
+
*/
|
|
471
|
+
type DevFlavor = "framework-worker" | "vite" | "wrangler";
|
|
472
|
+
/**
|
|
473
|
+
* Detect the dev flavor.
|
|
474
|
+
*
|
|
475
|
+
* A SvelteKit / Nuxt project needs the two-process `framework-worker` stack even
|
|
476
|
+
* though it also declares `@lunora/vite` (which its framework dev server uses for
|
|
477
|
+
* codegen/studio) — so the framework check comes FIRST. Everything else on
|
|
478
|
+
* `@lunora/vite` (class-A frameworks + Astro + standalone Vite) delegates to the
|
|
479
|
+
* project's own dev server (`vite`); a project without `@lunora/vite` is the
|
|
480
|
+
* classic standalone `wrangler` stack.
|
|
461
481
|
*/
|
|
462
|
-
type DevFlavor = "vite" | "wrangler";
|
|
463
|
-
/** Detect the dev flavor: a declared `@lunora/vite` dependency means Vite owns the dev server. */
|
|
464
482
|
/** A running worker child the orchestrator controls: send signals, await its exit. */
|
|
465
483
|
interface WorkerProcess {
|
|
466
484
|
/** Resolves with the worker's exit code (1 if it failed to start). */
|
|
@@ -543,11 +561,22 @@ interface DevCommandPlan {
|
|
|
543
561
|
ipv4LoopbackForced: boolean;
|
|
544
562
|
/** The remote-binding decision: which D1/KV/R2 bindings hit the deployed worker. */
|
|
545
563
|
remote: DevRemotePlan;
|
|
564
|
+
/**
|
|
565
|
+
* The `wrangler dev` sidecar for the `framework-worker` flavor (SvelteKit /
|
|
566
|
+
* Nuxt): a second child that owns the real `ShardDO` in `workerd`, wired via
|
|
567
|
+
* the committed `wrangler.dev.jsonc`. `undefined` for every other flavor —
|
|
568
|
+
* only the two-process class-B stack has a sidecar. When present, `wrangler`
|
|
569
|
+
* (above) is the framework's own dev server (the front door / HMR) and this
|
|
570
|
+
* is the Lunora realtime plane.
|
|
571
|
+
*/
|
|
572
|
+
sidecar?: SpawnDescriptor & {
|
|
573
|
+
tag: string;
|
|
574
|
+
};
|
|
546
575
|
studioEnabled: boolean;
|
|
547
576
|
studioPort: number;
|
|
548
577
|
workerOrigin: string;
|
|
549
578
|
workerPort: number;
|
|
550
|
-
/** The
|
|
579
|
+
/** The primary child `lunora dev` spawns: `wrangler dev` (wrangler flavor) or the framework/`vite dev` server (vite / framework-worker). */
|
|
551
580
|
wrangler: SpawnDescriptor & {
|
|
552
581
|
tag: string;
|
|
553
582
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { spawnSync, spawn } from 'node:child_process';
|
|
2
|
-
import {
|
|
2
|
+
import { runCodegen } from '@lunora/codegen';
|
|
3
|
+
import { detectAgentRules, claimDevServerState, clearDevServerState, readDevServerState, readLiveDevServerState, detectFramework, readProjectDependencyNames, DEV_HANDOFF_ENV, isRecordedProcessCurrent, DEV_LOG_FILE, DEV_LOG_FILE_ENV, DEV_DAEMON_ENV, updateDevServerState, detectAiAgent, resolveRemoteEnabled, readProjectRemotePreference, inferLunoraBindings, packageNamesFromBindings, ensureDevVarsExample, ensureDevVariables, isInteractive, DEV_VARS_FILE, DEV_VARS_EXAMPLE_FILE, fillDevSecrets, claimAgentRulesHint, AGENT_RULES_HINT, findWranglerFile, readWranglerJsonc, discoverContainerInfo, streamContainerLogs, materializeRemoteWranglerConfig, formatLunoraEvent } from '@lunora/config';
|
|
3
4
|
import { p as parseApiSpec } from '../packem_shared/api-spec-Bx0iKbxA.mjs';
|
|
4
5
|
import { existsSync, watch, readFileSync, statSync, openSync, readSync, closeSync, mkdirSync } from 'node:fs';
|
|
5
6
|
import { join, dirname } from 'node:path';
|
|
6
|
-
import { runCodegen } from '@lunora/codegen';
|
|
7
7
|
import { r as renderCodegenFailure } from '../packem_shared/codegen-error-DJG-ghs_.mjs';
|
|
8
8
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
9
9
|
import { d as detectPackageManager, e as execArgsFor, r as runScriptCommand } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
@@ -307,7 +307,13 @@ const DEFAULT_LOG_LINES = 100;
|
|
|
307
307
|
const FAILURE_LOG_TAIL_LINES = 40;
|
|
308
308
|
const LOG_TAIL_MAX_BYTES = 256 * 1024;
|
|
309
309
|
const READY_TIMEOUT_ENV = "LUNORA_DEV_READY_TIMEOUT_MS";
|
|
310
|
-
const
|
|
310
|
+
const SIDECAR_FRAMEWORKS = /* @__PURE__ */ new Set(["nuxt", "sveltekit"]);
|
|
311
|
+
const detectDevFlavor = (cwd) => {
|
|
312
|
+
if (SIDECAR_FRAMEWORKS.has(detectFramework(cwd).framework)) {
|
|
313
|
+
return "framework-worker";
|
|
314
|
+
}
|
|
315
|
+
return readProjectDependencyNames(cwd).has("@lunora/vite") ? "vite" : "wrangler";
|
|
316
|
+
};
|
|
311
317
|
const viteDevCommand = (cwd) => {
|
|
312
318
|
const manager = detectPackageManager(cwd);
|
|
313
319
|
let script;
|
|
@@ -505,7 +511,7 @@ const startBackground = async (context) => {
|
|
|
505
511
|
const { cwd, jsonLogs, logger, options, remote } = context;
|
|
506
512
|
const run = context.run ?? runDevBackground;
|
|
507
513
|
const flavor = detectDevFlavor(cwd);
|
|
508
|
-
const url = flavor === "
|
|
514
|
+
const url = flavor === "wrangler" ? `http://localhost:${String(options.workerPort ?? 8787)}` : "http://localhost:5173";
|
|
509
515
|
const claim = claimDevServerState(cwd, {
|
|
510
516
|
background: true,
|
|
511
517
|
mode: "cli",
|
|
@@ -700,6 +706,7 @@ const runLifecycleSubcommand = (parameters) => {
|
|
|
700
706
|
return void 0;
|
|
701
707
|
};
|
|
702
708
|
|
|
709
|
+
const DEV_WRANGLER_CONFIG = "wrangler.dev.jsonc";
|
|
703
710
|
const DEFAULT_STUDIO_PORT = 6173;
|
|
704
711
|
const DEFAULT_WORKER_PORT = 8787;
|
|
705
712
|
const DEFAULT_VITE_PORT = 5173;
|
|
@@ -746,14 +753,21 @@ const planDevCommand = (options) => {
|
|
|
746
753
|
const cwd = options.cwd ?? process.cwd();
|
|
747
754
|
const manager = detectPackageManager(cwd);
|
|
748
755
|
const flavor = options.flavor ?? detectDevFlavor(cwd);
|
|
749
|
-
if (flavor === "vite") {
|
|
756
|
+
if (flavor === "vite" || flavor === "framework-worker") {
|
|
750
757
|
const exec2 = viteDevCommand(cwd);
|
|
758
|
+
let sidecar;
|
|
759
|
+
if (flavor === "framework-worker") {
|
|
760
|
+
const loopbackArgs2 = resolveLoopbackArgs(cwd, options.hasIpv6Loopback ?? hasIpv6Loopback);
|
|
761
|
+
const sidecarExec = execArgsFor(manager, "wrangler", ["dev", "--config", DEV_WRANGLER_CONFIG, ...loopbackArgs2, "--var", "WORKER_ENV:development"]);
|
|
762
|
+
sidecar = { args: sidecarExec.args, command: sidecarExec.command, cwd, tag: "worker" };
|
|
763
|
+
}
|
|
751
764
|
return {
|
|
752
765
|
codegenEnabled: false,
|
|
753
766
|
flavor,
|
|
754
767
|
ipv4LoopbackForced: false,
|
|
755
768
|
remote: { bindings: [], cleanup: () => {
|
|
756
769
|
}, enabled: options.remote === true },
|
|
770
|
+
...sidecar ? { sidecar } : {},
|
|
757
771
|
studioEnabled: false,
|
|
758
772
|
studioPort: options.port ?? DEFAULT_STUDIO_PORT,
|
|
759
773
|
workerOrigin: `http://localhost:${String(DEFAULT_VITE_PORT)}`,
|
|
@@ -981,14 +995,99 @@ const buildDevPlan = async (options) => {
|
|
|
981
995
|
const workerPort = flavor === "wrangler" ? await resolveWorkerPort(options, cwd) : options.workerPort;
|
|
982
996
|
return planDevCommand({ ...options, cwd, flavor, workerPort });
|
|
983
997
|
};
|
|
998
|
+
const superviseWorkers = async (worker, sidecar, logger) => {
|
|
999
|
+
let sigintCount = 0;
|
|
1000
|
+
let escalationTimer;
|
|
1001
|
+
const killChildren = (signal) => {
|
|
1002
|
+
worker.kill(signal);
|
|
1003
|
+
sidecar?.kill(signal);
|
|
1004
|
+
};
|
|
1005
|
+
const onSigint = () => {
|
|
1006
|
+
sigintCount += 1;
|
|
1007
|
+
if (sigintCount === 1) {
|
|
1008
|
+
logger.info("received SIGINT — shutting down (press Ctrl-C again to force-kill)");
|
|
1009
|
+
killChildren("SIGTERM");
|
|
1010
|
+
escalationTimer = setTimeout(() => {
|
|
1011
|
+
killChildren("SIGKILL");
|
|
1012
|
+
}, SIGINT_GRACE_MS);
|
|
1013
|
+
escalationTimer.unref();
|
|
1014
|
+
} else {
|
|
1015
|
+
killChildren("SIGKILL");
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
const onSigterm = () => {
|
|
1019
|
+
killChildren("SIGTERM");
|
|
1020
|
+
};
|
|
1021
|
+
process.on("SIGINT", onSigint);
|
|
1022
|
+
process.on("SIGTERM", onSigterm);
|
|
1023
|
+
const exits = [
|
|
1024
|
+
worker.exited.then((code) => {
|
|
1025
|
+
return { code, who: "worker" };
|
|
1026
|
+
})
|
|
1027
|
+
];
|
|
1028
|
+
if (sidecar !== void 0) {
|
|
1029
|
+
exits.push(
|
|
1030
|
+
sidecar.exited.then((code) => {
|
|
1031
|
+
return { code, who: "sidecar" };
|
|
1032
|
+
})
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
const first = await Promise.race(exits);
|
|
1036
|
+
if (sidecar !== void 0) {
|
|
1037
|
+
if (first.who === "sidecar") {
|
|
1038
|
+
logger.warn("[worker] the Lunora sidecar (wrangler dev) exited — shutting down the framework dev server");
|
|
1039
|
+
worker.kill("SIGTERM");
|
|
1040
|
+
} else {
|
|
1041
|
+
sidecar.kill("SIGTERM");
|
|
1042
|
+
}
|
|
1043
|
+
await Promise.allSettled([worker.exited, sidecar.exited]);
|
|
1044
|
+
}
|
|
1045
|
+
if (escalationTimer) {
|
|
1046
|
+
clearTimeout(escalationTimer);
|
|
1047
|
+
}
|
|
1048
|
+
process.off("SIGINT", onSigint);
|
|
1049
|
+
process.off("SIGTERM", onSigterm);
|
|
1050
|
+
return first.code;
|
|
1051
|
+
};
|
|
1052
|
+
const startStudioBestEffort = async (options, plan, cwd, logger) => {
|
|
1053
|
+
if (!plan.studioEnabled) {
|
|
1054
|
+
return void 0;
|
|
1055
|
+
}
|
|
1056
|
+
try {
|
|
1057
|
+
return await (options.startStudio ?? startStudioServer)({
|
|
1058
|
+
cwd,
|
|
1059
|
+
logger: {
|
|
1060
|
+
warnOnce: (message) => {
|
|
1061
|
+
logger.warn(message);
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
port: plan.studioPort,
|
|
1065
|
+
workerOrigin: plan.workerOrigin
|
|
1066
|
+
});
|
|
1067
|
+
} catch (error) {
|
|
1068
|
+
logger.warn(`studio server failed to start (${error instanceof Error ? error.message : String(error)}) — continuing without it`);
|
|
1069
|
+
return void 0;
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
const ensureSidecarGenerated = (plan, options, cwd, logger) => {
|
|
1073
|
+
if (plan.sidecar === void 0) {
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
try {
|
|
1077
|
+
runCodegen({ apiSpec: options.apiSpec, lunoraDirectory: "lunora", projectRoot: cwd });
|
|
1078
|
+
} catch (error) {
|
|
1079
|
+
logger.warn(`codegen (pre-sidecar) failed: ${error instanceof Error ? error.message : String(error)} — the framework dev server will retry`);
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
984
1082
|
const runDevCommand = async (options) => {
|
|
985
1083
|
const plan = await buildDevPlan(options);
|
|
986
1084
|
const { logger } = options;
|
|
987
1085
|
const cwd = plan.wrangler.cwd ?? process.cwd();
|
|
988
1086
|
const handles = { remoteCleanup: plan.remote.cleanup };
|
|
989
1087
|
try {
|
|
1088
|
+
const handoffPid = Number(process.env[DEV_HANDOFF_ENV]);
|
|
990
1089
|
const existing = readLiveDevServerState(cwd);
|
|
991
|
-
if (existing !== void 0 && existing.pid !== process.pid) {
|
|
1090
|
+
if (existing !== void 0 && existing.pid !== process.pid && existing.pid !== handoffPid) {
|
|
992
1091
|
reportExistingServer(logger, existing);
|
|
993
1092
|
return { code: 0, plan };
|
|
994
1093
|
}
|
|
@@ -997,7 +1096,7 @@ const runDevCommand = async (options) => {
|
|
|
997
1096
|
reportExistingServer(logger, incumbent);
|
|
998
1097
|
return { code: 0, plan };
|
|
999
1098
|
}
|
|
1000
|
-
if (plan.flavor === "vite") {
|
|
1099
|
+
if (plan.flavor === "vite" || plan.flavor === "framework-worker") {
|
|
1001
1100
|
plan.wrangler.env = { ...plan.wrangler.env, [DEV_HANDOFF_ENV]: String(process.pid) };
|
|
1002
1101
|
}
|
|
1003
1102
|
await offerDevVariablesScaffold(options, cwd);
|
|
@@ -1012,56 +1111,18 @@ const runDevCommand = async (options) => {
|
|
|
1012
1111
|
if (plan.codegenEnabled) {
|
|
1013
1112
|
handles.codegen = (options.startCodegen ?? startCodegenWatch)({ apiSpec: options.apiSpec, logger, projectRoot: cwd });
|
|
1014
1113
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
try {
|
|
1018
|
-
handles.studio = await (options.startStudio ?? startStudioServer)({
|
|
1019
|
-
cwd,
|
|
1020
|
-
logger: {
|
|
1021
|
-
warnOnce: (message) => {
|
|
1022
|
-
logger.warn(message);
|
|
1023
|
-
}
|
|
1024
|
-
},
|
|
1025
|
-
port: plan.studioPort,
|
|
1026
|
-
workerOrigin: plan.workerOrigin
|
|
1027
|
-
});
|
|
1028
|
-
studioUrl = handles.studio.url;
|
|
1029
|
-
} catch (error) {
|
|
1030
|
-
logger.warn(`studio server failed to start (${error instanceof Error ? error.message : String(error)}) — continuing without it`);
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1114
|
+
handles.studio = await startStudioBestEffort(options, plan, cwd, logger);
|
|
1115
|
+
const studioUrl = handles.studio?.url;
|
|
1033
1116
|
if (plan.frameworkHint !== void 0) {
|
|
1034
1117
|
logger.warn(plan.frameworkHint);
|
|
1035
1118
|
}
|
|
1036
|
-
|
|
1119
|
+
ensureSidecarGenerated(plan, options, cwd, logger);
|
|
1120
|
+
const spawn = options.startWorker ?? defaultWorkerSpawner;
|
|
1121
|
+
const worker = spawn(plan.wrangler, logger);
|
|
1122
|
+
const sidecar = plan.sidecar === void 0 ? void 0 : spawn(plan.sidecar, logger);
|
|
1037
1123
|
handles.containerLogs = afterWorkerSpawn(plan, cwd, logger, studioUrl);
|
|
1038
1124
|
printAgentRulesHint(logger, cwd);
|
|
1039
|
-
|
|
1040
|
-
let escalationTimer;
|
|
1041
|
-
const onSigint = () => {
|
|
1042
|
-
sigintCount += 1;
|
|
1043
|
-
if (sigintCount === 1) {
|
|
1044
|
-
logger.info("received SIGINT — shutting down (press Ctrl-C again to force-kill)");
|
|
1045
|
-
worker.kill("SIGTERM");
|
|
1046
|
-
escalationTimer = setTimeout(() => {
|
|
1047
|
-
worker.kill("SIGKILL");
|
|
1048
|
-
}, SIGINT_GRACE_MS);
|
|
1049
|
-
escalationTimer.unref();
|
|
1050
|
-
} else {
|
|
1051
|
-
worker.kill("SIGKILL");
|
|
1052
|
-
}
|
|
1053
|
-
};
|
|
1054
|
-
const onSigterm = () => {
|
|
1055
|
-
worker.kill("SIGTERM");
|
|
1056
|
-
};
|
|
1057
|
-
process.on("SIGINT", onSigint);
|
|
1058
|
-
process.on("SIGTERM", onSigterm);
|
|
1059
|
-
const code = await worker.exited;
|
|
1060
|
-
if (escalationTimer) {
|
|
1061
|
-
clearTimeout(escalationTimer);
|
|
1062
|
-
}
|
|
1063
|
-
process.off("SIGINT", onSigint);
|
|
1064
|
-
process.off("SIGTERM", onSigterm);
|
|
1125
|
+
const code = await superviseWorkers(worker, sidecar, logger);
|
|
1065
1126
|
return { code, plan };
|
|
1066
1127
|
} finally {
|
|
1067
1128
|
clearDevServerState(cwd, process.pid);
|
|
@@ -1825,13 +1825,16 @@ const PNPM_BUILT_DEPENDENCIES = [
|
|
|
1825
1825
|
"unrs-resolver",
|
|
1826
1826
|
"workerd"
|
|
1827
1827
|
];
|
|
1828
|
+
const PNPM_DENIED_BUILD_DEPENDENCIES = ["cpu-features", "protobufjs", "ssh2"];
|
|
1828
1829
|
const PNPM_WORKSPACE_FILENAME = "pnpm-workspace.yaml";
|
|
1829
1830
|
const pnpmWorkspaceYaml = () => [
|
|
1830
1831
|
"# pnpm reads its settings from here (the package.json `pnpm` field is no longer read).",
|
|
1831
1832
|
"# Pre-approve the toolchain's native build scripts so `pnpm install` runs them",
|
|
1832
|
-
"# without the interactive `pnpm approve-builds` step
|
|
1833
|
+
"# without the interactive `pnpm approve-builds` step; deny the optional native",
|
|
1834
|
+
"# builds a scaffold doesn't need (so no C/C++ toolchain is required).",
|
|
1833
1835
|
"allowBuilds:",
|
|
1834
1836
|
...PNPM_BUILT_DEPENDENCIES.map((name) => ` ${name}: true`),
|
|
1837
|
+
...PNPM_DENIED_BUILD_DEPENDENCIES.map((name) => ` ${name}: false`),
|
|
1835
1838
|
""
|
|
1836
1839
|
].join("\n");
|
|
1837
1840
|
const collectFiles = (directory) => {
|