A little information on the side
mergeRemoteChanges purpose & name
I don’t find mergeRemoteChanges to be very intuitively named. It seems to be designed to reflect a use case of running tlDraw in multiple instances (even on different devices). In this kind of situation, changes by the user can be considered local to this instance, while changes by another user are coming from a remote instance.
However, that kind of use case is likely less common compared to simply wanting to make changes via code without firing listeners — Which I expect almost every project to do.
Tweaking the mergeRemoteChanges name
While I’ve become comfortable doing the mental gymnastics of using the word remote to mean not local user initiated (But including local code), if I ever stop working with tlDraw for a year or so, or if I need other people unfamiliar with the framework to make an edit, I don’t want either of us scratching our heads at the code for any longer than necessary.
Like my own variable and method names, I prefer when a framework uses names that are very clear as to their impact or meaning and accurately generalised. With framework APIs, however, mistakes or evolutions from early in development often can’t be changed later without unnecessarily making the framework more complex or introducing breaking changes.
But as users of the framework, we can create a helper function that wraps mergeRemoteChanges so that it’s more understandable in our codebase.
I made two.
export const silentlyChangeStore = (editor: Editor, func: () => void) => {
editor.store.mergeRemoteChanges(func)
}
export const silentlyChangeStoreAsync = async (editor: Editor, func: () => void) => {
editor.store.mergeRemoteChanges(func)
}
Here’s the example from above replaced with one of these functions:
function ReactComponent() {
const runMyCameraPostProcess = function(editor, entry) {
const someCoords = getRelevantCoords(entry);
silentlyChangeStore( editor, () = {
editor.setCamera(someCoords);
});
}
const handleTldrawMount = (editor) => {
editor.store.listen( (entry) => {
runMyCameraPostProcess(editor);
})
}
return %3CTldraw
onMount = {handleTldrawMount}
/>;
}