// FIXME: we need to specifically watch for the `error` and `end` events on the readable interface, to know when the transform stream has fully completed processing
// FIXME: we need to specifically watch for the `error` and `end` events on the readable interface, to know when the transform stream has fully completed processing
@ -109,19 +111,15 @@ function fromTransform(stream) {
// request, destroy
// request, destroy
letreadable=wireUpReadableInterface(stream,{
letreadable=wireUpReadableInterface(stream,{
onEnd:()=>{
onEnd:()=>{
if(completionDefer!=null){
debugTransform("Received end/close event from underlying stream");
completionDefer.resolve();
}
},
},
onError:(error)=>{
onError:()=>{
if(completionDefer!=null){
debugTransform("Received error event from underlying stream");
completionDefer.reject(error);
}
}
}
});
});
// write, end, destroy
// write, end, destroy
varwritable=wireUpWritableInterface(stream);
letwritable=wireUpWritableInterface(stream);
letconvertedStream={
letconvertedStream={
_promistreamVersion:0,
_promistreamVersion:0,
@ -129,32 +127,36 @@ function fromTransform(stream) {
// NOTE: This logic exists at the start, not in the upstream EndOfStream handling code, because any number of buffer reads may be required before the wrapped Node stream can be closed
}).then((value)=>{
// NOTE: The push-buffer will automatically produce EndOfStream markers once the buffer has run out and the underlying stream has closed, so long as we're using the wireUpReadableInterface function
writable.write(value);
returnPromise.try(()=>{
returnreadable.request();
// This will quite possibly return an empty buffer, but that is fine; the `buffer` stream downstream from us will just keep reading (and therefore queueing up new items to be transformed) until it gets some results.
}).then((result)=>{
returnreadable.consumeImmediateBuffer();
return[result];
}).catch(isEndOfStream,(marker)=>{
});
// Wait for transform stream to drain fully, `error`/`end` event, and then return whatever buffer remains.
}else{
// FIXME: Error propagation logic is pretty shaky here. Verify that we don't end up with double error reports.
returnPromise.try(()=>{
if(endHandled===false){
debugTransform("Doing upstream read...");
returnsource.read();
}).then((value)=>{
debugTransform("Writing upstream value to writable interface");
writable.write(value);
// This will quite possibly return an empty buffer, but that is fine; the `buffer` stream downstream from us will just keep reading (and therefore queueing up new items to be transformed) until it gets some results.
debugTransform("Consuming immediate buffer from readable interface");
returnreadable.consumeImmediateBuffer();
}).catch(isEndOfStream,()=>{
debugTransform("End of upstream reached");
endHandled=true;
endHandled=true;
debugTransform("Closing via writable interface");
writable.end();
writable.end();
returnPromise.try(()=>{
// Return nothing, let the next read call (and all of those after that) deal with either underlying stream completion or buffered results