删除 node_modules

This commit is contained in:
2025-06-22 17:27:35 +08:00
parent ebcd00ed99
commit 912d2d4a12
3852 changed files with 0 additions and 1061355 deletions

View File

@@ -1,15 +0,0 @@
import {initializeConcurrentStreams} from './concurrent.js';
import {createReadable} from './readable.js';
import {createWritable} from './writable.js';
import {createDuplex} from './duplex.js';
import {createIterable} from './iterable.js';
// Add methods to convert the subprocess to a stream or iterable
export const addConvertedStreams = (subprocess, {encoding}) => {
const concurrentStreams = initializeConcurrentStreams();
subprocess.readable = createReadable.bind(undefined, {subprocess, concurrentStreams, encoding});
subprocess.writable = createWritable.bind(undefined, {subprocess, concurrentStreams});
subprocess.duplex = createDuplex.bind(undefined, {subprocess, concurrentStreams, encoding});
subprocess.iterable = createIterable.bind(undefined, subprocess, encoding);
subprocess[Symbol.asyncIterator] = createIterable.bind(undefined, subprocess, encoding, {});
};

View File

@@ -1,33 +0,0 @@
import {createDeferred} from '../utils/deferred.js';
// When using multiple `.readable()`/`.writable()`/`.duplex()`, `final` and `destroy` should wait for other streams
export const initializeConcurrentStreams = () => ({
readableDestroy: new WeakMap(),
writableFinal: new WeakMap(),
writableDestroy: new WeakMap(),
});
// Each file descriptor + `waitName` has its own array of promises.
// Each promise is a single `.readable()`/`.writable()`/`.duplex()` call.
export const addConcurrentStream = (concurrentStreams, stream, waitName) => {
const weakMap = concurrentStreams[waitName];
if (!weakMap.has(stream)) {
weakMap.set(stream, []);
}
const promises = weakMap.get(stream);
const promise = createDeferred();
promises.push(promise);
const resolve = promise.resolve.bind(promise);
return {resolve, promises};
};
// Wait for other streams, but stop waiting when subprocess ends
export const waitForConcurrentStreams = async ({resolve, promises}, subprocess) => {
resolve();
const [isSubprocessExit] = await Promise.race([
Promise.allSettled([true, subprocess]),
Promise.all([false, ...promises]),
]);
return !isSubprocessExit;
};

View File

@@ -1,69 +0,0 @@
import {Duplex} from 'node:stream';
import {callbackify} from 'node:util';
import {BINARY_ENCODINGS} from '../arguments/encoding-option.js';
import {
getSubprocessStdout,
getReadableOptions,
getReadableMethods,
onStdoutFinished,
onReadableDestroy,
} from './readable.js';
import {
getSubprocessStdin,
getWritableMethods,
onStdinFinished,
onWritableDestroy,
} from './writable.js';
// Create a `Duplex` stream combining both `subprocess.readable()` and `subprocess.writable()`
export const createDuplex = ({subprocess, concurrentStreams, encoding}, {from, to, binary: binaryOption = true, preserveNewlines = true} = {}) => {
const binary = binaryOption || BINARY_ENCODINGS.has(encoding);
const {subprocessStdout, waitReadableDestroy} = getSubprocessStdout(subprocess, from, concurrentStreams);
const {subprocessStdin, waitWritableFinal, waitWritableDestroy} = getSubprocessStdin(subprocess, to, concurrentStreams);
const {readableEncoding, readableObjectMode, readableHighWaterMark} = getReadableOptions(subprocessStdout, binary);
const {read, onStdoutDataDone} = getReadableMethods({
subprocessStdout,
subprocess,
binary,
encoding,
preserveNewlines,
});
const duplex = new Duplex({
read,
...getWritableMethods(subprocessStdin, subprocess, waitWritableFinal),
destroy: callbackify(onDuplexDestroy.bind(undefined, {
subprocessStdout,
subprocessStdin,
subprocess,
waitReadableDestroy,
waitWritableFinal,
waitWritableDestroy,
})),
readableHighWaterMark,
writableHighWaterMark: subprocessStdin.writableHighWaterMark,
readableObjectMode,
writableObjectMode: subprocessStdin.writableObjectMode,
encoding: readableEncoding,
});
onStdoutFinished({
subprocessStdout,
onStdoutDataDone,
readable: duplex,
subprocess,
subprocessStdin,
});
onStdinFinished(subprocessStdin, duplex, subprocessStdout);
return duplex;
};
const onDuplexDestroy = async ({subprocessStdout, subprocessStdin, subprocess, waitReadableDestroy, waitWritableFinal, waitWritableDestroy}, error) => {
await Promise.all([
onReadableDestroy({subprocessStdout, subprocess, waitReadableDestroy}, error),
onWritableDestroy({
subprocessStdin,
subprocess,
waitWritableFinal,
waitWritableDestroy,
}, error),
]);
};

View File

