OK, well after further learning and testing, I'm not yet convinced that Gun.js will be usable easily as a context store.
You cannot actually "delete" anything.
You can only set an element to null. I've not actually tried to see whether setting something to null will be sufficient to work within the context API.
Even if this does work with the context API, it would only be useful if using 2.2 below. That is because all sub-elements in the hierarchy are retained, not deleted. All that Gun.js does is to break the chain, not actually delete anything.
You cannot store array's
Which means that you cannot directly trust Gun.js to store an arbitrary JavaScript object.
Two possible workarounds:
2.1. Serialise the object using JSON.stringify
2.2. Walk through the full hierarchy converting arrays using set
Of these only 2.1 is realistic and should be in keeping with the context storage principals.
The get-once node (now called "Gun: Out" in the palette) is pretty much there and should be quite usable. Just cosmetics left to tweak along with some more useful help. Also need to allow the path to be set from the input msg.topic.
The put node ("Gun: Update" in the palette) is also mainly ready and should be quite usable. However, as yet, you cannot set the update path from an input message, only the payload. This will be fixed soon.
The get node ("Gun: Listen") needs a few tweaks to bring it into line with the get-once node. Missing a couple of options and may not work entirely correctly yet.
The Readme as been updated and shows an overview of what is outstanding for each node and also gives an idea of what could be on the roadmap.
Please test and let me know what is broken. Then let me know what needs tweaking. Finally, let me know what is missing and what you would find useful.
Note that, in this release, the Gun.js data has been moved. Please look for any folders called "radata" and delete those as they will no longer be used. The data is now stored at <userDir>/_gun.
This version is MUCH better than previous ones. A lot more robust and handles a few more of the many oddities in Gun.js.
One or two things left to do before the release of v0.1.0 to npm so please do let me know if you find any issues.
The README has now been updated and should tell you everything you need to know about the nodes and some of the oddities of Gun.js.
Left to do before v0.1:
At the moment, there is only a single location for the Gun database so I am not sure what happens if you create a second config and try to use both. I am going to change this to make sure they keep their data separate.
Anything else will probably wait until v0.2
Check out the git commits for an overview of the changes.
Nice work!
Thanks so much for taking the time to do this, I'm sure a lot of people will find a use for it!
This is indeed a nice upgrade from the previous version. The new docs are a really nice upgrade too
The only suggestion that comes to mind at the moment is regarding the use of the word 'soul' in the nodes, which in my opinion does not quite align with how a soul is defined in the Gun docs. Here's the Gun docs definition.
Basically the soul is the unique ID of an object in the Gun DB, and may look something like this: eJgh6QkdhlFs8Ed.
In the nodes, the word 'soul' is used as follows:
"The output topic is set to the "soul", e.g. the whole path to the returned data."
I would prefer to see the word 'soul' dropped altogether in favour of 'path', as the user never has to worry about the soul (as defined in the docs that is), only the path.
Edit 1:
Actually, I just thought of another suggestion:
Perhaps it would be useful to add the location of the local DB store as descriptive text in the config node.
Hmm, to me a unique identifier in a hierarchical db would be the whole path and that is how I interpreted it. But I can see that you are right. Looks like the nodes will lose their soul then! I blame you
Path it is.
Yes, already had that in mind. I did a couple of tests with multiple instances of the config node and the results are somewhat odd - no surprises there, lots of Gun.js is odd. While Node-RED is running, the instances stay separate. But as soon as you restart the data from the two instances is merged. Definitely not an outcome we will want.
So rest assured that I will add some code to prevent separate instances from being in the same folder. There are some tricky edge-cases to think through though. Like you creating one instance and then a second before committing them. So I will probably create an API that keeps track of all folders and prevents reuse. I also need to add an option to delete the folder when deleting the config node.
What would be the easiest strategy in your opinion to delete (tombstone) values using the nodes?
My testing seems to indicate that the nodes cling on to the path passed on to them by the first message they get with a path in the msg.topic. Differing msg.topic paths that follow seem to be ignored and the initially passed path is reused. IS this the same for other people testing?
Hmm, not actually tested that I don't think. Certainly not right. I've probably got a check in the wrong place. Any chance you could create a quick issue so that I don't forget? Rather a lot on at the moment.
I don't think I have an answer to that right now as I'm not convinced I actually understand what the heck goes on in Gunjs for tombstoning. It appears that if you send a null to a path, that specific path is tombstoned but everything beneath it is still there and accessible, you just can't walk the tree to get there. To me this seems crazy and must surely result in some really nasty side-effects in real-world use - such as retaining out-of-date data which could easily come back into play if the tombstoned path were reconstituted.
I kind of understand why they did it and they've focussed on performance over data consistency. But it is one of the many issues with Gunjs that means you need to be really careful when using it. If you don't understand the subtleties of the way it works, it WILL bite you badly.
So to directly answer your question, you should be able to send a null to a specific path and it should do what Gunjs wants to do. Please let me know if it doesn't.
Just be aware that the put/set node does touch every node along the given path to try and avoid another Gunjs oddity where you use a single get with a compound path (e.g. db/node1/node2/) followed by a put, the intermediate nodes that you expect are not created. So in the case of the put/set node, I do a get for every stage of the path in order to ensure that Gunjs realises that they are real nodes.
Thanks. Don't forget to test manually as well though. I spotted a few issues that way and I think I left a test script in the package so you can look there for examples. That way, we know whether it is the logic in the node that is wrong or whether it is just the way that Gunjs works.