@danypops/papyrus 0.45.0 → 0.45.1
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/src/client.ts +26 -5
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { spawn as spawnProcess } from "node:child_process";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
connectWithVersionCheck,
|
|
5
|
+
type ExpectedVersion,
|
|
6
|
+
type SpawnPlatformOptions,
|
|
7
|
+
spawnDetachedDaemon,
|
|
8
|
+
} from "@danypops/vehicle-client/daemon-client";
|
|
4
9
|
import { createLiveVersionExpectation } from "@danypops/vehicle-client/version";
|
|
5
10
|
import { DAEMON_CLIENT_TIMEOUT_MS, DAEMON_DIR_ENV, DAEMON_PROBE_TIMEOUT_MS } from "./constants.ts";
|
|
6
11
|
import { type DaemonHandle, daemonStateDir, readDaemonHandle } from "./daemon/daemon-state.ts";
|
|
@@ -74,6 +79,25 @@ function papyrusCliPath(): string {
|
|
|
74
79
|
return fileURLToPath(new URL("cli.ts", import.meta.url));
|
|
75
80
|
}
|
|
76
81
|
|
|
82
|
+
/**
|
|
83
|
+
* spawnDetachedDaemon's injected spawn() callback, factored out for a direct unit test.
|
|
84
|
+
*
|
|
85
|
+
* A spawn() failure (missing binPath, no exec permission, wrong interpreter) surfaces
|
|
86
|
+
* asynchronously as an "error" event on the ChildProcess -- with no listener, Node treats it
|
|
87
|
+
* as an uncaught exception and kills the whole host process, not just this one connect
|
|
88
|
+
* attempt (a real incident: auto-spawning against a since-deleted binPath crashed Pi itself).
|
|
89
|
+
* The listener below turns that into an ordinary logged failure instead: the handle file
|
|
90
|
+
* simply never appears, and connectWithPolicy's own poll-then-timeout already reports that
|
|
91
|
+
* as its usual, catchable fallbackMessage error.
|
|
92
|
+
*/
|
|
93
|
+
export function spawnPapyrusDaemonProcess(command: string, args: string[], spawnOptions: SpawnPlatformOptions): void {
|
|
94
|
+
const child = spawnProcess(command, args, spawnOptions);
|
|
95
|
+
child.on("error", (error) => {
|
|
96
|
+
console.error(`Papyrus daemon auto-spawn failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
97
|
+
});
|
|
98
|
+
child.unref();
|
|
99
|
+
}
|
|
100
|
+
|
|
77
101
|
/** connectWithVersionCheck's killStaleProcess callback, factored out for a direct unit test -- a real spawned daemon can't be made to report a mismatched version without a second build. */
|
|
78
102
|
export function killStalePapyrusDaemon(handle: Pick<DaemonHandle, "pid">): void {
|
|
79
103
|
if (handle.pid <= 0) return; // daemon-state.ts's inert "unknown pid" sentinel -- never a real process.
|
|
@@ -123,10 +147,7 @@ export async function connectPapyrusClient(
|
|
|
123
147
|
binPath: papyrusCliPath(),
|
|
124
148
|
args: ["serve"],
|
|
125
149
|
env: { ...(options.env ?? process.env), [DAEMON_DIR_ENV]: dir },
|
|
126
|
-
spawn:
|
|
127
|
-
const child = spawnProcess(command, args, spawnOptions);
|
|
128
|
-
child.unref();
|
|
129
|
-
},
|
|
150
|
+
spawn: spawnPapyrusDaemonProcess,
|
|
130
151
|
});
|
|
131
152
|
},
|
|
132
153
|
fallbackMessage: "Papyrus daemon failed to start automatically; run `papyrus service install` or `papyrus serve` manually.",
|