@wonderwhy-er/desktop-commander
Version:
MCP server for terminal operations and file editing
45 lines (44 loc) • 1.87 kB
JavaScript
import { logger } from './logger.js';
/**
* A package only some files need, declared next to the code that uses it,
* whose load() loads it on first use (#715). Loading them before initialize
* took 25-90 s on one reporter's machine and timed the client out, and loading
* one inside the tool call that first needs it can take longer than a client
* waits. So the server preloads them right after initialize, one at a time
* (preloadFileSupport() in utils/files/factory.ts), and until one is loaded the
* calls that need it answer at once that it is still loading. preload() loads
* it on a later turn of the event loop, so a call that starts it answers
* first. `error` says why the last preload failed. Callers that load with
* import() can mark failures as requiring a restart, because Node caches a
* failed dynamic import.
*/
export class LazyPackage {
constructor(name, support, load, restartAfterFailure = false) {
this.name = name;
this.support = support;
this.load = load;
this.restartAfterFailure = restartAfterFailure;
this.loaded = false;
this.needsRestart = false;
}
preload() {
this.running ?? (this.running = new Promise((resolve) => setImmediate(resolve)).then(async () => {
let loading;
try {
loading = this.load();
await loading;
this.loaded = true;
this.error = undefined;
}
catch (error) {
this.error = error instanceof Error ? error.message : String(error);
this.needsRestart = this.restartAfterFailure;
logger.error(`Loading ${this.name} failed: ${this.error}`);
}
finally {
this.running = undefined;
}
}));
return this.running;
}
}