zyb 0c0b5d869c 加入了node_modules
添加了新的功能项
2025-05-13 21:23:41 +08:00

73 lines
2.2 KiB
JavaScript

import isPlainObject from 'is-plain-obj';
import {normalizePipeArguments} from './pipe-arguments.js';
import {handlePipeArgumentsError} from './throw.js';
import {waitForBothSubprocesses} from './sequence.js';
import {pipeSubprocessStream} from './streaming.js';
import {unpipeOnAbort} from './abort.js';
// Pipe a subprocess' `stdout`/`stderr`/`stdio` into another subprocess' `stdin`
export const pipeToSubprocess = (sourceInfo, ...pipeArguments) => {
if (isPlainObject(pipeArguments[0])) {
return pipeToSubprocess.bind(undefined, {
...sourceInfo,
boundOptions: {...sourceInfo.boundOptions, ...pipeArguments[0]},
});
}
const {destination, ...normalizedInfo} = normalizePipeArguments(sourceInfo, ...pipeArguments);
const promise = handlePipePromise({...normalizedInfo, destination});
promise.pipe = pipeToSubprocess.bind(undefined, {
...sourceInfo,
source: destination,
sourcePromise: promise,
boundOptions: {},
});
return promise;
};
// Asynchronous logic when piping subprocesses
const handlePipePromise = async ({
sourcePromise,
sourceStream,
sourceOptions,
sourceError,
destination,
destinationStream,
destinationError,
unpipeSignal,
fileDescriptors,
startTime,
}) => {
const subprocessPromises = getSubprocessPromises(sourcePromise, destination);
handlePipeArgumentsError({
sourceStream,
sourceError,
destinationStream,
destinationError,
fileDescriptors,
sourceOptions,
startTime,
});
const maxListenersController = new AbortController();
try {
const mergedStream = pipeSubprocessStream(sourceStream, destinationStream, maxListenersController);
return await Promise.race([
waitForBothSubprocesses(subprocessPromises),
...unpipeOnAbort(unpipeSignal, {
sourceStream,
mergedStream,
sourceOptions,
fileDescriptors,
startTime,
}),
]);
} finally {
maxListenersController.abort();
}
};
// `.pipe()` awaits the subprocess promises.
// When invalid arguments are passed to `.pipe()`, we throw an error, which prevents awaiting them.
// We need to ensure this does not create unhandled rejections.
const getSubprocessPromises = (sourcePromise, destination) => Promise.allSettled([sourcePromise, destination]);