Spec out DagPB path resolution
Currently, we're playing it fast-and-loose with DagPB path resolution. For context, the structure of DagPB IPLD objects is currently defined to be:
{
"Data": "binary data",
"Links": [
{
"Name": "thing", // may not be unique, may be omitted
"Tsize": 1234, // may be omitted
"Hash": "QmId"
}
]
}
Given this structure, the correct path to QmId would be /Links/0/Hash. However, this isn't very usable.
-
js-ipfs actually supports this pathing scheme. However, it also supports pathing by name (
/Links/thing/Hash). While nice and usable, this is technically transforming the object. -
go-ipfs uses the pathing scheme
/thing. That is, it treats the object as if it were a single map of names to CIDs (for the purposes of pathing). This is obviously problematic from an IPLD standpoint as many of the fields aren't addressable.
So, we need a scheme that's both consistent between implementations and consistent with other IPLD formats.
Given that we're basically the only real consumer of this format, I believe we have a bit of flexibility.
By the way, @diasdavid, your code organization is :100:. (despite the fact that you're using JavaScript)
Proposal: Simplicity over UX
Given that others are, hopefully at least, not using this format, we could just say that all paths must use link indices. We'll need to write a helper function to resolve named links.
Proposal: Named xor Unnamed
If we require that all links in an object either be named or unnamed, we can redefine the structure to either have a map of link names to links or an array of unnamed links. The question is, do we ever mix named links with unnamed links?
Re /Links/thing/Hash, I don't believe this is possible in the current js-ipld-dag-pb. I supports /thing and /Links/0/Hash style. (I can't find a historical version that shows clearly that /Links/thing/Hash was actually supported tbh).
So with them both supporting /thing, an easy fix might to be to define that, plus the /Links/0/Hash style as the way, then implement /Links/0/Hash in he Go implementation, then they'd be unified and there will be peace in the world, no?
So with them both supporting
/thing, an easy fix might to be to define that, plus the/Links/0/Hashstyle as the way, then implement/Links/0/Hashin he Go implementation, then they'd be unified and there will be peace in the world, no?
The biggest issue here is that you then can't path through named links named "Links" or "Data".
Hence I propose (that's from a JS perspective as we have this clear distinction here, not sure about the Go side): IPLD only implements pathing on the structure aka /Links/<index>/Hash. The named pathing only exists on the IPFS level.
By default the DAG API will only support the structured pathing (this would be a breaking change for go-ipfs). Though we could still allow /**ipfs**/Qmid… paths in those APIs that would allow currently implemented way of pathing from go-ipfs.
There will be no way to combine the pathing of both ways. This way there won't be a naming conflict and you can even path through named linkes called "Links".
Hence I propose (that's from a JS perspective as we have this clear distinction here, not sure about the Go side): IPLD only implements pathing on the structure aka /Links/
/Hash. The named pathing only exists on the IPFS level.
These 2 levels were once called resolvers and transformations and both were part of IPLD.
The biggest issue here is that you then can't path through named links named "Links" or "Data".
seems to me that (a) this hasn't been a problem discovered by JS consumers and (b) if we're really the only consumer, via IPFS + UnixFSv1, then it doesn't really matter as long as IPFS doesn't need a link named Links then it's just fine.
Wouldn't it be a more traumatic exercise to rip out /named support from Go than to add /Links/x/named as an optional - they're both technically breaking changes, but the latter is only breaking for links named Links?
seems to me that (a) this hasn't been a problem discovered by JS consumers and (b) if we're really the only consumer, via IPFS + UnixFSv1, then it doesn't really matter as long as IPFS doesn't need a link named
Linksthen it's just fine.
If you add a directory called Links into IPFS you will have a link with name Links. This e.g. breaks the Explorer in the WebUI when you use js-ipfs. Browsing it as files and retrieving it via the CLI works, just just can't use named links via the DAG API.
/named support in Go would still be there, just under the /ipfs namespace. To me having no support for named links within IPLD sounds more correct based on what IPLD is like today.