#  > The shared editing library Yjs is a library for automatic conflict resolution on shared state. It implements an [operation-based CRDT](#Yjs-CRDT-Algorithm) and exposes its internal model as shared types. Shared types are common data types like `Map` or `Array` with superpowers: changes are automatically distributed to other peers and merged without merge conflicts. Yjs is **network agnostic** (p2p!), supports many existing **rich text editors**, **offline editing**, **version snapshots**, **shared cursors**, and encodes update messages using **binary protocol encoding**. * Chat: [https://gitter.im/y-js/yjs](https://gitter.im/y-js/yjs) * Demos: [https://github.com/y-js/yjs-demos](https://github.com/y-js/yjs-demos) * API Docs: [https://yjs.website/](https://yjs.website/) # Table of Contents * [Overview](#Overview) * [Bindings](#Bindings) * [Providers](#Providers) * [Getting Started](#Getting-Started) * [API](#API) * [Transaction](#Transaction) * [Offline Editing](#Offline-Editing) * [Awareness](#Awareness) * [Working with Yjs](#Working-with-Yjs) * [Typescript Declarations](#Typescript-Declarations) * [Binary Protocols](#Binary-Protocols) * [Sync Protocol](#Sync-Protocols) * [Awareness Protocol](#Awareness-Protocols) * [Auth Protocol](#Auth-Protocol) * [Yjs CRDT Algorithm](#Yjs-CRDT-Algorithm) * [Evaluation](#Evaluation) * [Existing shared editing libraries](#Exisisting-Javascript-Products) * [CRDT Algorithms](#CRDT-Algorithms) * [Comparison of CRDT with OT](#Comparing-CRDT-with-OT) * [Comparison of CRDT Algorithms](#Comparing-CRDT-Algorithms) * [Comparison of Yjs with other Implementations](#Comparing-Yjs-with-other-Implementations) * [License and Author](#License-and-Author) ## Overview This repository contains a collection of shared types that can be observed for changes and manipulated concurrently. Network functionality and two-way-bindings are implemented in separate modules. ### Bindings | Name | Cursors | Binding | Demo | |---|:-:|---|---| | [ProseMirror](https://prosemirror.net/) | ✔ | [y-prosemirror](http://github.com/y-js/y-prosemirror) | [link](https://yjs.website/tutorial-prosemirror.html) | | [Quill](https://quilljs.com/) | | [y-quill](http://github.com/y-js/y-quill) | [link](https://yjs.website/tutorial-quill.html) | | [CodeMirror](https://codemirror.net/) | ✔ | [y-codemirror](http://github.com/y-js/y-codemirror) | [link](https://yjs.website/tutorial-codemirror.html) | | [Ace](https://ace.c9.io/) | | [y-ace](http://github.com/y-js/y-ace) | [link]() | | [Monaco](https://microsoft.github.io/monaco-editor/) | | [y-monaco](http://github.com/y-js/y-monaco) | [link]() | ### Providers Setting up the communication between clients, managing awareness information, and storing shared data for offline usage is quite a hassle. **Providers** manage all that for you and are a good off-the-shelf solution.
A shareable Array-like type that supports efficient insert/delete of elements at any position. Internally it uses a linked list of Arrays that is split when necessary.
const yarray = new Y.Array()
insert(index:number, content:Array<object|string|number|Y.Type>)
array.insert(0, [1]
splices the list and inserts 1 at position 0.
push(Array<Object|Array|string|number|Y.Type>)
delete(index:number, length:number)
get(index:number)
length:number
map(function(T, number, YArray):M):Array<M>
toArray():Array<Object|Array|string|number|Y.Type>
toJSON():Array<Object|Array|string|number>
toJSON
method.[Symbol.Iterator]
for (let value of yarray) { .. }
observe(function(YArrayEvent, Transaction):void)
unobserve(function(YArrayEvent, Transaction):void)
observe
event listener from this type.
observeDeep(function(Array<YEvent>, Transaction):void)
unobserveDeep(function(Array<YEvent>, Transaction):void)
observeDeep
event listener from this type.
A shareable Map type.
const ymap = new Y.Map()
get(key:string):object|string|number|Y.Type
set(key:string, value:object|string|number|Y.Type)
delete(key:string)
has(key:string):boolean
get(index:number)
toJSON():Object<string, Object|Array|string|number>
[key,value]
pairs of this YMap to a new Object. It transforms all child types to JSON using their toJSON
method.[Symbol.Iterator]
[key, value]
pairs.
for (let [key, value] of ymap) { .. }
entries()
[key, value]
pairs.
values()
keys()
observe(function(YMapEvent, Transaction):void)
unobserve(function(YMapEvent, Transaction):void)
observe
event listener from this type.
observeDeep(function(Array<YEvent>, Transaction):void)
unobserveDeep(function(Array<YEvent>, Transaction):void)
observeDeep
event listener from this type.
A shareable type that is optimized for shared editing on text. It allows to assign properties to ranges in the text. This makes it possible to implement rich-text bindings to this type.
This type can also be transformed to the delta format. Similarly the YTextEvents compute changes as deltas.
const ytext = new Y.Text()
insert(index:number, content:string, [formattingAttributes:Object<string,string>])
ytext.insert(0, 'bold text', { bold: true })
delete(index:number, length:number)
format(index:number, length:number, formattingAttributes:Object<string,string>)
applyDelta(delta)
length:number
toString():string
toJSON():string
toString
toDelta():Delta
observe(function(YTextEvent, Transaction):void)
unobserve(function(YTextEvent, Transaction):void)
observe
event listener from this type.
observeDeep(function(Array<YEvent>, Transaction):void)
unobserveDeep(function(Array<YEvent>, Transaction):void)
observeDeep
event listener from this type.
A container that holds an Array of Y.XmlElements.
const yxml = new Y.XmlFragment()
insert(index:number, content:Array<Y.XmlElement|Y.XmlText>)
delete(index:number, length:number)
get(index:number)
length:number
toArray():Array<Y.XmlElement|Y.XmlText>
toDOM():DocumentFragment
toString():string
toJSON():string
toString
.observe(function(YXmlEvent, Transaction):void)
unobserve(function(YXmlEvent, Transaction):void)
observe
event listener from this type.
observeDeep(function(Array<YEvent>, Transaction):void)
unobserveDeep(function(Array<YEvent>, Transaction):void)
observeDeep
event listener from this type.
A shareable type that represents an XML Element. It has a nodeName
, attributes, and a list of children. But it makes no effort to validate its content and be actually XML compliant.
const yxml = new Y.XmlElement()
insert(index:number, content:Array<Y.XmlElement|Y.XmlText>)
delete(index:number, length:number)
get(index:number)
length:number
setAttribute(attributeName:string, attributeValue:string)
removeAttribute(attributeName:string)
getAttribute(attributeName:string):string
getAttributes(attributeName:string):Object<string,string>
toArray():Array<Y.XmlElement|Y.XmlText>
toDOM():Element
toString():string
toJSON():string
toString
.observe(function(YXmlEvent, Transaction):void)
unobserve(function(YXmlEvent, Transaction):void)
observe
event listener from this type.
observeDeep(function(Array<YEvent>, Transaction):void)
unobserveDeep(function(Array<YEvent>, Transaction):void)
observeDeep
event listener from this type.