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.LinkSystem
type.- 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.ComputeLink
is a new feature that produces a Link without needing to store the data anywhere.- The
ipld.Loader
function is now most analogous toipld.BlockReadOpener
. You now put it into use by assigning it to aLinkLoader
'sStorageReadOpener
field. - The
ipld.Storer
function is now most analogous toipld.BlockWriteOpener
. You now put it into use by assigning it to aLinkLoader
'sStorageWriteOpener
field. - 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
cidlink
package hasn't gone anywhere. Hopefully it's a bit less obtrusive now, but it's still here.)
- (So, no -- the
- The
traversal
package'sConfig
struct now uses aLinkSystem
instead of aLoader
andStorer
pair, as you would now probably expect.- If you had code that was also previously passing around
Loader
andStorer
, 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/cid
package, 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/multicodec
package.- Previously, this registry was in the
linking/cid
package. 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.StorageReadOpener
andipld.StorageWriteOpener
function interfaces) have appeared! Find these in thego-ipld-prime/storage
package.- 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/g
s/dagjson.Decoder/dagjson.Encode/g
s/dagcbor.Decoder/dagcbor.Decode/g
s/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/quip
package! See #134, where it was introduced, for more details. - Check out the
go-ipld-prime/fluent/qp
package! See #138, where it was introduced, for more details. - Both of these offer variations on
fluent
which have much lower costs to use. (fluent
incurs 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
quip
andqp
will 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
fluent
package anytime soon, but we probably wouldn't recommend building new stuff on it.qp
andquip
are both drastically preferable for performance reasons.
- Check out the
- New: there is now an interface called
ipld.ADL
which 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.ADL
interface 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.