refactor(root): extract isOnPath and add extension-side server qualification
Extract isOnPath() to shared src/util.ts so both the daemon (client.ts) and extension (root.ts) can use it. Add isServerAvailable() with a per-process cache to pickServer(), skipping servers whose binary isn't on PATH before sending requests to the daemon. This avoids wasted daemon round-trips for missing binaries and sets up for upcoming multi-server diagnostics fan-out.
This commit is contained in:
18
src/root.ts
18
src/root.ts
@@ -4,6 +4,7 @@ import { pathToFileURL, fileURLToPath } from "node:url";
|
||||
import { servers, globalRootMarkers } from "../server.ts";
|
||||
import type { ServerConfig } from "./types.ts";
|
||||
import { UnsupportedExtensionError } from "./types.ts";
|
||||
import { isOnPath } from "./util.ts";
|
||||
|
||||
// Resolve File URI To Local Path
|
||||
export function uriToPath(uri: string): string {
|
||||
@@ -15,11 +16,24 @@ export function pathToUri(p: string): string {
|
||||
return pathToFileURL(path.resolve(p)).toString();
|
||||
}
|
||||
|
||||
// Server Availability Cache - Checked once per process lifetime per server.
|
||||
// Avoids repeated filesystem lookups on every tool call.
|
||||
const serverAvailability = new Map<string, boolean>();
|
||||
|
||||
// Is Server Available - Returns true if the server binary is on PATH.
|
||||
// Result is cached for the lifetime of this process.
|
||||
export function isServerAvailable(server: ServerConfig): boolean {
|
||||
if (serverAvailability.has(server.id)) return serverAvailability.get(server.id)!;
|
||||
const available = isOnPath(server.command, process.env);
|
||||
serverAvailability.set(server.id, available);
|
||||
return available;
|
||||
}
|
||||
|
||||
// Pick Server By File Extension - match[] entries are matched against the
|
||||
// file's extension (no dot). First server in the registry wins.
|
||||
// file's extension (no dot). First available server in the registry wins.
|
||||
export function pickServer(filePath: string): ServerConfig {
|
||||
const ext = path.extname(filePath).replace(/^\./, "");
|
||||
const hit = servers.find((s) => s.match.includes(ext));
|
||||
const hit = servers.find((s) => s.match.includes(ext) && isServerAvailable(s));
|
||||
if (!hit) {
|
||||
throw new UnsupportedExtensionError(`.${ext}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user