-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Cross-Platform (Node.js & Browsers) Binary #2259
Comments
Working with @Gozala I wrote up a better approach using |
I really love this idea. I wonder how difficult it would be to integrate it with IPFS! My gut feeling is that it would be a lot of refactoring and even then I do not know if there are modules we depend on that we wouldn't be able to convert which would mean we'd end up with a We always return In the Filecoin JS client we return "native" buffer (example) so I'll definitely use it there. |
It’s definitely a lot of refactoring, but I wonder how much would actually be in IPFS rather than the IPLD codecs. There shouldn’t be that many places where IPFS actually does something other than pass around binary, it mostly works with the deserialized form of the data. Another question that I don’t know the answer to is, how does libp2p handle binary? Because that would also need a refactor if it doesn’t accept Uint8Array’s and/or uses the Buffer API for anything. |
I would like to point out that at large I personally think it would be most effective to just switch to |
Here as some problems that I can see with normalizing to
|
I could be very naive in thinking that if there is a paths towards switching from At the end of the day you could still call toBuffer(bytes) before passing to libs that insist on Buffer, but that at least pushes towards the reduction of such cases. But yeah knowing when it’s safe to do and when it isn’t is not ideal |
What about other idea. What if instead of polyfilling browsers we polyfill node instead. Polyfill would just load in node and attach missing methods to Unit8Array so it’s API compatible with buffer. |
I guess problem with Buffer polyfill for node is that |
@mikeal I think best solution would be if bytesish had no canonical representation. And instead exposed |
It is also worth considering that if some library within the dependencies depends on |
Yup. TBH, I feel like we’ve spent the last 5 years in the JS ecosystem trying to make
Sure, but you have to start somewhere. |
|
Is this in response to my proposed solution #2259 (comment) ? I honestly also think that attempts had being pretty fruitful. Buffers work out of the box in browsers and Uin8Array’s work as replacements in node unless library does transcoding of bytes & all is left to have an alternative for Buffer methods available so there’s an option to be Buffer free. Problem with |
To be clear I’m not against DataView I just think Uin8Array has a higher chance to succeed |
Please read this as a simple comment, I don't have strong opinions about it and other folks have a way better understanding of the JavaScript ecosystem to know which things are actual practical and which are not. I trust others on this decision more than myself. Update: I wrote this without refreshing my Browser, so all I wrote was before @Gozala chimed in who has a similar view on things as I have. I'm unsure if I want to have Buffers on Node,js and TypedArrays in the Browser. This sounds like it would introduce a new class of possible bugs. Whenever I work on js-ipld/ipfs I always hope that if it works on Node.js that it also works in the Browser automatically. If it doesn't, it's a huge pain. Hence I'd be in favour of going full modern JS and not using Node.js Buffers. I see IPFS/IPLD JS implementations sweet spot in Browsers, not on the server-side. That's what we have the Go implementation for. Therefore I'd really like to do a Browser-first approach and also make sure that all our libraries work on the Browser (and tested there). For users of our libraries that work with Node.js Buffers, we could have recommended libraries (or our own) to convert from Buffers to/from Uint8Arrays. |
Ya, but it’s not global like it is in the Browser, so most browser code that uses it still fails :( |
It is in Node.js 12: $ node
Welcome to Node.js v12.6.0.
Type ".help" for more information.
> new TextEncoder()
TextEncoder { encoding: 'utf-8' } |
Finally! Once 12 goes LTS this will be a big help. |
We removed node Buffers from our APIs with #3220 (though some underlying modules still return them) and only support Node 12+. I'm going to close this because the approach we've settled on is to use Uint8Arrays everywhere (where the code is under our control). Please reopen if you think this needs further discussion. |
I’d like to document a problem we have across the
js-ipfs
code base and in most of the dependencies, including IPLD, and start a discussion about what we might do to resolve it.Node.js has its own binary API,
Buffer
, which is not in the Browser. This means that, when we hand peopleBuffer
instances in the browser they can’t use them with any Browser APIs. When you use theBuffer
API in your code, bundlers will inject a sizable polyfill.The Browser is kind of a mess when it comes to Binary. There’s a couple dozen types and interfaces just for representing binary, then a few more APIs that aren’t in Node.js at all for converting to/from strings (btoa, atob, TextEncoder and TextDecoder). Not to mention that there’s no out-of-the-box comparison or sorting tools.
It’s sort of an open question right now in modern JS what the “right thing” to do is. Ideally, a JS module that works with binary would:
Uint8Array
in browsers,Buffer
in Node.js).Buffer
polyfill when run through a bundler.This is quite difficult to do by hand and there aren’t any libraries that do a decent job at solving this without writing another binary API which itself contributes to the bundle size.
I’ve come up with a new approach and a library to try and help called
bytesish
. The basic idea is, we can get aDataView
for all Binary types without a memcopy. So the library only helps you to create, compare, and convert various binary types toDataView
and, potentially, back to “native.” So the usage is something like:Using separate entry points for Node.js and the Browser it avoids adding a
Buffer
polyfill and has zero deps so the size it ads to a bundle is quite small.I’d like to know what people think of this approach. If it seems like the right way forward I’ll take the time to update the IPLD libraries to follow this approach.
The text was updated successfully, but these errors were encountered: