Skip to content

Commit d4ffbd9

Browse files
committed
Lazily request stdin
1 parent ad80159 commit d4ffbd9

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

command.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,21 @@ class FakeStream extends PassThrough {
2626
}
2727
}
2828

29+
export const realStderrWrite = process.stderr.write.bind(process.stderr)
30+
export const realStdoutWrite = process.stdout.write.bind(process.stdout);
2931
// console.log, console.error maintain references to write(), so it must be replaced with a permenant hook
30-
let stderrWrite = process.stderr.write;
31-
let stdoutWrite = process.stdout.write;
32+
let stderrWrite = realStderrWrite;
33+
let stdoutWrite = realStdoutWrite;
3234

33-
Object.defineProperty(process, 'stdout', {
35+
Object.defineProperty(process, 'stderr', {
3436
configurable: true,
3537
enumerable: true,
36-
get: (stdin => () => stdin)(new FakeStream),
38+
get: (stderr => () => stderr)(new FakeStream),
3739
});
38-
Object.defineProperty(process, 'stderr', {
40+
Object.defineProperty(process, 'stdout', {
3941
configurable: true,
4042
enumerable: true,
41-
get: (stdin => () => stdin)(new FakeStream),
43+
get: (stdout => () => stdout)(new FakeStream),
4244
});
4345

4446
process.stderr.write = function() {
@@ -130,6 +132,14 @@ export class Command {
130132
this.removeListener('resume', stdinResume);
131133
ref.unref();
132134
});
135+
process.stdin.on('newListener', function listener(this: NodeJS.ReadStream, type) {
136+
switch (type) {
137+
case 'data':
138+
case 'end':
139+
this.removeListener('newListener', listener);
140+
stdin.request();
141+
}
142+
});
133143

134144
// stdout
135145
const stdout = new CommandStdout();
@@ -166,13 +176,12 @@ export class Command {
166176
class CommandStdin extends Transform {
167177
constructor(private readonly writer: Writable, private readonly ref: Ref) {
168178
super({writableObjectMode:true});
179+
}
180+
181+
request() {
169182
// NodeJS will not flush this buffer
170183
// a workaround is to send a newline (!) but that clutters the output
171184
// this.writer.write(new Chunk(ChunkType.Stderr, Buffer.from('\n')));
172-
this._request();
173-
}
174-
175-
private _request() {
176185
try {
177186
this.writer.write(new Chunk(ChunkType.StdinStart));
178187
} catch (e) {
@@ -183,7 +192,7 @@ class CommandStdin extends Transform {
183192
switch (chunk.type) {
184193
case ChunkType.Stdin:
185194
callback(null, chunk.data);
186-
this._request();
195+
this.request();
187196
break;
188197
case ChunkType.StdinEnd:
189198
callback();

0 commit comments

Comments
 (0)