blake-regalia / graphy.js

A collection of RDF libraries for JavaScript
https://graphy.link/
ISC License
163 stars 4 forks source link

Can Graphy preserve and return the full original JS 'objects' used to build quads in a Dataset? #40

Closed pmcb55 closed 3 years ago

pmcb55 commented 3 years ago

I know this is asking a lot, but is there any way that Graphy could preserve and return the full original JavaScript 'objects' used to make up quads added to a Dataset? For instance, if I construct a BNode subject, but attach extra data to it, can I access that 'extra data' on that subject object when I later iterate over the quads in the dataset, like this:

      const dataset = dataset();

      // Creates a BlankNode, but with our stuff 'stuck on' - i.e., 'internal_name'
      // which is completely outside the RDF data model.
      const subjectLocal: LocalNode = Object.assign(DataFactory.blankNode(), {
        internal_name: "some-subject-name",
      });

      const quadWithLocalNode = DataFactory.quad(
          subjectLocal,
          DataFactory.namedNode("https://arbitrary.vocab/predicate"),
          DataFactory.namedNode("https://arbitrary.vocab/object"));

      dataset.add(quadWithLocalNode);

      for (const quad in dataset) {
         // Our code assumes that quad.subject here still has the 'stuck on' internal_name
         // value, but Graphy is re-constructing our quad for us, and so all our
         // extra stuff is gone!
     ****** quad.subject.internal_name IS UNDEFINED! *******
      }

Just to note that N3 does preserve and return the original JavaScript objects, as does @rdfjs/dataset (which, of course, is also incredibly inefficient!).

blake-regalia commented 3 years ago

The short answer is unfortunately no. The dataset implementation only stores a string for each term so the original Term object is effectively discarded. This is what gives the dataset both its performance and low memory consumption.

I have been developing a store that allows the user to attach data to each term or triple/quad, but that is for an HDT-like read-only dataset which requires preprocessing to create.

Depending on your use case, it might work to "bring-your-own" dictionary that simply stores user data keyed by the c1 string of the term. The only drawback would be that if a term is deleted from the dataset you would not know about it and the user data dictionary would remain bloated, which may or may not be an issue for your app depending on circumstances.

pmcb55 commented 3 years ago

Thanks for the super-quick response Blake - yeah, I thought it was a big ask alright :) ! I'll need to look at the bigger picture issues behind the initial ask here, and see if we can achieve the same objectives some other way - thanks again! Feel free to close this issue (although perhaps mentioning this behaviour in the documentation (e.g., given that it differs to N3 and @rdfjs/dataset) might be useful for others making the same assumptions we did :) ).