refactor: deepen transport policy and output projection paths
This commit is contained in:
@@ -32,33 +32,48 @@ export class GSDTransport {
|
||||
) {}
|
||||
|
||||
async run(request: TransportRequest, policy: TransportPolicyLike): Promise<unknown> {
|
||||
const forceSubprocess = Boolean(request.workstream);
|
||||
|
||||
if (!forceSubprocess && policy.preferNative && this.registry.has(request.registryCommand)) {
|
||||
if (this.shouldUseNative(request, policy)) {
|
||||
try {
|
||||
const native = await this.adapters.dispatchNative(request);
|
||||
if (request.mode === 'raw') {
|
||||
if (this.adapters.formatNativeRaw) {
|
||||
return this.adapters.formatNativeRaw(request.registryCommand, native.data).trim();
|
||||
}
|
||||
return this.toRaw(native.data);
|
||||
}
|
||||
return native.data;
|
||||
return this.projectNativeOutput(request, native.data);
|
||||
} catch (error) {
|
||||
if (!policy.allowFallbackToSubprocess) throw error;
|
||||
// Do not subprocess-fallback after a timed-out native dispatch:
|
||||
// the timeout does not cancel the native handler, so falling through
|
||||
// would run the same command twice (double-execution race).
|
||||
if (toFailureSignal(error).kind === 'timeout') throw error;
|
||||
if (this.shouldRethrowNativeError(error, policy)) throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.dispatchSubprocess(request);
|
||||
}
|
||||
|
||||
private shouldUseNative(request: TransportRequest, policy: TransportPolicyLike): boolean {
|
||||
const forceSubprocess = Boolean(request.workstream);
|
||||
return !forceSubprocess && policy.preferNative && this.registry.has(request.registryCommand);
|
||||
}
|
||||
|
||||
private shouldRethrowNativeError(error: unknown, policy: TransportPolicyLike): boolean {
|
||||
if (!policy.allowFallbackToSubprocess) return true;
|
||||
// Do not subprocess-fallback after a timed-out native dispatch:
|
||||
// the timeout does not cancel the native handler, so falling through
|
||||
// would run the same command twice (double-execution race).
|
||||
return toFailureSignal(error).kind === 'timeout';
|
||||
}
|
||||
|
||||
private dispatchSubprocess(request: TransportRequest): Promise<unknown> {
|
||||
if (request.mode === 'raw') {
|
||||
return this.adapters.execSubprocessRaw(request.legacyCommand, request.legacyArgs);
|
||||
}
|
||||
return this.adapters.execSubprocessJson(request.legacyCommand, request.legacyArgs);
|
||||
}
|
||||
|
||||
private projectNativeOutput(request: TransportRequest, data: unknown): unknown {
|
||||
if (request.mode === 'raw') {
|
||||
if (this.adapters.formatNativeRaw) {
|
||||
return this.adapters.formatNativeRaw(request.registryCommand, data).trim();
|
||||
}
|
||||
return this.toRaw(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private toRaw(data: unknown): string {
|
||||
if (typeof data === 'string') return data.trim();
|
||||
const json = JSON.stringify(data, null, 2);
|
||||
|
||||
Reference in New Issue
Block a user