v0.9.0
v0.9.0 is a pretty significant release, including several neat new convenience features, but most noticeably, significantly reworking how linking works.
Almost any code that deals with storing and linking data will need some adaptation to handle this release.
We're sorry about the effort this may require, but it should be worth it.
The new LinkSystem API should let us introduce a lot more convenience features in the future, and do so without pushing additional breakage out to downstream users; this is an investment in the future.
The bullet points below contain all the fun details.
Note that a v0.8.0 release version has been skipped.
We use odd numbers to indicate the existence of significant changes;
and while usually we try to tag an even-number release between each odd number release so that migrations can be smoothed out,
in this case there simply weren't enough interesting points in between to be worth doing so.
- Change: linking has been significantly reworked, and now primarily works through the
ipld.LinkSystemtype.- This is cool, because it makes a lot of things less circuitous. Previously, working with links was a complicated combination of Loader and Storer functions, the Link interface contained the Load method, it was just... complicated to figure out where to start. Now, the answer is simple and constant: "Start with LinkSystem". Clearer to use; clearer to document; and also coincidentally a lot clearer to develop for, internally.
- The PR can be found here: #143
Link.Load->LinkSystem.Load(or, new:LinkSystem.Fill, which lets you control memory allocation more explicitly).LinkBuilder.Build->LinkSystem.Store.LinkSystem.ComputeLinkis a new feature that produces a Link without needing to store the data anywhere.- The
ipld.Loaderfunction is now most analogous toipld.BlockReadOpener. You now put it into use by assigning it to aLinkLoader'sStorageReadOpenerfield. - The
ipld.Storerfunction is now most analogous toipld.BlockWriteOpener. You now put it into use by assigning it to aLinkLoader'sStorageWriteOpenerfield. - 99% of the time, you'll probably start with
linking/cid.DefaultLinkSystem(). You can assign to fields of this to customize it further, but it'll get you started with multihashes and multicodecs and all the behavior you expect when working with CIDs.- (So, no -- the
cidlinkpackage hasn't gone anywhere. Hopefully it's a bit less obtrusive now, but it's still here.)
- (So, no -- the
- The
traversalpackage'sConfigstruct now uses aLinkSysteminstead of aLoaderandStorerpair, as you would now probably expect.- If you had code that was also previously passing around
LoaderandStorer, it's likely a similar pattern of change will be the right direction for that code.
- If you had code that was also previously passing around
- In the future, further improvements will come from this: we're now much, much closer to making a bunch of transitive dependencies become optional (especially, various hashers, which currently, whenever you pull in the
linking/cidpackage, come due togo-cid, and are quite large). When these improvements land (again, they're not in this release), you'll need to update your applications to import hashers you need if they're not in the golang standard library. For now: there's no change.
- Change: multicodec registration is now in the
go-ipld-prime/multicodecpackage.- Previously, this registry was in the
linking/cidpackage. These things are now better decoupled. - This will require packages which register codecs to make some very small updates: e.g.
s/cidlink.RegisterMulticodecDecoder/multicodec.RegisterDecoder/, and correspondingly, update the package imports at the top of the file.
- Previously, this registry was in the
- New: some pre-made storage options (e.g. satisfying the
ipld.StorageReadOpenerandipld.StorageWriteOpenerfunction interfaces) have appeared! Find these in thego-ipld-prime/storagepackage.- Currently this only includes a simple in-memory storage option. This may be useful for testing and examples, but probably not much else :)
- These are mostly intended to be illustrative. You should still expect to find better storage mechanisms in other repos.
- Change: some function names in codec packages are ever-so-slightly updated. (They're verbs now, instead of nouns, which makes sense because they're functions. I have no idea what I was thinking with the previous naming. Sorry.)
s/dagjson.Decoder/dagjson.Decode/gs/dagjson.Decoder/dagjson.Encode/gs/dagcbor.Decoder/dagcbor.Decode/gs/dagcbor.Encoder/dagcbor.Encode/g- If you've only been using these indirectly, via their multicodec indicators, you won't have to update anything at all to account for this change.
- New: several new forms of helpers to make it syntactically easy to create new IPLD data trees with golang code!
- Check out the
go-ipld-prime/fluent/quippackage! See #134, where it was introduced, for more details. - Check out the
go-ipld-prime/fluent/qppackage! See #138, where it was introduced, for more details. - Both of these offer variations on
fluentwhich have much lower costs to use. (fluentincurs allocations during operation, which has a noticable impact on performance if used in a "hot" code path. Neither of these two new solutions do!) - For now, both
quipandqpwill be maintained. They have similar goals, but different syntaxes. If one is shown drastically more popular over time, we might begin to consider deprecating one in favor of the other, but we'll need lots of data before considering that. - We won't be removing the
fluentpackage anytime soon, but we probably wouldn't recommend building new stuff on it.qpandquipare both drastically preferable for performance reasons.
- Check out the
- New: there is now an interface called
ipld.ADLwhich can be used for a certain kind of feature detection.- This is an experimental new concept and likely subject to change.
- The one key trait we've found all ADLs tend to share right now is that they have a "synthesized" view and "substrate" view of their data. So: the
ipld.ADLinterface states that a thing is anipld.Node(for the synthesized view), and from it you should be able to access aSubstrate() ipld.Node, and that's about it.