WOOT with Scala.js
- Collaborative text editing, using the WOOT algorithm.
For the Impatient
$ sbt server/run
Then open http://127.0.0.1:8080/ to edit a document.
Open another browser at the same address, and you'll get the idea of collaboration.
What is WOOT?
WOOT is a collaborative text editing algorithm, allowing multiple users ("sites") to insert or delete characters (
WChar) from a shared document (
WString). The algorithm preserves the intention of users, and ensures that the text converges to the same state for all users.
Its key properties are simplicity, and avoiding the need for a reliable network or vector clocks (it can be peer-to-peer).
The key references are:
Oster et al. (2005) Real time group editors without Operational transformation, report paper 5580, INRIA - PDF
Oster et al. (2006) Data Consistency for P2P Collaborative Editing, CSCW'06 - PDF
WOOT stands for With Out Operational Transforms.
WOOT is only the algorithm for text consistency. You need to bring your own editor and network layer.
This example includes the ACE editor, which is wired up to the Scala.js implementation of WOOT locally within the browser. Updates are sent over a web socket to a http4s server which also maintains a copy of the model, but on the JVM.
This is a simple implementation that is slow for bulk actions (e.g., paste and cut).
To improve performance you will want to:
- measure what's slow for your scenarios
- batch messages between client and server (maybe)
- optimize the
I may get round to doing this at some point!
What Happens When You Run the Web Server
Running the sever code will likely produce:
$ sbt "project server" run [info] Loading global plugins from ... [info] Loading project definition from wootjs/project/project [info] Loading project definition from wootjs/project [info] Set current project to woot [info] Set current project to woot-server [info] Fast optimizing wootjs/client/target/scala-2.11/woot-client-fastopt.js [info] Running Main 2015-04-08 13:43:52 [run-main-0] INFO WootServer - Starting Http4s-blaze WootServer on '0.0.0.0:8080' ...
This reflects the structure of the project:
Exploring the Code
- editor.js creates a local instance of the "woot client" and kicks off the web socket interactions.
- server/src/main/scala/main.scala is the server that accepts and broadcasts WOOT operations to clients.
The tests for this project are implemented as ScalaCheck properties.
Running the tests in the JVM
sbt> project wootModelJVM sbt> coverage sbt> test
Then open wootModel/jvm/target/scala-2.11/scoverage-report/index.html
Publishing Woot Model
- Follow bintray-sbt publishing instructions
It will now be available with
resolvers += "<repo-name>" at "http://dl.bintray.com/content/<repo-name>/maven", libraryDependencies += "com.dallaway.richard" %%% "woot-model" % "<current-version>",
- Semantics of Scala.js - exceptions to the rule that Scala.js prorgrams behave the same as Scala on the JVM.
- http4s - the server used in this demo.
Scala.js Learning Path
If you're new to Scala:
- Creative Scala - a free course from Underscore teaching Scala using drawing primitives backed by Scala.js.
Copyright 2015 Richard Dallaway
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.