amark / gun

An open source cybersecurity protocol for syncing decentralized graph data.
https://gun.eco/docs
Other
17.96k stars 1.16k forks source link

[Question] setting an empty object does not trigger any event handlers? #1319

Open rozek opened 1 year ago

rozek commented 1 year ago

Hello!

I'm currently trying to learn how to use Gun - please forgive me if my question turns out to be nonsense (or has been documented somewhere, but I missed that)

I know that setting a shared object triggers an event handler

let sharedData = Gun.get('sharingTest').get('sharedData')
sharedData.on((Data) => { console.log(JSON.stringified(Data)) }
sharedData.put('Test') // outputs "Test"

This works for null, booleans, numbers, strings and (non-empty) objects.

However, if I set an empty object, the event handler is not triggered

sharedData.put({}) // outputs nothing

Is this intended? sharedData seems to have been changed successfully, but I can't even retrieve this value using

Gun.get('sharingTest').get('sharedData').once((Data) => {
  console.log(JSON.stringified(Data)) // gets never called
})

which is strange since an empty object is still an object - and setting s.th. to null does very well trigger an event handler...

rozek commented 1 year ago

Ah, I got s.th.:

Sorry for bothering you!

rozek commented 1 year ago

I'm completely lost...

what I did:

the last step shows that the previous contents (namely { a:'a' }) reappear again - although I previously successfully overwrote the node with a primitive!

How can that be? I am not yet using any relay - everything works locally only (albeit with "localStorage" in the background, if I understood the concepts correctly)

amark commented 1 year ago

{} is an empty set, so if it is merging into an existing object then no actual change occurs, however I do believe the lower level events get fired, but .on( etc. dedups it.

if you overwrite something with a primitive, then re-save an object to it... it'll re-generate the same deterministic soul on that path, thus it'll "re-find" the old data.

var newNode = gun.get("randomID").put({b: 'b'}); sharedData.put(newNode); will force a different node onto it, overwriting the previous and NOT re-merging with a previous node. But note: This can lead to disparity in offline apps if this happens a lot, as offline apps might not generate the same "location" to converge too.

rozek commented 1 year ago

Thank you very much for your explanation.

However, I somewhere found the "recipe" to first nullify an object and then to write a new one using the same context (I have to find where, but I'm really lost in the jungle of overlapping doc sections and wiki pages...). This recipe would contradict your explanation then.