ondras / my-mind

Online Mindmapping Software
https://my-mind.github.io
MIT License
3.29k stars 650 forks source link

Real-time process #136

Open clodion opened 2 years ago

clodion commented 2 years ago

Hi Ondras, what a great job!! After looking at so many mind maps on the web i find your job as the best one available. well done!

I have a question because i would like to make it real-time possible without using firebase. I would like to do it with websockets and an express node server, but i am not as good as you are on programming. Someone tried to do the same, but i can't understand how to install its software (TQmindmap) So i have difficulties in reading the code.

What is the technology you used for real-timing your mindmap. ?

I first thought to send the changes made on one node from the user who changes the node to all users and update the same node on the map for everybody, but I read that you would have chosen another technology to update the map to everybody. Could you explain how you has done it with firebase ?

And then, which are the functions / objects used to exchange information between users ?

thanks to answer,

ondras commented 2 years ago

Hi @clodion,

thanks for your interest in My Mind! It should be noted that I am currently refatoring the codebase rather massively (see https://github.com/ondras/my-mind/issues/134), so the current code shape might change quite a bit in the following days and weeks.

I decided to pick Firebase as a synchronization medium, because they provided the storage and change-notification mechanism for free. If you want to implement that yourself, you will have to create the necessary server-side logic.

The current implementation:

1) every local change generates an app-wide event (pubsub message) "item-change" 2) this event is listened to by the UI.Backend.Firebase object 3) this leads to the mergeWith call in Backend.Firebase 4) which finally recursively merges current Map data with the server-side copy, publishing the updated map object to Firebase

Which brings use to the corresponding remote change that is auto-magically published (Firebase) to all other listening clients:

1) the Firebase client JS lib listens to any changes of remote data 2) once this happens, local "firebase-change" event (pubsub message) is generated 3) the UI.Backend.Firebase object listens for this event, retrieves current remote version of the data and calls the Map.prototype.mergeWith function 4) the map does the actual merging (of remote-to-local data) by recursively calling mergeWith on individual MM.Item instances (those correspond to map nodes); these then update their visualization accordingly.

clodion commented 2 years ago

Thanks so much for this detailed process description. Just one more thing to be very clear : does the merge function get ALL the map data to do its comparison or does it get only the data depending on the node (the item) which has just been changed ?

ondras commented 2 years ago

does the merge function get ALL the map data

Yes. It always gets the whole remote map data. The remote data is retrieved via the val() call on the top-level firebase ref; this retrieves the complete object.

Note that some operations cannot be expressed as a per-node change: if you move around a whole subtree, you basically change the whole structure (in one action). So merging the whole map is the safest option.