-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
First parameter has member 'readable' that is not a ReadableStream #6249
Comments
I have the same issue with It also seems related to #3862 |
I followed a couple of threads on the @Kalkut provided. It looks like it's because remix uses https://github.com/MattiasBuelens/web-streams-polyfill/tree/master under the hood to polyfill I tried Node 16 is at EOL (< 1 month left in security support at the time of this comment), and the vast majority of browsers support most of the streams API (https://caniuse.com/streams). It seems pretty safe to remove the polyfill at this point. vercel/ai#199 (comment) provides one solution. I'm going to see if there's a simpler option. And post back if I find one. |
Alright, I figured something out: // stream-compat.server.ts
import {
ReadableStream as NodeReadableStream,
TextDecoderStream as NodeTextDecoderStream,
TextEncoderStream as NodeTextEncoderStream,
TransformStream as NodeTransformStream,
WritableStream as NodeWritableStream,
} from "node:stream/web";
async function* iterStream<T>(body?: ReadableStream<T> | null) {
if (!body) {
return;
}
const reader = body.getReader();
while (true) {
const r = await reader.read();
if (r.done) {
break;
} else {
yield r.value;
}
}
}
// Ensures that custom streams are compatible with node streams
(global as any).ReadableStream = NodeReadableStream;
(global as any).TransformStream = NodeTransformStream;
(global as any).WritableStream = NodeWritableStream;
(global as any).TextDecoderStream = NodeTextDecoderStream;
(global as any).TextEncoderStream = NodeTextEncoderStream;
export const toNodeReadableStream = <T>(
polyStream: ReadableStream<T> | null | undefined
) => {
const iterator = iterStream(polyStream);
return new NodeReadableStream<T>({
async pull(controller) {
const r = await iterator.next();
if (r.done) {
controller.close();
} else {
controller.enqueue(r.value);
}
},
// This is *mostly* correct. There are slight type issues between the two streams
}) as ReadableStream<T>;
};
export const StreamCompat = {
toReadable: toNodeReadableStream,
// lib.dom.d.ts and web.d.ts typings are apparently incompatible.
// Remix routes use web.d.ts and .server.ts files use lib.dom.d.ts
// This exposes lib.dom.d.ts typings for the routes
TextEncoderStream,
TextDecoderStream,
}; In an action, you can now do StreamCompat.toReadable(response.body).pipeThrough(...) And everything should JustWork™️. I'm using In theory, this problem goes away with Remix@v2, so hopefully this solves the issue for people in the meantime. |
See #3862 (comment) for why supporting fromWeb / toWeb isn't going to be doable. If you need a native node ReadableStream you can use something like: const passthrough = new PassThrough();
writeReadableStreamToWritable(polyfilledReadable, passthrough);
const nativeReadable = Readable.toWeb(passthrough); |
Ran into this error when using the vercel ai package. Fixed by commenting out remix's fetch (using patch-package) diff --git a/node_modules/@remix-run/node/dist/globals.js b/node_modules/@remix-run/node/dist/globals.js
index b96820b..7277c69 100644
--- a/node_modules/@remix-run/node/dist/globals.js
+++ b/node_modules/@remix-run/node/dist/globals.js
@@ -28,7 +28,7 @@ function installGlobals({
global.Headers = UndiciHeaders;
global.Request = UndiciRequest;
global.Response = UndiciResponse;
- global.fetch = undiciFetch;
+ // global.fetch = undiciFetch;
global.FormData = UndiciFormData;
} else {
let {
@@ -43,7 +43,7 @@ function installGlobals({
global.Headers = RemixHeaders;
global.Request = RemixRequest;
global.Response = RemixResponse;
- global.fetch = RemixFetch;
+ // global.fetch = RemixFetch;
global.FormData = RemixFormData;
}
} |
What fixed it for me without patching: vercel/ai#199 (comment) |
What version of Remix are you using?
1.15.0
Are all your remix dependencies & dev-dependencies using the same version?
Steps to Reproduce
Using
response.body.pipeThrough( new TextDecoderStream() ).getReader()
throws an error if executed through a Remix Loader:Expected Behavior
response.body.pipeThrough( new TextDecoderStream() ).getReader()
should work as expectedActual Behavior
Instead it throws an error:
The text was updated successfully, but these errors were encountered: