You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
1.5 KiB
JavaScript

"use strict";
const Promise = require("bluebird");
const propagateAbort = require("@promistream/propagate-abort");
const unreachable = require("@joepie91/unreachable")("@promistream/buffer");
module.exports = function bufferStream() {
let buffer;
let bufferPeeked;
function attemptRead(readFunc) {
return Promise.try(() => {
return readFunc();
}).then((result) => {
if (Array.isArray(result)) {
if (result.length > 0) {
buffer = result;
bufferPeeked = result.map(() => false);
} else {
return attemptRead(readFunc);
}
} else {
throw new Error("Buffered stream produced a non-array value");
}
});
}
return {
_promistreamVersion: 0,
description: "buffer stream",
abort: propagateAbort,
peek: function peekValue_bufferedSourceStream(source) {
if (buffer == null) {
return source.peek();
} else {
let unpeekedIndex = bufferPeeked.indexOf(false);
if (unpeekedIndex > 0) {
bufferPeeked[unpeekedIndex] = true;
return true;
} else {
return source.peek();
}
}
},
read: function produceValue_bufferedSourceStream(source) {
return Promise.try(() => {
if (buffer == null) {
return attemptRead(source.read);
}
}).then(() => {
if (buffer != null) {
let value = buffer.shift();
bufferPeeked.shift();
if (buffer.length === 0) {
buffer = null;
bufferPeeked = null;
}
return value;
} else {
unreachable("No buffer was present");
}
});
}
};
};