Skip to content
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

1078 use right buffer in browser #1079

Merged
merged 7 commits into from
Aug 22, 2024
Merged

Conversation

diksipav
Copy link
Contributor

@diksipav diksipav commented Aug 9, 2024

fix #1078

This is tricky, I spend some time today to track this down (@jaclarke helped with some debugging):
we need encode/decode for Node, Deno and browser.

  • Here the "Buffer not defined" err was thrown because on line 35 typeof was missing: if (Buffer === "function") {. So native node Buffer was never used until new PR that fixes that but broke browser functioning.

  • Require doesn't work in Deno. Test is failing. I believe err should be caught in catch block but for some reason test fails.
    In browser require can work but requiring node:Buffer not. Node prefix is not recognised by Webpack, so building is failing. So I guess going with this try/catch block with require in try block will anyway not be good enough.

  • CloudFlare needs nodejs compat flag if node comp libs are used. I don't know what we want here to be default behaviour for Cloudflare, do we use browser libs by default or we use node compat libs and require users to set Cloudflare to use node libs.

We can revert everything to that first solution when checking if global Buffer was available and fallback to atob/btoa versions. In Deno global Buffer should exists so it will be used, in CloudFlare browser replacements will be used.
Or investigate further how to use node:buffer in deno and cloudflare by default.

@jaclarke
Copy link
Member

jaclarke commented Aug 9, 2024

I thought we had updated everything to use Uint8Array instead of Buffer so it could work in the browser in this PR: #457, so this seems like a regression somewhere?

Edit: The linked issue has the PR with the regression: #1015

@jaclarke jaclarke linked an issue Aug 9, 2024 that may be closed by this pull request
@scotttrinh
Copy link
Collaborator

I thought we had updated everything to use Uint8Array instead of Buffer so it could work in the browser

Yeah, for what it's worth, I think we should try to use the platform's faster/better APIs when we can rather than taking a least-common denominator approach. The issue here was that I did not consider the browser platform when I worked on #1015, only the Deno environment and was leaning on both Deno and Bun having node:buffer compatibility.

We absolutely can just do the base64 decoding ourselves in pure JS, but the old implementation was also subject to unicode problems (atob and btoa don't handle unicode).

At the moment, I think we should attempt to import node:buffer and if we fail, fall back to a pure JS implementation. In the future, I think we should rethink our platform strategy to be able to more easily take advantage of platform-specific APIs and do less runtime/buildtime magic.

Would also be a good idea to add some browser-like smoke tests (maybe JSDom is good enough 🤷 ) to ensure I don't break this again 😅


try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const Buffer = require("node:buffer").Buffer;
Copy link
Collaborator

Choose a reason for hiding this comment

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

The tests are failing because we cannot use require in Deno, and Deno will unconditionally try to run this code. We typically can get around this by putting the non-Deno stuff in the adapter.node.ts module, and making a Deno-compatible import available in adapter.deno.ts, and at buildDeno-time, we swap these out in the source. This is what we did before by exporting Buffer from the adapter.

I think we should be able to do that if we move these base64-related functions into the adapter.* modules and import them instead of importing Buffer. And having the adapter.node.ts module do this check instead.

Copy link
Contributor Author

@diksipav diksipav Aug 22, 2024

Choose a reason for hiding this comment

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

this will probably not work in browser because we will import from adapter.node and that file imports node libs that are not available in browser

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah, that's true. I didn't really consider how this module before was totally runtime-agnostic, where the adapter stuff was always imported into server-only contexts.

#1003 the "Buffer not defined" err was thrown because on line 35 typeof was missing: if (Buffer === "function") {. So native node Buffer was never used until new PR that fixes that but broke browser functioning.

Let's just adopt this where we fix the check, and keep most of the old code. I think a more thorough fix will come when we make platform-specific packages so the modules don't need to be so dynamic, but we are still a ways off from working on that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@scotttrinh @jaclarke I think this should be it. Btw I didnt add any new tests, can do that too.

@diksipav diksipav marked this pull request as ready for review August 22, 2024 15:18
let encodeB64: (_: Uint8Array) => string;

// @ts-ignore: Buffer is not defined in Deno
if (typeof Buffer === "function") {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you try this form and see if it allows us to remove the @ts-ignore here?

Suggested change
if (typeof Buffer === "function") {
if (typeof globalThis.Buffer === "function") {

diksipav and others added 3 commits August 22, 2024 18:06
A recent update of pnpm (9.8.0) started to cause failures. I believe
this is due to the "temporary" projects being made within the main
repo's directory, causing some weird "project" detection in pnpm.
Copy link
Collaborator

@scotttrinh scotttrinh left a comment

Choose a reason for hiding this comment

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

Thanks for working through all of the various ideas and speed bumps here!

@scotttrinh scotttrinh merged commit 8aa49d9 into master Aug 22, 2024
10 checks passed
@scotttrinh scotttrinh deleted the 1078-use-right-buffer-in-browser branch August 22, 2024 18:33
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.

createHttpClient: crypto lib gets imported in the browser
3 participants