What is the issue with the Streams Standard?
I know this has been discussed a number of times before but I would very much appreciate if we could revisit whether passing a sync iterable, string/single value to a ReadableStream.from would be possible.
Specifically, in reviewing real world code, it's become evident that the following is actually a fairly common usage pattern as awful as it is:
const rs = new ReadableStream({
start(controller) {
controller.enqueue(aSingleChunkOfSomething);
controller.close();
}
});
Then using the ReadableStream as part of a component in a larger rendering pipeline. The fundamental issue with this is that it's actually fairly difficult to optimize around since we are forced to allocate the controller, handle the start call and resulting microtask, etc.
It's also fairly common to seed a ReadableStream with an existing in memory data source like an array:
const chunks = [1,2,3];
const rs = new ReadableStream({
pull(controller) {
let chunk = chunks.shift();
if (chunk !== undefined) {
controller.enqueue(chunk);
} else {
controller.close();
}
}
});
We could provide more optimizations internally for cases like this by allowing ReadableStream.from(...) to accept a single value and/or sync iterator... Passing a string or BufferSource as a single value would special case in that they would not be treated as sync iterators:
ReadableStream.from('hello'); // yields only a single string 'hello' then closes
ReadableStream.from(new Uint8Array(10)); // yields only the single Uint8Array
ReadableStream.from([1,2,3]); // yields 1, 2, then 3, then closes
This eliminates a significant amount of boilerplate and gives an opportunity to optimize by avoiding allocation of the underlying controller and not having to worry about user code grabbing and retaining a reference to the controller. It also means avoiding having to call out to the start and pull algorithms and the associated mechanism around it. The fact that it is more ergonomic for users is just another benefit.
/cc @MattiasBuelens @lucacasonato
What is the issue with the Streams Standard?
I know this has been discussed a number of times before but I would very much appreciate if we could revisit whether passing a sync iterable, string/single value to a
ReadableStream.fromwould be possible.Specifically, in reviewing real world code, it's become evident that the following is actually a fairly common usage pattern as awful as it is:
Then using the
ReadableStreamas part of a component in a larger rendering pipeline. The fundamental issue with this is that it's actually fairly difficult to optimize around since we are forced to allocate thecontroller, handle thestartcall and resulting microtask, etc.It's also fairly common to seed a
ReadableStreamwith an existing in memory data source like an array:We could provide more optimizations internally for cases like this by allowing
ReadableStream.from(...)to accept a single value and/or sync iterator... Passing a string or BufferSource as a single value would special case in that they would not be treated as sync iterators:This eliminates a significant amount of boilerplate and gives an opportunity to optimize by avoiding allocation of the underlying controller and not having to worry about user code grabbing and retaining a reference to the
controller. It also means avoiding having to call out to thestartandpullalgorithms and the associated mechanism around it. The fact that it is more ergonomic for users is just another benefit./cc @MattiasBuelens @lucacasonato