-
Notifications
You must be signed in to change notification settings - Fork 32
CIDs across the message channels #109
Description
In the context ipfs/js-ipfs#3022 I'm running into problem with CID
s that is not too dissimilar from ones that come from Buffer
s. I would like to bring those up here for a discussion.
Problem
When you post things across browsing contexts data browsers perform structured cloning which implies that only handful of things will come out with the same prototype chain on the other end. Including table from MDN below:
Supported types
Object type | Notes |
---|---|
All primitive types | However, not symbols. |
Boolean objects | |
String objects | |
Date | |
RegExp | lastIndex is not preserved. |
Blob |
|
File |
|
FileList |
|
ArrayBuffer | |
ArrayBufferView | Including other typed arrays. |
ImageBitmap |
|
ImageData |
|
Array | |
Object | Only plain objects (e.g. from object literals) |
Map | |
Set |
This implies that node Buffer
s come out as Uint8Arrays
(as they are sub-classes) and CID
s come out as plain objects, that is following most of the time:
{
version: 0|1,
codec: string,
multihash: Uint8Array,
multibaseName: string
}
Which is problematic because e.g. dag-cbor encoder will not recognize such structures as CID
and would encode it as JSON. In other words only way for things to work across message-channel we need either to:
-
DeepCopy+Encode -> Structure Clone -> Traverse+Decode
- Sender needs to deep-copy arbitrary data structures to swap CIDs with some encoded version.
- Which browser will structure clone (another copy).
- Receiver needs to traverse inputs to find endoced CIDs and swap those with decoded instances (I think copying can be avoided here)
-
Structure Clone -> Traverse+Decode
- CID class can be made recognizable to remove need for deep-copy + CID encoding.
- Browser will structure clone.
- Receiver will traverse inputs to find structure cloned CIDs and swap those with decoded instances
Neither of two is ideal. What would be much better if CID
had a canonical representation that is not tied to specific class. Kind of how ArrayBuffer
represents bytes and Uint8Array
is just a view.
I am recognizing that this might be almost impossible change to make at this point, however it is still worse having a discussion I think. Furthermore there might be certain compromises that may provide workable compromise. E.g. if all the IPFS internals did recognized canonical representation which is not tied to CID class that would remove need for decode / encode at least on messages going from client to server. I can also imagine that new Block
API might be made to recognize that canonical representation which would effectively remove need for arbitrary traversals and limit CID encode / decode to very specific API endpoints.