Efficient interface when combined with CRDT
Thank you for publishing such an interesting library.
I have created a sample collaborative editing feature by combining your js-draw with Yjs. https://y-phoenix.gigalixirapp.com/js-draw
As you can see from the source code, the current method of obtaining differences is very inefficient.
To achieve this more efficiently, I need a way to determine the changes made when a user edits.
Additionally, I need a method to override the handlers for Undo/Redo so that they work on a per-user basis.
Thank you.
Thank you for your interest in js-draw!
Would it be possible to serialize commands instead of components? This is, for example, what's done in examples/example-collaborative, or, in a simpler form, in this part of the custom components guide.
Since I want to apply change diffs within Yjs, it’s simpler to synchronize the component state directly rather than sending commands. Handling change diffs with Yjs is essential because Yjs relies on them to function as a CRDT, one of its core features. This allows users to stay synchronized without a centralized server, ensuring a consistent final state.
While command serialization is possible, keeping the final state consistent would require tracking the order of command applications. If an earlier, unapplied command is received, we would need to revert the state to its previous stage before reapplying subsequent commands. This makes the process unnecessarily complex.
Therefore, instead of working with commands themselves, we need an interface that extracts the change diffs applied to the component as a result of executing a command.
https://y-phoenix.gigalixirapp.com/js-draw I have added a feature to display other users’ cursors. It would be great if objects being drawn by other users were also updated in real time. Is there a way to retrieve them?
Therefore, instead of working with commands themselves, we need an interface that extracts the change diffs applied to the component as a result of executing a command.
I've pushed an (~~unreleased~~ released in 1.29.0) commit that may help with this: https://github.com/personalizedrefrigerator/js-draw/commit/be429feb16d5cbdb20ced18cfb65a2297bc3400e. It adds ComponentAdded and ComponentRemoved events to the editor.image object, with the ID of the component that was added or removed.
It would be great if objects being drawn by other users were also updated in real time. Is there a way to retrieve them?
At present, this might be possible by replacing the default Pen tool with a subclass, but it might be a bit complicated. The Pen subclass would:
- override
previewStroke - In
previewStroke, callsuper.previewStroke. - Build a preview of the in-progress stroke using
this.builder.preview. Render to a custom SVGRenderer (or some other renderer type)..buildmight also work, but in some stroke builders, it changes the current state.
- Send the preview to other clients.