@@ -1,34 +0,0 @@
import {BINARY_ENCODINGS} from '../arguments/encoding-option.js';
import {getFromStream} from '../arguments/fd-options.js';
import {iterateOnSubprocessStream} from '../io/iterate.js';
// Convert the subprocess to an async iterable
export const createIterable = (subprocess, encoding, {
from,
binary: binaryOption = false,
preserveNewlines = false,
} = {}) => {
const binary = binaryOption || BINARY_ENCODINGS.has(encoding);
const subprocessStdout = getFromStream(subprocess, from);
const onStdoutData = iterateOnSubprocessStream({
subprocessStdout,
subprocess,
binary,
shouldEncode: true,
encoding,
preserveNewlines,
});
return iterateOnStdoutData(onStdoutData, subprocessStdout, subprocess);
};
const iterateOnStdoutData = async function * (onStdoutData, subprocessStdout, subprocess) {
try {
yield * onStdoutData;
} finally {
if (subprocessStdout.readable) {
subprocessStdout.destroy();
}
await subprocess;
}
};

View File

@@ -1,113 +0,0 @@
import {Readable} from 'node:stream';
import {callbackify} from 'node:util';
import {BINARY_ENCODINGS} from '../arguments/encoding-option.js';
import {getFromStream} from '../arguments/fd-options.js';
import {iterateOnSubprocessStream, DEFAULT_OBJECT_HIGH_WATER_MARK} from '../io/iterate.js';
import {createDeferred} from '../utils/deferred.js';
import {addConcurrentStream, waitForConcurrentStreams} from './concurrent.js';
import {
safeWaitForSubprocessStdin,
waitForSubprocessStdout,
waitForSubprocess,
destroyOtherStream,
} from './shared.js';
// Create a `Readable` stream that forwards from `stdout` and awaits the subprocess
export const createReadable = ({subprocess, concurrentStreams, encoding}, {from, binary: binaryOption = true, preserveNewlines = true} = {}) => {
const binary = binaryOption || BINARY_ENCODINGS.has(encoding);
const {subprocessStdout, waitReadableDestroy} = getSubprocessStdout(subprocess, from, concurrentStreams);
const {readableEncoding, readableObjectMode, readableHighWaterMark} = getReadableOptions(subprocessStdout, binary);
const {read, onStdoutDataDone} = getReadableMethods({
subprocessStdout,
subprocess,
binary,
encoding,
preserveNewlines,
});
const readable = new Readable({
read,
destroy: callbackify(onReadableDestroy.bind(undefined, {subprocessStdout, subprocess, waitReadableDestroy})),
highWaterMark: readableHighWaterMark,
objectMode: readableObjectMode,
encoding: readableEncoding,
});
onStdoutFinished({
subprocessStdout,
onStdoutDataDone,
readable,
subprocess,
});
return readable;
};
// Retrieve `stdout` (or other stream depending on `from`)
export const getSubprocessStdout = (subprocess, from, concurrentStreams) => {
const subprocessStdout = getFromStream(subprocess, from);
const waitReadableDestroy = addConcurrentStream(concurrentStreams, subprocessStdout, 'readableDestroy');
return {subprocessStdout, waitReadableDestroy};
};
export const getReadableOptions = ({readableEncoding, readableObjectMode, readableHighWaterMark}, binary) => binary
? {readableEncoding, readableObjectMode, readableHighWaterMark}
: {readableEncoding, readableObjectMode: true, readableHighWaterMark: DEFAULT_OBJECT_HIGH_WATER_MARK};
export const getReadableMethods = ({subprocessStdout, subprocess, binary, encoding, preserveNewlines}) => {
const onStdoutDataDone = createDeferred();
const onStdoutData = iterateOnSubprocessStream({
subprocessStdout,
subprocess,
binary,
shouldEncode: !binary,
encoding,
preserveNewlines,
});
return {
read() {
onRead(this, onStdoutData, onStdoutDataDone);
},
onStdoutDataDone,
};
};
// Forwards data from `stdout` to `readable`
const onRead = async (readable, onStdoutData, onStdoutDataDone) => {
try {
const {value, done} = await onStdoutData.next();
if (done) {
onStdoutDataDone.resolve();
} else {
readable.push(value);
}
} catch {}
};
// When `subprocess.stdout` ends/aborts/errors, do the same on `readable`.
// Await the subprocess, for the same reason as above.
export const onStdoutFinished = async ({subprocessStdout, onStdoutDataDone, readable, subprocess, subprocessStdin}) => {
try {
await waitForSubprocessStdout(subprocessStdout);
await subprocess;
await safeWaitForSubprocessStdin(subprocessStdin);
await onStdoutDataDone;
if (readable.readable) {
readable.push(null);
}
} catch (error) {
await safeWaitForSubprocessStdin(subprocessStdin);
destroyOtherReadable(readable, error);
}
};
// When `readable` aborts/errors, do the same on `subprocess.stdout`
export const onReadableDestroy = async ({subprocessStdout, subprocess, waitReadableDestroy}, error) => {
if (await waitForConcurrentStreams(waitReadableDestroy, subprocess)) {
destroyOtherReadable(subprocessStdout, error);
await waitForSubprocess(subprocess, error);
}
};
const destroyOtherReadable = (stream, error) => {
destroyOtherStream(stream, stream.readable, error);
};

