Skip to content

only use ponyfilled ReadableStream when necessary #151

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

Conversation

pgoldberg
Copy link
Contributor

Before this PR

web-streams-polyfill doesn't include any checks to see if the browser it's running in has native streams. This causes conflicts between the native streams and the polyfilled ones.

After this PR

==COMMIT_MSG==
We now use the ponyfilled ReadableStream from web-streams-polyfill only if the browser doesn't have ReadableStream.
==COMMIT_MSG==

Possible downsides?

This already existed, but web-streams-polyfill will still get loaded even if it's unused.

@pgoldberg pgoldberg force-pushed the pgoldberg/dontAlwaysPolyfillReadableStream branch from 660a58b to e2a3a06 Compare August 19, 2022 21:04
@pgoldberg pgoldberg marked this pull request as draft August 19, 2022 22:02
@pgoldberg pgoldberg mentioned this pull request Aug 20, 2022
@pgoldberg pgoldberg force-pushed the pgoldberg/dontAlwaysPolyfillReadableStream branch 2 times, most recently from f4ff8d2 to b9f1dde Compare August 20, 2022 06:09
@pgoldberg pgoldberg marked this pull request as ready for review August 20, 2022 06:13
@gluxon gluxon self-assigned this Aug 22, 2022
start: controller => {
export function blobToReadableStream(
blobPromise: Promise<Blob>,
): ReadableStream<Uint8Array> | PonyfilledReadableStream<Uint8Array> {
Copy link
Contributor

@gluxon gluxon Aug 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Is it a bit strange for PonyfilledReadableStream<T> to be exposed as a return type of this function? Ideally the polyfill usage of this function is an implementation detail that doesn't affect its calling API contract.

Assuming this was added since PonyfilledReadableStream<T> isn't a subset of ReadableStream<T>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think it's strange, but unfortunately it is necessary.

Type 'ReadableStream<Uint8Array> | ReadableStream<...>' is not assignable to type 'ReadableStream<Uint8Array>'.
  Type 'import("/Volumes/git/conjure-typescript-runtime/node_modules/web-streams-polyfill/dist/types/polyfill").ReadableStream<Uint8Array>' is not assignable to type 'ReadableStream<Uint8Array>'.
    Types of property 'getReader' are incompatible.
      Type '{ ({ mode }: { mode: "byob"; }): ReadableStreamBYOBReader_2; (): ReadableStreamDefaultReader_2<Uint8Array>; }' is not assignable to type '() => ReadableStreamDefaultReader<Uint8Array>'.

Copy link
Contributor

@gluxon gluxon Aug 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. Thanks for copying out the compile error.

Although I dislike as assertions, I'm a bit conflicted on whether an as ReadableStream<Uint8Array> type assertion in this function might be the best option. The | PonyfilledReadableStream<Uint8Array> addition to the return type here might mean downstream consumers have to cast that portion away later. If a cast somewhere in the call stack is necessary, it might be best to do it here where it's introduced?

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filling in some offline discussion here:

The ponyfill typing and the native ReadableStream type don't have sufficient overlap to cast, so we have to cast as unknown first. Currently we cast as any here, downstream of blobToReadableStream:

return this.handleBinaryResponseBody(response) as any;

So this shouldn't affect downstream consumers regardless, but changing anyway to prevent any future change to that cast unintentionally affecting downstream consumers. Also, @gluxon pointed out we probably should have needed to change the return type here:

private handleBinaryResponseBody(response: IFetchResponse): ReadableStream<Uint8Array> {

Not sure why that wasn't causing a compilation error

@pgoldberg pgoldberg force-pushed the pgoldberg/dontAlwaysPolyfillReadableStream branch from b9f1dde to 311dad8 Compare August 26, 2022 15:13
@pgoldberg
Copy link
Contributor Author

Force push was just a rebase after #152 merged

Copy link
Contributor

@gluxon gluxon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good on my side! (Pending some discussion on the return type changing.) Let's get a look from @walkerburgin or @styu before merging too.

@pgoldberg pgoldberg merged commit eb31ed3 into palantir:develop Sep 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants