-
Notifications
You must be signed in to change notification settings - Fork 632
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BREAKING(streams): have toJson()
and toText()
accept ReadableStream<Uint8Array>
#5079
Conversation
…eam<Uint8Array>`
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #5079 +/- ##
==========================================
- Coverage 92.43% 92.43% -0.01%
==========================================
Files 481 481
Lines 38750 38746 -4
Branches 5449 5448 -1
==========================================
- Hits 35817 35813 -4
Misses 2878 2878
Partials 55 55 ☔ View full report in Codecov by Sentry. |
I don't understand why we need to align them to Response methods. This seems unnecessarily reducing the use cases. |
That's what it originally said in the descriptions of these functions. Alternatively, we can go ahead with what I described in the Discussion section of the initial comment, but I'd prefer not to. |
The original inspiration for these APIs are stream/consumers APIs of Node.js (see #3587 ), and they accept streams of strings |
Then why don't users use |
I don't see the point well. Is this argument related to this PR? Or do you suggest removing these APIs? |
Yes, I suggest removing them. Frankly, I've never understood the reasons for adding them in the first place 😅 |
Maybe let's keep discussing that as RC feedback to |
I still don't understand why excluding string (and other type) input is desirable. Why do we need to align the behavior to |
I think a better question is why should we support |
Because they are exposed as public API and we should avoid unnecessary breaking changes as far as possible.
It's also explicitly documented that they accept string inputs. So this is intentional design, not a mistake. |
Also there seem no downside of accepting |
If we try to justify having code we don't need, we end up with a bloated codebase.
Yes, but that should be vetted on a case-by-case basis, and within reason. There seems to be no good reason to do this for these functions, as most are using import { toJson } from "./streams/to_json.ts";
async function toText(stream: ReadableStream<Uint8Array>): Promise<string> {
const textDecoder = new TextDecoder();
const reader = stream.getReader();
let result = "";
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
result += textDecoder.decode(value, { stream: true });
}
result += textDecoder.decode();
return result;
}
function toJson2(stream: ReadableStream<Uint8Array>): Promise<unknown> {
return toText(stream).then(JSON.parse);
}
function createStream() {
const chunks = [
"[1, true",
', [], {}, "hello',
'", null]',
];
return ReadableStream.from(chunks).pipeThrough(new TextEncoderStream());
}
const group = "x";
Deno.bench("current", { group, baseline: true }, async () => {
await toJson(createStream());
});
Deno.bench("new", { group }, async () => {
await toJson2(createStream());
});
|
I disagree with this observation. There are several std APIs that return
Also this change causes perf penalty when the user has |
Ok. I'll submit a superseding PR that clarifies these functions and unblocks |
What's changed
Previously,
toJson()
andtoText()
acceptedReadableStream
, without the type of stream being defined. Now, these functions acceptReadableStream<Uint8Array>
.Why this change was made
This change was made to align
toJson()
toRequest.json()
andResponse.json()
, andtoText()
toRequest.text()
andResponse.text()
, which seems to be the most common use case for these functions. The change also aligned these two functions with the similarly-orientedtoBlob()
, which did correctly acceptReadableStream<Uint8Array>
.Migration guide
To migrate, ensure that a
ReadableStream
ofUint8Array
s is being passed to these functions:In most cases, adding
.pipeThrough(new TextEncoderStream())
for existing use cases that useReadableStream<string>
is all that's needed to migrate.Discussion
Alternatively, all 3 functions could be modified to accept
ReadbleStream<Uint8Array> | ReadableStream<string>
. However, this wasn't done in order to align with theRequest
andResponse
objects and slightly improve performance while still catering to the majority of use cases.