View File

@@ -1,46 +0,0 @@
import {finished} from 'node:stream/promises';
import {isStreamAbort} from '../resolve/wait-stream.js';
export const safeWaitForSubprocessStdin = async subprocessStdin => {
if (subprocessStdin === undefined) {
return;
}
try {
await waitForSubprocessStdin(subprocessStdin);
} catch {}
};
export const safeWaitForSubprocessStdout = async subprocessStdout => {
if (subprocessStdout === undefined) {
return;
}
try {
await waitForSubprocessStdout(subprocessStdout);
} catch {}
};
export const waitForSubprocessStdin = async subprocessStdin => {
await finished(subprocessStdin, {cleanup: true, readable: false, writable: true});
};
export const waitForSubprocessStdout = async subprocessStdout => {
await finished(subprocessStdout, {cleanup: true, readable: true, writable: false});
};
// When `readable` or `writable` aborts/errors, awaits the subprocess, for the reason mentioned above
export const waitForSubprocess = async (subprocess, error) => {
await subprocess;
if (error) {
throw error;
}
};
export const destroyOtherStream = (stream, isOpen, error) => {
if (error && !isStreamAbort(error)) {
stream.destroy(error);
} else if (isOpen) {
stream.destroy();
}
};

View File

@@ -1,90 +0,0 @@
import {Writable} from 'node:stream';
import {callbackify} from 'node:util';
import {getToStream} from '../arguments/fd-options.js';
import {addConcurrentStream, waitForConcurrentStreams} from './concurrent.js';
import {
safeWaitForSubprocessStdout,
waitForSubprocessStdin,
waitForSubprocess,
destroyOtherStream,
} from './shared.js';
// Create a `Writable` stream that forwards to `stdin` and awaits the subprocess
export const createWritable = ({subprocess, concurrentStreams}, {to} = {}) => {
const {subprocessStdin, waitWritableFinal, waitWritableDestroy} = getSubprocessStdin(subprocess, to, concurrentStreams);
const writable = new Writable({
...getWritableMethods(subprocessStdin, subprocess, waitWritableFinal),
destroy: callbackify(onWritableDestroy.bind(undefined, {
subprocessStdin,
subprocess,
waitWritableFinal,
waitWritableDestroy,
})),
highWaterMark: subprocessStdin.writableHighWaterMark,
objectMode: subprocessStdin.writableObjectMode,
});
onStdinFinished(subprocessStdin, writable);
return writable;
};
// Retrieve `stdin` (or other stream depending on `to`)
export const getSubprocessStdin = (subprocess, to, concurrentStreams) => {
const subprocessStdin = getToStream(subprocess, to);
const waitWritableFinal = addConcurrentStream(concurrentStreams, subprocessStdin, 'writableFinal');
const waitWritableDestroy = addConcurrentStream(concurrentStreams, subprocessStdin, 'writableDestroy');
return {subprocessStdin, waitWritableFinal, waitWritableDestroy};
};
export const getWritableMethods = (subprocessStdin, subprocess, waitWritableFinal) => ({
write: onWrite.bind(undefined, subprocessStdin),
final: callbackify(onWritableFinal.bind(undefined, subprocessStdin, subprocess, waitWritableFinal)),
});
// Forwards data from `writable` to `stdin`
const onWrite = (subprocessStdin, chunk, encoding, done) => {
if (subprocessStdin.write(chunk, encoding)) {
done();
} else {
subprocessStdin.once('drain', done);
}
};
// Ensures that the writable `final` and readable `end` events awaits the subprocess.
// Like this, any subprocess failure is propagated as a stream `error` event, instead of being lost.
// The user does not need to `await` the subprocess anymore, but now needs to await the stream completion or error.
// When multiple writables are targeting the same stream, they wait for each other, unless the subprocess ends first.
const onWritableFinal = async (subprocessStdin, subprocess, waitWritableFinal) => {
if (await waitForConcurrentStreams(waitWritableFinal, subprocess)) {
if (subprocessStdin.writable) {
subprocessStdin.end();
}
await subprocess;
}
};
// When `subprocess.stdin` ends/aborts/errors, do the same on `writable`.
export const onStdinFinished = async (subprocessStdin, writable, subprocessStdout) => {
try {
await waitForSubprocessStdin(subprocessStdin);
if (writable.writable) {
writable.end();
}
} catch (error) {
await safeWaitForSubprocessStdout(subprocessStdout);
destroyOtherWritable(writable, error);
}
};
// When `writable` aborts/errors, do the same on `subprocess.stdin`
export const onWritableDestroy = async ({subprocessStdin, subprocess, waitWritableFinal, waitWritableDestroy}, error) => {
await waitForConcurrentStreams(waitWritableFinal, subprocess);
if (await waitForConcurrentStreams(waitWritableDestroy, subprocess)) {
destroyOtherWritable(subprocessStdin, error);
await waitForSubprocess(subprocess, error);
}
};
const destroyOtherWritable = (stream, error) => {
destroyOtherStream(stream, stream.writable, error);
};