Skip to content

Implement CID.asCID and depracte CID.isCID #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 17, 2020

Conversation

Gozala
Copy link
Contributor

@Gozala Gozala commented Jul 14, 2020

This change builds upon #18 as per discussion at multiformats/js-cid#111.

It does following:

  • Introduces .asCID property that points to the CID instance that has it. This is a unique (enough) marker to distinguish CID values form other values.
    • Unlike [Symbol.for('@ipld/js-cid/CID')] marker this:
      • Marker is preserved when CID is moved across JS realms / threads (so CIDs could be identified on receiver end without sender having to do any work).
  • Introduces CID.asCID static method as a replacement for CID.isCID, which improves following:
    • Two incompatible versions of CID library could co-exist and inter-op (as long as binary interface doesn't change)
    • Code (codecs) which migrate to CID.asCID will be able to work with CID instances from other threads without (receiver doing any work). Because const cid = CID.asCID(value) will return instance of this CID class.

--

Things I could use some help with:

  • Get rid of deprecation warnings in the test output (is there way to do this with mocha ?)
  • Test to verify that deprecation warning is printed. Related to above.
  • Test coverage complains about line 19. I'm not sure how to exercise that line. Is the whole warn or throw worth it ?

cid.js Outdated
}

static isCID (value) {
deprecate(/^0\.0/, `CID.isCID(v) is deprecated and will be removed in the next major release.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this string up to the top so that the indentation doesn’t flow backwards below?

@mikeal
Copy link
Contributor

mikeal commented Jul 15, 2020

So, first of all, I’m +1 on dropping class-is and we don’t have another PR for it so I’m fine with it being part of this PR. But for any future reviewers, that’s not really part of asCID but it is a change worth taking, so let’s take it.

For the record, I’m +1 on this change, but I think I need to spend some time explaining it for the benefit of others and for myself a month from now because I already got my head around this once and then forgot it.

Currently, we write code like this:

if (typeof value === ‘object’) {
  if (CID.isCID(value)) return handleLink(value)
  return handleObject(value)
}

Since isCID() uses a symbol check it works for different conflicting versions of the same CID class. This means that we assume the CID implementation the value is using is correct. Something that this refactoring of multiformats has done is made that a bit more problematic than it used to be because the toString() method of CID is limited to the multibase implementations that CID instance is bound to.

If you have a CID class you actually need link values to be of that specific class bound to that specific multiformats instance.

Separately, we have another issue with CID in both this implementation and js-cid with regard to Workers. Symbols don’t make it through the Worker boundary, so this method of detection has become problematic.

What @Gozala figured out, which is quite brilliant, is that all serialization libraries will choke on circular references, but circular references are preserved when passed to a Worker. This means that we can move to a method of detection that uses circular references, as we have done here, and we have a good way to preserve the type over the process boundary without introducing a property that could potentially conflict with real data when it passes over the Worker boundary.

This does mean we will need to migrate to writing code that looks more like.

if (typeof value === ‘object’) {
  const link = CID.asCID(value)
  if (link) return handleLink(link)
  return handleObject(value)
}

@Gozala
Copy link
Contributor Author

Gozala commented Jul 16, 2020

So, first of all, I’m +1 on dropping class-is and we don’t have another PR for it so I’m fine with it being part of this PR. But for any future reviewers, that’s not really part of asCID but it is a change worth taking, so let’s take it.

I actually thought of this. That is why removal of class-isis seperate commit. Here is the pull request to do that #24

@Gozala Gozala requested a review from mikeal July 16, 2020 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants