Skip to content

Commit 266fe46

Browse files
committed
Eliminate buffering in slice
1 parent c605f81 commit 266fe46

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

lib/streams.js

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,19 +462,45 @@ function slice(input, begin=0, end=Infinity) {
462462
}
463463
if (isStream(input)) {
464464
if (begin >= 0 && end >= 0) {
465+
let reader;
465466
let bytesRead = 0;
466-
return transformRaw(input, {
467-
transform(value, controller) {
468-
if (bytesRead < end) {
469-
if (bytesRead + value.length >= begin) {
470-
controller.enqueue(slice(value, Math.max(begin - bytesRead, 0), end - bytesRead));
467+
return new ReadableStream({
468+
start() {
469+
reader = input.getReader();
470+
},
471+
async pull(controller) {
472+
try {
473+
while (true) {
474+
if (bytesRead < end) {
475+
const { value, done } = await reader.read();
476+
if (done) {
477+
controller.close();
478+
input.releaseLock();
479+
return;
480+
}
481+
let valueToEnqueue;
482+
if (bytesRead + value.length >= begin) {
483+
valueToEnqueue = slice(value, Math.max(begin - bytesRead, 0), end - bytesRead);
484+
}
485+
bytesRead += value.length;
486+
if (valueToEnqueue) {
487+
controller.enqueue(valueToEnqueue);
488+
return;
489+
}
490+
} else {
491+
controller.close();
492+
input.releaseLock();
493+
return;
494+
}
471495
}
472-
bytesRead += value.length;
473-
} else {
474-
controller.terminate();
496+
} catch (e) {
497+
controller.error(e);
475498
}
499+
},
500+
async cancel(reason) {
501+
await reader.cancel(reason);
476502
}
477-
});
503+
}, { highWaterMark: 0 });
478504
}
479505
if (begin < 0 && (end < 0 || end === Infinity)) {
480506
let lastBytes = [];

0 commit comments

Comments
 (0)