I think it's fair to expect divergence with an API that was made for browsers being mimicked elsewhere; here it's more about faithfulness and predictability
node-fetch, cross-fetch, undici fetch, deno fetch, etc. these are all faithful to the original API, and behave in ways that wouldn't surprise you if you're familiar with fetch. the more unfamiliar nooks and crannies of the API (e.g. ReadableStream) is sort of a rats nest unfortunately 😅 but that's beside the point
here's the difference with Next.js: now I'm not writing fetch with fetch in mind, I'm writing fetch with Next.js's caching behaviors in mind, and a hidden fetch call multiple levels down in the stack can unexpectedly change that behavior in potentially unexpected ways
happy to be convinced otherwise though. I know y'all give this a lot of thought, but this was just really out of left field for me 🫠
Thanks for helping me get my head around this, it's really helpful - was very skeptical before this comment but now I'm open to seeing how it all plays out.
The important bit for me was the idea of transparently extending fetch for the duration of a single server render.
I'm deep into algebraic effects right now, so in my mind what you're doing sounds like implementing a "fetch effect" in the React runtime. It doesn't leak outside of the
render()
call at all, and anyfetch()
calls inside of the component tree (but not outside) will follow the caching semantics. Opting out with an AbortSignal is cool too, I guess in a typed alg effect lang that's kind of equivalent to producing your own distinct fetch effect to indicate that you want to handle the lifetime of the request yourself.