Collaborative Editing & Monaco

 Introduction

I love Visual Studio Code and I use it everyday. Visual Studio Code uses Monaco as it’s code editor.

Monaco is a really impressive code editor with some amazing features. One of the best features is really how fast it feels. Here is a HN discussion about why Monaco is really really fast. As i started to experiment with the editor more, I realized how amazing it would be if someone used Monaco as the base of a new collaborative editor. Maybe, I should do it.

Thinking about this problem a bit more, if I was going to build a collaborative editor it would need to have the following featureset:

 Choosing my backend

There are a couple of choices.

 Web Sockets / WebRTC

One approach is the use of Web Sockets / WebRTC, and operational transforms. I could use something like Socket.IO. The client could use the OT model of Monaco editor.

 Disadvantages

 Google Drive Realtime API

I could use the Google Drive Realtime APIs.

 Advantages

 Firebase Realtime Database and Firebase Cloud Fire Store

 Advantages

 Disadvantages

Looking at all the above options, I decided to go with Google Drive Realtime API, given that I get all the permissions management for free. The Firebase Cloud Fire Store API is another great option. It could be another alternative datastore that I could support in the future.

 Okay, Let’s really build this

I realized I need a couple of Cloud functions that will create new documents on Google Drive, using their REST API and annotate them with custom attributes, to help with discovering them.

The official documentation for Google Drive Realtime APIs stated that I need the https://www.googleapis.com/auth/drive scope. That was going to be too broad. So I figured out that I could use shortcut files. One shortcoming of shortcut files however, is they seem to get implicitly filtered by the Drive v3 list files API. So need to attach custom attributes that will help surface these files. Now i can finally use the less scary https://www.googleapis.com/auth/drive.file scope.

I started diving into Monaco editor, to understand the underlying editor model. I discovered Monaco exposes low level change events, that can be transformed into a set of changes that can be applied using the applyEdits API. I use the Google Realtime API to store these changes in Google Drive.

I had also fortunately authored AppAuth-JS. This is the library that I used to help the users log in, and request the drive scopes I need.

Once I got the basic mechanics of synchronizing changes working, I started to work on synchronizing cursor selections which turned into a slightly bigger challenge. I also had to synchronize selection invalidations and some spurious selections while editing a range. But eventually i got that working.

 Demo time

Here is a demo of all of this working.

 Try it out

Try it out here. For more information about the application take a look at this.

 Epilogue

 Google Drive Realtime API deprecation.

Google Drive Realtime APIs are now deprecated in favor of the Firebase platform (Firestore and the Realtime database). So I am in the middle of migrating my datastores at the moment.

 Video Editing / Recording

My apologies for the slight cold I had when i recorded the video.

 
12
Kudos
 
12
Kudos

Now read this

ProGuard and Debugging

Android’s infamous dex limit is a huge problem. One of the ways you can fix the problem is to use ProGuard. If you decide to use it, the you can look forward to 2 things. Longer build times. Not being able to debug your application,... Continue →