From e2f93af86e9dd207cb57d313c6ac305cd69e34d1 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Sat, 30 Apr 2016 23:00:23 +0100 Subject: [PATCH] added drawing example --- Examples/Drawing/index.html | 19 + Examples/Drawing/index.js | 88 + Examples/bower.json | 5 +- y.es6 | 4 +- y.es6.map | 2 +- y.js | 6698 ++++++++++++++++++++++++++++++++++- y.js.map | 2 +- 7 files changed, 6809 insertions(+), 9 deletions(-) create mode 100644 Examples/Drawing/index.html create mode 100644 Examples/Drawing/index.js diff --git a/Examples/Drawing/index.html b/Examples/Drawing/index.html new file mode 100644 index 00000000..75e4ed53 --- /dev/null +++ b/Examples/Drawing/index.html @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/Examples/Drawing/index.js b/Examples/Drawing/index.js new file mode 100644 index 00000000..6320ab55 --- /dev/null +++ b/Examples/Drawing/index.js @@ -0,0 +1,88 @@ +/* globals Y, d3 */ +'strict mode' + +Y({ + db: { + name: 'memory' + }, + connector: { + name: 'websockets-client', + room: 'drawing-example' + // url: 'localhost:1234' + }, + sourceDir: '/bower_components', + share: { + drawing: 'Array' + } +}).then(function (y) { + window.yDrawing = y + var drawing = y.share.drawing + var renderPath = d3.svg.line() + .x(function (d) { return d[0] }) + .y(function (d) { return d[1] }) + .interpolate('basis') + + var svg = d3.select('#drawingCanvas') + .call(d3.behavior.drag() + .on('dragstart', dragstart) + .on('drag', drag) + .on('dragend', dragend)) + + // create line from a shared array object and update the line when the array changes + function drawLine (yarray) { + var line = svg.append('path').datum(yarray.toArray()) + line.attr('d', renderPath) + yarray.observe(function (event) { + // we only implement insert events that are appended to the end of the array + event.values.forEach(function (value) { + line.datum().push(value) + }) + line.attr('d', renderPath) + }) + } + // call drawLine every time an array is appended + y.share.drawing.observe(function (event) { + if (event.type === 'insert') { + event.values().then(function (values) { + values.forEach(drawLine) + }) + } else { + // just remove all elements (thats what we do anyway) + svg.selectAll('path').remove() + } + }) + // draw all existing content + for (var i = 0; i < drawing.length; i++) { + drawing.get(i).then(drawLine) + } + + // clear canvas on request + document.querySelector('#clearDrawingCanvas').onclick = function () { + drawing.delete(0, drawing.length) + } + + var sharedLine = null + function dragstart () { + drawing.insert(drawing.length, [Y.Array]) + drawing.get(drawing.length - 1).then(function (array) { + sharedLine = array + }) + } + + // After one dragged event is recognized, we ignore them for 33ms. + var ignoreDrag = null + function drag () { + if (sharedLine != null && ignoreDrag == null) { + ignoreDrag = window.setTimeout(function () { + ignoreDrag = null + }, 33) + sharedLine.push([d3.mouse(this)]) + } + } + + function dragend () { + sharedLine = null + window.clearTimeout(ignoreDrag) + ignoreDrag = null + } +}) diff --git a/Examples/bower.json b/Examples/bower.json index 066ee76c..11f61c9f 100644 --- a/Examples/bower.json +++ b/Examples/bower.json @@ -18,10 +18,11 @@ "y-websockets-client": "latest", "y-text": "latest", "y-indexeddb": "latest", - "y-xml": "latest", + "y-xml": "latest", "quill": "~0.20.1", "ace": "~1.2.3", "ace-builds": "~1.2.3", - "jquery": "~2.2.2" + "jquery": "~2.2.2", + "d3": "^3.5.16" } } diff --git a/y.es6 b/y.es6 index 7e5c3cae..7700a638 100644 --- a/y.es6 +++ b/y.es6 @@ -2894,9 +2894,9 @@ module.exports = function (Y /* : any*/) { I tried to optimize this for performance, therefore no highlevel operations. */ class SmallLookupBuffer extends Store { - constructor (arg) { + constructor (arg1, arg2) { // super(...arguments) -- do this when this is supported by stable nodejs - super(arg) + super(arg1, arg2) this.writeBuffer = createEmptyOpsArray(5) this.readBuffer = createEmptyOpsArray(10) } diff --git a/y.es6.map b/y.es6.map index 51d57289..0e9a4c3b 100644 --- a/y.es6.map +++ b/y.es6.map @@ -1 +1 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","src/Connector.js","src/Connectors/Test.js","src/Database.js","src/Struct.js","src/Transaction.js","src/Utils.js","src/y.js"],"names":[],"mappings":"AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9eA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5kCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3bA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"y.es6","sourceRoot":"/source/","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o;\n whenSyncedListeners: Array;\n currentSyncTarget: ?UserId;\n syncingClients: Array;\n forwardToSyncingClients: boolean;\n debug: boolean;\n broadcastedHB: boolean;\n syncStep2: Promise;\n userId: UserId;\n send: Function;\n broadcast: Function;\n broadcastOpBuffer: Array;\n protocolVersion: number;\n */\n /*\n opts contains the following information:\n role : String Role of this client (\"master\" or \"slave\")\n userId : String Uniquely defines the user.\n debug: Boolean Whether to print debug messages (optional)\n */\n constructor (y, opts) {\n this.y = y\n if (opts == null) {\n opts = {}\n }\n if (opts.role == null || opts.role === 'master') {\n this.role = 'master'\n } else if (opts.role === 'slave') {\n this.role = 'slave'\n } else {\n throw new Error(\"Role must be either 'master' or 'slave'!\")\n }\n this.y.db.forwardAppliedOperations = opts.forwardAppliedOperations || false\n this.role = opts.role\n this.connections = {}\n this.isSynced = false\n this.userEventListeners = []\n this.whenSyncedListeners = []\n this.currentSyncTarget = null\n this.syncingClients = []\n this.forwardToSyncingClients = opts.forwardToSyncingClients !== false\n this.debug = opts.debug === true\n this.broadcastedHB = false\n this.syncStep2 = Promise.resolve()\n this.broadcastOpBuffer = []\n this.protocolVersion = 11\n }\n reconnect () {\n }\n disconnect () {\n this.connections = {}\n this.isSynced = false\n this.currentSyncTarget = null\n this.broadcastedHB = false\n this.syncingClients = []\n this.whenSyncedListeners = []\n return this.y.db.stopGarbageCollector()\n }\n setUserId (userId) {\n if (this.userId == null) {\n this.userId = userId\n return this.y.db.setUserId(userId)\n } else {\n return null\n }\n }\n onUserEvent (f) {\n this.userEventListeners.push(f)\n }\n userLeft (user) {\n if (this.connections[user] != null) {\n delete this.connections[user]\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null\n this.findNextSyncTarget()\n }\n this.syncingClients = this.syncingClients.filter(function (cli) {\n return cli !== user\n })\n for (var f of this.userEventListeners) {\n f({\n action: 'userLeft',\n user: user\n })\n }\n }\n }\n userJoined (user, role) {\n if (role == null) {\n throw new Error('You must specify the role of the joined user!')\n }\n if (this.connections[user] != null) {\n throw new Error('This user already joined!')\n }\n this.connections[user] = {\n isSynced: false,\n role: role\n }\n for (var f of this.userEventListeners) {\n f({\n action: 'userJoined',\n user: user,\n role: role\n })\n }\n if (this.currentSyncTarget == null) {\n this.findNextSyncTarget()\n }\n }\n // Execute a function _when_ we are connected.\n // If not connected, wait until connected\n whenSynced (f) {\n if (this.isSynced) {\n f()\n } else {\n this.whenSyncedListeners.push(f)\n }\n }\n /*\n\n returns false, if there is no sync target\n true otherwise\n */\n findNextSyncTarget () {\n if (this.currentSyncTarget != null || this.isSynced) {\n return // \"The current sync has not finished!\"\n }\n\n var syncUser = null\n for (var uid in this.connections) {\n if (!this.connections[uid].isSynced) {\n syncUser = uid\n break\n }\n }\n var conn = this\n if (syncUser != null) {\n this.currentSyncTarget = syncUser\n this.y.db.requestTransaction(function *() {\n var stateSet = yield* this.getStateSet()\n var deleteSet = yield* this.getDeleteSet()\n conn.send(syncUser, {\n type: 'sync step 1',\n stateSet: stateSet,\n deleteSet: deleteSet,\n protocolVersion: conn.protocolVersion\n })\n })\n } else {\n this.y.db.requestTransaction(function *() {\n // it is crucial that isSynced is set at the time garbageCollectAfterSync is called\n conn.isSynced = true\n yield* this.garbageCollectAfterSync()\n // call whensynced listeners\n for (var f of conn.whenSyncedListeners) {\n f()\n }\n conn.whenSyncedListeners = []\n })\n }\n }\n send (uid, message) {\n if (this.debug) {\n console.log(`send ${this.userId} -> ${uid}: ${message.type}`, message) // eslint-disable-line\n }\n }\n /*\n Buffer operations, and broadcast them when ready.\n */\n broadcastOps (ops) {\n ops = ops.map(function (op) {\n return Y.Struct[op.struct].encode(op)\n })\n var self = this\n function broadcastOperations () {\n if (self.broadcastOpBuffer.length > 0) {\n self.broadcast({\n type: 'update',\n ops: self.broadcastOpBuffer\n })\n self.broadcastOpBuffer = []\n }\n }\n if (this.broadcastOpBuffer.length === 0) {\n this.broadcastOpBuffer = ops\n if (this.y.db.transactionInProgress) {\n this.y.db.whenTransactionsFinished().then(broadcastOperations)\n } else {\n setTimeout(broadcastOperations, 0)\n }\n } else {\n this.broadcastOpBuffer = this.broadcastOpBuffer.concat(ops)\n }\n }\n /*\n You received a raw message, and you know that it is intended for Yjs. Then call this function.\n */\n receiveMessage (sender/* :UserId */, message/* :Message */) {\n if (sender === this.userId) {\n return\n }\n if (this.debug) {\n console.log(`receive ${sender} -> ${this.userId}: ${message.type}`, JSON.parse(JSON.stringify(message))) // eslint-disable-line\n }\n if (message.protocolVersion != null && message.protocolVersion !== this.protocolVersion) {\n console.error(\n `You tried to sync with a yjs instance that has a different protocol version\n (You: ${this.protocolVersion}, Client: ${message.protocolVersion}).\n The sync was stopped. You need to upgrade your dependencies (especially Yjs & the Connector)!\n `)\n this.send(sender, {\n type: 'sync stop',\n protocolVersion: this.protocolVersion\n })\n return\n }\n if (message.type === 'sync step 1') {\n let conn = this\n let m = message\n this.y.db.requestTransaction(function *() {\n var currentStateSet = yield* this.getStateSet()\n yield* this.applyDeleteSet(m.deleteSet)\n\n var ds = yield* this.getDeleteSet()\n var ops = yield* this.getOperations(m.stateSet)\n conn.send(sender, {\n type: 'sync step 2',\n os: ops,\n stateSet: currentStateSet,\n deleteSet: ds,\n protocolVersion: this.protocolVersion\n })\n if (this.forwardToSyncingClients) {\n conn.syncingClients.push(sender)\n setTimeout(function () {\n conn.syncingClients = conn.syncingClients.filter(function (cli) {\n return cli !== sender\n })\n conn.send(sender, {\n type: 'sync done'\n })\n }, 5000) // TODO: conn.syncingClientDuration)\n } else {\n conn.send(sender, {\n type: 'sync done'\n })\n }\n conn._setSyncedWith(sender)\n })\n } else if (message.type === 'sync step 2') {\n let conn = this\n var broadcastHB = !this.broadcastedHB\n this.broadcastedHB = true\n var db = this.y.db\n var defer = {}\n defer.promise = new Promise(function (resolve) {\n defer.resolve = resolve\n })\n this.syncStep2 = defer.promise\n let m /* :MessageSyncStep2 */ = message\n db.requestTransaction(function * () {\n yield* this.applyDeleteSet(m.deleteSet)\n this.store.apply(m.os)\n db.requestTransaction(function * () {\n var ops = yield* this.getOperations(m.stateSet)\n if (ops.length > 0) {\n if (!broadcastHB) { // TODO: consider to broadcast here..\n conn.send(sender, {\n type: 'update',\n ops: ops\n })\n } else {\n // broadcast only once!\n conn.broadcastOps(ops)\n }\n }\n defer.resolve()\n })\n })\n } else if (message.type === 'sync done') {\n var self = this\n this.syncStep2.then(function () {\n self._setSyncedWith(sender)\n })\n } else if (message.type === 'update') {\n if (this.forwardToSyncingClients) {\n for (var client of this.syncingClients) {\n this.send(client, message)\n }\n }\n if (this.y.db.forwardAppliedOperations) {\n var delops = message.ops.filter(function (o) {\n return o.struct === 'Delete'\n })\n if (delops.length > 0) {\n this.broadcastOps(delops)\n }\n }\n this.y.db.apply(message.ops)\n }\n }\n _setSyncedWith (user) {\n var conn = this.connections[user]\n if (conn != null) {\n conn.isSynced = true\n }\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null\n this.findNextSyncTarget()\n }\n }\n /*\n Currently, the HB encodes operations as JSON. For the moment I want to keep it\n that way. Maybe we support encoding in the HB as XML in the future, but for now I don't want\n too much overhead. Y is very likely to get changed a lot in the future\n\n Because we don't want to encode JSON as string (with character escaping, wich makes it pretty much unreadable)\n we encode the JSON as XML.\n\n When the HB support encoding as XML, the format should look pretty much like this.\n\n does not support primitive values as array elements\n expects an ltx (less than xml) object\n */\n parseMessageFromXml (m/* :any */) {\n function parseArray (node) {\n for (var n of node.children) {\n if (n.getAttribute('isArray') === 'true') {\n return parseArray(n)\n } else {\n return parseObject(n)\n }\n }\n }\n function parseObject (node/* :any */) {\n var json = {}\n for (var attrName in node.attrs) {\n var value = node.attrs[attrName]\n var int = parseInt(value, 10)\n if (isNaN(int) || ('' + int) !== value) {\n json[attrName] = value\n } else {\n json[attrName] = int\n }\n }\n for (var n/* :any */ in node.children) {\n var name = n.name\n if (n.getAttribute('isArray') === 'true') {\n json[name] = parseArray(n)\n } else {\n json[name] = parseObject(n)\n }\n }\n return json\n }\n parseObject(m)\n }\n /*\n encode message in xml\n we use string because Strophe only accepts an \"xml-string\"..\n So {a:4,b:{c:5}} will look like\n \n \n \n m - ltx element\n json - Object\n */\n encodeMessageToXml (msg, obj) {\n // attributes is optional\n function encodeObject (m, json) {\n for (var name in json) {\n var value = json[name]\n if (name == null) {\n // nop\n } else if (value.constructor === Object) {\n encodeObject(m.c(name), value)\n } else if (value.constructor === Array) {\n encodeArray(m.c(name), value)\n } else {\n m.setAttribute(name, value)\n }\n }\n }\n function encodeArray (m, array) {\n m.setAttribute('isArray', 'true')\n for (var e of array) {\n if (e.constructor === Object) {\n encodeObject(m.c('array-element'), e)\n } else {\n encodeArray(m.c('array-element'), e)\n }\n }\n }\n if (obj.constructor === Object) {\n encodeObject(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj)\n } else if (obj.constructor === Array) {\n encodeArray(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj)\n } else {\n throw new Error(\"I can't encode this json!\")\n }\n }\n }\n Y.AbstractConnector = AbstractConnector\n}\n","/* global getRandom, async */\n'use strict'\n\nmodule.exports = function (Y) {\n var globalRoom = {\n users: {},\n buffers: {}, // TODO: reimplement this idea. This does not cover all cases!! Here, you have a queue which is unrealistic (i.e. think about multiple incoming connections)\n removeUser: function (user) {\n for (var i in this.users) {\n this.users[i].userLeft(user)\n }\n delete this.users[user]\n delete this.buffers[user]\n },\n addUser: function (connector) {\n this.users[connector.userId] = connector\n this.buffers[connector.userId] = {}\n for (var uname in this.users) {\n if (uname !== connector.userId) {\n var u = this.users[uname]\n u.userJoined(connector.userId, 'master')\n connector.userJoined(u.userId, 'master')\n }\n }\n },\n whenTransactionsFinished: function () {\n var ps = []\n for (var name in this.users) {\n ps.push(this.users[name].y.db.whenTransactionsFinished())\n }\n return Promise.all(ps)\n },\n flushOne: function flushOne () {\n var bufs = []\n for (var receiver in globalRoom.buffers) {\n let buff = globalRoom.buffers[receiver]\n var push = false\n for (let sender in buff) {\n if (buff[sender].length > 0) {\n push = true\n break\n }\n }\n if (push) {\n bufs.push(receiver)\n }\n }\n if (bufs.length > 0) {\n var userId = getRandom(bufs)\n let buff = globalRoom.buffers[userId]\n let sender = getRandom(Object.keys(buff))\n var m = buff[sender].shift()\n if (buff[sender].length === 0) {\n delete buff[sender]\n }\n var user = globalRoom.users[userId]\n user.receiveMessage(m[0], m[1])\n return user.y.db.whenTransactionsFinished()\n } else {\n return false\n }\n },\n flushAll: function () {\n return new Promise(function (resolve) {\n // flushes may result in more created operations,\n // flush until there is nothing more to flush\n function nextFlush () {\n var c = globalRoom.flushOne()\n if (c) {\n while (c) {\n c = globalRoom.flushOne()\n }\n globalRoom.whenTransactionsFinished().then(nextFlush)\n } else {\n setTimeout(function () {\n var c = globalRoom.flushOne()\n if (c) {\n c.then(function () {\n globalRoom.whenTransactionsFinished().then(nextFlush)\n })\n } else {\n resolve()\n }\n }, 10)\n }\n }\n globalRoom.whenTransactionsFinished().then(nextFlush)\n })\n }\n }\n Y.utils.globalRoom = globalRoom\n\n var userIdCounter = 0\n\n class Test extends Y.AbstractConnector {\n constructor (y, options) {\n if (options === undefined) {\n throw new Error('Options must not be undefined!')\n }\n options.role = 'master'\n options.forwardToSyncingClients = false\n super(y, options)\n this.setUserId((userIdCounter++) + '').then(() => {\n globalRoom.addUser(this)\n })\n this.globalRoom = globalRoom\n this.syncingClientDuration = 0\n }\n receiveMessage (sender, m) {\n super.receiveMessage(sender, JSON.parse(JSON.stringify(m)))\n }\n send (userId, message) {\n var buffer = globalRoom.buffers[userId]\n if (buffer != null) {\n if (buffer[this.userId] == null) {\n buffer[this.userId] = []\n }\n buffer[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n broadcast (message) {\n for (var key in globalRoom.buffers) {\n var buff = globalRoom.buffers[key]\n if (buff[this.userId] == null) {\n buff[this.userId] = []\n }\n buff[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n isDisconnected () {\n return globalRoom.users[this.userId] == null\n }\n reconnect () {\n if (this.isDisconnected()) {\n globalRoom.addUser(this)\n super.reconnect()\n }\n return Y.utils.globalRoom.flushAll()\n }\n disconnect () {\n if (!this.isDisconnected()) {\n globalRoom.removeUser(this.userId)\n super.disconnect()\n }\n return this.y.db.whenTransactionsFinished()\n }\n flush () {\n var self = this\n return async(function * () {\n var buff = globalRoom.buffers[self.userId]\n while (Object.keys(buff).length > 0) {\n var sender = getRandom(Object.keys(buff))\n var m = buff[sender].shift()\n if (buff[sender].length === 0) {\n delete buff[sender]\n }\n this.receiveMessage(m[0], m[1])\n }\n yield self.whenTransactionsFinished()\n })\n }\n }\n\n Y.Test = Test\n}\n","/* @flow */\n'use strict'\n\nmodule.exports = function (Y /* :any */) {\n /*\n Partial definition of an OperationStore.\n TODO: name it Database, operation store only holds operations.\n\n A database definition must alse define the following methods:\n * logTable() (optional)\n - show relevant information information in a table\n * requestTransaction(makeGen)\n - request a transaction\n * destroy()\n - destroy the database\n */\n class AbstractDatabase {\n /* ::\n y: YConfig;\n forwardAppliedOperations: boolean;\n listenersById: Object;\n listenersByIdExecuteNow: Array;\n listenersByIdRequestPending: boolean;\n initializedTypes: Object;\n whenUserIdSetListener: ?Function;\n waitingTransactions: Array;\n transactionInProgress: boolean;\n executeOrder: Array;\n gc1: Array;\n gc2: Array;\n gcTimeout: number;\n gcInterval: any;\n garbageCollect: Function;\n executeOrder: Array; // for debugging only\n userId: UserId;\n opClock: number;\n transactionsFinished: ?{promise: Promise, resolve: any};\n transact: (x: ?Generator) => any;\n */\n constructor (y, opts) {\n this.y = y\n var os = this\n this.userId = null\n var resolve\n this.userIdPromise = new Promise(function (r) {\n resolve = r\n })\n this.userIdPromise.resolve = resolve\n // whether to broadcast all applied operations (insert & delete hook)\n this.forwardAppliedOperations = false\n // E.g. this.listenersById[id] : Array\n this.listenersById = {}\n // Execute the next time a transaction is requested\n this.listenersByIdExecuteNow = []\n // A transaction is requested\n this.listenersByIdRequestPending = false\n /* To make things more clear, the following naming conventions:\n * ls : we put this.listenersById on ls\n * l : Array\n * id : Id (can't use as property name)\n * sid : String (converted from id via JSON.stringify\n so we can use it as a property name)\n\n Always remember to first overwrite\n a property before you iterate over it!\n */\n // TODO: Use ES7 Weak Maps. This way types that are no longer user,\n // wont be kept in memory.\n this.initializedTypes = {}\n this.waitingTransactions = []\n this.transactionInProgress = false\n this.transactionIsFlushed = false\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n this.executeOrder = []\n }\n this.gc1 = [] // first stage\n this.gc2 = [] // second stage -> after that, remove the op\n this.gcTimeout = !opts.gcTimeout ? 50000 : opts.gcTimeoutÅ›\n function garbageCollect () {\n return os.whenTransactionsFinished().then(function () {\n if (os.gc1.length > 0 || os.gc2.length > 0) {\n if (!os.y.isConnected()) {\n console.warn('gc should be empty when disconnected!')\n }\n return new Promise((resolve) => {\n os.requestTransaction(function * () {\n if (os.y.connector != null && os.y.connector.isSynced) {\n for (var i = 0; i < os.gc2.length; i++) {\n var oid = os.gc2[i]\n yield* this.garbageCollectOperation(oid)\n }\n os.gc2 = os.gc1\n os.gc1 = []\n }\n // TODO: Use setInterval here instead (when garbageCollect is called several times there will be several timeouts..)\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout)\n }\n resolve()\n })\n })\n } else {\n // TODO: see above\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout)\n }\n return Promise.resolve()\n }\n })\n }\n this.garbageCollect = garbageCollect\n if (this.gcTimeout > 0) {\n garbageCollect()\n }\n }\n queueGarbageCollector (id) {\n if (this.y.isConnected()) {\n this.gc1.push(id)\n }\n }\n emptyGarbageCollector () {\n return new Promise(resolve => {\n var check = () => {\n if (this.gc1.length > 0 || this.gc2.length > 0) {\n this.garbageCollect().then(check)\n } else {\n resolve()\n }\n }\n setTimeout(check, 0)\n })\n }\n addToDebug () {\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n var command /* :string */ = Array.prototype.map.call(arguments, function (s) {\n if (typeof s === 'string') {\n return s\n } else {\n return JSON.stringify(s)\n }\n }).join('').replace(/\"/g, \"'\").replace(/,/g, ', ').replace(/:/g, ': ')\n this.executeOrder.push(command)\n }\n }\n getDebugData () {\n console.log(this.executeOrder.join('\\n'))\n }\n stopGarbageCollector () {\n var self = this\n return new Promise(function (resolve) {\n self.requestTransaction(function * () {\n var ungc /* :Array */ = self.gc1.concat(self.gc2)\n self.gc1 = []\n self.gc2 = []\n for (var i = 0; i < ungc.length; i++) {\n var op = yield* this.getOperation(ungc[i])\n if (op != null) {\n delete op.gc\n yield* this.setOperation(op)\n }\n }\n resolve()\n })\n })\n }\n /*\n Try to add to GC.\n\n TODO: rename this function\n\n Rulez:\n * Only gc if this user is online\n * The most left element in a list must not be gc'd.\n => There is at least one element in the list\n\n returns true iff op was added to GC\n */\n * addToGarbageCollector (op, left) {\n if (\n op.gc == null &&\n op.deleted === true\n ) {\n var gc = false\n if (left != null && left.deleted === true) {\n gc = true\n } else if (op.content != null && op.content.length > 1) {\n op = yield* this.getInsertionCleanStart([op.id[0], op.id[1] + 1])\n gc = true\n }\n if (gc) {\n op.gc = true\n yield* this.setOperation(op)\n this.store.queueGarbageCollector(op.id)\n return true\n }\n }\n return false\n }\n removeFromGarbageCollector (op) {\n function filter (o) {\n return !Y.utils.compareIds(o, op.id)\n }\n this.gc1 = this.gc1.filter(filter)\n this.gc2 = this.gc2.filter(filter)\n delete op.gc\n }\n * destroy () {\n clearInterval(this.gcInterval)\n this.gcInterval = null\n for (var key in this.initializedTypes) {\n var type = this.initializedTypes[key]\n if (type._destroy != null) {\n type._destroy()\n } else {\n console.error('The type you included does not provide destroy functionality, it will remain in memory (updating your packages will help).')\n }\n }\n }\n setUserId (userId) {\n if (!this.userIdPromise.inProgress) {\n this.userIdPromise.inProgress = true\n var self = this\n self.requestTransaction(function * () {\n self.userId = userId\n var state = yield* this.getState(userId)\n self.opClock = state.clock\n self.userIdPromise.resolve(userId)\n })\n }\n return this.userIdPromise\n }\n whenUserIdSet (f) {\n this.userIdPromise.then(f)\n }\n getNextOpId (numberOfIds) {\n if (numberOfIds == null) {\n throw new Error('getNextOpId expects the number of created ids to create!')\n } else if (this.userId == null) {\n throw new Error('OperationStore not yet initialized!')\n } else {\n var id = [this.userId, this.opClock]\n this.opClock += numberOfIds\n return id\n }\n }\n /*\n Apply a list of operations.\n\n * get a transaction\n * check whether all Struct.*.requiredOps are in the OS\n * check if it is an expected op (otherwise wait for it)\n * check if was deleted, apply a delete operation after op was applied\n */\n apply (ops) {\n for (var i = 0; i < ops.length; i++) {\n var o = ops[i]\n if (o.id == null || o.id[0] !== this.y.connector.userId) {\n var required = Y.Struct[o.struct].requiredOps(o)\n if (o.requires != null) {\n required = required.concat(o.requires)\n }\n this.whenOperationsExist(required, o)\n }\n }\n }\n /*\n op is executed as soon as every operation requested is available.\n Note that Transaction can (and should) buffer requests.\n */\n whenOperationsExist (ids, op) {\n if (ids.length > 0) {\n let listener = {\n op: op,\n missing: ids.length\n }\n\n for (let i = 0; i < ids.length; i++) {\n let id = ids[i]\n let sid = JSON.stringify(id)\n let l = this.listenersById[sid]\n if (l == null) {\n l = []\n this.listenersById[sid] = l\n }\n l.push(listener)\n }\n } else {\n this.listenersByIdExecuteNow.push({\n op: op\n })\n }\n\n if (this.listenersByIdRequestPending) {\n return\n }\n\n this.listenersByIdRequestPending = true\n var store = this\n\n this.requestTransaction(function * () {\n var exeNow = store.listenersByIdExecuteNow\n store.listenersByIdExecuteNow = []\n\n var ls = store.listenersById\n store.listenersById = {}\n\n store.listenersByIdRequestPending = false\n\n for (let key = 0; key < exeNow.length; key++) {\n let o = exeNow[key].op\n yield* store.tryExecute.call(this, o)\n }\n\n for (var sid in ls) {\n var l = ls[sid]\n var id = JSON.parse(sid)\n var op\n if (typeof id[1] === 'string') {\n op = yield* this.getOperation(id)\n } else {\n op = yield* this.getInsertion(id)\n }\n if (op == null) {\n store.listenersById[sid] = l\n } else {\n for (let i = 0; i < l.length; i++) {\n let listener = l[i]\n let o = listener.op\n if (--listener.missing === 0) {\n yield* store.tryExecute.call(this, o)\n }\n }\n }\n }\n })\n }\n /*\n Actually execute an operation, when all expected operations are available.\n */\n /* :: // TODO: this belongs somehow to transaction\n store: Object;\n getOperation: any;\n isGarbageCollected: any;\n addOperation: any;\n whenOperationsExist: any;\n */\n * tryExecute (op) {\n this.store.addToDebug('yield* this.store.tryExecute.call(this, ', JSON.stringify(op), ')')\n if (op.struct === 'Delete') {\n yield* Y.Struct.Delete.execute.call(this, op)\n // this is now called in Transaction.deleteOperation!\n // yield* this.store.operationAdded(this, op)\n } else {\n // check if this op was defined\n var defined = yield* this.getInsertion(op.id)\n while (defined != null && defined.content != null) {\n // check if this op has a longer content in the case it is defined\n if (defined.id[1] + defined.content.length < op.id[1] + op.content.length) {\n var overlapSize = defined.content.length - (op.id[1] - defined.id[1])\n op.content.splice(0, overlapSize)\n op.id = [op.id[0], op.id[1] + overlapSize]\n op.left = Y.utils.getLastId(defined)\n op.origin = op.left\n defined = yield* this.getOperation(op.id) // getOperation suffices here\n } else {\n break\n }\n }\n if (defined == null) {\n var isGarbageCollected = yield* this.isGarbageCollected(op.id)\n if (!isGarbageCollected) {\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n\n // if insertion, try to combine with left\n yield* this.tryCombineWithLeft(op)\n }\n }\n }\n }\n // called by a transaction when an operation is added\n * operationAdded (transaction, op) {\n // increase SS\n yield* transaction.updateState(op.id[0])\n\n var opLen = op.content != null ? op.content.length : 1\n for (let i = 0; i < opLen; i++) {\n // notify whenOperation listeners (by id)\n var sid = JSON.stringify([op.id[0], op.id[1] + i])\n var l = this.listenersById[sid]\n delete this.listenersById[sid]\n\n if (l != null) {\n for (var key in l) {\n var listener = l[key]\n if (--listener.missing === 0) {\n this.whenOperationsExist([], listener.op)\n }\n }\n }\n }\n var t = this.initializedTypes[JSON.stringify(op.parent)]\n\n // if parent is deleted, mark as gc'd and return\n if (op.parent != null) {\n var parentIsDeleted = yield* transaction.isDeleted(op.parent)\n if (parentIsDeleted) {\n yield* transaction.deleteList(op.id)\n return\n }\n }\n\n // notify parent, if it was instanciated as a custom type\n if (t != null) {\n let o = Y.utils.copyObject(op)\n yield* t._changed(transaction, o)\n }\n if (!op.deleted) {\n // Delete if DS says this is actually deleted\n var len = op.content != null ? op.content.length : 1\n var startId = op.id // You must not use op.id in the following loop, because op will change when deleted\n for (let i = 0; i < len; i++) {\n var id = [startId[0], startId[1] + i]\n var opIsDeleted = yield* transaction.isDeleted(id)\n if (opIsDeleted) {\n var delop = {\n struct: 'Delete',\n target: id\n }\n yield* this.tryExecute.call(transaction, delop)\n }\n }\n }\n }\n whenTransactionsFinished () {\n if (this.transactionInProgress) {\n if (this.transactionsFinished == null) {\n var resolve\n var promise = new Promise(function (r) {\n resolve = r\n })\n this.transactionsFinished = {\n resolve: resolve,\n promise: promise\n }\n return promise\n } else {\n return this.transactionsFinished.promise\n }\n } else {\n return Promise.resolve()\n }\n }\n // Check if there is another transaction request.\n // * the last transaction is always a flush :)\n getNextRequest () {\n if (this.waitingTransactions.length === 0) {\n if (this.transactionIsFlushed) {\n this.transactionInProgress = false\n this.transactionIsFlushed = false\n if (this.transactionsFinished != null) {\n this.transactionsFinished.resolve()\n this.transactionsFinished = null\n }\n return null\n } else {\n this.transactionIsFlushed = true\n return function * () {\n yield* this.flush()\n }\n }\n } else {\n this.transactionIsFlushed = false\n return this.waitingTransactions.shift()\n }\n }\n requestTransaction (makeGen/* :any */, callImmediately) {\n this.waitingTransactions.push(makeGen)\n if (!this.transactionInProgress) {\n this.transactionInProgress = true\n if (false || callImmediately) { // TODO: decide whether this is ok or not..\n this.transact(this.getNextRequest())\n } else {\n var self = this\n setTimeout(function () {\n self.transact(self.getNextRequest())\n }, 0)\n }\n }\n }\n }\n Y.AbstractDatabase = AbstractDatabase\n}\n","/* @flow */\n'use strict'\n\n/*\n An operation also defines the structure of a type. This is why operation and\n structure are used interchangeably here.\n\n It must be of the type Object. I hope to achieve some performance\n improvements when working on databases that support the json format.\n\n An operation must have the following properties:\n\n * encode\n - Encode the structure in a readable format (preferably string- todo)\n * decode (todo)\n - decode structure to json\n * execute\n - Execute the semantics of an operation.\n * requiredOps\n - Operations that are required to execute this operation.\n*/\nmodule.exports = function (Y/* :any */) {\n var Struct = {\n /* This is the only operation that is actually not a structure, because\n it is not stored in the OS. This is why it _does not_ have an id\n\n op = {\n target: Id\n }\n */\n Delete: {\n encode: function (op) {\n return op\n },\n requiredOps: function (op) {\n return [] // [op.target]\n },\n execute: function * (op) {\n return yield* this.deleteOperation(op.target, op.length || 1)\n }\n },\n Insert: {\n /* {\n content: [any],\n opContent: Id,\n id: Id,\n left: Id,\n origin: Id,\n right: Id,\n parent: Id,\n parentSub: string (optional), // child of Map type\n }\n */\n encode: function (op/* :Insertion */) /* :Insertion */ {\n // TODO: you could not send the \"left\" property, then you also have to\n // \"op.left = null\" in $execute or $decode\n var e/* :any */ = {\n id: op.id,\n left: op.left,\n right: op.right,\n origin: op.origin,\n parent: op.parent,\n struct: op.struct\n }\n if (op.parentSub != null) {\n e.parentSub = op.parentSub\n }\n if (op.hasOwnProperty('opContent')) {\n e.opContent = op.opContent\n } else {\n e.content = op.content.slice()\n }\n\n return e\n },\n requiredOps: function (op) {\n var ids = []\n if (op.left != null) {\n ids.push(op.left)\n }\n if (op.right != null) {\n ids.push(op.right)\n }\n if (op.origin != null && !Y.utils.compareIds(op.left, op.origin)) {\n ids.push(op.origin)\n }\n // if (op.right == null && op.left == null) {\n ids.push(op.parent)\n\n if (op.opContent != null) {\n ids.push(op.opContent)\n }\n return ids\n },\n getDistanceToOrigin: function * (op) {\n if (op.left == null) {\n return 0\n } else {\n var d = 0\n var o = yield* this.getInsertion(op.left)\n while (!Y.utils.matchesId(o, op.origin)) {\n d++\n if (o.left == null) {\n break\n } else {\n o = yield* this.getInsertion(o.left)\n }\n }\n return d\n }\n },\n /*\n # $this has to find a unique position between origin and the next known character\n # case 1: $origin equals $o.origin: the $creator parameter decides if left or right\n # let $OL= [o1,o2,o3,o4], whereby $this is to be inserted between o1 and o4\n # o2,o3 and o4 origin is 1 (the position of o2)\n # there is the case that $this.creator < o2.creator, but o3.creator < $this.creator\n # then o2 knows o3. Since on another client $OL could be [o1,o3,o4] the problem is complex\n # therefore $this would be always to the right of o3\n # case 2: $origin < $o.origin\n # if current $this insert_position > $o origin: $this ins\n # else $insert_position will not change\n # (maybe we encounter case 1 later, then this will be to the right of $o)\n # case 3: $origin > $o.origin\n # $this insert_position is to the left of $o (forever!)\n */\n execute: function * (op) {\n var i // loop counter\n\n // during this function some ops may get split into two pieces (e.g. with getInsertionCleanEnd)\n // We try to merge them later, if possible\n var tryToRemergeLater = []\n\n if (op.origin != null) { // TODO: !== instead of !=\n // we save in origin that op originates in it\n // we need that later when we eventually garbage collect origin (see transaction)\n var origin = yield* this.getInsertionCleanEnd(op.origin)\n if (origin.originOf == null) {\n origin.originOf = []\n }\n origin.originOf.push(op.id)\n yield* this.setOperation(origin)\n if (origin.right != null) {\n tryToRemergeLater.push(origin.right)\n }\n }\n var distanceToOrigin = i = yield* Struct.Insert.getDistanceToOrigin.call(this, op) // most cases: 0 (starts from 0)\n\n // now we begin to insert op in the list of insertions..\n var o\n var parent\n var start\n\n // find o. o is the first conflicting operation\n if (op.left != null) {\n o = yield* this.getInsertionCleanEnd(op.left)\n if (!Y.utils.compareIds(op.left, op.origin) && o.right != null) {\n // only if not added previously\n tryToRemergeLater.push(o.right)\n }\n o = (o.right == null) ? null : yield* this.getOperation(o.right)\n } else { // left == null\n parent = yield* this.getOperation(op.parent)\n let startId = op.parentSub ? parent.map[op.parentSub] : parent.start\n start = startId == null ? null : yield* this.getOperation(startId)\n o = start\n }\n\n // make sure to split op.right if necessary (also add to tryCombineWithLeft)\n if (op.right != null) {\n tryToRemergeLater.push(op.right)\n yield* this.getInsertionCleanStart(op.right)\n }\n\n // handle conflicts\n while (true) {\n if (o != null && !Y.utils.compareIds(o.id, op.right)) {\n var oOriginDistance = yield* Struct.Insert.getDistanceToOrigin.call(this, o)\n if (oOriginDistance === i) {\n // case 1\n if (o.id[0] < op.id[0]) {\n op.left = Y.utils.getLastId(o)\n distanceToOrigin = i + 1 // just ignore o.content.length, doesn't make a difference\n }\n } else if (oOriginDistance < i) {\n // case 2\n if (i - distanceToOrigin <= oOriginDistance) {\n op.left = Y.utils.getLastId(o)\n distanceToOrigin = i + 1 // just ignore o.content.length, doesn't make a difference\n }\n } else {\n break\n }\n i++\n if (o.right != null) {\n o = yield* this.getInsertion(o.right)\n } else {\n o = null\n }\n } else {\n break\n }\n }\n\n // reconnect..\n var left = null\n var right = null\n if (parent == null) {\n parent = yield* this.getOperation(op.parent)\n }\n\n // reconnect left and set right of op\n if (op.left != null) {\n left = yield* this.getInsertion(op.left)\n // link left\n op.right = left.right\n left.right = op.id\n\n yield* this.setOperation(left)\n } else {\n // set op.right from parent, if necessary\n op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start\n }\n // reconnect right\n if (op.right != null) {\n // TODO: wanna connect right too?\n right = yield* this.getOperation(op.right)\n right.left = Y.utils.getLastId(op)\n\n // if right exists, and it is supposed to be gc'd. Remove it from the gc\n if (right.gc != null) {\n if (right.content != null && right.content.length > 1) {\n right = yield* this.getInsertionCleanEnd(right.id)\n }\n this.store.removeFromGarbageCollector(right)\n }\n yield* this.setOperation(right)\n }\n\n // update parents .map/start/end properties\n if (op.parentSub != null) {\n if (left == null) {\n parent.map[op.parentSub] = op.id\n yield* this.setOperation(parent)\n }\n // is a child of a map struct.\n // Then also make sure that only the most left element is not deleted\n // We do not call the type in this case (this is what the third parameter is for)\n if (op.right != null) {\n yield* this.deleteOperation(op.right, 1, true)\n }\n if (op.left != null) {\n yield* this.deleteOperation(op.id, 1, true)\n }\n } else {\n if (right == null || left == null) {\n if (right == null) {\n parent.end = Y.utils.getLastId(op)\n }\n if (left == null) {\n parent.start = op.id\n }\n yield* this.setOperation(parent)\n }\n }\n\n // try to merge original op.left and op.origin\n for (let i = 0; i < tryToRemergeLater.length; i++) {\n var m = yield* this.getOperation(tryToRemergeLater[i])\n yield* this.tryCombineWithLeft(m)\n }\n }\n },\n List: {\n /*\n {\n start: null,\n end: null,\n struct: \"List\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function (id) {\n return {\n start: null,\n end: null,\n struct: 'List',\n id: id\n }\n },\n encode: function (op) {\n var e = {\n struct: 'List',\n id: op.id,\n type: op.type\n }\n if (op.requires != null) {\n e.requires = op.requires\n }\n if (op.info != null) {\n e.info = op.info\n }\n return e\n },\n requiredOps: function () {\n /*\n var ids = []\n if (op.start != null) {\n ids.push(op.start)\n }\n if (op.end != null){\n ids.push(op.end)\n }\n return ids\n */\n return []\n },\n execute: function * (op) {\n op.start = null\n op.end = null\n },\n ref: function * (op, pos) {\n if (op.start == null) {\n return null\n }\n var res = null\n var o = yield* this.getOperation(op.start)\n\n while (true) {\n if (!o.deleted) {\n res = o\n pos--\n }\n if (pos >= 0 && o.right != null) {\n o = yield* this.getOperation(o.right)\n } else {\n break\n }\n }\n return res\n },\n map: function * (o, f) {\n o = o.start\n var res = []\n while (o != null) { // TODO: change to != (at least some convention)\n var operation = yield* this.getOperation(o)\n if (!operation.deleted) {\n res.push(f(operation))\n }\n o = operation.right\n }\n return res\n }\n },\n Map: {\n /*\n {\n map: {},\n struct: \"Map\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function (id) {\n return {\n id: id,\n map: {},\n struct: 'Map'\n }\n },\n encode: function (op) {\n var e = {\n struct: 'Map',\n type: op.type,\n id: op.id,\n map: {} // overwrite map!!\n }\n if (op.requires != null) {\n e.requires = op.requires\n }\n if (op.info != null) {\n e.info = op.info\n }\n return e\n },\n requiredOps: function () {\n return []\n },\n execute: function * () {},\n /*\n Get a property by name\n */\n get: function * (op, name) {\n var oid = op.map[name]\n if (oid != null) {\n var res = yield* this.getOperation(oid)\n if (res == null || res.deleted) {\n return void 0\n } else if (res.opContent == null) {\n return res.content[0]\n } else {\n return yield* this.getType(res.opContent)\n }\n }\n }\n }\n }\n Y.Struct = Struct\n}\n","/* @flow */\n'use strict'\n\n/*\n Partial definition of a transaction\n\n A transaction provides all the the async functionality on a database.\n\n By convention, a transaction has the following properties:\n * ss for StateSet\n * os for OperationStore\n * ds for DeleteStore\n\n A transaction must also define the following methods:\n * checkDeleteStoreForState(state)\n - When increasing the state of a user, an operation with an higher id\n may already be garbage collected, and therefore it will never be received.\n update the state to reflect this knowledge. This won't call a method to save the state!\n * getDeleteSet(id)\n - Get the delete set in a readable format:\n {\n \"userX\": [\n [5,1], // starting from position 5, one operations is deleted\n [9,4] // starting from position 9, four operations are deleted\n ],\n \"userY\": ...\n }\n * getOpsFromDeleteSet(ds) -- TODO: just call this.deleteOperation(id) here\n - get a set of deletions that need to be applied in order to get to\n achieve the state of the supplied ds\n * setOperation(op)\n - write `op` to the database.\n Note: this is allowed to return an in-memory object.\n E.g. the Memory adapter returns the object that it has in-memory.\n Changing values on this object will be stored directly in the database\n without calling this function. Therefore,\n setOperation may have no functionality in some adapters. This also has\n implications on the way we use operations that were served from the database.\n We try not to call copyObject, if not necessary.\n * addOperation(op)\n - add an operation to the database.\n This may only be called once for every op.id\n Must return a function that returns the next operation in the database (ordered by id)\n * getOperation(id)\n * removeOperation(id)\n - remove an operation from the database. This is called when an operation\n is garbage collected.\n * setState(state)\n - `state` is of the form\n {\n user: \"1\",\n clock: 4\n } <- meaning that we have four operations from user \"1\"\n (with these id's respectively: 0, 1, 2, and 3)\n * getState(user)\n * getStateVector()\n - Get the state of the OS in the form\n [{\n user: \"userX\",\n clock: 11\n },\n ..\n ]\n * getStateSet()\n - Get the state of the OS in the form\n {\n \"userX\": 11,\n \"userY\": 22\n }\n * getOperations(startSS)\n - Get the all the operations that are necessary in order to achive the\n stateSet of this user, starting from a stateSet supplied by another user\n * makeOperationReady(ss, op)\n - this is called only by `getOperations(startSS)`. It makes an operation\n applyable on a given SS.\n*/\nmodule.exports = function (Y/* :any */) {\n class TransactionInterface {\n /* ::\n store: Y.AbstractDatabase;\n ds: Store;\n os: Store;\n ss: Store;\n */\n /*\n Get a type based on the id of its model.\n If it does not exist yes, create it.\n TODO: delete type from store.initializedTypes[id] when corresponding id was deleted!\n */\n * getType (id, args) {\n var sid = JSON.stringify(id)\n var t = this.store.initializedTypes[sid]\n if (t == null) {\n var op/* :MapStruct | ListStruct */ = yield* this.getOperation(id)\n if (op != null) {\n t = yield* Y[op.type].typeDefinition.initType.call(this, this.store, op, args)\n this.store.initializedTypes[sid] = t\n }\n }\n return t\n }\n * createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op\n if (id[0] === '_') {\n op = yield* this.getOperation(id)\n } else {\n op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n }\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n if (op[0] === '_') {\n yield* this.setOperation(op)\n } else {\n yield* this.applyCreatedOperations([op])\n }\n return yield* this.getType(id, typedefinition[1])\n }\n /* createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n // yield* this.applyCreatedOperations([op])\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n return yield* this.getType(id, typedefinition[1])\n }*/\n /*\n Apply operations that this user created (no remote ones!)\n * does not check for Struct.*.requiredOps()\n * also broadcasts it through the connector\n */\n * applyCreatedOperations (ops) {\n var send = []\n for (var i = 0; i < ops.length; i++) {\n var op = ops[i]\n yield* this.store.tryExecute.call(this, op)\n if (op.id == null || typeof op.id[1] !== 'string') {\n send.push(Y.Struct[op.struct].encode(op))\n }\n }\n if (!this.store.y.connector.isDisconnected() && send.length > 0) { // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops)\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps(send)\n }\n }\n\n * deleteList (start) {\n while (start != null) {\n start = yield* this.getOperation(start)\n if (!start.gc) {\n start.gc = true\n start.deleted = true\n yield* this.setOperation(start)\n var delLength = start.content != null ? start.content.length : 1\n yield* this.markDeleted(start.id, delLength)\n if (start.opContent != null) {\n yield* this.deleteOperation(start.opContent)\n }\n this.store.queueGarbageCollector(start.id)\n }\n start = start.right\n }\n }\n\n /*\n Mark an operation as deleted, and add it to the GC, if possible.\n */\n * deleteOperation (targetId, length, preventCallType) /* :Generator */ {\n if (length == null) {\n length = 1\n }\n yield* this.markDeleted(targetId, length)\n while (length > 0) {\n var callType = false\n var target = yield* this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1])\n var targetLength = target != null && target.content != null ? target.content.length : 1\n if (target == null || target.id[0] !== targetId[0] || target.id[1] + targetLength <= targetId[1]) {\n // does not exist or is not in the range of the deletion\n target = null\n length = 0\n } else {\n // does exist, check if it is too long\n if (!target.deleted) {\n if (target.id[1] < targetId[1]) {\n // starts to the left of the deletion range\n target = yield* this.getInsertionCleanStart(targetId)\n targetLength = target.content.length // must have content property!\n }\n if (target.id[1] + targetLength > targetId[1] + length) {\n // ends to the right of the deletion range\n target = yield* this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1])\n targetLength = target.content.length\n }\n }\n length = target.id[1] - targetId[1]\n }\n\n if (target != null) {\n if (!target.deleted) {\n callType = true\n // set deleted & notify type\n target.deleted = true\n // delete containing lists\n if (target.start != null) {\n // TODO: don't do it like this .. -.-\n yield* this.deleteList(target.start)\n // yield* this.deleteList(target.id) -- do not gc itself because this may still get referenced\n }\n if (target.map != null) {\n for (var name in target.map) {\n yield* this.deleteList(target.map[name])\n }\n // TODO: here to.. (see above)\n // yield* this.deleteList(target.id) -- see above\n }\n if (target.opContent != null) {\n yield* this.deleteOperation(target.opContent)\n // target.opContent = null\n }\n if (target.requires != null) {\n for (var i = 0; i < target.requires.length; i++) {\n yield* this.deleteOperation(target.requires[i])\n }\n }\n }\n var left\n if (target.left != null) {\n left = yield* this.getInsertion(target.left)\n } else {\n left = null\n }\n\n // set here because it was deleted and/or gc'd\n yield* this.setOperation(target)\n\n /*\n Check if it is possible to add right to the gc.\n Because this delete can't be responsible for left being gc'd,\n we don't have to add left to the gc..\n */\n var right\n if (target.right != null) {\n right = yield* this.getOperation(target.right)\n } else {\n right = null\n }\n if (callType && !preventCallType) {\n var type = this.store.initializedTypes[JSON.stringify(target.parent)]\n if (type != null) {\n yield* type._changed(this, {\n struct: 'Delete',\n target: target.id,\n length: targetLength\n })\n }\n }\n // need to gc in the end!\n yield* this.store.addToGarbageCollector.call(this, target, left)\n if (right != null) {\n yield* this.store.addToGarbageCollector.call(this, right, target)\n }\n }\n }\n }\n /*\n Mark an operation as deleted&gc'd\n */\n * markGarbageCollected (id, len) {\n // this.mem.push([\"gc\", id]);\n this.store.addToDebug('yield* this.markGarbageCollected(', id, ', ', len, ')')\n var n = yield* this.markDeleted(id, len)\n if (n.id[1] < id[1] && !n.gc) {\n // un-extend left\n var newlen = n.len - (id[1] - n.id[1])\n n.len -= newlen\n yield* this.ds.put(n)\n n = {id: id, len: newlen, gc: false}\n yield* this.ds.put(n)\n }\n // get prev&next before adding a new operation\n var prev = yield* this.ds.findPrev(id)\n var next = yield* this.ds.findNext(id)\n\n if (id[1] + len < n.id[1] + n.len && !n.gc) {\n // un-extend right\n yield* this.ds.put({id: [id[0], id[1] + len], len: n.len - len, gc: false})\n n.len = len\n }\n // set gc'd\n n.gc = true\n // can extend left?\n if (\n prev != null &&\n prev.gc &&\n Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id)\n ) {\n prev.len += n.len\n yield* this.ds.delete(n.id)\n n = prev\n // ds.put n here?\n }\n // can extend right?\n if (\n next != null &&\n next.gc &&\n Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id)\n ) {\n n.len += next.len\n yield* this.ds.delete(next.id)\n }\n yield* this.ds.put(n)\n yield* this.updateState(n.id[0])\n }\n /*\n Mark an operation as deleted.\n\n returns the delete node\n */\n * markDeleted (id, length) {\n if (length == null) {\n length = 1\n }\n // this.mem.push([\"del\", id]);\n var n = yield* this.ds.findWithUpperBound(id)\n if (n != null && n.id[0] === id[0]) {\n if (n.id[1] <= id[1] && id[1] <= n.id[1] + n.len) {\n // id is in n's range\n var diff = id[1] + length - (n.id[1] + n.len) // overlapping right\n if (diff > 0) {\n // id+length overlaps n\n if (!n.gc) {\n n.len += diff\n } else {\n diff = n.id[1] + n.len - id[1] // overlapping left (id till n.end)\n if (diff < length) {\n // a partial deletion\n n = {id: [id[0], id[1] + diff], len: length - diff, gc: false}\n yield* this.ds.put(n)\n } else {\n // already gc'd\n throw new Error('Cannot happen! (it dit though.. :()')\n // return n\n }\n }\n } else {\n // no overlapping, already deleted\n return n\n }\n } else {\n // cannot extend left (there is no left!)\n n = {id: id, len: length, gc: false}\n yield* this.ds.put(n) // TODO: you double-put !!\n }\n } else {\n // cannot extend left\n n = {id: id, len: length, gc: false}\n yield* this.ds.put(n)\n }\n // can extend right?\n var next = yield* this.ds.findNext(n.id)\n if (\n next != null &&\n n.id[0] === next.id[0] &&\n n.id[1] + n.len >= next.id[1]\n ) {\n diff = n.id[1] + n.len - next.id[1] // from next.start to n.end\n while (diff >= 0) {\n // n overlaps with next\n if (next.gc) {\n // gc is stronger, so reduce length of n\n n.len -= diff\n if (diff >= next.len) {\n // delete the missing range after next\n diff = diff - next.len // missing range after next\n if (diff > 0) {\n yield* this.ds.put(n) // unneccessary? TODO!\n yield* this.markDeleted([next.id[0], next.id[1] + next.len], diff)\n }\n }\n break\n } else {\n // we can extend n with next\n if (diff > next.len) {\n // n is even longer than next\n // get next.next, and try to extend it\n var _next = yield* this.ds.findNext(next.id)\n yield* this.ds.delete(next.id)\n if (_next == null || n.id[0] !== _next.id[0]) {\n break\n } else {\n next = _next\n diff = n.id[1] + n.len - next.id[1] // from next.start to n.end\n // continue!\n }\n } else {\n // n just partially overlaps with next. extend n, delete next, and break this loop\n n.len += next.len - diff\n yield* this.ds.delete(next.id)\n break\n }\n }\n }\n }\n yield* this.ds.put(n)\n return n\n }\n /*\n Call this method when the client is connected&synced with the\n other clients (e.g. master). This will query the database for\n operations that can be gc'd and add them to the garbage collector.\n */\n * garbageCollectAfterSync () {\n if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {\n console.warn('gc should be empty after sync')\n }\n yield* this.os.iterate(this, null, null, function * (op) {\n if (op.gc) {\n delete op.gc\n yield* this.setOperation(op)\n }\n if (op.parent != null) {\n var parentDeleted = yield* this.isDeleted(op.parent)\n if (parentDeleted) {\n op.gc = true\n if (!op.deleted) {\n yield* this.markDeleted(op.id, op.content != null ? op.content.length : 1)\n op.deleted = true\n if (op.opContent != null) {\n yield* this.deleteOperation(op.opContent)\n }\n if (op.requires != null) {\n for (var i = 0; i < op.requires.length; i++) {\n yield* this.deleteOperation(op.requires[i])\n }\n }\n }\n yield* this.setOperation(op)\n this.store.gc1.push(op.id) // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!)\n return\n }\n }\n if (op.deleted) {\n var left = null\n if (op.left != null) {\n left = yield* this.getInsertion(op.left)\n }\n yield* this.store.addToGarbageCollector.call(this, op, left)\n }\n })\n }\n /*\n Really remove an op and all its effects.\n The complicated case here is the Insert operation:\n * reset left\n * reset right\n * reset parent.start\n * reset parent.end\n * reset origins of all right ops\n */\n * garbageCollectOperation (id) {\n this.store.addToDebug('yield* this.garbageCollectOperation(', id, ')')\n var o = yield* this.getOperation(id)\n yield* this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd\n // if op exists, then clean that mess up..\n if (o != null) {\n var deps = []\n if (o.opContent != null) {\n deps.push(o.opContent)\n }\n if (o.requires != null) {\n deps = deps.concat(o.requires)\n }\n for (var i = 0; i < deps.length; i++) {\n var dep = yield* this.getOperation(deps[i])\n if (dep != null) {\n if (!dep.deleted) {\n yield* this.deleteOperation(dep.id)\n dep = yield* this.getOperation(dep.id)\n }\n dep.gc = true\n yield* this.setOperation(dep)\n this.store.queueGarbageCollector(dep.id)\n } else {\n yield* this.markGarbageCollected(deps[i], 1)\n }\n }\n\n // remove gc'd op from the left op, if it exists\n if (o.left != null) {\n var left = yield* this.getInsertion(o.left)\n left.right = o.right\n yield* this.setOperation(left)\n }\n // remove gc'd op from the right op, if it exists\n // also reset origins of right ops\n if (o.right != null) {\n var right = yield* this.getOperation(o.right)\n right.left = o.left\n\n if (o.originOf != null && o.originOf.length > 0) {\n // find new origin of right ops\n // origin is the first left deleted operation\n var neworigin = o.left\n var neworigin_ = null\n while (neworigin != null) {\n neworigin_ = yield* this.getInsertion(neworigin)\n if (neworigin_.deleted) {\n break\n }\n neworigin = neworigin_.left\n }\n\n // reset origin of all right ops (except first right - duh!),\n\n /* ** The following code does not rely on the the originOf property **\n I recently added originOf to all Insert Operations (see Struct.Insert.execute),\n which saves which operations originate in a Insert operation.\n Garbage collecting without originOf is more memory efficient, but is nearly impossible for large texts, or lists!\n But I keep this code for now\n ```\n // reset origin of right\n right.origin = neworigin\n // search until you find origin pointer to the left of o\n if (right.right != null) {\n var i = yield* this.getOperation(right.right)\n var ids = [o.id, o.right]\n while (ids.some(function (id) {\n return Y.utils.compareIds(id, i.origin)\n })) {\n if (Y.utils.compareIds(i.origin, o.id)) {\n // reset origin of i\n i.origin = neworigin\n yield* this.setOperation(i)\n }\n // get next i\n if (i.right == null) {\n break\n } else {\n ids.push(i.id)\n i = yield* this.getOperation(i.right)\n }\n }\n }\n ```\n */\n // ** Now the new implementation starts **\n // reset neworigin of all originOf[*]\n for (var _i in o.originOf) {\n var originsIn = yield* this.getOperation(o.originOf[_i])\n if (originsIn != null) {\n originsIn.origin = neworigin\n yield* this.setOperation(originsIn)\n }\n }\n if (neworigin != null) {\n if (neworigin_.originOf == null) {\n neworigin_.originOf = o.originOf\n } else {\n neworigin_.originOf = o.originOf.concat(neworigin_.originOf)\n }\n yield* this.setOperation(neworigin_)\n }\n // we don't need to set right here, because\n // right should be in o.originOf => it is set it the previous for loop\n } else {\n // we didn't need to reset the origin of right\n // so we have to set right here\n yield* this.setOperation(right)\n }\n }\n // o may originate in another operation.\n // Since o is deleted, we have to reset o.origin's `originOf` property\n if (o.origin != null) {\n var origin = yield* this.getInsertion(o.origin)\n origin.originOf = origin.originOf.filter(function (_id) {\n return !Y.utils.compareIds(id, _id)\n })\n yield* this.setOperation(origin)\n }\n var parent\n if (o.parent != null) {\n parent = yield* this.getOperation(o.parent)\n }\n // remove gc'd op from parent, if it exists\n if (parent != null) {\n var setParent = false // whether to save parent to the os\n if (o.parentSub != null) {\n if (Y.utils.compareIds(parent.map[o.parentSub], o.id)) {\n setParent = true\n if (o.right != null) {\n parent.map[o.parentSub] = o.right\n } else {\n delete parent.map[o.parentSub]\n }\n }\n } else {\n if (Y.utils.compareIds(parent.start, o.id)) {\n // gc'd op is the start\n setParent = true\n parent.start = o.right\n }\n if (Y.utils.matchesId(o, parent.end)) {\n // gc'd op is the end\n setParent = true\n parent.end = o.left\n }\n }\n if (setParent) {\n yield* this.setOperation(parent)\n }\n }\n // finally remove it from the os\n yield* this.removeOperation(o.id)\n }\n }\n * checkDeleteStoreForState (state) {\n var n = yield* this.ds.findWithUpperBound([state.user, state.clock])\n if (n != null && n.id[0] === state.user && n.gc) {\n state.clock = Math.max(state.clock, n.id[1] + n.len)\n }\n }\n * updateState (user) {\n var state = yield* this.getState(user)\n yield* this.checkDeleteStoreForState(state)\n var o = yield* this.getInsertion([user, state.clock])\n var oLength = (o != null && o.content != null) ? o.content.length : 1\n while (o != null && user === o.id[0] && o.id[1] <= state.clock && o.id[1] + oLength > state.clock) {\n // either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS\n state.clock += oLength\n yield* this.checkDeleteStoreForState(state)\n o = yield* this.os.findNext(o.id)\n oLength = (o != null && o.content != null) ? o.content.length : 1\n }\n yield* this.setState(state)\n }\n /*\n apply a delete set in order to get\n the state of the supplied ds\n */\n * applyDeleteSet (ds) {\n var deletions = []\n\n for (var user in ds) {\n var dv = ds[user]\n var pos = 0\n var d = dv[pos]\n yield* this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], function * (n) {\n // cases:\n // 1. d deletes something to the right of n\n // => go to next n (break)\n // 2. d deletes something to the left of n\n // => create deletions\n // => reset d accordingly\n // *)=> if d doesn't delete anything anymore, go to next d (continue)\n // 3. not 2) and d deletes something that also n deletes\n // => reset d so that it doesn't contain n's deletion\n // *)=> if d does not delete anything anymore, go to next d (continue)\n while (d != null) {\n var diff = 0 // describe the diff of length in 1) and 2)\n if (n.id[1] + n.len <= d[0]) {\n // 1)\n break\n } else if (d[0] < n.id[1]) {\n // 2)\n // delete maximum the len of d\n // else delete as much as possible\n diff = Math.min(n.id[1] - d[0], d[1])\n deletions.push([user, d[0], diff, d[2]])\n } else {\n // 3)\n diff = n.id[1] + n.len - d[0] // never null (see 1)\n if (d[2] && !n.gc) {\n // d marks as gc'd but n does not\n // then delete either way\n deletions.push([user, d[0], Math.min(diff, d[1]), d[2]])\n }\n }\n if (d[1] <= diff) {\n // d doesn't delete anything anymore\n d = dv[++pos]\n } else {\n d[0] = d[0] + diff // reset pos\n d[1] = d[1] - diff // reset length\n }\n }\n })\n // for the rest.. just apply it\n for (; pos < dv.length; pos++) {\n d = dv[pos]\n deletions.push([user, d[0], d[1], d[2]])\n }\n }\n for (var i = 0; i < deletions.length; i++) {\n var del = deletions[i]\n // always try to delete..\n yield* this.deleteOperation([del[0], del[1]], del[2])\n if (del[3]) {\n // gc..\n yield* this.markGarbageCollected([del[0], del[1]], del[2]) // always mark gc'd\n // remove operation..\n var counter = del[1] + del[2]\n while (counter >= del[1]) {\n var o = yield* this.os.findWithUpperBound([del[0], counter - 1])\n if (o == null) {\n break\n }\n var oLen = o.content != null ? o.content.length : 1\n if (o.id[0] !== del[0] || o.id[1] + oLen <= del[1]) {\n // not in range\n break\n }\n if (o.id[1] + oLen > del[1] + del[2]) {\n // overlaps right\n o = yield* this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1])\n }\n if (o.id[1] < del[1]) {\n // overlaps left\n o = yield* this.getInsertionCleanStart([del[0], del[1]])\n }\n counter = o.id[1]\n yield* this.garbageCollectOperation(o.id)\n }\n }\n if (this.store.forwardAppliedOperations) {\n var ops = []\n ops.push({struct: 'Delete', target: [d[0], d[1]], length: del[2]})\n this.store.y.connector.broadcastOps(ops)\n }\n }\n }\n * isGarbageCollected (id) {\n var n = yield* this.ds.findWithUpperBound(id)\n return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len && n.gc\n }\n /*\n A DeleteSet (ds) describes all the deleted ops in the OS\n */\n * getDeleteSet () {\n var ds = {}\n yield* this.ds.iterate(this, null, null, function * (n) {\n var user = n.id[0]\n var counter = n.id[1]\n var len = n.len\n var gc = n.gc\n var dv = ds[user]\n if (dv === void 0) {\n dv = []\n ds[user] = dv\n }\n dv.push([counter, len, gc])\n })\n return ds\n }\n * isDeleted (id) {\n var n = yield* this.ds.findWithUpperBound(id)\n return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len\n }\n * setOperation (op) {\n yield* this.os.put(op)\n return op\n }\n * addOperation (op) {\n yield* this.os.put(op)\n if (!this.store.y.connector.isDisconnected() && this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') {\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps([op])\n }\n }\n // if insertion, try to combine with left insertion (if both have content property)\n * tryCombineWithLeft (op) {\n if (\n op != null &&\n op.left != null &&\n op.content != null &&\n op.left[0] === op.id[0] &&\n Y.utils.compareIds(op.left, op.origin)\n ) {\n var left = yield* this.getInsertion(op.left)\n if (left.content != null &&\n left.id[1] + left.content.length === op.id[1] &&\n left.originOf.length === 1 &&\n !left.gc && !left.deleted &&\n !op.gc && !op.deleted\n ) {\n // combine!\n if (op.originOf != null) {\n left.originOf = op.originOf\n } else {\n delete left.originOf\n }\n left.content = left.content.concat(op.content)\n left.right = op.right\n yield* this.os.delete(op.id)\n yield* this.setOperation(left)\n }\n }\n }\n * getInsertion (id) {\n var ins = yield* this.os.findWithUpperBound(id)\n if (ins == null) {\n return null\n } else {\n var len = ins.content != null ? ins.content.length : 1 // in case of opContent\n if (id[0] === ins.id[0] && id[1] < ins.id[1] + len) {\n return ins\n } else {\n return null\n }\n }\n }\n * getInsertionCleanStartEnd (id) {\n yield* this.getInsertionCleanStart(id)\n return yield* this.getInsertionCleanEnd(id)\n }\n // Return an insertion such that id is the first element of content\n // This function manipulates an operation, if necessary\n * getInsertionCleanStart (id) {\n var ins = yield* this.getInsertion(id)\n if (ins != null) {\n if (ins.id[1] === id[1]) {\n return ins\n } else {\n var left = Y.utils.copyObject(ins)\n ins.content = left.content.splice(id[1] - ins.id[1])\n ins.id = id\n var leftLid = Y.utils.getLastId(left)\n ins.origin = leftLid\n left.originOf = [ins.id]\n left.right = ins.id\n ins.left = leftLid\n // debugger // check\n yield* this.setOperation(left)\n yield* this.setOperation(ins)\n if (left.gc) {\n this.store.queueGarbageCollector(ins.id)\n }\n return ins\n }\n } else {\n return null\n }\n }\n // Return an insertion such that id is the last element of content\n // This function manipulates an operation, if necessary\n * getInsertionCleanEnd (id) {\n var ins = yield* this.getInsertion(id)\n if (ins != null) {\n if (ins.content == null || (ins.id[1] + ins.content.length - 1 === id[1])) {\n return ins\n } else {\n var right = Y.utils.copyObject(ins)\n right.content = ins.content.splice(id[1] - ins.id[1] + 1) // cut off remainder\n right.id = [id[0], id[1] + 1]\n var insLid = Y.utils.getLastId(ins)\n right.origin = insLid\n ins.originOf = [right.id]\n ins.right = right.id\n right.left = insLid\n // debugger // check\n yield* this.setOperation(right)\n yield* this.setOperation(ins)\n if (ins.gc) {\n this.store.queueGarbageCollector(right.id)\n }\n return ins\n }\n } else {\n return null\n }\n }\n * getOperation (id/* :any */)/* :Transaction */ {\n var o = yield* this.os.find(id)\n if (id[0] !== '_' || o != null) {\n return o\n } else { // type is string\n // generate this operation?\n var comp = id[1].split('_')\n if (comp.length > 1) {\n var struct = comp[0]\n var op = Y.Struct[struct].create(id)\n op.type = comp[1]\n yield* this.setOperation(op)\n return op\n } else {\n // won't be called. but just in case..\n console.error('Unexpected case. How can this happen?')\n debugger // eslint-disable-line\n return null\n }\n }\n }\n * removeOperation (id) {\n yield* this.os.delete(id)\n }\n * setState (state) {\n var val = {\n id: [state.user],\n clock: state.clock\n }\n yield* this.ss.put(val)\n }\n * getState (user) {\n var n = yield* this.ss.find([user])\n var clock = n == null ? null : n.clock\n if (clock == null) {\n clock = 0\n }\n return {\n user: user,\n clock: clock\n }\n }\n * getStateVector () {\n var stateVector = []\n yield* this.ss.iterate(this, null, null, function * (n) {\n stateVector.push({\n user: n.id[0],\n clock: n.clock\n })\n })\n return stateVector\n }\n * getStateSet () {\n var ss = {}\n yield* this.ss.iterate(this, null, null, function * (n) {\n ss[n.id[0]] = n.clock\n })\n return ss\n }\n /*\n Here, we make all missing operations executable for the receiving user.\n\n Notes:\n startSS: denotes to the SV that the remote user sent\n currSS: denotes to the state vector that the user should have if he\n applies all already sent operations (increases is each step)\n\n We face several problems:\n * Execute op as is won't work because ops depend on each other\n -> find a way so that they do not anymore\n * When changing left, must not go more to the left than the origin\n * When changing right, you have to consider that other ops may have op\n as their origin, this means that you must not set one of these ops\n as the new right (interdependencies of ops)\n * can't just go to the right until you find the first known operation,\n With currSS\n -> interdependency of ops is a problem\n With startSS\n -> leads to inconsistencies when two users join at the same time.\n Then the position depends on the order of execution -> error!\n\n Solution:\n -> re-create originial situation\n -> set op.left = op.origin (which never changes)\n -> set op.right\n to the first operation that is known (according to startSS)\n or to the first operation that has an origin that is not to the\n right of op.\n -> Enforces unique execution order -> happy user\n\n Improvements: TODO\n * Could set left to origin, or the first known operation\n (startSS or currSS.. ?)\n -> Could be necessary when I turn GC again.\n -> Is a bad(ish) idea because it requires more computation\n\n What we do:\n * Iterate over all missing operations.\n * When there is an operation, where the right op is known, send this op all missing ops to the left to the user\n * I explained above what we have to do with each operation. Here is how we do it efficiently:\n 1. Go to the left until you find either op.origin, or a known operation (let o denote current operation in the iteration)\n 2. Found a known operation -> set op.left = o, and send it to the user. stop\n 3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o)\n 4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue\n */\n * getOperations (startSS) {\n // TODO: use bounds here!\n if (startSS == null) {\n startSS = {}\n }\n var send = []\n\n var endSV = yield* this.getStateVector()\n for (var endState of endSV) {\n var user = endState.user\n if (user === '_') {\n continue\n }\n var startPos = startSS[user] || 0\n if (startPos > 0) {\n // There is a change that [user, startPos] is in a composed Insertion (with a smaller counter)\n // find out if that is the case\n var firstMissing = yield* this.getInsertion([user, startPos])\n if (firstMissing != null) {\n // update startPos\n startPos = firstMissing.id[1]\n }\n }\n yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {\n op = Y.Struct[op.struct].encode(op)\n if (op.struct !== 'Insert') {\n send.push(op)\n } else if (op.right == null || op.right[1] < (startSS[op.right[0]] || 0)) {\n // case 1. op.right is known\n var o = op\n // Remember: ?\n // -> set op.right\n // 1. to the first operation that is known (according to startSS)\n // 2. or to the first operation that has an origin that is not to the\n // right of op.\n // For this we maintain a list of ops which origins are not found yet.\n var missing_origins = [op]\n var newright = op.right\n while (true) {\n if (o.left == null) {\n op.left = null\n send.push(op)\n if (!Y.utils.compareIds(o.id, op.id)) {\n o = Y.Struct[op.struct].encode(o)\n o.right = missing_origins[missing_origins.length - 1].id\n send.push(o)\n }\n break\n }\n o = yield* this.getInsertion(o.left)\n // we set another o, check if we can reduce $missing_origins\n while (missing_origins.length > 0 && Y.utils.matchesId(o, missing_origins[missing_origins.length - 1].origin)) {\n missing_origins.pop()\n }\n if (o.id[1] < (startSS[o.id[0]] || 0)) {\n // case 2. o is known\n op.left = Y.utils.getLastId(o)\n send.push(op)\n break\n } else if (Y.utils.matchesId(o, op.origin)) {\n // case 3. o is op.origin\n op.left = op.origin\n send.push(op)\n op = Y.Struct[op.struct].encode(o)\n op.right = newright\n if (missing_origins.length > 0) {\n console.log('This should not happen .. :( please report this')\n }\n missing_origins = [op]\n } else {\n // case 4. send o, continue to find op.origin\n var s = Y.Struct[op.struct].encode(o)\n s.right = missing_origins[missing_origins.length - 1].id\n s.left = s.origin\n send.push(s)\n missing_origins.push(o)\n }\n }\n }\n })\n }\n return send.reverse()\n }\n /* this is what we used before.. use this as a reference..\n * makeOperationReady (startSS, op) {\n op = Y.Struct[op.struct].encode(op)\n op = Y.utils.copyObject(op)\n var o = op\n var ids = [op.id]\n // search for the new op.right\n // it is either the first known op (according to startSS)\n // or the o that has no origin to the right of op\n // (this is why we use the ids array)\n while (o.right != null) {\n var right = yield* this.getOperation(o.right)\n if (o.right[1] < (startSS[o.right[0]] || 0) || !ids.some(function (id) {\n return Y.utils.compareIds(id, right.origin)\n })) {\n break\n }\n ids.push(o.right)\n o = right\n }\n op.right = o.right\n op.left = op.origin\n return op\n }\n */\n * flush () {\n yield* this.os.flush()\n yield* this.ss.flush()\n yield* this.ds.flush()\n }\n }\n Y.Transaction = TransactionInterface\n}\n","/* @flow */\n'use strict'\n\n/*\n EventHandler is an helper class for constructing custom types.\n\n Why: When constructing custom types, you sometimes want your types to work\n synchronous: E.g.\n ``` Synchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === \"yay\"\n ```\n versus\n ``` Asynchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === undefined\n mytype.waitForSomething().then(function(){\n mytype.getSomething() === \"yay\"\n })\n ```\n\n The structures usually work asynchronously (you have to wait for the\n database request to finish). EventHandler helps you to make your type\n synchronous.\n*/\nmodule.exports = function (Y /* : any*/) {\n Y.utils = {}\n\n class EventListenerHandler {\n constructor () {\n this.eventListeners = []\n }\n destroy () {\n this.eventListeners = null\n }\n /*\n Basic event listener boilerplate...\n */\n addEventListener (f) {\n this.eventListeners.push(f)\n }\n removeEventListener (f) {\n this.eventListeners = this.eventListeners.filter(function (g) {\n return f !== g\n })\n }\n removeAllEventListeners () {\n this.eventListeners = []\n }\n callEventListeners (event) {\n for (var i = 0; i < this.eventListeners.length; i++) {\n try {\n this.eventListeners[i](event)\n } catch (e) {\n console.error('User events must not throw Errors!')\n }\n }\n }\n }\n Y.utils.EventListenerHandler = EventListenerHandler\n\n class EventHandler extends EventListenerHandler {\n /* ::\n waiting: Array;\n awaiting: number;\n onevent: Function;\n eventListeners: Array;\n */\n /*\n onevent: is called when the structure changes.\n\n Note: \"awaiting opertations\" is used to denote operations that were\n prematurely called. Events for received operations can not be executed until\n all prematurely called operations were executed (\"waiting operations\")\n */\n constructor (onevent /* : Function */) {\n super()\n this.waiting = []\n this.awaiting = 0\n this.onevent = onevent\n }\n destroy () {\n super.destroy()\n this.waiting = null\n this.awaiting = null\n this.onevent = null\n }\n /*\n Call this when a new operation arrives. It will be executed right away if\n there are no waiting operations, that you prematurely executed\n */\n receivedOp (op) {\n if (this.awaiting <= 0) {\n this.onevent(op)\n } else {\n this.waiting.push(op)\n }\n }\n /*\n You created some operations, and you want the `onevent` function to be\n called right away. Received operations will not be executed untill all\n prematurely called operations are executed\n */\n awaitAndPrematurelyCall (ops) {\n this.awaiting += ops.length\n ops.forEach(this.onevent)\n }\n /*\n Call this when you successfully awaited the execution of n Insert operations\n */\n awaitedInserts (n) {\n var ops = this.waiting.splice(this.waiting.length - n)\n for (var oid = 0; oid < ops.length; oid++) {\n var op = ops[oid]\n if (op.struct === 'Insert') {\n for (var i = this.waiting.length - 1; i >= 0; i--) {\n let w = this.waiting[i]\n // TODO: do I handle split operations correctly here? Super unlikely, but yeah..\n // Also: can this case happen? Can op be inserted in the middle of a larger op that is in $waiting?\n if (w.struct === 'Insert') {\n if (Y.utils.matchesId(w, op.left)) {\n // include the effect of op in w\n w.right = op.id\n // exclude the effect of w in op\n op.left = w.left\n } else if (Y.utils.compareIds(w.id, op.right)) {\n // similar..\n w.left = Y.utils.getLastId(op)\n op.right = w.right\n }\n }\n }\n } else {\n throw new Error('Expected Insert Operation!')\n }\n }\n this._tryCallEvents(n)\n }\n /*\n Call this when you successfully awaited the execution of n Delete operations\n */\n awaitedDeletes (n, newLeft) {\n var ops = this.waiting.splice(this.waiting.length - n)\n for (var j = 0; j < ops.length; j++) {\n var del = ops[j]\n if (del.struct === 'Delete') {\n if (newLeft != null) {\n for (var i = 0; i < this.waiting.length; i++) {\n let w = this.waiting[i]\n // We will just care about w.left\n if (w.struct === 'Insert' && Y.utils.compareIds(del.target, w.left)) {\n w.left = newLeft\n }\n }\n }\n } else {\n throw new Error('Expected Delete Operation!')\n }\n }\n this._tryCallEvents(n)\n }\n /* (private)\n Try to execute the events for the waiting operations\n */\n _tryCallEvents (n) {\n this.awaiting -= n\n if (this.awaiting === 0 && this.waiting.length > 0) {\n var ops = this.waiting\n this.waiting = []\n ops.forEach(this.onevent)\n }\n }\n }\n Y.utils.EventHandler = EventHandler\n\n /*\n A wrapper for the definition of a custom type.\n Every custom type must have three properties:\n\n * struct\n - Structname of this type\n * initType\n - Given a model, creates a custom type\n * class\n - the constructor of the custom type (e.g. in order to inherit from a type)\n */\n class CustomType { // eslint-disable-line\n /* ::\n struct: any;\n initType: any;\n class: Function;\n name: String;\n */\n constructor (def) {\n if (def.struct == null ||\n def.initType == null ||\n def.class == null ||\n def.name == null\n ) {\n throw new Error('Custom type was not initialized correctly!')\n }\n this.struct = def.struct\n this.initType = def.initType\n this.class = def.class\n this.name = def.name\n if (def.appendAdditionalInfo != null) {\n this.appendAdditionalInfo = def.appendAdditionalInfo\n }\n this.parseArguments = (def.parseArguments || function () {\n return [this]\n }).bind(this)\n this.parseArguments.typeDefinition = this\n }\n }\n Y.utils.CustomType = CustomType\n\n Y.utils.isTypeDefinition = function isTypeDefinition (v) {\n if (v != null) {\n if (v instanceof Y.utils.CustomType) return [v]\n else if (v.constructor === Array && v[0] instanceof Y.utils.CustomType) return v\n else if (v instanceof Function && v.typeDefinition instanceof Y.utils.CustomType) return [v.typeDefinition]\n }\n return false\n }\n\n /*\n Make a flat copy of an object\n (just copy properties)\n */\n function copyObject (o) {\n var c = {}\n for (var key in o) {\n c[key] = o[key]\n }\n return c\n }\n Y.utils.copyObject = copyObject\n\n /*\n Defines a smaller relation on Id's\n */\n function smaller (a, b) {\n return a[0] < b[0] || (a[0] === b[0] && (a[1] < b[1] || typeof a[1] < typeof b[1]))\n }\n Y.utils.smaller = smaller\n\n function compareIds (id1, id2) {\n if (id1 == null || id2 == null) {\n return id1 === id2\n } else {\n return id1[0] === id2[0] && id1[1] === id2[1]\n }\n }\n Y.utils.compareIds = compareIds\n\n function matchesId (op, id) {\n if (id == null || op == null) {\n return id === op\n } else {\n if (id[0] === op.id[0]) {\n if (op.content == null) {\n return id[1] === op.id[1]\n } else {\n return id[1] >= op.id[1] && id[1] < op.id[1] + op.content.length\n }\n }\n }\n }\n Y.utils.matchesId = matchesId\n\n function getLastId (op) {\n if (op.content == null || op.content.length === 1) {\n return op.id\n } else {\n return [op.id[0], op.id[1] + op.content.length - 1]\n }\n }\n Y.utils.getLastId = getLastId\n\n function createEmptyOpsArray (n) {\n var a = new Array(n)\n for (var i = 0; i < a.length; i++) {\n a[i] = {\n id: [null, null]\n }\n }\n return a\n }\n\n function createSmallLookupBuffer (Store) {\n /*\n This buffer implements a very small buffer that temporarily stores operations\n after they are read / before they are written.\n The buffer basically implements FIFO. Often requested lookups will be re-queued every time they are looked up / written.\n\n It can speed up lookups on Operation Stores and State Stores. But it does not require notable use of memory or processing power.\n\n Good for os and ss, bot not for ds (because it often uses methods that require a flush)\n\n I tried to optimize this for performance, therefore no highlevel operations.\n */\n class SmallLookupBuffer extends Store {\n constructor (arg) {\n // super(...arguments) -- do this when this is supported by stable nodejs\n super(arg)\n this.writeBuffer = createEmptyOpsArray(5)\n this.readBuffer = createEmptyOpsArray(10)\n }\n * find (id, noSuperCall) {\n var i, r\n for (i = this.readBuffer.length - 1; i >= 0; i--) {\n r = this.readBuffer[i]\n // we don't have to use compareids, because id is always defined!\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n // found r\n // move r to the end of readBuffer\n for (; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1]\n }\n this.readBuffer[this.readBuffer.length - 1] = r\n return r\n }\n }\n var o\n for (i = this.writeBuffer.length - 1; i >= 0; i--) {\n r = this.writeBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n o = r\n break\n }\n }\n if (i < 0 && noSuperCall === undefined) {\n // did not reach break in last loop\n // read id and put it to the end of readBuffer\n o = yield* super.find(id)\n }\n if (o != null) {\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1]\n }\n this.readBuffer[this.readBuffer.length - 1] = o\n }\n return o\n }\n * put (o) {\n var id = o.id\n var i, r // helper variables\n for (i = this.writeBuffer.length - 1; i >= 0; i--) {\n r = this.writeBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n // is already in buffer\n // forget r, and move o to the end of writeBuffer\n for (; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1]\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o\n break\n }\n }\n if (i < 0) {\n // did not reach break in last loop\n // write writeBuffer[0]\n var write = this.writeBuffer[0]\n if (write.id[0] !== null) {\n yield* super.put(write)\n }\n // put o to the end of writeBuffer\n for (i = 0; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1]\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o\n }\n // check readBuffer for every occurence of o.id, overwrite if found\n // whether found or not, we'll append o to the readbuffer\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n r = this.readBuffer[i + 1]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = o\n } else {\n this.readBuffer[i] = r\n }\n }\n this.readBuffer[this.readBuffer.length - 1] = o\n }\n * delete (id) {\n var i, r\n for (i = 0; i < this.readBuffer.length; i++) {\n r = this.readBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = {\n id: [null, null]\n }\n }\n }\n yield* this.flush()\n yield* super.delete(id)\n }\n * findWithLowerBound (id) {\n var o = yield* this.find(id, true)\n if (o != null) {\n return o\n } else {\n yield* this.flush()\n return yield* super.findWithLowerBound.apply(this, arguments)\n }\n }\n * findWithUpperBound (id) {\n var o = yield* this.find(id, true)\n if (o != null) {\n return o\n } else {\n yield* this.flush()\n return yield* super.findWithUpperBound.apply(this, arguments)\n }\n }\n * findNext () {\n yield* this.flush()\n return yield* super.findNext.apply(this, arguments)\n }\n * findPrev () {\n yield* this.flush()\n return yield* super.findPrev.apply(this, arguments)\n }\n * iterate () {\n yield* this.flush()\n yield* super.iterate.apply(this, arguments)\n }\n * flush () {\n for (var i = 0; i < this.writeBuffer.length; i++) {\n var write = this.writeBuffer[i]\n if (write.id[0] !== null) {\n yield* super.put(write)\n this.writeBuffer[i] = {\n id: [null, null]\n }\n }\n }\n }\n }\n return SmallLookupBuffer\n }\n Y.utils.createSmallLookupBuffer = createSmallLookupBuffer\n}\n","/* @flow */\r\n'use strict'\r\n\r\nrequire('./Connector.js')(Y)\r\nrequire('./Database.js')(Y)\r\nrequire('./Transaction.js')(Y)\r\nrequire('./Struct.js')(Y)\r\nrequire('./Utils.js')(Y)\r\nrequire('./Connectors/Test.js')(Y)\r\n\r\nvar requiringModules = {}\r\n\r\nmodule.exports = Y\r\nY.requiringModules = requiringModules\r\n\r\nY.extend = function (name, value) {\r\n if (value instanceof Y.utils.CustomType) {\r\n Y[name] = value.parseArguments\r\n } else {\r\n Y[name] = value\r\n }\r\n if (requiringModules[name] != null) {\r\n requiringModules[name].resolve()\r\n delete requiringModules[name]\r\n }\r\n}\r\n\r\nY.requestModules = requestModules\r\nfunction requestModules (modules) {\r\n // determine if this module was compiled for es5 or es6 (y.js vs. y.es6)\r\n // if Insert.execute is a Function, then it isnt a generator..\r\n // then load the es5(.js) files..\r\n var extention = typeof regeneratorRuntime !== 'undefined' ? '.js' : '.es6'\r\n var promises = []\r\n for (var i = 0; i < modules.length; i++) {\r\n var module = modules[i].split('(')[0]\r\n var modulename = 'y-' + module.toLowerCase()\r\n if (Y[module] == null) {\r\n if (requiringModules[module] == null) {\r\n // module does not exist\r\n if (typeof window !== 'undefined' && window.Y !== 'undefined') {\r\n var imported = document.createElement('script')\r\n imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention\r\n document.head.appendChild(imported)\r\n\r\n let requireModule = {}\r\n requiringModules[module] = requireModule\r\n requireModule.promise = new Promise(function (resolve) {\r\n requireModule.resolve = resolve\r\n })\r\n promises.push(requireModule.promise)\r\n } else {\r\n require(modulename)(Y)\r\n }\r\n } else {\r\n promises.push(requiringModules[modules[i]].promise)\r\n }\r\n }\r\n }\r\n return Promise.all(promises)\r\n}\r\n\r\n/* ::\r\ntype MemoryOptions = {\r\n name: 'memory'\r\n}\r\ntype IndexedDBOptions = {\r\n name: 'indexeddb',\r\n namespace: string\r\n}\r\ntype DbOptions = MemoryOptions | IndexedDBOptions\r\n\r\ntype WebRTCOptions = {\r\n name: 'webrtc',\r\n room: string\r\n}\r\ntype WebsocketsClientOptions = {\r\n name: 'websockets-client',\r\n room: string\r\n}\r\ntype ConnectionOptions = WebRTCOptions | WebsocketsClientOptions\r\n\r\ntype YOptions = {\r\n connector: ConnectionOptions,\r\n db: DbOptions,\r\n types: Array,\r\n sourceDir: string,\r\n share: {[key: string]: TypeName}\r\n}\r\n*/\r\n\r\nfunction Y (opts/* :YOptions */) /* :Promise */ {\r\n opts.types = opts.types != null ? opts.types : []\r\n var modules = [opts.db.name, opts.connector.name].concat(opts.types)\r\n for (var name in opts.share) {\r\n modules.push(opts.share[name])\r\n }\r\n Y.sourceDir = opts.sourceDir\r\n return Y.requestModules(modules).then(function () {\r\n return new Promise(function (resolve, reject) {\r\n if (opts == null) reject('An options object is expected! ')\r\n else if (opts.connector == null) reject('You must specify a connector! (missing connector property)')\r\n else if (opts.connector.name == null) reject('You must specify connector name! (missing connector.name property)')\r\n else if (opts.db == null) reject('You must specify a database! (missing db property)')\r\n else if (opts.connector.name == null) reject('You must specify db name! (missing db.name property)')\r\n else if (opts.share == null) reject('You must specify a set of shared types!')\r\n else {\r\n var yconfig = new YConfig(opts)\r\n yconfig.db.whenUserIdSet(function () {\r\n yconfig.init(function () {\r\n resolve(yconfig)\r\n })\r\n })\r\n }\r\n })\r\n })\r\n}\r\n\r\nclass YConfig {\r\n /* ::\r\n db: Y.AbstractDatabase;\r\n connector: Y.AbstractConnector;\r\n share: {[key: string]: any};\r\n options: Object;\r\n */\r\n constructor (opts, callback) {\r\n this.options = opts\r\n this.db = new Y[opts.db.name](this, opts.db)\r\n this.connector = new Y[opts.connector.name](this, opts.connector)\r\n }\r\n init (callback) {\r\n var opts = this.options\r\n var share = {}\r\n this.share = share\r\n this.db.requestTransaction(function * requestTransaction () {\r\n // create shared object\r\n for (var propertyname in opts.share) {\r\n var typeConstructor = opts.share[propertyname].split('(')\r\n var typeName = typeConstructor.splice(0, 1)\r\n var args = []\r\n if (typeConstructor.length === 1) {\r\n try {\r\n args = JSON.parse('[' + typeConstructor[0].split(')')[0] + ']')\r\n } catch (e) {\r\n throw new Error('Was not able to parse type definition! (share.' + propertyname + ')')\r\n }\r\n }\r\n var type = Y[typeName]\r\n var typedef = type.typeDefinition\r\n var id = ['_', typedef.struct + '_' + typeName + '_' + propertyname + '_' + typeConstructor]\r\n share[propertyname] = yield* this.createType(type.apply(typedef, args), id)\r\n }\r\n this.store.whenTransactionsFinished()\r\n .then(callback)\r\n })\r\n }\r\n isConnected () {\r\n return this.connector.isSynced\r\n }\r\n disconnect () {\r\n return this.connector.disconnect()\r\n }\r\n reconnect () {\r\n return this.connector.reconnect()\r\n }\r\n destroy () {\r\n if (this.connector.destroy != null) {\r\n this.connector.destroy()\r\n } else {\r\n this.connector.disconnect()\r\n }\r\n var self = this\r\n this.db.requestTransaction(function * () {\r\n yield* self.db.destroy()\r\n self.connector = null\r\n self.db = null\r\n })\r\n }\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n window.Y = Y\r\n}\r\n"]} \ No newline at end of file +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","src/Connector.js","src/Connectors/Test.js","src/Database.js","src/Struct.js","src/Transaction.js","src/Utils.js","src/y.js"],"names":[],"mappings":"AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9eA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5kCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3bA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"y.es6","sourceRoot":"/source/","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o;\n whenSyncedListeners: Array;\n currentSyncTarget: ?UserId;\n syncingClients: Array;\n forwardToSyncingClients: boolean;\n debug: boolean;\n broadcastedHB: boolean;\n syncStep2: Promise;\n userId: UserId;\n send: Function;\n broadcast: Function;\n broadcastOpBuffer: Array;\n protocolVersion: number;\n */\n /*\n opts contains the following information:\n role : String Role of this client (\"master\" or \"slave\")\n userId : String Uniquely defines the user.\n debug: Boolean Whether to print debug messages (optional)\n */\n constructor (y, opts) {\n this.y = y\n if (opts == null) {\n opts = {}\n }\n if (opts.role == null || opts.role === 'master') {\n this.role = 'master'\n } else if (opts.role === 'slave') {\n this.role = 'slave'\n } else {\n throw new Error(\"Role must be either 'master' or 'slave'!\")\n }\n this.y.db.forwardAppliedOperations = opts.forwardAppliedOperations || false\n this.role = opts.role\n this.connections = {}\n this.isSynced = false\n this.userEventListeners = []\n this.whenSyncedListeners = []\n this.currentSyncTarget = null\n this.syncingClients = []\n this.forwardToSyncingClients = opts.forwardToSyncingClients !== false\n this.debug = opts.debug === true\n this.broadcastedHB = false\n this.syncStep2 = Promise.resolve()\n this.broadcastOpBuffer = []\n this.protocolVersion = 11\n }\n reconnect () {\n }\n disconnect () {\n this.connections = {}\n this.isSynced = false\n this.currentSyncTarget = null\n this.broadcastedHB = false\n this.syncingClients = []\n this.whenSyncedListeners = []\n return this.y.db.stopGarbageCollector()\n }\n setUserId (userId) {\n if (this.userId == null) {\n this.userId = userId\n return this.y.db.setUserId(userId)\n } else {\n return null\n }\n }\n onUserEvent (f) {\n this.userEventListeners.push(f)\n }\n userLeft (user) {\n if (this.connections[user] != null) {\n delete this.connections[user]\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null\n this.findNextSyncTarget()\n }\n this.syncingClients = this.syncingClients.filter(function (cli) {\n return cli !== user\n })\n for (var f of this.userEventListeners) {\n f({\n action: 'userLeft',\n user: user\n })\n }\n }\n }\n userJoined (user, role) {\n if (role == null) {\n throw new Error('You must specify the role of the joined user!')\n }\n if (this.connections[user] != null) {\n throw new Error('This user already joined!')\n }\n this.connections[user] = {\n isSynced: false,\n role: role\n }\n for (var f of this.userEventListeners) {\n f({\n action: 'userJoined',\n user: user,\n role: role\n })\n }\n if (this.currentSyncTarget == null) {\n this.findNextSyncTarget()\n }\n }\n // Execute a function _when_ we are connected.\n // If not connected, wait until connected\n whenSynced (f) {\n if (this.isSynced) {\n f()\n } else {\n this.whenSyncedListeners.push(f)\n }\n }\n /*\n\n returns false, if there is no sync target\n true otherwise\n */\n findNextSyncTarget () {\n if (this.currentSyncTarget != null || this.isSynced) {\n return // \"The current sync has not finished!\"\n }\n\n var syncUser = null\n for (var uid in this.connections) {\n if (!this.connections[uid].isSynced) {\n syncUser = uid\n break\n }\n }\n var conn = this\n if (syncUser != null) {\n this.currentSyncTarget = syncUser\n this.y.db.requestTransaction(function *() {\n var stateSet = yield* this.getStateSet()\n var deleteSet = yield* this.getDeleteSet()\n conn.send(syncUser, {\n type: 'sync step 1',\n stateSet: stateSet,\n deleteSet: deleteSet,\n protocolVersion: conn.protocolVersion\n })\n })\n } else {\n this.y.db.requestTransaction(function *() {\n // it is crucial that isSynced is set at the time garbageCollectAfterSync is called\n conn.isSynced = true\n yield* this.garbageCollectAfterSync()\n // call whensynced listeners\n for (var f of conn.whenSyncedListeners) {\n f()\n }\n conn.whenSyncedListeners = []\n })\n }\n }\n send (uid, message) {\n if (this.debug) {\n console.log(`send ${this.userId} -> ${uid}: ${message.type}`, message) // eslint-disable-line\n }\n }\n /*\n Buffer operations, and broadcast them when ready.\n */\n broadcastOps (ops) {\n ops = ops.map(function (op) {\n return Y.Struct[op.struct].encode(op)\n })\n var self = this\n function broadcastOperations () {\n if (self.broadcastOpBuffer.length > 0) {\n self.broadcast({\n type: 'update',\n ops: self.broadcastOpBuffer\n })\n self.broadcastOpBuffer = []\n }\n }\n if (this.broadcastOpBuffer.length === 0) {\n this.broadcastOpBuffer = ops\n if (this.y.db.transactionInProgress) {\n this.y.db.whenTransactionsFinished().then(broadcastOperations)\n } else {\n setTimeout(broadcastOperations, 0)\n }\n } else {\n this.broadcastOpBuffer = this.broadcastOpBuffer.concat(ops)\n }\n }\n /*\n You received a raw message, and you know that it is intended for Yjs. Then call this function.\n */\n receiveMessage (sender/* :UserId */, message/* :Message */) {\n if (sender === this.userId) {\n return\n }\n if (this.debug) {\n console.log(`receive ${sender} -> ${this.userId}: ${message.type}`, JSON.parse(JSON.stringify(message))) // eslint-disable-line\n }\n if (message.protocolVersion != null && message.protocolVersion !== this.protocolVersion) {\n console.error(\n `You tried to sync with a yjs instance that has a different protocol version\n (You: ${this.protocolVersion}, Client: ${message.protocolVersion}).\n The sync was stopped. You need to upgrade your dependencies (especially Yjs & the Connector)!\n `)\n this.send(sender, {\n type: 'sync stop',\n protocolVersion: this.protocolVersion\n })\n return\n }\n if (message.type === 'sync step 1') {\n let conn = this\n let m = message\n this.y.db.requestTransaction(function *() {\n var currentStateSet = yield* this.getStateSet()\n yield* this.applyDeleteSet(m.deleteSet)\n\n var ds = yield* this.getDeleteSet()\n var ops = yield* this.getOperations(m.stateSet)\n conn.send(sender, {\n type: 'sync step 2',\n os: ops,\n stateSet: currentStateSet,\n deleteSet: ds,\n protocolVersion: this.protocolVersion\n })\n if (this.forwardToSyncingClients) {\n conn.syncingClients.push(sender)\n setTimeout(function () {\n conn.syncingClients = conn.syncingClients.filter(function (cli) {\n return cli !== sender\n })\n conn.send(sender, {\n type: 'sync done'\n })\n }, 5000) // TODO: conn.syncingClientDuration)\n } else {\n conn.send(sender, {\n type: 'sync done'\n })\n }\n conn._setSyncedWith(sender)\n })\n } else if (message.type === 'sync step 2') {\n let conn = this\n var broadcastHB = !this.broadcastedHB\n this.broadcastedHB = true\n var db = this.y.db\n var defer = {}\n defer.promise = new Promise(function (resolve) {\n defer.resolve = resolve\n })\n this.syncStep2 = defer.promise\n let m /* :MessageSyncStep2 */ = message\n db.requestTransaction(function * () {\n yield* this.applyDeleteSet(m.deleteSet)\n this.store.apply(m.os)\n db.requestTransaction(function * () {\n var ops = yield* this.getOperations(m.stateSet)\n if (ops.length > 0) {\n if (!broadcastHB) { // TODO: consider to broadcast here..\n conn.send(sender, {\n type: 'update',\n ops: ops\n })\n } else {\n // broadcast only once!\n conn.broadcastOps(ops)\n }\n }\n defer.resolve()\n })\n })\n } else if (message.type === 'sync done') {\n var self = this\n this.syncStep2.then(function () {\n self._setSyncedWith(sender)\n })\n } else if (message.type === 'update') {\n if (this.forwardToSyncingClients) {\n for (var client of this.syncingClients) {\n this.send(client, message)\n }\n }\n if (this.y.db.forwardAppliedOperations) {\n var delops = message.ops.filter(function (o) {\n return o.struct === 'Delete'\n })\n if (delops.length > 0) {\n this.broadcastOps(delops)\n }\n }\n this.y.db.apply(message.ops)\n }\n }\n _setSyncedWith (user) {\n var conn = this.connections[user]\n if (conn != null) {\n conn.isSynced = true\n }\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null\n this.findNextSyncTarget()\n }\n }\n /*\n Currently, the HB encodes operations as JSON. For the moment I want to keep it\n that way. Maybe we support encoding in the HB as XML in the future, but for now I don't want\n too much overhead. Y is very likely to get changed a lot in the future\n\n Because we don't want to encode JSON as string (with character escaping, wich makes it pretty much unreadable)\n we encode the JSON as XML.\n\n When the HB support encoding as XML, the format should look pretty much like this.\n\n does not support primitive values as array elements\n expects an ltx (less than xml) object\n */\n parseMessageFromXml (m/* :any */) {\n function parseArray (node) {\n for (var n of node.children) {\n if (n.getAttribute('isArray') === 'true') {\n return parseArray(n)\n } else {\n return parseObject(n)\n }\n }\n }\n function parseObject (node/* :any */) {\n var json = {}\n for (var attrName in node.attrs) {\n var value = node.attrs[attrName]\n var int = parseInt(value, 10)\n if (isNaN(int) || ('' + int) !== value) {\n json[attrName] = value\n } else {\n json[attrName] = int\n }\n }\n for (var n/* :any */ in node.children) {\n var name = n.name\n if (n.getAttribute('isArray') === 'true') {\n json[name] = parseArray(n)\n } else {\n json[name] = parseObject(n)\n }\n }\n return json\n }\n parseObject(m)\n }\n /*\n encode message in xml\n we use string because Strophe only accepts an \"xml-string\"..\n So {a:4,b:{c:5}} will look like\n \n \n \n m - ltx element\n json - Object\n */\n encodeMessageToXml (msg, obj) {\n // attributes is optional\n function encodeObject (m, json) {\n for (var name in json) {\n var value = json[name]\n if (name == null) {\n // nop\n } else if (value.constructor === Object) {\n encodeObject(m.c(name), value)\n } else if (value.constructor === Array) {\n encodeArray(m.c(name), value)\n } else {\n m.setAttribute(name, value)\n }\n }\n }\n function encodeArray (m, array) {\n m.setAttribute('isArray', 'true')\n for (var e of array) {\n if (e.constructor === Object) {\n encodeObject(m.c('array-element'), e)\n } else {\n encodeArray(m.c('array-element'), e)\n }\n }\n }\n if (obj.constructor === Object) {\n encodeObject(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj)\n } else if (obj.constructor === Array) {\n encodeArray(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj)\n } else {\n throw new Error(\"I can't encode this json!\")\n }\n }\n }\n Y.AbstractConnector = AbstractConnector\n}\n","/* global getRandom, async */\n'use strict'\n\nmodule.exports = function (Y) {\n var globalRoom = {\n users: {},\n buffers: {}, // TODO: reimplement this idea. This does not cover all cases!! Here, you have a queue which is unrealistic (i.e. think about multiple incoming connections)\n removeUser: function (user) {\n for (var i in this.users) {\n this.users[i].userLeft(user)\n }\n delete this.users[user]\n delete this.buffers[user]\n },\n addUser: function (connector) {\n this.users[connector.userId] = connector\n this.buffers[connector.userId] = {}\n for (var uname in this.users) {\n if (uname !== connector.userId) {\n var u = this.users[uname]\n u.userJoined(connector.userId, 'master')\n connector.userJoined(u.userId, 'master')\n }\n }\n },\n whenTransactionsFinished: function () {\n var ps = []\n for (var name in this.users) {\n ps.push(this.users[name].y.db.whenTransactionsFinished())\n }\n return Promise.all(ps)\n },\n flushOne: function flushOne () {\n var bufs = []\n for (var receiver in globalRoom.buffers) {\n let buff = globalRoom.buffers[receiver]\n var push = false\n for (let sender in buff) {\n if (buff[sender].length > 0) {\n push = true\n break\n }\n }\n if (push) {\n bufs.push(receiver)\n }\n }\n if (bufs.length > 0) {\n var userId = getRandom(bufs)\n let buff = globalRoom.buffers[userId]\n let sender = getRandom(Object.keys(buff))\n var m = buff[sender].shift()\n if (buff[sender].length === 0) {\n delete buff[sender]\n }\n var user = globalRoom.users[userId]\n user.receiveMessage(m[0], m[1])\n return user.y.db.whenTransactionsFinished()\n } else {\n return false\n }\n },\n flushAll: function () {\n return new Promise(function (resolve) {\n // flushes may result in more created operations,\n // flush until there is nothing more to flush\n function nextFlush () {\n var c = globalRoom.flushOne()\n if (c) {\n while (c) {\n c = globalRoom.flushOne()\n }\n globalRoom.whenTransactionsFinished().then(nextFlush)\n } else {\n setTimeout(function () {\n var c = globalRoom.flushOne()\n if (c) {\n c.then(function () {\n globalRoom.whenTransactionsFinished().then(nextFlush)\n })\n } else {\n resolve()\n }\n }, 10)\n }\n }\n globalRoom.whenTransactionsFinished().then(nextFlush)\n })\n }\n }\n Y.utils.globalRoom = globalRoom\n\n var userIdCounter = 0\n\n class Test extends Y.AbstractConnector {\n constructor (y, options) {\n if (options === undefined) {\n throw new Error('Options must not be undefined!')\n }\n options.role = 'master'\n options.forwardToSyncingClients = false\n super(y, options)\n this.setUserId((userIdCounter++) + '').then(() => {\n globalRoom.addUser(this)\n })\n this.globalRoom = globalRoom\n this.syncingClientDuration = 0\n }\n receiveMessage (sender, m) {\n super.receiveMessage(sender, JSON.parse(JSON.stringify(m)))\n }\n send (userId, message) {\n var buffer = globalRoom.buffers[userId]\n if (buffer != null) {\n if (buffer[this.userId] == null) {\n buffer[this.userId] = []\n }\n buffer[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n broadcast (message) {\n for (var key in globalRoom.buffers) {\n var buff = globalRoom.buffers[key]\n if (buff[this.userId] == null) {\n buff[this.userId] = []\n }\n buff[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n isDisconnected () {\n return globalRoom.users[this.userId] == null\n }\n reconnect () {\n if (this.isDisconnected()) {\n globalRoom.addUser(this)\n super.reconnect()\n }\n return Y.utils.globalRoom.flushAll()\n }\n disconnect () {\n if (!this.isDisconnected()) {\n globalRoom.removeUser(this.userId)\n super.disconnect()\n }\n return this.y.db.whenTransactionsFinished()\n }\n flush () {\n var self = this\n return async(function * () {\n var buff = globalRoom.buffers[self.userId]\n while (Object.keys(buff).length > 0) {\n var sender = getRandom(Object.keys(buff))\n var m = buff[sender].shift()\n if (buff[sender].length === 0) {\n delete buff[sender]\n }\n this.receiveMessage(m[0], m[1])\n }\n yield self.whenTransactionsFinished()\n })\n }\n }\n\n Y.Test = Test\n}\n","/* @flow */\n'use strict'\n\nmodule.exports = function (Y /* :any */) {\n /*\n Partial definition of an OperationStore.\n TODO: name it Database, operation store only holds operations.\n\n A database definition must alse define the following methods:\n * logTable() (optional)\n - show relevant information information in a table\n * requestTransaction(makeGen)\n - request a transaction\n * destroy()\n - destroy the database\n */\n class AbstractDatabase {\n /* ::\n y: YConfig;\n forwardAppliedOperations: boolean;\n listenersById: Object;\n listenersByIdExecuteNow: Array;\n listenersByIdRequestPending: boolean;\n initializedTypes: Object;\n whenUserIdSetListener: ?Function;\n waitingTransactions: Array;\n transactionInProgress: boolean;\n executeOrder: Array;\n gc1: Array;\n gc2: Array;\n gcTimeout: number;\n gcInterval: any;\n garbageCollect: Function;\n executeOrder: Array; // for debugging only\n userId: UserId;\n opClock: number;\n transactionsFinished: ?{promise: Promise, resolve: any};\n transact: (x: ?Generator) => any;\n */\n constructor (y, opts) {\n this.y = y\n var os = this\n this.userId = null\n var resolve\n this.userIdPromise = new Promise(function (r) {\n resolve = r\n })\n this.userIdPromise.resolve = resolve\n // whether to broadcast all applied operations (insert & delete hook)\n this.forwardAppliedOperations = false\n // E.g. this.listenersById[id] : Array\n this.listenersById = {}\n // Execute the next time a transaction is requested\n this.listenersByIdExecuteNow = []\n // A transaction is requested\n this.listenersByIdRequestPending = false\n /* To make things more clear, the following naming conventions:\n * ls : we put this.listenersById on ls\n * l : Array\n * id : Id (can't use as property name)\n * sid : String (converted from id via JSON.stringify\n so we can use it as a property name)\n\n Always remember to first overwrite\n a property before you iterate over it!\n */\n // TODO: Use ES7 Weak Maps. This way types that are no longer user,\n // wont be kept in memory.\n this.initializedTypes = {}\n this.waitingTransactions = []\n this.transactionInProgress = false\n this.transactionIsFlushed = false\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n this.executeOrder = []\n }\n this.gc1 = [] // first stage\n this.gc2 = [] // second stage -> after that, remove the op\n this.gcTimeout = !opts.gcTimeout ? 50000 : opts.gcTimeoutÅ›\n function garbageCollect () {\n return os.whenTransactionsFinished().then(function () {\n if (os.gc1.length > 0 || os.gc2.length > 0) {\n if (!os.y.isConnected()) {\n console.warn('gc should be empty when disconnected!')\n }\n return new Promise((resolve) => {\n os.requestTransaction(function * () {\n if (os.y.connector != null && os.y.connector.isSynced) {\n for (var i = 0; i < os.gc2.length; i++) {\n var oid = os.gc2[i]\n yield* this.garbageCollectOperation(oid)\n }\n os.gc2 = os.gc1\n os.gc1 = []\n }\n // TODO: Use setInterval here instead (when garbageCollect is called several times there will be several timeouts..)\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout)\n }\n resolve()\n })\n })\n } else {\n // TODO: see above\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout)\n }\n return Promise.resolve()\n }\n })\n }\n this.garbageCollect = garbageCollect\n if (this.gcTimeout > 0) {\n garbageCollect()\n }\n }\n queueGarbageCollector (id) {\n if (this.y.isConnected()) {\n this.gc1.push(id)\n }\n }\n emptyGarbageCollector () {\n return new Promise(resolve => {\n var check = () => {\n if (this.gc1.length > 0 || this.gc2.length > 0) {\n this.garbageCollect().then(check)\n } else {\n resolve()\n }\n }\n setTimeout(check, 0)\n })\n }\n addToDebug () {\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n var command /* :string */ = Array.prototype.map.call(arguments, function (s) {\n if (typeof s === 'string') {\n return s\n } else {\n return JSON.stringify(s)\n }\n }).join('').replace(/\"/g, \"'\").replace(/,/g, ', ').replace(/:/g, ': ')\n this.executeOrder.push(command)\n }\n }\n getDebugData () {\n console.log(this.executeOrder.join('\\n'))\n }\n stopGarbageCollector () {\n var self = this\n return new Promise(function (resolve) {\n self.requestTransaction(function * () {\n var ungc /* :Array */ = self.gc1.concat(self.gc2)\n self.gc1 = []\n self.gc2 = []\n for (var i = 0; i < ungc.length; i++) {\n var op = yield* this.getOperation(ungc[i])\n if (op != null) {\n delete op.gc\n yield* this.setOperation(op)\n }\n }\n resolve()\n })\n })\n }\n /*\n Try to add to GC.\n\n TODO: rename this function\n\n Rulez:\n * Only gc if this user is online\n * The most left element in a list must not be gc'd.\n => There is at least one element in the list\n\n returns true iff op was added to GC\n */\n * addToGarbageCollector (op, left) {\n if (\n op.gc == null &&\n op.deleted === true\n ) {\n var gc = false\n if (left != null && left.deleted === true) {\n gc = true\n } else if (op.content != null && op.content.length > 1) {\n op = yield* this.getInsertionCleanStart([op.id[0], op.id[1] + 1])\n gc = true\n }\n if (gc) {\n op.gc = true\n yield* this.setOperation(op)\n this.store.queueGarbageCollector(op.id)\n return true\n }\n }\n return false\n }\n removeFromGarbageCollector (op) {\n function filter (o) {\n return !Y.utils.compareIds(o, op.id)\n }\n this.gc1 = this.gc1.filter(filter)\n this.gc2 = this.gc2.filter(filter)\n delete op.gc\n }\n * destroy () {\n clearInterval(this.gcInterval)\n this.gcInterval = null\n for (var key in this.initializedTypes) {\n var type = this.initializedTypes[key]\n if (type._destroy != null) {\n type._destroy()\n } else {\n console.error('The type you included does not provide destroy functionality, it will remain in memory (updating your packages will help).')\n }\n }\n }\n setUserId (userId) {\n if (!this.userIdPromise.inProgress) {\n this.userIdPromise.inProgress = true\n var self = this\n self.requestTransaction(function * () {\n self.userId = userId\n var state = yield* this.getState(userId)\n self.opClock = state.clock\n self.userIdPromise.resolve(userId)\n })\n }\n return this.userIdPromise\n }\n whenUserIdSet (f) {\n this.userIdPromise.then(f)\n }\n getNextOpId (numberOfIds) {\n if (numberOfIds == null) {\n throw new Error('getNextOpId expects the number of created ids to create!')\n } else if (this.userId == null) {\n throw new Error('OperationStore not yet initialized!')\n } else {\n var id = [this.userId, this.opClock]\n this.opClock += numberOfIds\n return id\n }\n }\n /*\n Apply a list of operations.\n\n * get a transaction\n * check whether all Struct.*.requiredOps are in the OS\n * check if it is an expected op (otherwise wait for it)\n * check if was deleted, apply a delete operation after op was applied\n */\n apply (ops) {\n for (var i = 0; i < ops.length; i++) {\n var o = ops[i]\n if (o.id == null || o.id[0] !== this.y.connector.userId) {\n var required = Y.Struct[o.struct].requiredOps(o)\n if (o.requires != null) {\n required = required.concat(o.requires)\n }\n this.whenOperationsExist(required, o)\n }\n }\n }\n /*\n op is executed as soon as every operation requested is available.\n Note that Transaction can (and should) buffer requests.\n */\n whenOperationsExist (ids, op) {\n if (ids.length > 0) {\n let listener = {\n op: op,\n missing: ids.length\n }\n\n for (let i = 0; i < ids.length; i++) {\n let id = ids[i]\n let sid = JSON.stringify(id)\n let l = this.listenersById[sid]\n if (l == null) {\n l = []\n this.listenersById[sid] = l\n }\n l.push(listener)\n }\n } else {\n this.listenersByIdExecuteNow.push({\n op: op\n })\n }\n\n if (this.listenersByIdRequestPending) {\n return\n }\n\n this.listenersByIdRequestPending = true\n var store = this\n\n this.requestTransaction(function * () {\n var exeNow = store.listenersByIdExecuteNow\n store.listenersByIdExecuteNow = []\n\n var ls = store.listenersById\n store.listenersById = {}\n\n store.listenersByIdRequestPending = false\n\n for (let key = 0; key < exeNow.length; key++) {\n let o = exeNow[key].op\n yield* store.tryExecute.call(this, o)\n }\n\n for (var sid in ls) {\n var l = ls[sid]\n var id = JSON.parse(sid)\n var op\n if (typeof id[1] === 'string') {\n op = yield* this.getOperation(id)\n } else {\n op = yield* this.getInsertion(id)\n }\n if (op == null) {\n store.listenersById[sid] = l\n } else {\n for (let i = 0; i < l.length; i++) {\n let listener = l[i]\n let o = listener.op\n if (--listener.missing === 0) {\n yield* store.tryExecute.call(this, o)\n }\n }\n }\n }\n })\n }\n /*\n Actually execute an operation, when all expected operations are available.\n */\n /* :: // TODO: this belongs somehow to transaction\n store: Object;\n getOperation: any;\n isGarbageCollected: any;\n addOperation: any;\n whenOperationsExist: any;\n */\n * tryExecute (op) {\n this.store.addToDebug('yield* this.store.tryExecute.call(this, ', JSON.stringify(op), ')')\n if (op.struct === 'Delete') {\n yield* Y.Struct.Delete.execute.call(this, op)\n // this is now called in Transaction.deleteOperation!\n // yield* this.store.operationAdded(this, op)\n } else {\n // check if this op was defined\n var defined = yield* this.getInsertion(op.id)\n while (defined != null && defined.content != null) {\n // check if this op has a longer content in the case it is defined\n if (defined.id[1] + defined.content.length < op.id[1] + op.content.length) {\n var overlapSize = defined.content.length - (op.id[1] - defined.id[1])\n op.content.splice(0, overlapSize)\n op.id = [op.id[0], op.id[1] + overlapSize]\n op.left = Y.utils.getLastId(defined)\n op.origin = op.left\n defined = yield* this.getOperation(op.id) // getOperation suffices here\n } else {\n break\n }\n }\n if (defined == null) {\n var isGarbageCollected = yield* this.isGarbageCollected(op.id)\n if (!isGarbageCollected) {\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n\n // if insertion, try to combine with left\n yield* this.tryCombineWithLeft(op)\n }\n }\n }\n }\n // called by a transaction when an operation is added\n * operationAdded (transaction, op) {\n // increase SS\n yield* transaction.updateState(op.id[0])\n\n var opLen = op.content != null ? op.content.length : 1\n for (let i = 0; i < opLen; i++) {\n // notify whenOperation listeners (by id)\n var sid = JSON.stringify([op.id[0], op.id[1] + i])\n var l = this.listenersById[sid]\n delete this.listenersById[sid]\n\n if (l != null) {\n for (var key in l) {\n var listener = l[key]\n if (--listener.missing === 0) {\n this.whenOperationsExist([], listener.op)\n }\n }\n }\n }\n var t = this.initializedTypes[JSON.stringify(op.parent)]\n\n // if parent is deleted, mark as gc'd and return\n if (op.parent != null) {\n var parentIsDeleted = yield* transaction.isDeleted(op.parent)\n if (parentIsDeleted) {\n yield* transaction.deleteList(op.id)\n return\n }\n }\n\n // notify parent, if it was instanciated as a custom type\n if (t != null) {\n let o = Y.utils.copyObject(op)\n yield* t._changed(transaction, o)\n }\n if (!op.deleted) {\n // Delete if DS says this is actually deleted\n var len = op.content != null ? op.content.length : 1\n var startId = op.id // You must not use op.id in the following loop, because op will change when deleted\n for (let i = 0; i < len; i++) {\n var id = [startId[0], startId[1] + i]\n var opIsDeleted = yield* transaction.isDeleted(id)\n if (opIsDeleted) {\n var delop = {\n struct: 'Delete',\n target: id\n }\n yield* this.tryExecute.call(transaction, delop)\n }\n }\n }\n }\n whenTransactionsFinished () {\n if (this.transactionInProgress) {\n if (this.transactionsFinished == null) {\n var resolve\n var promise = new Promise(function (r) {\n resolve = r\n })\n this.transactionsFinished = {\n resolve: resolve,\n promise: promise\n }\n return promise\n } else {\n return this.transactionsFinished.promise\n }\n } else {\n return Promise.resolve()\n }\n }\n // Check if there is another transaction request.\n // * the last transaction is always a flush :)\n getNextRequest () {\n if (this.waitingTransactions.length === 0) {\n if (this.transactionIsFlushed) {\n this.transactionInProgress = false\n this.transactionIsFlushed = false\n if (this.transactionsFinished != null) {\n this.transactionsFinished.resolve()\n this.transactionsFinished = null\n }\n return null\n } else {\n this.transactionIsFlushed = true\n return function * () {\n yield* this.flush()\n }\n }\n } else {\n this.transactionIsFlushed = false\n return this.waitingTransactions.shift()\n }\n }\n requestTransaction (makeGen/* :any */, callImmediately) {\n this.waitingTransactions.push(makeGen)\n if (!this.transactionInProgress) {\n this.transactionInProgress = true\n if (false || callImmediately) { // TODO: decide whether this is ok or not..\n this.transact(this.getNextRequest())\n } else {\n var self = this\n setTimeout(function () {\n self.transact(self.getNextRequest())\n }, 0)\n }\n }\n }\n }\n Y.AbstractDatabase = AbstractDatabase\n}\n","/* @flow */\n'use strict'\n\n/*\n An operation also defines the structure of a type. This is why operation and\n structure are used interchangeably here.\n\n It must be of the type Object. I hope to achieve some performance\n improvements when working on databases that support the json format.\n\n An operation must have the following properties:\n\n * encode\n - Encode the structure in a readable format (preferably string- todo)\n * decode (todo)\n - decode structure to json\n * execute\n - Execute the semantics of an operation.\n * requiredOps\n - Operations that are required to execute this operation.\n*/\nmodule.exports = function (Y/* :any */) {\n var Struct = {\n /* This is the only operation that is actually not a structure, because\n it is not stored in the OS. This is why it _does not_ have an id\n\n op = {\n target: Id\n }\n */\n Delete: {\n encode: function (op) {\n return op\n },\n requiredOps: function (op) {\n return [] // [op.target]\n },\n execute: function * (op) {\n return yield* this.deleteOperation(op.target, op.length || 1)\n }\n },\n Insert: {\n /* {\n content: [any],\n opContent: Id,\n id: Id,\n left: Id,\n origin: Id,\n right: Id,\n parent: Id,\n parentSub: string (optional), // child of Map type\n }\n */\n encode: function (op/* :Insertion */) /* :Insertion */ {\n // TODO: you could not send the \"left\" property, then you also have to\n // \"op.left = null\" in $execute or $decode\n var e/* :any */ = {\n id: op.id,\n left: op.left,\n right: op.right,\n origin: op.origin,\n parent: op.parent,\n struct: op.struct\n }\n if (op.parentSub != null) {\n e.parentSub = op.parentSub\n }\n if (op.hasOwnProperty('opContent')) {\n e.opContent = op.opContent\n } else {\n e.content = op.content.slice()\n }\n\n return e\n },\n requiredOps: function (op) {\n var ids = []\n if (op.left != null) {\n ids.push(op.left)\n }\n if (op.right != null) {\n ids.push(op.right)\n }\n if (op.origin != null && !Y.utils.compareIds(op.left, op.origin)) {\n ids.push(op.origin)\n }\n // if (op.right == null && op.left == null) {\n ids.push(op.parent)\n\n if (op.opContent != null) {\n ids.push(op.opContent)\n }\n return ids\n },\n getDistanceToOrigin: function * (op) {\n if (op.left == null) {\n return 0\n } else {\n var d = 0\n var o = yield* this.getInsertion(op.left)\n while (!Y.utils.matchesId(o, op.origin)) {\n d++\n if (o.left == null) {\n break\n } else {\n o = yield* this.getInsertion(o.left)\n }\n }\n return d\n }\n },\n /*\n # $this has to find a unique position between origin and the next known character\n # case 1: $origin equals $o.origin: the $creator parameter decides if left or right\n # let $OL= [o1,o2,o3,o4], whereby $this is to be inserted between o1 and o4\n # o2,o3 and o4 origin is 1 (the position of o2)\n # there is the case that $this.creator < o2.creator, but o3.creator < $this.creator\n # then o2 knows o3. Since on another client $OL could be [o1,o3,o4] the problem is complex\n # therefore $this would be always to the right of o3\n # case 2: $origin < $o.origin\n # if current $this insert_position > $o origin: $this ins\n # else $insert_position will not change\n # (maybe we encounter case 1 later, then this will be to the right of $o)\n # case 3: $origin > $o.origin\n # $this insert_position is to the left of $o (forever!)\n */\n execute: function * (op) {\n var i // loop counter\n\n // during this function some ops may get split into two pieces (e.g. with getInsertionCleanEnd)\n // We try to merge them later, if possible\n var tryToRemergeLater = []\n\n if (op.origin != null) { // TODO: !== instead of !=\n // we save in origin that op originates in it\n // we need that later when we eventually garbage collect origin (see transaction)\n var origin = yield* this.getInsertionCleanEnd(op.origin)\n if (origin.originOf == null) {\n origin.originOf = []\n }\n origin.originOf.push(op.id)\n yield* this.setOperation(origin)\n if (origin.right != null) {\n tryToRemergeLater.push(origin.right)\n }\n }\n var distanceToOrigin = i = yield* Struct.Insert.getDistanceToOrigin.call(this, op) // most cases: 0 (starts from 0)\n\n // now we begin to insert op in the list of insertions..\n var o\n var parent\n var start\n\n // find o. o is the first conflicting operation\n if (op.left != null) {\n o = yield* this.getInsertionCleanEnd(op.left)\n if (!Y.utils.compareIds(op.left, op.origin) && o.right != null) {\n // only if not added previously\n tryToRemergeLater.push(o.right)\n }\n o = (o.right == null) ? null : yield* this.getOperation(o.right)\n } else { // left == null\n parent = yield* this.getOperation(op.parent)\n let startId = op.parentSub ? parent.map[op.parentSub] : parent.start\n start = startId == null ? null : yield* this.getOperation(startId)\n o = start\n }\n\n // make sure to split op.right if necessary (also add to tryCombineWithLeft)\n if (op.right != null) {\n tryToRemergeLater.push(op.right)\n yield* this.getInsertionCleanStart(op.right)\n }\n\n // handle conflicts\n while (true) {\n if (o != null && !Y.utils.compareIds(o.id, op.right)) {\n var oOriginDistance = yield* Struct.Insert.getDistanceToOrigin.call(this, o)\n if (oOriginDistance === i) {\n // case 1\n if (o.id[0] < op.id[0]) {\n op.left = Y.utils.getLastId(o)\n distanceToOrigin = i + 1 // just ignore o.content.length, doesn't make a difference\n }\n } else if (oOriginDistance < i) {\n // case 2\n if (i - distanceToOrigin <= oOriginDistance) {\n op.left = Y.utils.getLastId(o)\n distanceToOrigin = i + 1 // just ignore o.content.length, doesn't make a difference\n }\n } else {\n break\n }\n i++\n if (o.right != null) {\n o = yield* this.getInsertion(o.right)\n } else {\n o = null\n }\n } else {\n break\n }\n }\n\n // reconnect..\n var left = null\n var right = null\n if (parent == null) {\n parent = yield* this.getOperation(op.parent)\n }\n\n // reconnect left and set right of op\n if (op.left != null) {\n left = yield* this.getInsertion(op.left)\n // link left\n op.right = left.right\n left.right = op.id\n\n yield* this.setOperation(left)\n } else {\n // set op.right from parent, if necessary\n op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start\n }\n // reconnect right\n if (op.right != null) {\n // TODO: wanna connect right too?\n right = yield* this.getOperation(op.right)\n right.left = Y.utils.getLastId(op)\n\n // if right exists, and it is supposed to be gc'd. Remove it from the gc\n if (right.gc != null) {\n if (right.content != null && right.content.length > 1) {\n right = yield* this.getInsertionCleanEnd(right.id)\n }\n this.store.removeFromGarbageCollector(right)\n }\n yield* this.setOperation(right)\n }\n\n // update parents .map/start/end properties\n if (op.parentSub != null) {\n if (left == null) {\n parent.map[op.parentSub] = op.id\n yield* this.setOperation(parent)\n }\n // is a child of a map struct.\n // Then also make sure that only the most left element is not deleted\n // We do not call the type in this case (this is what the third parameter is for)\n if (op.right != null) {\n yield* this.deleteOperation(op.right, 1, true)\n }\n if (op.left != null) {\n yield* this.deleteOperation(op.id, 1, true)\n }\n } else {\n if (right == null || left == null) {\n if (right == null) {\n parent.end = Y.utils.getLastId(op)\n }\n if (left == null) {\n parent.start = op.id\n }\n yield* this.setOperation(parent)\n }\n }\n\n // try to merge original op.left and op.origin\n for (let i = 0; i < tryToRemergeLater.length; i++) {\n var m = yield* this.getOperation(tryToRemergeLater[i])\n yield* this.tryCombineWithLeft(m)\n }\n }\n },\n List: {\n /*\n {\n start: null,\n end: null,\n struct: \"List\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function (id) {\n return {\n start: null,\n end: null,\n struct: 'List',\n id: id\n }\n },\n encode: function (op) {\n var e = {\n struct: 'List',\n id: op.id,\n type: op.type\n }\n if (op.requires != null) {\n e.requires = op.requires\n }\n if (op.info != null) {\n e.info = op.info\n }\n return e\n },\n requiredOps: function () {\n /*\n var ids = []\n if (op.start != null) {\n ids.push(op.start)\n }\n if (op.end != null){\n ids.push(op.end)\n }\n return ids\n */\n return []\n },\n execute: function * (op) {\n op.start = null\n op.end = null\n },\n ref: function * (op, pos) {\n if (op.start == null) {\n return null\n }\n var res = null\n var o = yield* this.getOperation(op.start)\n\n while (true) {\n if (!o.deleted) {\n res = o\n pos--\n }\n if (pos >= 0 && o.right != null) {\n o = yield* this.getOperation(o.right)\n } else {\n break\n }\n }\n return res\n },\n map: function * (o, f) {\n o = o.start\n var res = []\n while (o != null) { // TODO: change to != (at least some convention)\n var operation = yield* this.getOperation(o)\n if (!operation.deleted) {\n res.push(f(operation))\n }\n o = operation.right\n }\n return res\n }\n },\n Map: {\n /*\n {\n map: {},\n struct: \"Map\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function (id) {\n return {\n id: id,\n map: {},\n struct: 'Map'\n }\n },\n encode: function (op) {\n var e = {\n struct: 'Map',\n type: op.type,\n id: op.id,\n map: {} // overwrite map!!\n }\n if (op.requires != null) {\n e.requires = op.requires\n }\n if (op.info != null) {\n e.info = op.info\n }\n return e\n },\n requiredOps: function () {\n return []\n },\n execute: function * () {},\n /*\n Get a property by name\n */\n get: function * (op, name) {\n var oid = op.map[name]\n if (oid != null) {\n var res = yield* this.getOperation(oid)\n if (res == null || res.deleted) {\n return void 0\n } else if (res.opContent == null) {\n return res.content[0]\n } else {\n return yield* this.getType(res.opContent)\n }\n }\n }\n }\n }\n Y.Struct = Struct\n}\n","/* @flow */\n'use strict'\n\n/*\n Partial definition of a transaction\n\n A transaction provides all the the async functionality on a database.\n\n By convention, a transaction has the following properties:\n * ss for StateSet\n * os for OperationStore\n * ds for DeleteStore\n\n A transaction must also define the following methods:\n * checkDeleteStoreForState(state)\n - When increasing the state of a user, an operation with an higher id\n may already be garbage collected, and therefore it will never be received.\n update the state to reflect this knowledge. This won't call a method to save the state!\n * getDeleteSet(id)\n - Get the delete set in a readable format:\n {\n \"userX\": [\n [5,1], // starting from position 5, one operations is deleted\n [9,4] // starting from position 9, four operations are deleted\n ],\n \"userY\": ...\n }\n * getOpsFromDeleteSet(ds) -- TODO: just call this.deleteOperation(id) here\n - get a set of deletions that need to be applied in order to get to\n achieve the state of the supplied ds\n * setOperation(op)\n - write `op` to the database.\n Note: this is allowed to return an in-memory object.\n E.g. the Memory adapter returns the object that it has in-memory.\n Changing values on this object will be stored directly in the database\n without calling this function. Therefore,\n setOperation may have no functionality in some adapters. This also has\n implications on the way we use operations that were served from the database.\n We try not to call copyObject, if not necessary.\n * addOperation(op)\n - add an operation to the database.\n This may only be called once for every op.id\n Must return a function that returns the next operation in the database (ordered by id)\n * getOperation(id)\n * removeOperation(id)\n - remove an operation from the database. This is called when an operation\n is garbage collected.\n * setState(state)\n - `state` is of the form\n {\n user: \"1\",\n clock: 4\n } <- meaning that we have four operations from user \"1\"\n (with these id's respectively: 0, 1, 2, and 3)\n * getState(user)\n * getStateVector()\n - Get the state of the OS in the form\n [{\n user: \"userX\",\n clock: 11\n },\n ..\n ]\n * getStateSet()\n - Get the state of the OS in the form\n {\n \"userX\": 11,\n \"userY\": 22\n }\n * getOperations(startSS)\n - Get the all the operations that are necessary in order to achive the\n stateSet of this user, starting from a stateSet supplied by another user\n * makeOperationReady(ss, op)\n - this is called only by `getOperations(startSS)`. It makes an operation\n applyable on a given SS.\n*/\nmodule.exports = function (Y/* :any */) {\n class TransactionInterface {\n /* ::\n store: Y.AbstractDatabase;\n ds: Store;\n os: Store;\n ss: Store;\n */\n /*\n Get a type based on the id of its model.\n If it does not exist yes, create it.\n TODO: delete type from store.initializedTypes[id] when corresponding id was deleted!\n */\n * getType (id, args) {\n var sid = JSON.stringify(id)\n var t = this.store.initializedTypes[sid]\n if (t == null) {\n var op/* :MapStruct | ListStruct */ = yield* this.getOperation(id)\n if (op != null) {\n t = yield* Y[op.type].typeDefinition.initType.call(this, this.store, op, args)\n this.store.initializedTypes[sid] = t\n }\n }\n return t\n }\n * createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op\n if (id[0] === '_') {\n op = yield* this.getOperation(id)\n } else {\n op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n }\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n if (op[0] === '_') {\n yield* this.setOperation(op)\n } else {\n yield* this.applyCreatedOperations([op])\n }\n return yield* this.getType(id, typedefinition[1])\n }\n /* createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n // yield* this.applyCreatedOperations([op])\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n return yield* this.getType(id, typedefinition[1])\n }*/\n /*\n Apply operations that this user created (no remote ones!)\n * does not check for Struct.*.requiredOps()\n * also broadcasts it through the connector\n */\n * applyCreatedOperations (ops) {\n var send = []\n for (var i = 0; i < ops.length; i++) {\n var op = ops[i]\n yield* this.store.tryExecute.call(this, op)\n if (op.id == null || typeof op.id[1] !== 'string') {\n send.push(Y.Struct[op.struct].encode(op))\n }\n }\n if (!this.store.y.connector.isDisconnected() && send.length > 0) { // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops)\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps(send)\n }\n }\n\n * deleteList (start) {\n while (start != null) {\n start = yield* this.getOperation(start)\n if (!start.gc) {\n start.gc = true\n start.deleted = true\n yield* this.setOperation(start)\n var delLength = start.content != null ? start.content.length : 1\n yield* this.markDeleted(start.id, delLength)\n if (start.opContent != null) {\n yield* this.deleteOperation(start.opContent)\n }\n this.store.queueGarbageCollector(start.id)\n }\n start = start.right\n }\n }\n\n /*\n Mark an operation as deleted, and add it to the GC, if possible.\n */\n * deleteOperation (targetId, length, preventCallType) /* :Generator */ {\n if (length == null) {\n length = 1\n }\n yield* this.markDeleted(targetId, length)\n while (length > 0) {\n var callType = false\n var target = yield* this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1])\n var targetLength = target != null && target.content != null ? target.content.length : 1\n if (target == null || target.id[0] !== targetId[0] || target.id[1] + targetLength <= targetId[1]) {\n // does not exist or is not in the range of the deletion\n target = null\n length = 0\n } else {\n // does exist, check if it is too long\n if (!target.deleted) {\n if (target.id[1] < targetId[1]) {\n // starts to the left of the deletion range\n target = yield* this.getInsertionCleanStart(targetId)\n targetLength = target.content.length // must have content property!\n }\n if (target.id[1] + targetLength > targetId[1] + length) {\n // ends to the right of the deletion range\n target = yield* this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1])\n targetLength = target.content.length\n }\n }\n length = target.id[1] - targetId[1]\n }\n\n if (target != null) {\n if (!target.deleted) {\n callType = true\n // set deleted & notify type\n target.deleted = true\n // delete containing lists\n if (target.start != null) {\n // TODO: don't do it like this .. -.-\n yield* this.deleteList(target.start)\n // yield* this.deleteList(target.id) -- do not gc itself because this may still get referenced\n }\n if (target.map != null) {\n for (var name in target.map) {\n yield* this.deleteList(target.map[name])\n }\n // TODO: here to.. (see above)\n // yield* this.deleteList(target.id) -- see above\n }\n if (target.opContent != null) {\n yield* this.deleteOperation(target.opContent)\n // target.opContent = null\n }\n if (target.requires != null) {\n for (var i = 0; i < target.requires.length; i++) {\n yield* this.deleteOperation(target.requires[i])\n }\n }\n }\n var left\n if (target.left != null) {\n left = yield* this.getInsertion(target.left)\n } else {\n left = null\n }\n\n // set here because it was deleted and/or gc'd\n yield* this.setOperation(target)\n\n /*\n Check if it is possible to add right to the gc.\n Because this delete can't be responsible for left being gc'd,\n we don't have to add left to the gc..\n */\n var right\n if (target.right != null) {\n right = yield* this.getOperation(target.right)\n } else {\n right = null\n }\n if (callType && !preventCallType) {\n var type = this.store.initializedTypes[JSON.stringify(target.parent)]\n if (type != null) {\n yield* type._changed(this, {\n struct: 'Delete',\n target: target.id,\n length: targetLength\n })\n }\n }\n // need to gc in the end!\n yield* this.store.addToGarbageCollector.call(this, target, left)\n if (right != null) {\n yield* this.store.addToGarbageCollector.call(this, right, target)\n }\n }\n }\n }\n /*\n Mark an operation as deleted&gc'd\n */\n * markGarbageCollected (id, len) {\n // this.mem.push([\"gc\", id]);\n this.store.addToDebug('yield* this.markGarbageCollected(', id, ', ', len, ')')\n var n = yield* this.markDeleted(id, len)\n if (n.id[1] < id[1] && !n.gc) {\n // un-extend left\n var newlen = n.len - (id[1] - n.id[1])\n n.len -= newlen\n yield* this.ds.put(n)\n n = {id: id, len: newlen, gc: false}\n yield* this.ds.put(n)\n }\n // get prev&next before adding a new operation\n var prev = yield* this.ds.findPrev(id)\n var next = yield* this.ds.findNext(id)\n\n if (id[1] + len < n.id[1] + n.len && !n.gc) {\n // un-extend right\n yield* this.ds.put({id: [id[0], id[1] + len], len: n.len - len, gc: false})\n n.len = len\n }\n // set gc'd\n n.gc = true\n // can extend left?\n if (\n prev != null &&\n prev.gc &&\n Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id)\n ) {\n prev.len += n.len\n yield* this.ds.delete(n.id)\n n = prev\n // ds.put n here?\n }\n // can extend right?\n if (\n next != null &&\n next.gc &&\n Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id)\n ) {\n n.len += next.len\n yield* this.ds.delete(next.id)\n }\n yield* this.ds.put(n)\n yield* this.updateState(n.id[0])\n }\n /*\n Mark an operation as deleted.\n\n returns the delete node\n */\n * markDeleted (id, length) {\n if (length == null) {\n length = 1\n }\n // this.mem.push([\"del\", id]);\n var n = yield* this.ds.findWithUpperBound(id)\n if (n != null && n.id[0] === id[0]) {\n if (n.id[1] <= id[1] && id[1] <= n.id[1] + n.len) {\n // id is in n's range\n var diff = id[1] + length - (n.id[1] + n.len) // overlapping right\n if (diff > 0) {\n // id+length overlaps n\n if (!n.gc) {\n n.len += diff\n } else {\n diff = n.id[1] + n.len - id[1] // overlapping left (id till n.end)\n if (diff < length) {\n // a partial deletion\n n = {id: [id[0], id[1] + diff], len: length - diff, gc: false}\n yield* this.ds.put(n)\n } else {\n // already gc'd\n throw new Error('Cannot happen! (it dit though.. :()')\n // return n\n }\n }\n } else {\n // no overlapping, already deleted\n return n\n }\n } else {\n // cannot extend left (there is no left!)\n n = {id: id, len: length, gc: false}\n yield* this.ds.put(n) // TODO: you double-put !!\n }\n } else {\n // cannot extend left\n n = {id: id, len: length, gc: false}\n yield* this.ds.put(n)\n }\n // can extend right?\n var next = yield* this.ds.findNext(n.id)\n if (\n next != null &&\n n.id[0] === next.id[0] &&\n n.id[1] + n.len >= next.id[1]\n ) {\n diff = n.id[1] + n.len - next.id[1] // from next.start to n.end\n while (diff >= 0) {\n // n overlaps with next\n if (next.gc) {\n // gc is stronger, so reduce length of n\n n.len -= diff\n if (diff >= next.len) {\n // delete the missing range after next\n diff = diff - next.len // missing range after next\n if (diff > 0) {\n yield* this.ds.put(n) // unneccessary? TODO!\n yield* this.markDeleted([next.id[0], next.id[1] + next.len], diff)\n }\n }\n break\n } else {\n // we can extend n with next\n if (diff > next.len) {\n // n is even longer than next\n // get next.next, and try to extend it\n var _next = yield* this.ds.findNext(next.id)\n yield* this.ds.delete(next.id)\n if (_next == null || n.id[0] !== _next.id[0]) {\n break\n } else {\n next = _next\n diff = n.id[1] + n.len - next.id[1] // from next.start to n.end\n // continue!\n }\n } else {\n // n just partially overlaps with next. extend n, delete next, and break this loop\n n.len += next.len - diff\n yield* this.ds.delete(next.id)\n break\n }\n }\n }\n }\n yield* this.ds.put(n)\n return n\n }\n /*\n Call this method when the client is connected&synced with the\n other clients (e.g. master). This will query the database for\n operations that can be gc'd and add them to the garbage collector.\n */\n * garbageCollectAfterSync () {\n if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {\n console.warn('gc should be empty after sync')\n }\n yield* this.os.iterate(this, null, null, function * (op) {\n if (op.gc) {\n delete op.gc\n yield* this.setOperation(op)\n }\n if (op.parent != null) {\n var parentDeleted = yield* this.isDeleted(op.parent)\n if (parentDeleted) {\n op.gc = true\n if (!op.deleted) {\n yield* this.markDeleted(op.id, op.content != null ? op.content.length : 1)\n op.deleted = true\n if (op.opContent != null) {\n yield* this.deleteOperation(op.opContent)\n }\n if (op.requires != null) {\n for (var i = 0; i < op.requires.length; i++) {\n yield* this.deleteOperation(op.requires[i])\n }\n }\n }\n yield* this.setOperation(op)\n this.store.gc1.push(op.id) // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!)\n return\n }\n }\n if (op.deleted) {\n var left = null\n if (op.left != null) {\n left = yield* this.getInsertion(op.left)\n }\n yield* this.store.addToGarbageCollector.call(this, op, left)\n }\n })\n }\n /*\n Really remove an op and all its effects.\n The complicated case here is the Insert operation:\n * reset left\n * reset right\n * reset parent.start\n * reset parent.end\n * reset origins of all right ops\n */\n * garbageCollectOperation (id) {\n this.store.addToDebug('yield* this.garbageCollectOperation(', id, ')')\n var o = yield* this.getOperation(id)\n yield* this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd\n // if op exists, then clean that mess up..\n if (o != null) {\n var deps = []\n if (o.opContent != null) {\n deps.push(o.opContent)\n }\n if (o.requires != null) {\n deps = deps.concat(o.requires)\n }\n for (var i = 0; i < deps.length; i++) {\n var dep = yield* this.getOperation(deps[i])\n if (dep != null) {\n if (!dep.deleted) {\n yield* this.deleteOperation(dep.id)\n dep = yield* this.getOperation(dep.id)\n }\n dep.gc = true\n yield* this.setOperation(dep)\n this.store.queueGarbageCollector(dep.id)\n } else {\n yield* this.markGarbageCollected(deps[i], 1)\n }\n }\n\n // remove gc'd op from the left op, if it exists\n if (o.left != null) {\n var left = yield* this.getInsertion(o.left)\n left.right = o.right\n yield* this.setOperation(left)\n }\n // remove gc'd op from the right op, if it exists\n // also reset origins of right ops\n if (o.right != null) {\n var right = yield* this.getOperation(o.right)\n right.left = o.left\n\n if (o.originOf != null && o.originOf.length > 0) {\n // find new origin of right ops\n // origin is the first left deleted operation\n var neworigin = o.left\n var neworigin_ = null\n while (neworigin != null) {\n neworigin_ = yield* this.getInsertion(neworigin)\n if (neworigin_.deleted) {\n break\n }\n neworigin = neworigin_.left\n }\n\n // reset origin of all right ops (except first right - duh!),\n\n /* ** The following code does not rely on the the originOf property **\n I recently added originOf to all Insert Operations (see Struct.Insert.execute),\n which saves which operations originate in a Insert operation.\n Garbage collecting without originOf is more memory efficient, but is nearly impossible for large texts, or lists!\n But I keep this code for now\n ```\n // reset origin of right\n right.origin = neworigin\n // search until you find origin pointer to the left of o\n if (right.right != null) {\n var i = yield* this.getOperation(right.right)\n var ids = [o.id, o.right]\n while (ids.some(function (id) {\n return Y.utils.compareIds(id, i.origin)\n })) {\n if (Y.utils.compareIds(i.origin, o.id)) {\n // reset origin of i\n i.origin = neworigin\n yield* this.setOperation(i)\n }\n // get next i\n if (i.right == null) {\n break\n } else {\n ids.push(i.id)\n i = yield* this.getOperation(i.right)\n }\n }\n }\n ```\n */\n // ** Now the new implementation starts **\n // reset neworigin of all originOf[*]\n for (var _i in o.originOf) {\n var originsIn = yield* this.getOperation(o.originOf[_i])\n if (originsIn != null) {\n originsIn.origin = neworigin\n yield* this.setOperation(originsIn)\n }\n }\n if (neworigin != null) {\n if (neworigin_.originOf == null) {\n neworigin_.originOf = o.originOf\n } else {\n neworigin_.originOf = o.originOf.concat(neworigin_.originOf)\n }\n yield* this.setOperation(neworigin_)\n }\n // we don't need to set right here, because\n // right should be in o.originOf => it is set it the previous for loop\n } else {\n // we didn't need to reset the origin of right\n // so we have to set right here\n yield* this.setOperation(right)\n }\n }\n // o may originate in another operation.\n // Since o is deleted, we have to reset o.origin's `originOf` property\n if (o.origin != null) {\n var origin = yield* this.getInsertion(o.origin)\n origin.originOf = origin.originOf.filter(function (_id) {\n return !Y.utils.compareIds(id, _id)\n })\n yield* this.setOperation(origin)\n }\n var parent\n if (o.parent != null) {\n parent = yield* this.getOperation(o.parent)\n }\n // remove gc'd op from parent, if it exists\n if (parent != null) {\n var setParent = false // whether to save parent to the os\n if (o.parentSub != null) {\n if (Y.utils.compareIds(parent.map[o.parentSub], o.id)) {\n setParent = true\n if (o.right != null) {\n parent.map[o.parentSub] = o.right\n } else {\n delete parent.map[o.parentSub]\n }\n }\n } else {\n if (Y.utils.compareIds(parent.start, o.id)) {\n // gc'd op is the start\n setParent = true\n parent.start = o.right\n }\n if (Y.utils.matchesId(o, parent.end)) {\n // gc'd op is the end\n setParent = true\n parent.end = o.left\n }\n }\n if (setParent) {\n yield* this.setOperation(parent)\n }\n }\n // finally remove it from the os\n yield* this.removeOperation(o.id)\n }\n }\n * checkDeleteStoreForState (state) {\n var n = yield* this.ds.findWithUpperBound([state.user, state.clock])\n if (n != null && n.id[0] === state.user && n.gc) {\n state.clock = Math.max(state.clock, n.id[1] + n.len)\n }\n }\n * updateState (user) {\n var state = yield* this.getState(user)\n yield* this.checkDeleteStoreForState(state)\n var o = yield* this.getInsertion([user, state.clock])\n var oLength = (o != null && o.content != null) ? o.content.length : 1\n while (o != null && user === o.id[0] && o.id[1] <= state.clock && o.id[1] + oLength > state.clock) {\n // either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS\n state.clock += oLength\n yield* this.checkDeleteStoreForState(state)\n o = yield* this.os.findNext(o.id)\n oLength = (o != null && o.content != null) ? o.content.length : 1\n }\n yield* this.setState(state)\n }\n /*\n apply a delete set in order to get\n the state of the supplied ds\n */\n * applyDeleteSet (ds) {\n var deletions = []\n\n for (var user in ds) {\n var dv = ds[user]\n var pos = 0\n var d = dv[pos]\n yield* this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], function * (n) {\n // cases:\n // 1. d deletes something to the right of n\n // => go to next n (break)\n // 2. d deletes something to the left of n\n // => create deletions\n // => reset d accordingly\n // *)=> if d doesn't delete anything anymore, go to next d (continue)\n // 3. not 2) and d deletes something that also n deletes\n // => reset d so that it doesn't contain n's deletion\n // *)=> if d does not delete anything anymore, go to next d (continue)\n while (d != null) {\n var diff = 0 // describe the diff of length in 1) and 2)\n if (n.id[1] + n.len <= d[0]) {\n // 1)\n break\n } else if (d[0] < n.id[1]) {\n // 2)\n // delete maximum the len of d\n // else delete as much as possible\n diff = Math.min(n.id[1] - d[0], d[1])\n deletions.push([user, d[0], diff, d[2]])\n } else {\n // 3)\n diff = n.id[1] + n.len - d[0] // never null (see 1)\n if (d[2] && !n.gc) {\n // d marks as gc'd but n does not\n // then delete either way\n deletions.push([user, d[0], Math.min(diff, d[1]), d[2]])\n }\n }\n if (d[1] <= diff) {\n // d doesn't delete anything anymore\n d = dv[++pos]\n } else {\n d[0] = d[0] + diff // reset pos\n d[1] = d[1] - diff // reset length\n }\n }\n })\n // for the rest.. just apply it\n for (; pos < dv.length; pos++) {\n d = dv[pos]\n deletions.push([user, d[0], d[1], d[2]])\n }\n }\n for (var i = 0; i < deletions.length; i++) {\n var del = deletions[i]\n // always try to delete..\n yield* this.deleteOperation([del[0], del[1]], del[2])\n if (del[3]) {\n // gc..\n yield* this.markGarbageCollected([del[0], del[1]], del[2]) // always mark gc'd\n // remove operation..\n var counter = del[1] + del[2]\n while (counter >= del[1]) {\n var o = yield* this.os.findWithUpperBound([del[0], counter - 1])\n if (o == null) {\n break\n }\n var oLen = o.content != null ? o.content.length : 1\n if (o.id[0] !== del[0] || o.id[1] + oLen <= del[1]) {\n // not in range\n break\n }\n if (o.id[1] + oLen > del[1] + del[2]) {\n // overlaps right\n o = yield* this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1])\n }\n if (o.id[1] < del[1]) {\n // overlaps left\n o = yield* this.getInsertionCleanStart([del[0], del[1]])\n }\n counter = o.id[1]\n yield* this.garbageCollectOperation(o.id)\n }\n }\n if (this.store.forwardAppliedOperations) {\n var ops = []\n ops.push({struct: 'Delete', target: [d[0], d[1]], length: del[2]})\n this.store.y.connector.broadcastOps(ops)\n }\n }\n }\n * isGarbageCollected (id) {\n var n = yield* this.ds.findWithUpperBound(id)\n return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len && n.gc\n }\n /*\n A DeleteSet (ds) describes all the deleted ops in the OS\n */\n * getDeleteSet () {\n var ds = {}\n yield* this.ds.iterate(this, null, null, function * (n) {\n var user = n.id[0]\n var counter = n.id[1]\n var len = n.len\n var gc = n.gc\n var dv = ds[user]\n if (dv === void 0) {\n dv = []\n ds[user] = dv\n }\n dv.push([counter, len, gc])\n })\n return ds\n }\n * isDeleted (id) {\n var n = yield* this.ds.findWithUpperBound(id)\n return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len\n }\n * setOperation (op) {\n yield* this.os.put(op)\n return op\n }\n * addOperation (op) {\n yield* this.os.put(op)\n if (!this.store.y.connector.isDisconnected() && this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') {\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps([op])\n }\n }\n // if insertion, try to combine with left insertion (if both have content property)\n * tryCombineWithLeft (op) {\n if (\n op != null &&\n op.left != null &&\n op.content != null &&\n op.left[0] === op.id[0] &&\n Y.utils.compareIds(op.left, op.origin)\n ) {\n var left = yield* this.getInsertion(op.left)\n if (left.content != null &&\n left.id[1] + left.content.length === op.id[1] &&\n left.originOf.length === 1 &&\n !left.gc && !left.deleted &&\n !op.gc && !op.deleted\n ) {\n // combine!\n if (op.originOf != null) {\n left.originOf = op.originOf\n } else {\n delete left.originOf\n }\n left.content = left.content.concat(op.content)\n left.right = op.right\n yield* this.os.delete(op.id)\n yield* this.setOperation(left)\n }\n }\n }\n * getInsertion (id) {\n var ins = yield* this.os.findWithUpperBound(id)\n if (ins == null) {\n return null\n } else {\n var len = ins.content != null ? ins.content.length : 1 // in case of opContent\n if (id[0] === ins.id[0] && id[1] < ins.id[1] + len) {\n return ins\n } else {\n return null\n }\n }\n }\n * getInsertionCleanStartEnd (id) {\n yield* this.getInsertionCleanStart(id)\n return yield* this.getInsertionCleanEnd(id)\n }\n // Return an insertion such that id is the first element of content\n // This function manipulates an operation, if necessary\n * getInsertionCleanStart (id) {\n var ins = yield* this.getInsertion(id)\n if (ins != null) {\n if (ins.id[1] === id[1]) {\n return ins\n } else {\n var left = Y.utils.copyObject(ins)\n ins.content = left.content.splice(id[1] - ins.id[1])\n ins.id = id\n var leftLid = Y.utils.getLastId(left)\n ins.origin = leftLid\n left.originOf = [ins.id]\n left.right = ins.id\n ins.left = leftLid\n // debugger // check\n yield* this.setOperation(left)\n yield* this.setOperation(ins)\n if (left.gc) {\n this.store.queueGarbageCollector(ins.id)\n }\n return ins\n }\n } else {\n return null\n }\n }\n // Return an insertion such that id is the last element of content\n // This function manipulates an operation, if necessary\n * getInsertionCleanEnd (id) {\n var ins = yield* this.getInsertion(id)\n if (ins != null) {\n if (ins.content == null || (ins.id[1] + ins.content.length - 1 === id[1])) {\n return ins\n } else {\n var right = Y.utils.copyObject(ins)\n right.content = ins.content.splice(id[1] - ins.id[1] + 1) // cut off remainder\n right.id = [id[0], id[1] + 1]\n var insLid = Y.utils.getLastId(ins)\n right.origin = insLid\n ins.originOf = [right.id]\n ins.right = right.id\n right.left = insLid\n // debugger // check\n yield* this.setOperation(right)\n yield* this.setOperation(ins)\n if (ins.gc) {\n this.store.queueGarbageCollector(right.id)\n }\n return ins\n }\n } else {\n return null\n }\n }\n * getOperation (id/* :any */)/* :Transaction */ {\n var o = yield* this.os.find(id)\n if (id[0] !== '_' || o != null) {\n return o\n } else { // type is string\n // generate this operation?\n var comp = id[1].split('_')\n if (comp.length > 1) {\n var struct = comp[0]\n var op = Y.Struct[struct].create(id)\n op.type = comp[1]\n yield* this.setOperation(op)\n return op\n } else {\n // won't be called. but just in case..\n console.error('Unexpected case. How can this happen?')\n debugger // eslint-disable-line\n return null\n }\n }\n }\n * removeOperation (id) {\n yield* this.os.delete(id)\n }\n * setState (state) {\n var val = {\n id: [state.user],\n clock: state.clock\n }\n yield* this.ss.put(val)\n }\n * getState (user) {\n var n = yield* this.ss.find([user])\n var clock = n == null ? null : n.clock\n if (clock == null) {\n clock = 0\n }\n return {\n user: user,\n clock: clock\n }\n }\n * getStateVector () {\n var stateVector = []\n yield* this.ss.iterate(this, null, null, function * (n) {\n stateVector.push({\n user: n.id[0],\n clock: n.clock\n })\n })\n return stateVector\n }\n * getStateSet () {\n var ss = {}\n yield* this.ss.iterate(this, null, null, function * (n) {\n ss[n.id[0]] = n.clock\n })\n return ss\n }\n /*\n Here, we make all missing operations executable for the receiving user.\n\n Notes:\n startSS: denotes to the SV that the remote user sent\n currSS: denotes to the state vector that the user should have if he\n applies all already sent operations (increases is each step)\n\n We face several problems:\n * Execute op as is won't work because ops depend on each other\n -> find a way so that they do not anymore\n * When changing left, must not go more to the left than the origin\n * When changing right, you have to consider that other ops may have op\n as their origin, this means that you must not set one of these ops\n as the new right (interdependencies of ops)\n * can't just go to the right until you find the first known operation,\n With currSS\n -> interdependency of ops is a problem\n With startSS\n -> leads to inconsistencies when two users join at the same time.\n Then the position depends on the order of execution -> error!\n\n Solution:\n -> re-create originial situation\n -> set op.left = op.origin (which never changes)\n -> set op.right\n to the first operation that is known (according to startSS)\n or to the first operation that has an origin that is not to the\n right of op.\n -> Enforces unique execution order -> happy user\n\n Improvements: TODO\n * Could set left to origin, or the first known operation\n (startSS or currSS.. ?)\n -> Could be necessary when I turn GC again.\n -> Is a bad(ish) idea because it requires more computation\n\n What we do:\n * Iterate over all missing operations.\n * When there is an operation, where the right op is known, send this op all missing ops to the left to the user\n * I explained above what we have to do with each operation. Here is how we do it efficiently:\n 1. Go to the left until you find either op.origin, or a known operation (let o denote current operation in the iteration)\n 2. Found a known operation -> set op.left = o, and send it to the user. stop\n 3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o)\n 4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue\n */\n * getOperations (startSS) {\n // TODO: use bounds here!\n if (startSS == null) {\n startSS = {}\n }\n var send = []\n\n var endSV = yield* this.getStateVector()\n for (var endState of endSV) {\n var user = endState.user\n if (user === '_') {\n continue\n }\n var startPos = startSS[user] || 0\n if (startPos > 0) {\n // There is a change that [user, startPos] is in a composed Insertion (with a smaller counter)\n // find out if that is the case\n var firstMissing = yield* this.getInsertion([user, startPos])\n if (firstMissing != null) {\n // update startPos\n startPos = firstMissing.id[1]\n }\n }\n yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {\n op = Y.Struct[op.struct].encode(op)\n if (op.struct !== 'Insert') {\n send.push(op)\n } else if (op.right == null || op.right[1] < (startSS[op.right[0]] || 0)) {\n // case 1. op.right is known\n var o = op\n // Remember: ?\n // -> set op.right\n // 1. to the first operation that is known (according to startSS)\n // 2. or to the first operation that has an origin that is not to the\n // right of op.\n // For this we maintain a list of ops which origins are not found yet.\n var missing_origins = [op]\n var newright = op.right\n while (true) {\n if (o.left == null) {\n op.left = null\n send.push(op)\n if (!Y.utils.compareIds(o.id, op.id)) {\n o = Y.Struct[op.struct].encode(o)\n o.right = missing_origins[missing_origins.length - 1].id\n send.push(o)\n }\n break\n }\n o = yield* this.getInsertion(o.left)\n // we set another o, check if we can reduce $missing_origins\n while (missing_origins.length > 0 && Y.utils.matchesId(o, missing_origins[missing_origins.length - 1].origin)) {\n missing_origins.pop()\n }\n if (o.id[1] < (startSS[o.id[0]] || 0)) {\n // case 2. o is known\n op.left = Y.utils.getLastId(o)\n send.push(op)\n break\n } else if (Y.utils.matchesId(o, op.origin)) {\n // case 3. o is op.origin\n op.left = op.origin\n send.push(op)\n op = Y.Struct[op.struct].encode(o)\n op.right = newright\n if (missing_origins.length > 0) {\n console.log('This should not happen .. :( please report this')\n }\n missing_origins = [op]\n } else {\n // case 4. send o, continue to find op.origin\n var s = Y.Struct[op.struct].encode(o)\n s.right = missing_origins[missing_origins.length - 1].id\n s.left = s.origin\n send.push(s)\n missing_origins.push(o)\n }\n }\n }\n })\n }\n return send.reverse()\n }\n /* this is what we used before.. use this as a reference..\n * makeOperationReady (startSS, op) {\n op = Y.Struct[op.struct].encode(op)\n op = Y.utils.copyObject(op)\n var o = op\n var ids = [op.id]\n // search for the new op.right\n // it is either the first known op (according to startSS)\n // or the o that has no origin to the right of op\n // (this is why we use the ids array)\n while (o.right != null) {\n var right = yield* this.getOperation(o.right)\n if (o.right[1] < (startSS[o.right[0]] || 0) || !ids.some(function (id) {\n return Y.utils.compareIds(id, right.origin)\n })) {\n break\n }\n ids.push(o.right)\n o = right\n }\n op.right = o.right\n op.left = op.origin\n return op\n }\n */\n * flush () {\n yield* this.os.flush()\n yield* this.ss.flush()\n yield* this.ds.flush()\n }\n }\n Y.Transaction = TransactionInterface\n}\n","/* @flow */\n'use strict'\n\n/*\n EventHandler is an helper class for constructing custom types.\n\n Why: When constructing custom types, you sometimes want your types to work\n synchronous: E.g.\n ``` Synchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === \"yay\"\n ```\n versus\n ``` Asynchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === undefined\n mytype.waitForSomething().then(function(){\n mytype.getSomething() === \"yay\"\n })\n ```\n\n The structures usually work asynchronously (you have to wait for the\n database request to finish). EventHandler helps you to make your type\n synchronous.\n*/\nmodule.exports = function (Y /* : any*/) {\n Y.utils = {}\n\n class EventListenerHandler {\n constructor () {\n this.eventListeners = []\n }\n destroy () {\n this.eventListeners = null\n }\n /*\n Basic event listener boilerplate...\n */\n addEventListener (f) {\n this.eventListeners.push(f)\n }\n removeEventListener (f) {\n this.eventListeners = this.eventListeners.filter(function (g) {\n return f !== g\n })\n }\n removeAllEventListeners () {\n this.eventListeners = []\n }\n callEventListeners (event) {\n for (var i = 0; i < this.eventListeners.length; i++) {\n try {\n this.eventListeners[i](event)\n } catch (e) {\n console.error('User events must not throw Errors!')\n }\n }\n }\n }\n Y.utils.EventListenerHandler = EventListenerHandler\n\n class EventHandler extends EventListenerHandler {\n /* ::\n waiting: Array;\n awaiting: number;\n onevent: Function;\n eventListeners: Array;\n */\n /*\n onevent: is called when the structure changes.\n\n Note: \"awaiting opertations\" is used to denote operations that were\n prematurely called. Events for received operations can not be executed until\n all prematurely called operations were executed (\"waiting operations\")\n */\n constructor (onevent /* : Function */) {\n super()\n this.waiting = []\n this.awaiting = 0\n this.onevent = onevent\n }\n destroy () {\n super.destroy()\n this.waiting = null\n this.awaiting = null\n this.onevent = null\n }\n /*\n Call this when a new operation arrives. It will be executed right away if\n there are no waiting operations, that you prematurely executed\n */\n receivedOp (op) {\n if (this.awaiting <= 0) {\n this.onevent(op)\n } else {\n this.waiting.push(op)\n }\n }\n /*\n You created some operations, and you want the `onevent` function to be\n called right away. Received operations will not be executed untill all\n prematurely called operations are executed\n */\n awaitAndPrematurelyCall (ops) {\n this.awaiting += ops.length\n ops.forEach(this.onevent)\n }\n /*\n Call this when you successfully awaited the execution of n Insert operations\n */\n awaitedInserts (n) {\n var ops = this.waiting.splice(this.waiting.length - n)\n for (var oid = 0; oid < ops.length; oid++) {\n var op = ops[oid]\n if (op.struct === 'Insert') {\n for (var i = this.waiting.length - 1; i >= 0; i--) {\n let w = this.waiting[i]\n // TODO: do I handle split operations correctly here? Super unlikely, but yeah..\n // Also: can this case happen? Can op be inserted in the middle of a larger op that is in $waiting?\n if (w.struct === 'Insert') {\n if (Y.utils.matchesId(w, op.left)) {\n // include the effect of op in w\n w.right = op.id\n // exclude the effect of w in op\n op.left = w.left\n } else if (Y.utils.compareIds(w.id, op.right)) {\n // similar..\n w.left = Y.utils.getLastId(op)\n op.right = w.right\n }\n }\n }\n } else {\n throw new Error('Expected Insert Operation!')\n }\n }\n this._tryCallEvents(n)\n }\n /*\n Call this when you successfully awaited the execution of n Delete operations\n */\n awaitedDeletes (n, newLeft) {\n var ops = this.waiting.splice(this.waiting.length - n)\n for (var j = 0; j < ops.length; j++) {\n var del = ops[j]\n if (del.struct === 'Delete') {\n if (newLeft != null) {\n for (var i = 0; i < this.waiting.length; i++) {\n let w = this.waiting[i]\n // We will just care about w.left\n if (w.struct === 'Insert' && Y.utils.compareIds(del.target, w.left)) {\n w.left = newLeft\n }\n }\n }\n } else {\n throw new Error('Expected Delete Operation!')\n }\n }\n this._tryCallEvents(n)\n }\n /* (private)\n Try to execute the events for the waiting operations\n */\n _tryCallEvents (n) {\n this.awaiting -= n\n if (this.awaiting === 0 && this.waiting.length > 0) {\n var ops = this.waiting\n this.waiting = []\n ops.forEach(this.onevent)\n }\n }\n }\n Y.utils.EventHandler = EventHandler\n\n /*\n A wrapper for the definition of a custom type.\n Every custom type must have three properties:\n\n * struct\n - Structname of this type\n * initType\n - Given a model, creates a custom type\n * class\n - the constructor of the custom type (e.g. in order to inherit from a type)\n */\n class CustomType { // eslint-disable-line\n /* ::\n struct: any;\n initType: any;\n class: Function;\n name: String;\n */\n constructor (def) {\n if (def.struct == null ||\n def.initType == null ||\n def.class == null ||\n def.name == null\n ) {\n throw new Error('Custom type was not initialized correctly!')\n }\n this.struct = def.struct\n this.initType = def.initType\n this.class = def.class\n this.name = def.name\n if (def.appendAdditionalInfo != null) {\n this.appendAdditionalInfo = def.appendAdditionalInfo\n }\n this.parseArguments = (def.parseArguments || function () {\n return [this]\n }).bind(this)\n this.parseArguments.typeDefinition = this\n }\n }\n Y.utils.CustomType = CustomType\n\n Y.utils.isTypeDefinition = function isTypeDefinition (v) {\n if (v != null) {\n if (v instanceof Y.utils.CustomType) return [v]\n else if (v.constructor === Array && v[0] instanceof Y.utils.CustomType) return v\n else if (v instanceof Function && v.typeDefinition instanceof Y.utils.CustomType) return [v.typeDefinition]\n }\n return false\n }\n\n /*\n Make a flat copy of an object\n (just copy properties)\n */\n function copyObject (o) {\n var c = {}\n for (var key in o) {\n c[key] = o[key]\n }\n return c\n }\n Y.utils.copyObject = copyObject\n\n /*\n Defines a smaller relation on Id's\n */\n function smaller (a, b) {\n return a[0] < b[0] || (a[0] === b[0] && (a[1] < b[1] || typeof a[1] < typeof b[1]))\n }\n Y.utils.smaller = smaller\n\n function compareIds (id1, id2) {\n if (id1 == null || id2 == null) {\n return id1 === id2\n } else {\n return id1[0] === id2[0] && id1[1] === id2[1]\n }\n }\n Y.utils.compareIds = compareIds\n\n function matchesId (op, id) {\n if (id == null || op == null) {\n return id === op\n } else {\n if (id[0] === op.id[0]) {\n if (op.content == null) {\n return id[1] === op.id[1]\n } else {\n return id[1] >= op.id[1] && id[1] < op.id[1] + op.content.length\n }\n }\n }\n }\n Y.utils.matchesId = matchesId\n\n function getLastId (op) {\n if (op.content == null || op.content.length === 1) {\n return op.id\n } else {\n return [op.id[0], op.id[1] + op.content.length - 1]\n }\n }\n Y.utils.getLastId = getLastId\n\n function createEmptyOpsArray (n) {\n var a = new Array(n)\n for (var i = 0; i < a.length; i++) {\n a[i] = {\n id: [null, null]\n }\n }\n return a\n }\n\n function createSmallLookupBuffer (Store) {\n /*\n This buffer implements a very small buffer that temporarily stores operations\n after they are read / before they are written.\n The buffer basically implements FIFO. Often requested lookups will be re-queued every time they are looked up / written.\n\n It can speed up lookups on Operation Stores and State Stores. But it does not require notable use of memory or processing power.\n\n Good for os and ss, bot not for ds (because it often uses methods that require a flush)\n\n I tried to optimize this for performance, therefore no highlevel operations.\n */\n class SmallLookupBuffer extends Store {\n constructor (arg1, arg2) {\n // super(...arguments) -- do this when this is supported by stable nodejs\n super(arg1, arg2)\n this.writeBuffer = createEmptyOpsArray(5)\n this.readBuffer = createEmptyOpsArray(10)\n }\n * find (id, noSuperCall) {\n var i, r\n for (i = this.readBuffer.length - 1; i >= 0; i--) {\n r = this.readBuffer[i]\n // we don't have to use compareids, because id is always defined!\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n // found r\n // move r to the end of readBuffer\n for (; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1]\n }\n this.readBuffer[this.readBuffer.length - 1] = r\n return r\n }\n }\n var o\n for (i = this.writeBuffer.length - 1; i >= 0; i--) {\n r = this.writeBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n o = r\n break\n }\n }\n if (i < 0 && noSuperCall === undefined) {\n // did not reach break in last loop\n // read id and put it to the end of readBuffer\n o = yield* super.find(id)\n }\n if (o != null) {\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1]\n }\n this.readBuffer[this.readBuffer.length - 1] = o\n }\n return o\n }\n * put (o) {\n var id = o.id\n var i, r // helper variables\n for (i = this.writeBuffer.length - 1; i >= 0; i--) {\n r = this.writeBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n // is already in buffer\n // forget r, and move o to the end of writeBuffer\n for (; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1]\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o\n break\n }\n }\n if (i < 0) {\n // did not reach break in last loop\n // write writeBuffer[0]\n var write = this.writeBuffer[0]\n if (write.id[0] !== null) {\n yield* super.put(write)\n }\n // put o to the end of writeBuffer\n for (i = 0; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1]\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o\n }\n // check readBuffer for every occurence of o.id, overwrite if found\n // whether found or not, we'll append o to the readbuffer\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n r = this.readBuffer[i + 1]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = o\n } else {\n this.readBuffer[i] = r\n }\n }\n this.readBuffer[this.readBuffer.length - 1] = o\n }\n * delete (id) {\n var i, r\n for (i = 0; i < this.readBuffer.length; i++) {\n r = this.readBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = {\n id: [null, null]\n }\n }\n }\n yield* this.flush()\n yield* super.delete(id)\n }\n * findWithLowerBound (id) {\n var o = yield* this.find(id, true)\n if (o != null) {\n return o\n } else {\n yield* this.flush()\n return yield* super.findWithLowerBound.apply(this, arguments)\n }\n }\n * findWithUpperBound (id) {\n var o = yield* this.find(id, true)\n if (o != null) {\n return o\n } else {\n yield* this.flush()\n return yield* super.findWithUpperBound.apply(this, arguments)\n }\n }\n * findNext () {\n yield* this.flush()\n return yield* super.findNext.apply(this, arguments)\n }\n * findPrev () {\n yield* this.flush()\n return yield* super.findPrev.apply(this, arguments)\n }\n * iterate () {\n yield* this.flush()\n yield* super.iterate.apply(this, arguments)\n }\n * flush () {\n for (var i = 0; i < this.writeBuffer.length; i++) {\n var write = this.writeBuffer[i]\n if (write.id[0] !== null) {\n yield* super.put(write)\n this.writeBuffer[i] = {\n id: [null, null]\n }\n }\n }\n }\n }\n return SmallLookupBuffer\n }\n Y.utils.createSmallLookupBuffer = createSmallLookupBuffer\n}\n","/* @flow */\r\n'use strict'\r\n\r\nrequire('./Connector.js')(Y)\r\nrequire('./Database.js')(Y)\r\nrequire('./Transaction.js')(Y)\r\nrequire('./Struct.js')(Y)\r\nrequire('./Utils.js')(Y)\r\nrequire('./Connectors/Test.js')(Y)\r\n\r\nvar requiringModules = {}\r\n\r\nmodule.exports = Y\r\nY.requiringModules = requiringModules\r\n\r\nY.extend = function (name, value) {\r\n if (value instanceof Y.utils.CustomType) {\r\n Y[name] = value.parseArguments\r\n } else {\r\n Y[name] = value\r\n }\r\n if (requiringModules[name] != null) {\r\n requiringModules[name].resolve()\r\n delete requiringModules[name]\r\n }\r\n}\r\n\r\nY.requestModules = requestModules\r\nfunction requestModules (modules) {\r\n // determine if this module was compiled for es5 or es6 (y.js vs. y.es6)\r\n // if Insert.execute is a Function, then it isnt a generator..\r\n // then load the es5(.js) files..\r\n var extention = typeof regeneratorRuntime !== 'undefined' ? '.js' : '.es6'\r\n var promises = []\r\n for (var i = 0; i < modules.length; i++) {\r\n var module = modules[i].split('(')[0]\r\n var modulename = 'y-' + module.toLowerCase()\r\n if (Y[module] == null) {\r\n if (requiringModules[module] == null) {\r\n // module does not exist\r\n if (typeof window !== 'undefined' && window.Y !== 'undefined') {\r\n var imported = document.createElement('script')\r\n imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention\r\n document.head.appendChild(imported)\r\n\r\n let requireModule = {}\r\n requiringModules[module] = requireModule\r\n requireModule.promise = new Promise(function (resolve) {\r\n requireModule.resolve = resolve\r\n })\r\n promises.push(requireModule.promise)\r\n } else {\r\n require(modulename)(Y)\r\n }\r\n } else {\r\n promises.push(requiringModules[modules[i]].promise)\r\n }\r\n }\r\n }\r\n return Promise.all(promises)\r\n}\r\n\r\n/* ::\r\ntype MemoryOptions = {\r\n name: 'memory'\r\n}\r\ntype IndexedDBOptions = {\r\n name: 'indexeddb',\r\n namespace: string\r\n}\r\ntype DbOptions = MemoryOptions | IndexedDBOptions\r\n\r\ntype WebRTCOptions = {\r\n name: 'webrtc',\r\n room: string\r\n}\r\ntype WebsocketsClientOptions = {\r\n name: 'websockets-client',\r\n room: string\r\n}\r\ntype ConnectionOptions = WebRTCOptions | WebsocketsClientOptions\r\n\r\ntype YOptions = {\r\n connector: ConnectionOptions,\r\n db: DbOptions,\r\n types: Array,\r\n sourceDir: string,\r\n share: {[key: string]: TypeName}\r\n}\r\n*/\r\n\r\nfunction Y (opts/* :YOptions */) /* :Promise */ {\r\n opts.types = opts.types != null ? opts.types : []\r\n var modules = [opts.db.name, opts.connector.name].concat(opts.types)\r\n for (var name in opts.share) {\r\n modules.push(opts.share[name])\r\n }\r\n Y.sourceDir = opts.sourceDir\r\n return Y.requestModules(modules).then(function () {\r\n return new Promise(function (resolve, reject) {\r\n if (opts == null) reject('An options object is expected! ')\r\n else if (opts.connector == null) reject('You must specify a connector! (missing connector property)')\r\n else if (opts.connector.name == null) reject('You must specify connector name! (missing connector.name property)')\r\n else if (opts.db == null) reject('You must specify a database! (missing db property)')\r\n else if (opts.connector.name == null) reject('You must specify db name! (missing db.name property)')\r\n else if (opts.share == null) reject('You must specify a set of shared types!')\r\n else {\r\n var yconfig = new YConfig(opts)\r\n yconfig.db.whenUserIdSet(function () {\r\n yconfig.init(function () {\r\n resolve(yconfig)\r\n })\r\n })\r\n }\r\n })\r\n })\r\n}\r\n\r\nclass YConfig {\r\n /* ::\r\n db: Y.AbstractDatabase;\r\n connector: Y.AbstractConnector;\r\n share: {[key: string]: any};\r\n options: Object;\r\n */\r\n constructor (opts, callback) {\r\n this.options = opts\r\n this.db = new Y[opts.db.name](this, opts.db)\r\n this.connector = new Y[opts.connector.name](this, opts.connector)\r\n }\r\n init (callback) {\r\n var opts = this.options\r\n var share = {}\r\n this.share = share\r\n this.db.requestTransaction(function * requestTransaction () {\r\n // create shared object\r\n for (var propertyname in opts.share) {\r\n var typeConstructor = opts.share[propertyname].split('(')\r\n var typeName = typeConstructor.splice(0, 1)\r\n var args = []\r\n if (typeConstructor.length === 1) {\r\n try {\r\n args = JSON.parse('[' + typeConstructor[0].split(')')[0] + ']')\r\n } catch (e) {\r\n throw new Error('Was not able to parse type definition! (share.' + propertyname + ')')\r\n }\r\n }\r\n var type = Y[typeName]\r\n var typedef = type.typeDefinition\r\n var id = ['_', typedef.struct + '_' + typeName + '_' + propertyname + '_' + typeConstructor]\r\n share[propertyname] = yield* this.createType(type.apply(typedef, args), id)\r\n }\r\n this.store.whenTransactionsFinished()\r\n .then(callback)\r\n })\r\n }\r\n isConnected () {\r\n return this.connector.isSynced\r\n }\r\n disconnect () {\r\n return this.connector.disconnect()\r\n }\r\n reconnect () {\r\n return this.connector.reconnect()\r\n }\r\n destroy () {\r\n if (this.connector.destroy != null) {\r\n this.connector.destroy()\r\n } else {\r\n this.connector.disconnect()\r\n }\r\n var self = this\r\n this.db.requestTransaction(function * () {\r\n yield* self.db.destroy()\r\n self.connector = null\r\n self.db = null\r\n })\r\n }\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n window.Y = Y\r\n}\r\n"]} \ No newline at end of file diff --git a/y.js b/y.js index 4c2bbe68..4cede260 100644 --- a/y.js +++ b/y.js @@ -1,4 +1,6696 @@ -!function e(t,r,n){function i(s,o){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!o&&u)return u(s,!0);if(a)return a(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=r[s]={exports:{}};t[s][0].call(l.exports,function(e){var r=t[s][1][e];return i(r?r:e)},l,l.exports,e,t,r,n)}return r[s].exports}for(var a="function"==typeof require&&require,s=0;s1)for(var r=1;r=0;--n){var i=this.tryEntries[n],a=i.completion;if("root"===i.tryLoc)return t("end");if(i.tryLoc<=this.prev){var s=m.call(i,"catchLoc"),o=m.call(i,"finallyLoc");if(s&&o){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&m.call(n,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),p(r),C}},"catch":function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var i=n.arg;p(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:y(e),resultName:t,nextLoc:r},C}}}("object"===("undefined"==typeof r?"undefined":n(r))?r:"object"===("undefined"==typeof window?"undefined":n(window))?window:"object"===("undefined"==typeof self?"undefined":n(self))?self:void 0)}).call(this,e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{_process:1}],3:[function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=function(){function e(e,t){for(var r=0;r "+e+": "+t.type,t)}},{key:"broadcastOps",value:function(t){function r(){n.broadcastOpBuffer.length>0&&(n.broadcast({type:"update",ops:n.broadcastOpBuffer}),n.broadcastOpBuffer=[])}t=t.map(function(t){return e.Struct[t.struct].encode(t)});var n=this;0===this.broadcastOpBuffer.length?(this.broadcastOpBuffer=t,this.y.db.transactionInProgress?this.y.db.whenTransactionsFinished().then(r):setTimeout(r,0)):this.broadcastOpBuffer=this.broadcastOpBuffer.concat(t)}},{key:"receiveMessage",value:function(e,t){var r=this;if(e!==this.userId){if(this.debug&&console.log("receive "+e+" -> "+this.userId+": "+t.type,JSON.parse(JSON.stringify(t))),null!=t.protocolVersion&&t.protocolVersion!==this.protocolVersion)return console.error("You tried to sync with a yjs instance that has a different protocol version\n (You: "+this.protocolVersion+", Client: "+t.protocolVersion+").\n The sync was stopped. You need to upgrade your dependencies (especially Yjs & the Connector)!\n "),void this.send(e,{type:"sync stop",protocolVersion:this.protocolVersion});if("sync step 1"===t.type)!function(){var n=r,i=t;r.y.db.requestTransaction(regeneratorRuntime.mark(function a(){var t,r,s;return regeneratorRuntime.wrap(function(a){for(;;)switch(a.prev=a.next){case 0:return a.delegateYield(this.getStateSet(),"t0",1);case 1:return t=a.t0,a.delegateYield(this.applyDeleteSet(i.deleteSet),"t1",3);case 3:return a.delegateYield(this.getDeleteSet(),"t2",4);case 4:return r=a.t2,a.delegateYield(this.getOperations(i.stateSet),"t3",6);case 6:s=a.t3,n.send(e,{type:"sync step 2",os:s,stateSet:t,deleteSet:r,protocolVersion:this.protocolVersion}),this.forwardToSyncingClients?(n.syncingClients.push(e),setTimeout(function(){n.syncingClients=n.syncingClients.filter(function(t){return t!==e}),n.send(e,{type:"sync done"})},5e3)):n.send(e,{type:"sync done"}),n._setSyncedWith(e);case 10:case"end":return a.stop()}},a,this)}))}();else if("sync step 2"===t.type){var n,i,a;!function(){var s=r;n=!r.broadcastedHB,r.broadcastedHB=!0,i=r.y.db,a={},a.promise=new Promise(function(e){a.resolve=e}),r.syncStep2=a.promise;var o=t;i.requestTransaction(regeneratorRuntime.mark(function u(){return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.delegateYield(this.applyDeleteSet(o.deleteSet),"t0",1);case 1:this.store.apply(o.os),i.requestTransaction(regeneratorRuntime.mark(function r(){var t;return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:return r.delegateYield(this.getOperations(o.stateSet),"t0",1);case 1:t=r.t0,t.length>0&&(n?s.broadcastOps(t):s.send(e,{type:"update",ops:t})),a.resolve();case 4:case"end":return r.stop()}},r,this)}));case 3:case"end":return t.stop()}},u,this)}))}()}else if("sync done"===t.type){var s=this;this.syncStep2.then(function(){s._setSyncedWith(e)})}else if("update"===t.type){if(this.forwardToSyncingClients){var o=!0,u=!1,c=void 0;try{for(var l,d=this.syncingClients[Symbol.iterator]();!(o=(l=d.next()).done);o=!0){var f=l.value;this.send(f,t)}}catch(h){u=!0,c=h}finally{try{!o&&d["return"]&&d["return"]()}finally{if(u)throw c}}}if(this.y.db.forwardAppliedOperations){var p=t.ops.filter(function(e){return"Delete"===e.struct});p.length>0&&this.broadcastOps(p)}this.y.db.apply(t.ops)}}}},{key:"_setSyncedWith",value:function(e){var t=this.connections[e];null!=t&&(t.isSynced=!0),e===this.currentSyncTarget&&(this.currentSyncTarget=null,this.findNextSyncTarget())}},{key:"parseMessageFromXml",value:function(e){function t(e){var n=!0,i=!1,a=void 0;try{for(var s,o=e.children[Symbol.iterator]();!(n=(s=o.next()).done);n=!0){var u=s.value;return"true"===u.getAttribute("isArray")?t(u):r(u)}}catch(c){i=!0,a=c}finally{try{!n&&o["return"]&&o["return"]()}finally{if(i)throw a}}}function r(e){var n={};for(var i in e.attrs){var a=e.attrs[i],s=parseInt(a,10);isNaN(s)||""+s!==a?n[i]=a:n[i]=s}for(var o in e.children){var u=o.name;"true"===o.getAttribute("isArray")?n[u]=t(o):n[u]=r(o)}return n}r(e)}},{key:"encodeMessageToXml",value:function(e,t){function r(e,t){for(var i in t){var a=t[i];null==i||(a.constructor===Object?r(e.c(i),a):a.constructor===Array?n(e.c(i),a):e.setAttribute(i,a))}}function n(e,t){e.setAttribute("isArray","true");var i=!0,a=!1,s=void 0;try{for(var o,u=t[Symbol.iterator]();!(i=(o=u.next()).done);i=!0){var c=o.value;c.constructor===Object?r(e.c("array-element"),c):n(e.c("array-element"),c)}}catch(l){a=!0,s=l}finally{try{!i&&u["return"]&&u["return"]()}finally{if(a)throw s}}}if(t.constructor===Object)r(e.c("y",{xmlns:"http://y.ninja/connector-stanza"}),t);else{if(t.constructor!==Array)throw new Error("I can't encode this json!");n(e.c("y",{xmlns:"http://y.ninja/connector-stanza"}),t)}}}]),t}();e.AbstractConnector=t}},{}],4:[function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var s=function(){function e(e,t){for(var r=0;r0){i=!0;break}i&&e.push(r)}if(e.length>0){var s=getRandom(e),n=t.buffers[s],a=getRandom(Object.keys(n)),o=n[a].shift();0===n[a].length&&delete n[a];var u=t.users[s];return u.receiveMessage(o[0],o[1]),u.y.db.whenTransactionsFinished()}return!1},flushAll:function(){return new Promise(function(e){function r(){var n=t.flushOne();if(n){for(;n;)n=t.flushOne();t.whenTransactionsFinished().then(r)}else setTimeout(function(){var n=t.flushOne();n?n.then(function(){t.whenTransactionsFinished().then(r)}):e()},10)}t.whenTransactionsFinished().then(r)})}};e.utils.globalRoom=t;var r=0,u=function(u){function c(e,a){if(n(this,c),void 0===a)throw new Error("Options must not be undefined!");a.role="master",a.forwardToSyncingClients=!1;var s=i(this,Object.getPrototypeOf(c).call(this,e,a));return s.setUserId(r++ +"").then(function(){t.addUser(s)}),s.globalRoom=t,s.syncingClientDuration=0,s}return a(c,u),s(c,[{key:"receiveMessage",value:function(e,t){o(Object.getPrototypeOf(c.prototype),"receiveMessage",this).call(this,e,JSON.parse(JSON.stringify(t)))}},{key:"send",value:function(e,r){var n=t.buffers[e];null!=n&&(null==n[this.userId]&&(n[this.userId]=[]),n[this.userId].push(JSON.parse(JSON.stringify([this.userId,r]))))}},{key:"broadcast",value:function(e){for(var r in t.buffers){var n=t.buffers[r];null==n[this.userId]&&(n[this.userId]=[]),n[this.userId].push(JSON.parse(JSON.stringify([this.userId,e])))}}},{key:"isDisconnected",value:function(){return null==t.users[this.userId]}},{key:"reconnect",value:function(){return this.isDisconnected()&&(t.addUser(this),o(Object.getPrototypeOf(c.prototype),"reconnect",this).call(this)),e.utils.globalRoom.flushAll()}},{key:"disconnect",value:function(){return this.isDisconnected()||(t.removeUser(this.userId),o(Object.getPrototypeOf(c.prototype),"disconnect",this).call(this)),this.y.db.whenTransactionsFinished()}},{key:"flush",value:function(){var e=this;return async(regeneratorRuntime.mark(function r(){var n,i,a;return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:for(n=t.buffers[e.userId];Object.keys(n).length>0;)i=getRandom(Object.keys(n)),a=n[i].shift(),0===n[i].length&&delete n[i],this.receiveMessage(a[0],a[1]);return r.next=4,e.whenTransactionsFinished();case 4:case"end":return r.stop()}},r,this)}))}}]),c}(e.AbstractConnector);e.Test=u}},{}],5:[function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=function(){function e(e,t){for(var r=0;r0||a.gc2.length>0?(a.y.isConnected()||console.warn("gc should be empty when disconnected!"),new Promise(function(e){a.requestTransaction(regeneratorRuntime.mark(function t(){var r,n;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(null==a.y.connector||!a.y.connector.isSynced){t.next=10;break}r=0;case 2:if(!(r0&&(a.gcInterval=setTimeout(i,a.gcTimeout)),e();case 12:case"end":return t.stop()}},t,this)}))})):(a.gcTimeout>0&&(a.gcInterval=setTimeout(i,a.gcTimeout)),Promise.resolve())})}n(this,t),this.y=e;var a=this;this.userId=null;var s;this.userIdPromise=new Promise(function(e){s=e}),this.userIdPromise.resolve=s,this.forwardAppliedOperations=!1,this.listenersById={},this.listenersByIdExecuteNow=[],this.listenersByIdRequestPending=!1,this.initializedTypes={},this.waitingTransactions=[],this.transactionInProgress=!1,this.transactionIsFlushed=!1,"undefined"!=typeof YConcurrency_TestingMode&&(this.executeOrder=[]),this.gc1=[],this.gc2=[],this.gcTimeout=r.gcTimeout?r.gcTimeoutÅ›:5e4,this.garbageCollect=i,this.gcTimeout>0&&i()}return i(t,[{key:"queueGarbageCollector",value:function(e){this.y.isConnected()&&this.gc1.push(e)}},{key:"emptyGarbageCollector",value:function(){var e=this;return new Promise(function(t){var r=function n(){e.gc1.length>0||e.gc2.length>0?e.garbageCollect().then(n):t()};setTimeout(r,0)})}},{key:"addToDebug",value:function(){if("undefined"!=typeof YConcurrency_TestingMode){var e=Array.prototype.map.call(arguments,function(e){return"string"==typeof e?e:JSON.stringify(e)}).join("").replace(/"/g,"'").replace(/,/g,", ").replace(/:/g,": ");this.executeOrder.push(e)}}},{key:"getDebugData",value:function(){console.log(this.executeOrder.join("\n"))}},{key:"stopGarbageCollector",value:function(){var e=this;return new Promise(function(t){e.requestTransaction(regeneratorRuntime.mark(function r(){var n,i,a;return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:n=e.gc1.concat(e.gc2),e.gc1=[],e.gc2=[],i=0;case 4:if(!(i1)){r.next=10;break}return r.delegateYield(this.getInsertionCleanStart([e.id[0],e.id[1]+1]),"t0",8);case 8:e=r.t0,n=!0;case 10:if(!n){r.next=15;break}return e.gc=!0,r.delegateYield(this.setOperation(e),"t1",13);case 13:return this.store.queueGarbageCollector(e.id),r.abrupt("return",!0);case 15:return r.abrupt("return",!1);case 16:case"end":return r.stop()}},r,this)})},{key:"removeFromGarbageCollector",value:function(t){function r(r){return!e.utils.compareIds(r,t.id)}this.gc1=this.gc1.filter(r),this.gc2=this.gc2.filter(r),delete t.gc}},{key:"destroy",value:regeneratorRuntime.mark(function a(){var e,t;return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:clearInterval(this.gcInterval),this.gcInterval=null;for(e in this.initializedTypes)t=this.initializedTypes[e],null!=t._destroy?t._destroy():console.error("The type you included does not provide destroy functionality, it will remain in memory (updating your packages will help).");case 3:case"end":return r.stop()}},a,this)})},{key:"setUserId",value:function(e){if(!this.userIdPromise.inProgress){this.userIdPromise.inProgress=!0;var t=this;t.requestTransaction(regeneratorRuntime.mark(function r(){var n;return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:return t.userId=e,r.delegateYield(this.getState(e),"t0",2);case 2:n=r.t0,t.opClock=n.clock,t.userIdPromise.resolve(e);case 5:case"end":return r.stop()}},r,this)}))}return this.userIdPromise}},{key:"whenUserIdSet",value:function(e){this.userIdPromise.then(e)}},{key:"getNextOpId",value:function(e){if(null==e)throw new Error("getNextOpId expects the number of created ids to create!");if(null==this.userId)throw new Error("OperationStore not yet initialized!");var t=[this.userId,this.opClock];return this.opClock+=e,t}},{key:"apply",value:function(t){for(var r=0;r0)for(var r={op:t,missing:e.length},n=0;ni;i++)if(a=JSON.stringify([r.id[0],r.id[1]+i]),s=this.listenersById[a],delete this.listenersById[a],null!=s)for(u in s)c=s[u],0===--c.missing&&this.whenOperationsExist([],c.op);if(l=this.initializedTypes[JSON.stringify(r.parent)],null==r.parent){o.next=10;break}return o.delegateYield(t.isDeleted(r.parent),"t1",6);case 6:if(d=o.t1,!d){o.next=10;break}return o.delegateYield(t.deleteList(r.id),"t2",9);case 9:return o.abrupt("return");case 10:if(null==l){o.next=13;break}return f=e.utils.copyObject(r),o.delegateYield(l._changed(t,f),"t3",13);case 13:if(r.deleted){o.next=27;break}h=null!=r.content?r.content.length:1,p=r.id,g=0;case 17:if(!(h>g)){o.next=27;break}return y=[p[0],p[1]+g],o.delegateYield(t.isDeleted(y),"t4",20);case 20:if(b=o.t4,!b){o.next=24;break}return v={struct:"Delete",target:y},o.delegateYield(this.tryExecute.call(t,v),"t5",24);case 24:g++,o.next=17;break;case 27:case"end":return o.stop()}},o,this)})},{key:"whenTransactionsFinished",value:function(){if(this.transactionInProgress){if(null==this.transactionsFinished){var e,t=new Promise(function(t){e=t});return this.transactionsFinished={resolve:e,promise:t},t}return this.transactionsFinished.promise}return Promise.resolve()}},{key:"getNextRequest",value:function(){return 0===this.waitingTransactions.length?this.transactionIsFlushed?(this.transactionInProgress=!1,this.transactionIsFlushed=!1,null!=this.transactionsFinished&&(this.transactionsFinished.resolve(),this.transactionsFinished=null),null):(this.transactionIsFlushed=!0,regeneratorRuntime.mark(function e(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.delegateYield(this.flush(),"t0",1);case 1:case"end":return e.stop()}},e,this)})):(this.transactionIsFlushed=!1,this.waitingTransactions.shift())}},{key:"requestTransaction",value:function(e,t){if(this.waitingTransactions.push(e),!this.transactionInProgress)if(this.transactionInProgress=!0,t)this.transact(this.getNextRequest());else{var r=this;setTimeout(function(){r.transact(r.getNextRequest())},0)}}}]),t}();e.AbstractDatabase=t}},{}],6:[function(e,t,r){"use strict";t.exports=function(e){var t={Delete:{encode:function(e){return e},requiredOps:function(e){return[]},execute:regeneratorRuntime.mark(function r(e){return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.delegateYield(this.deleteOperation(e.target,e.length||1),"t0",1);case 1:return t.abrupt("return",t.t0);case 2:case"end":return t.stop()}},r,this)})},Insert:{encode:function(e){var t={id:e.id,left:e.left,right:e.right,origin:e.origin,parent:e.parent,struct:e.struct};return null!=e.parentSub&&(t.parentSub=e.parentSub),e.hasOwnProperty("opContent")?t.opContent=e.opContent:t.content=e.content.slice(),t},requiredOps:function(t){var r=[];return null!=t.left&&r.push(t.left),null!=t.right&&r.push(t.right),null==t.origin||e.utils.compareIds(t.left,t.origin)||r.push(t.origin),r.push(t.parent),null!=t.opContent&&r.push(t.opContent),r},getDistanceToOrigin:regeneratorRuntime.mark(function n(t){var r,i;return regeneratorRuntime.wrap(function(n){for(;;)switch(n.prev=n.next){case 0:if(null!=t.left){n.next=4;break}return n.abrupt("return",0);case 4:return r=0,n.delegateYield(this.getInsertion(t.left),"t0",6);case 6:i=n.t0;case 7:if(e.utils.matchesId(i,t.origin)){ -n.next=17;break}if(r++,null!=i.left){n.next=13;break}return n.abrupt("break",17);case 13:return n.delegateYield(this.getInsertion(i.left),"t1",14);case 14:i=n.t1;case 15:n.next=7;break;case 17:return n.abrupt("return",r);case 18:case"end":return n.stop()}},n,this)}),execute:regeneratorRuntime.mark(function i(r){var n,a,s,o,u,c,l,d,f,h,p,g,y;return regeneratorRuntime.wrap(function(i){for(;;)switch(i.prev=i.next){case 0:if(a=[],null==r.origin){i.next=8;break}return i.delegateYield(this.getInsertionCleanEnd(r.origin),"t0",3);case 3:return s=i.t0,null==s.originOf&&(s.originOf=[]),s.originOf.push(r.id),i.delegateYield(this.setOperation(s),"t1",7);case 7:null!=s.right&&a.push(s.right);case 8:return i.delegateYield(t.Insert.getDistanceToOrigin.call(this,r),"t2",9);case 9:if(o=n=i.t2,null==r.left){i.next=23;break}return i.delegateYield(this.getInsertionCleanEnd(r.left),"t3",12);case 12:if(u=i.t3,e.utils.compareIds(r.left,r.origin)||null==u.right||a.push(u.right),null!=u.right){i.next=18;break}i.t4=null,i.next=20;break;case 18:return i.delegateYield(this.getOperation(u.right),"t5",19);case 19:i.t4=i.t5;case 20:u=i.t4,i.next=34;break;case 23:return i.delegateYield(this.getOperation(r.parent),"t6",24);case 24:if(c=i.t6,d=r.parentSub?c.map[r.parentSub]:c.start,null!=d){i.next=30;break}i.t7=null,i.next=32;break;case 30:return i.delegateYield(this.getOperation(d),"t8",31);case 31:i.t7=i.t8;case 32:l=i.t7,u=l;case 34:if(null==r.right){i.next=37;break}return a.push(r.right),i.delegateYield(this.getInsertionCleanStart(r.right),"t9",37);case 37:if(null==u||e.utils.compareIds(u.id,r.right)){i.next=59;break}return i.delegateYield(t.Insert.getDistanceToOrigin.call(this,u),"t10",40);case 40:if(f=i.t10,f!==n){i.next=45;break}u.id[0]f)){i.next=49;break}f>=n-o&&(r.left=e.utils.getLastId(u),o=n+1),i.next=50;break;case 49:return i.abrupt("break",62);case 50:if(n++,null==u.right){i.next=56;break}return i.delegateYield(this.getInsertion(u.right),"t11",53);case 53:u=i.t11,i.next=57;break;case 56:u=null;case 57:i.next=60;break;case 59:return i.abrupt("break",62);case 60:i.next=37;break;case 62:if(h=null,p=null,null!=c){i.next=67;break}return i.delegateYield(this.getOperation(r.parent),"t12",66);case 66:c=i.t12;case 67:if(null==r.left){i.next=75;break}return i.delegateYield(this.getInsertion(r.left),"t13",69);case 69:return h=i.t13,r.right=h.right,h.right=r.id,i.delegateYield(this.setOperation(h),"t14",73);case 73:i.next=76;break;case 75:r.right=r.parentSub?c.map[r.parentSub]||null:c.start;case 76:if(null==r.right){i.next=86;break}return i.delegateYield(this.getOperation(r.right),"t15",78);case 78:if(p=i.t15,p.left=e.utils.getLastId(r),null==p.gc){i.next=85;break}if(!(null!=p.content&&p.content.length>1)){i.next=84;break}return i.delegateYield(this.getInsertionCleanEnd(p.id),"t16",83);case 83:p=i.t16;case 84:this.store.removeFromGarbageCollector(p);case 85:return i.delegateYield(this.setOperation(p),"t17",86);case 86:if(null==r.parentSub){i.next=96;break}if(null!=h){i.next=90;break}return c.map[r.parentSub]=r.id,i.delegateYield(this.setOperation(c),"t18",90);case 90:if(null==r.right){i.next=92;break}return i.delegateYield(this.deleteOperation(r.right,1,!0),"t19",92);case 92:if(null==r.left){i.next=94;break}return i.delegateYield(this.deleteOperation(r.id,1,!0),"t20",94);case 94:i.next=100;break;case 96:if(null!=p&&null!=h){i.next=100;break}return null==p&&(c.end=e.utils.getLastId(r)),null==h&&(c.start=r.id),i.delegateYield(this.setOperation(c),"t21",100);case 100:g=0;case 101:if(!(g=0&&null!=n.right)){i.next=12;break}return i.delegateYield(this.getOperation(n.right),"t1",9);case 9:n=i.t1,i.next=13;break;case 12:return i.abrupt("break",15);case 13:i.next=5;break;case 15:return i.abrupt("return",r);case 16:case"end":return i.stop()}},s,this)}),map:regeneratorRuntime.mark(function o(e,t){var r,n;return regeneratorRuntime.wrap(function(i){for(;;)switch(i.prev=i.next){case 0:e=e.start,r=[];case 2:if(null==e){i.next=9;break}return i.delegateYield(this.getOperation(e),"t0",4);case 4:n=i.t0,n.deleted||r.push(t(n)),e=n.right,i.next=2;break;case 9:return i.abrupt("return",r);case 10:case"end":return i.stop()}},o,this)})},Map:{create:function(e){return{id:e,map:{},struct:"Map"}},encode:function(e){var t={struct:"Map",type:e.type,id:e.id,map:{}};return null!=e.requires&&(t.requires=e.requires),null!=e.info&&(t.info=e.info),t},requiredOps:function(){return[]},execute:regeneratorRuntime.mark(function u(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:case"end":return e.stop()}},u,this)}),get:regeneratorRuntime.mark(function c(e,t){var r,n;return regeneratorRuntime.wrap(function(i){for(;;)switch(i.prev=i.next){case 0:if(r=e.map[t],null==r){i.next=14;break}return i.delegateYield(this.getOperation(r),"t0",3);case 3:if(n=i.t0,null!=n&&!n.deleted){i.next=8;break}return i.abrupt("return",void 0);case 8:if(null!=n.opContent){i.next=12;break}return i.abrupt("return",n.content[0]);case 12:return i.delegateYield(this.getType(n.opContent),"t1",13);case 13:return i.abrupt("return",i.t1);case 14:case"end":return i.stop()}},c,this)})}};e.Struct=t}},{}],7:[function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=function(){function e(e,t){for(var r=0;r0&&this.store.y.connector.broadcastOps(r);case 10:case"end":return a.stop()}},s,this)})},{key:"deleteList",value:regeneratorRuntime.mark(function o(e){var t;return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:if(null==e){r.next=15;break}return r.delegateYield(this.getOperation(e),"t0",2);case 2:if(e=r.t0,e.gc){r.next=12;break}return e.gc=!0,e.deleted=!0,r.delegateYield(this.setOperation(e),"t1",7);case 7:return t=null!=e.content?e.content.length:1,r.delegateYield(this.markDeleted(e.id,t),"t2",9);case 9:if(null==e.opContent){r.next=11;break}return r.delegateYield(this.deleteOperation(e.opContent),"t3",11);case 11:this.store.queueGarbageCollector(e.id);case 12:e=e.right,r.next=0;break;case 15:case"end":return r.stop()}},o,this)})},{key:"deleteOperation",value:regeneratorRuntime.mark(function u(e,t,r){var n,i,a,s,o,c,l,d;return regeneratorRuntime.wrap(function(u){for(;;)switch(u.prev=u.next){case 0:return null==t&&(t=1),u.delegateYield(this.markDeleted(e,t),"t0",2);case 2:if(!(t>0)){u.next=66;break}return n=!1,u.delegateYield(this.os.findWithUpperBound([e[0],e[1]+t-1]),"t1",5);case 5:if(i=u.t1,a=null!=i&&null!=i.content?i.content.length:1,!(null==i||i.id[0]!==e[0]||i.id[1]+a<=e[1])){u.next=12;break}i=null,t=0,u.next=22;break;case 12:if(i.deleted){u.next=21;break}if(!(i.id[1]e[1]+t)){u.next=21;break}return u.delegateYield(this.getInsertionCleanEnd([e[0],e[1]+t-1]),"t3",19);case 19:i=u.t3,a=i.content.length;case 21:t=i.id[1]-e[1];case 22:if(null==i){u.next=64;break}if(i.deleted){u.next=44;break}if(n=!0,i.deleted=!0,null==i.start){u.next=28;break}return u.delegateYield(this.deleteList(i.start),"t4",28);case 28:if(null==i.map){u.next=35;break}u.t5=regeneratorRuntime.keys(i.map);case 30:if((u.t6=u.t5()).done){u.next=35;break}return s=u.t6.value,u.delegateYield(this.deleteList(i.map[s]),"t7",33);case 33:u.next=30;break;case 35:if(null==i.opContent){u.next=37;break}return u.delegateYield(this.deleteOperation(i.opContent),"t8",37);case 37:if(null==i.requires){u.next=44;break}o=0;case 39:if(!(o0)){s.next=20;break}if(r.gc){s.next=11;break}r.len+=n,s.next=18;break;case 11:if(n=r.id[1]+r.len-e[1],!(t>n)){s.next=17;break}return r={id:[e[0],e[1]+n],len:t-n,gc:!1},s.delegateYield(this.ds.put(r),"t1",15);case 15:s.next=18;break;case 17:throw new Error("Cannot happen! (it dit though.. :()");case 18:s.next=21;break;case 20:return s.abrupt("return",r);case 21:s.next=25;break;case 23:return r={id:e,len:t,gc:!1},s.delegateYield(this.ds.put(r),"t2",25);case 25:s.next=29;break;case 27:return r={id:e,len:t,gc:!1},s.delegateYield(this.ds.put(r),"t3",29);case 29:return s.delegateYield(this.ds.findNext(r.id),"t4",30);case 30:if(i=s.t4,!(null!=i&&r.id[0]===i.id[0]&&r.id[1]+r.len>=i.id[1])){s.next=61;break}n=r.id[1]+r.len-i.id[1];case 33:if(!(n>=0)){s.next=61;break}if(!i.gc){s.next=44;break}if(r.len-=n,!(n>=i.len)){s.next=41;break}if(n-=i.len,!(n>0)){s.next=41;break}return s.delegateYield(this.ds.put(r),"t5",40);case 40:return s.delegateYield(this.markDeleted([i.id[0],i.id[1]+i.len],n),"t6",41);case 41:return s.abrupt("break",61);case 44:if(!(n>i.len)){s.next=56;break}return s.delegateYield(this.ds.findNext(i.id),"t7",46);case 46:return a=s.t7,s.delegateYield(this.ds["delete"](i.id),"t8",48);case 48:if(null!=a&&r.id[0]===a.id[0]){s.next=52;break}return s.abrupt("break",61);case 52:i=a,n=r.id[1]+r.len-i.id[1];case 54:s.next=59;break;case 56:return r.len+=i.len-n,s.delegateYield(this.ds["delete"](i.id),"t9",58);case 58:return s.abrupt("break",61);case 59:s.next=33;break;case 61:return s.delegateYield(this.ds.put(r),"t10",62);case 62:return s.abrupt("return",r);case 63:case"end":return s.stop()}},l,this)})},{key:"garbageCollectAfterSync",value:regeneratorRuntime.mark(function d(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return(this.store.gc1.length>0||this.store.gc2.length>0)&&console.warn("gc should be empty after sync"),e.delegateYield(this.os.iterate(this,null,null,regeneratorRuntime.mark(function t(e){var r,n,i;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(!e.gc){t.next=3;break}return delete e.gc,t.delegateYield(this.setOperation(e),"t0",3);case 3:if(null==e.parent){t.next=23;break}return t.delegateYield(this.isDeleted(e.parent),"t1",5);case 5:if(r=t.t1,!r){t.next=23;break}if(e.gc=!0,e.deleted){t.next=20;break}return t.delegateYield(this.markDeleted(e.id,null!=e.content?e.content.length:1),"t2",10);case 10:if(e.deleted=!0,null==e.opContent){t.next=13;break}return t.delegateYield(this.deleteOperation(e.opContent),"t3",13);case 13:if(null==e.requires){t.next=20;break}n=0;case 15:if(!(n0)){f.next=61;break}u=r.left,c=null;case 38:if(null==u){f.next=46;break}return f.delegateYield(this.getInsertion(u),"t10",40);case 40:if(c=f.t10,!c.deleted){f.next=43;break}return f.abrupt("break",46);case 43:u=c.left,f.next=38;break;case 46:f.t11=regeneratorRuntime.keys(r.originOf);case 47:if((f.t12=f.t11()).done){f.next=56;break}return l=f.t12.value,f.delegateYield(this.getOperation(r.originOf[l]),"t13",50);case 50:if(d=f.t13,null==d){f.next=54;break}return d.origin=u,f.delegateYield(this.setOperation(d),"t14",54);case 54:f.next=47;break;case 56:if(null==u){f.next=59;break}return null==c.originOf?c.originOf=r.originOf:c.originOf=r.originOf.concat(c.originOf),f.delegateYield(this.setOperation(c),"t15",59);case 59:f.next=62;break;case 61:return f.delegateYield(this.setOperation(o),"t16",62);case 62:if(null==r.origin){f.next=67;break}return f.delegateYield(this.getInsertion(r.origin),"t17",64);case 64:return h=f.t17,h.originOf=h.originOf.filter(function(r){return!e.utils.compareIds(t,r)}),f.delegateYield(this.setOperation(h),"t18",67);case 67:if(null==r.parent){f.next=70;break}return f.delegateYield(this.getOperation(r.parent),"t19",69);case 69:p=f.t19;case 70:if(null==p){f.next=75;break}if(g=!1,null!=r.parentSub?e.utils.compareIds(p.map[r.parentSub],r.id)&&(g=!0,null!=r.right?p.map[r.parentSub]=r.right:delete p.map[r.parentSub]):(e.utils.compareIds(p.start,r.id)&&(g=!0,p.start=r.right),e.utils.matchesId(r,p.end)&&(g=!0,p.end=r.left)),!g){f.next=75;break}return f.delegateYield(this.setOperation(p),"t20",75);case 75:return f.delegateYield(this.removeOperation(r.id),"t21",76);case 76:case"end":return f.stop()}},f,this)})},{key:"checkDeleteStoreForState",value:regeneratorRuntime.mark(function h(e){var t;return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:return r.delegateYield(this.ds.findWithUpperBound([e.user,e.clock]),"t0",1);case 1:t=r.t0,null!=t&&t.id[0]===e.user&&t.gc&&(e.clock=Math.max(e.clock,t.id[1]+t.len));case 3:case"end":return r.stop()}},h,this)})},{key:"updateState",value:regeneratorRuntime.mark(function p(e){var t,r,n;return regeneratorRuntime.wrap(function(i){for(;;)switch(i.prev=i.next){case 0:return i.delegateYield(this.getState(e),"t0",1);case 1:return t=i.t0,i.delegateYield(this.checkDeleteStoreForState(t),"t1",3);case 3:return i.delegateYield(this.getInsertion([e,t.clock]),"t2",4);case 4:r=i.t2,n=null!=r&&null!=r.content?r.content.length:1;case 6:if(!(null!=r&&e===r.id[0]&&r.id[1]<=t.clock&&r.id[1]+n>t.clock)){i.next=14;break}return t.clock+=n,i.delegateYield(this.checkDeleteStoreForState(t),"t3",9);case 9:return i.delegateYield(this.os.findNext(r.id),"t4",10);case 10:r=i.t4,n=null!=r&&null!=r.content?r.content.length:1,i.next=6;break;case 14:return i.delegateYield(this.setState(t),"t5",15);case 15:case"end":return i.stop()}},p,this)})},{key:"applyDeleteSet",value:regeneratorRuntime.mark(function g(e){var t,r,n,i,a,s,o,u,c,l,d;return regeneratorRuntime.wrap(function(f){for(;;)switch(f.prev=f.next){case 0:t=[],f.t0=regeneratorRuntime.keys(e);case 2:if((f.t1=f.t0()).done){f.next=11;break}return r=f.t1.value,n=e[r],i=0,a=n[i],f.delegateYield(this.ds.iterate(this,[r,0],[r,Number.MAX_VALUE],regeneratorRuntime.mark(function h(e){var s;return regeneratorRuntime.wrap(function(o){for(;;)switch(o.prev=o.next){case 0:if(null==a){o.next=10;break}if(s=0,!(e.id[1]+e.len<=a[0])){o.next=6;break}return o.abrupt("break",10);case 6:a[0]=o[1])){f.next=36;break}return f.delegateYield(this.os.findWithUpperBound([o[0],u-1]),"t5",20);case 20:if(c=f.t5,null!=c){f.next=23;break}return f.abrupt("break",36);case 23:if(l=null!=c.content?c.content.length:1,!(c.id[0]!==o[0]||c.id[1]+l<=o[1])){f.next=26;break}return f.abrupt("break",36);case 26:if(!(c.id[1]+l>o[1]+o[2])){f.next=29;break}return f.delegateYield(this.getInsertionCleanEnd([o[0],o[1]+o[2]-1]),"t6",28);case 28:c=f.t6;case 29:if(!(c.id[1]1)){s.next=15;break}return i=n[0],a=e.Struct[i].create(t),a.type=n[1],s.delegateYield(this.setOperation(a),"t1",12);case 12:return s.abrupt("return",a);case 15:return console.error("Unexpected case. How can this happen?"),s.abrupt("return",null);case 18:case"end":return s.stop()}},S,this)})},{key:"removeOperation",value:regeneratorRuntime.mark(function I(e){return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.delegateYield(this.os["delete"](e),"t0",1);case 1:case"end":return t.stop()}},I,this)})},{key:"setState",value:regeneratorRuntime.mark(function T(e){var t;return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:return t={id:[e.user],clock:e.clock},r.delegateYield(this.ss.put(t),"t0",2);case 2:case"end":return r.stop()}},T,this)})},{key:"getState",value:regeneratorRuntime.mark(function C(e){var t,r;return regeneratorRuntime.wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.delegateYield(this.ss.find([e]),"t0",1);case 1:return t=n.t0,r=null==t?null:t.clock,null==r&&(r=0),n.abrupt("return",{user:e,clock:r});case 5:case"end":return n.stop()}},C,this)})},{key:"getStateVector",value:regeneratorRuntime.mark(function E(){var e;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return e=[],t.delegateYield(this.ss.iterate(this,null,null,regeneratorRuntime.mark(function r(t){return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:e.push({user:t.id[0],clock:t.clock});case 1:case"end":return r.stop()}},r,this)})),"t0",2);case 2:return t.abrupt("return",e);case 3:case"end":return t.stop()}},E,this)})},{key:"getStateSet",value:regeneratorRuntime.mark(function L(){var e;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return e={},t.delegateYield(this.ss.iterate(this,null,null,regeneratorRuntime.mark(function r(t){return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:e[t.id[0]]=t.clock;case 1:case"end":return r.stop()}},r,this)})),"t0",2);case 2:return t.abrupt("return",e);case 3:case"end":return t.stop()}},L,this)})},{key:"getOperations",value:regeneratorRuntime.mark(function B(t){var r,n,i,a,s,o,u,c,l,d,f;return regeneratorRuntime.wrap(function(h){for(;;)switch(h.prev=h.next){case 0:return null==t&&(t={}),r=[],h.delegateYield(this.getStateVector(),"t0",3);case 3:n=h.t0,i=!0,a=!1,s=void 0,h.prev=7,o=n[Symbol.iterator]();case 9:if(i=(u=o.next()).done){h.next=23;break}if(c=u.value,l=c.user,"_"!==l){h.next=14;break}return h.abrupt("continue",20);case 14:if(d=t[l]||0,!(d>0)){h.next=19;break}return h.delegateYield(this.getInsertion([l,d]),"t1",17);case 17:f=h.t1,null!=f&&(d=f.id[1]);case 19:return h.delegateYield(this.os.iterate(this,[l,d],[l,Number.MAX_VALUE],regeneratorRuntime.mark(function p(n){var i,a,s,o;return regeneratorRuntime.wrap(function(u){for(;;)switch(u.prev=u.next){case 0:if(n=e.Struct[n.struct].encode(n),"Insert"===n.struct){u.next=5;break}r.push(n),u.next=27;break;case 5:if(!(null==n.right||n.right[1]<(t[n.right[0]]||0))){u.next=27;break}i=n,a=[n],s=n.right;case 9:if(null!=i.left){u.next=15;break}return n.left=null,r.push(n),e.utils.compareIds(i.id,n.id)||(i=e.Struct[n.struct].encode(i),i.right=a[a.length-1].id,r.push(i)),u.abrupt("break",27);case 15:return u.delegateYield(this.getInsertion(i.left),"t0",16);case 16:for(i=u.t0;a.length>0&&e.utils.matchesId(i,a[a.length-1].origin);)a.pop();if(!(i.id[1]<(t[i.id[0]]||0))){u.next=24;break}return n.left=e.utils.getLastId(i),r.push(n),u.abrupt("break",27);case 24:e.utils.matchesId(i,n.origin)?(n.left=n.origin,r.push(n),n=e.Struct[n.struct].encode(i),n.right=s,a.length>0&&console.log("This should not happen .. :( please report this"), -a=[n]):(o=e.Struct[n.struct].encode(i),o.right=a[a.length-1].id,o.left=o.origin,r.push(o),a.push(i));case 25:u.next=9;break;case 27:case"end":return u.stop()}},p,this)})),"t2",20);case 20:i=!0,h.next=9;break;case 23:h.next=29;break;case 25:h.prev=25,h.t3=h["catch"](7),a=!0,s=h.t3;case 29:h.prev=29,h.prev=30,!i&&o["return"]&&o["return"]();case 32:if(h.prev=32,!a){h.next=35;break}throw s;case 35:return h.finish(32);case 36:return h.finish(29);case 37:return h.abrupt("return",r.reverse());case 38:case"end":return h.stop()}},B,this,[[7,25,29,37],[30,,32,36]])})},{key:"flush",value:regeneratorRuntime.mark(function j(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.delegateYield(this.os.flush(),"t0",1);case 1:return e.delegateYield(this.ss.flush(),"t1",2);case 2:return e.delegateYield(this.ds.flush(),"t2",3);case 3:case"end":return e.stop()}},j,this)})}]),t}();e.Transaction=t}},{}],8:[function(e,t,r){"use strict";function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e},o=function c(e,t,r){null===e&&(e=Function.prototype);var n=Object.getOwnPropertyDescriptor(e,t);if(void 0===n){var i=Object.getPrototypeOf(e);return null===i?void 0:c(i,t,r)}if("value"in n)return n.value;var a=n.get;if(void 0!==a)return a.call(r)},u=function(){function e(e,t){for(var r=0;r=e.id[1]&&t[1]=0)){r.next=10;break}if(a=this.readBuffer[i],a.id[1]!==e[1]||a.id[0]!==e[0]){r.next=7;break}for(;i=0)){r.next=19;break}if(a=this.writeBuffer[i],a.id[1]!==e[1]||a.id[0]!==e[0]){r.next=16;break}return s=a,r.abrupt("break",19);case 16:i--,r.next=11;break;case 19:if(!(0>i&&void 0===n)){r.next=22;break}return r.delegateYield(o(Object.getPrototypeOf(t.prototype),"find",this).call(this,e),"t0",21);case 21:s=r.t0;case 22:if(null!=s){for(i=0;i=0)){s.next=11;break}if(i=this.writeBuffer[n],i.id[1]!==r[1]||i.id[0]!==r[0]){s.next=8;break}for(;nn)){s.next=17;break}if(a=this.writeBuffer[0],null===a.id[0]){s.next=15;break}return s.delegateYield(o(Object.getPrototypeOf(t.prototype),"put",this).call(this,a),"t0",15);case 15:for(n=0;n=0;a--){var s=this.waiting[a];"Insert"===s.struct&&(e.utils.matchesId(s,i.left)?(s.right=i.id,i.left=s.left):e.utils.compareIds(s.id,i.right)&&(s.left=e.utils.getLastId(i),i.right=s.right))}}this._tryCallEvents(t)}},{key:"awaitedDeletes",value:function(t,r){for(var n=this.waiting.splice(this.waiting.length-t),i=0;i0){var t=this.waiting;this.waiting=[],t.forEach(this.onevent)}}}]),r}(p);e.utils.EventHandler=g;var y=function b(e){if(a(this,b),null==e.struct||null==e.initType||null==e["class"]||null==e.name)throw new Error("Custom type was not initialized correctly!");this.struct=e.struct,this.initType=e.initType,this["class"]=e["class"],this.name=e.name,null!=e.appendAdditionalInfo&&(this.appendAdditionalInfo=e.appendAdditionalInfo),this.parseArguments=(e.parseArguments||function(){return[this]}).bind(this),this.parseArguments.typeDefinition=this};e.utils.CustomType=y,e.utils.isTypeDefinition=function(t){if(null!=t){if(t instanceof e.utils.CustomType)return[t];if(t.constructor===Array&&t[0]instanceof e.utils.CustomType)return t;if(t instanceof Function&&t.typeDefinition instanceof e.utils.CustomType)return[t.typeDefinition]}return!1},e.utils.copyObject=t,e.utils.smaller=r,e.utils.compareIds=c,e.utils.matchesId=l,e.utils.getLastId=d,e.utils.createSmallLookupBuffer=h}},{}],9:[function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(t){for(var r="undefined"!=typeof regeneratorRuntime?".js":".es6",n=[],i=0;i 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + setTimeout(drainQueue, 0); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],2:[function(require,module,exports){ +(function (process,global){ +"use strict"; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; + +/** + * Copyright (c) 2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * https://raw.github.com/facebook/regenerator/master/LICENSE file. An + * additional grant of patent rights can be found in the PATENTS file in + * the same directory. + */ + +!function (global) { + "use strict"; + + var hasOwn = Object.prototype.hasOwnProperty; + var undefined; // More compressible than void 0. + var $Symbol = typeof Symbol === "function" ? Symbol : {}; + var iteratorSymbol = $Symbol.iterator || "@@iterator"; + var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + + var inModule = (typeof module === "undefined" ? "undefined" : _typeof(module)) === "object"; + var runtime = global.regeneratorRuntime; + if (runtime) { + if (inModule) { + // If regeneratorRuntime is defined globally and we're in a module, + // make the exports object identical to regeneratorRuntime. + module.exports = runtime; + } + // Don't bother evaluating the rest of this file if the runtime was + // already defined globally. + return; + } + + // Define the runtime globally (as expected by generated code) as either + // module.exports (if we're in a module) or a new, empty object. + runtime = global.regeneratorRuntime = inModule ? module.exports : {}; + + function wrap(innerFn, outerFn, self, tryLocsList) { + // If outerFn provided, then outerFn.prototype instanceof Generator. + var generator = Object.create((outerFn || Generator).prototype); + var context = new Context(tryLocsList || []); + + // The ._invoke method unifies the implementations of the .next, + // .throw, and .return methods. + generator._invoke = makeInvokeMethod(innerFn, self, context); + + return generator; + } + runtime.wrap = wrap; + + // Try/catch helper to minimize deoptimizations. Returns a completion + // record like context.tryEntries[i].completion. This interface could + // have been (and was previously) designed to take a closure to be + // invoked without arguments, but in all the cases we care about we + // already have an existing method we want to call, so there's no need + // to create a new function object. We can even get away with assuming + // the method takes exactly one argument, since that happens to be true + // in every case, so we don't have to touch the arguments object. The + // only additional allocation required is the completion record, which + // has a stable shape and so hopefully should be cheap to allocate. + function tryCatch(fn, obj, arg) { + try { + return { type: "normal", arg: fn.call(obj, arg) }; + } catch (err) { + return { type: "throw", arg: err }; + } + } + + var GenStateSuspendedStart = "suspendedStart"; + var GenStateSuspendedYield = "suspendedYield"; + var GenStateExecuting = "executing"; + var GenStateCompleted = "completed"; + + // Returning this object from the innerFn has the same effect as + // breaking out of the dispatch switch statement. + var ContinueSentinel = {}; + + // Dummy constructor functions that we use as the .constructor and + // .constructor.prototype properties for functions that return Generator + // objects. For full spec compliance, you may wish to configure your + // minifier not to mangle the names of these two functions. + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} + + var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype; + GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; + GeneratorFunctionPrototype.constructor = GeneratorFunction; + GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; + + // Helper for defining the .next, .throw, and .return methods of the + // Iterator interface in terms of a single ._invoke method. + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function (method) { + prototype[method] = function (arg) { + return this._invoke(method, arg); + }; + }); + } + + runtime.isGeneratorFunction = function (genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor ? ctor === GeneratorFunction || + // For the native GeneratorFunction constructor, the best we can + // do is to check its .name property. + (ctor.displayName || ctor.name) === "GeneratorFunction" : false; + }; + + runtime.mark = function (genFun) { + if (Object.setPrototypeOf) { + Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); + } else { + genFun.__proto__ = GeneratorFunctionPrototype; + if (!(toStringTagSymbol in genFun)) { + genFun[toStringTagSymbol] = "GeneratorFunction"; + } + } + genFun.prototype = Object.create(Gp); + return genFun; + }; + + // Within the body of any async function, `await x` is transformed to + // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test + // `value instanceof AwaitArgument` to determine if the yielded value is + // meant to be awaited. Some may consider the name of this method too + // cutesy, but they are curmudgeons. + runtime.awrap = function (arg) { + return new AwaitArgument(arg); + }; + + function AwaitArgument(arg) { + this.arg = arg; + } + + function AsyncIterator(generator) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if (record.type === "throw") { + reject(record.arg); + } else { + var result = record.arg; + var value = result.value; + if (value instanceof AwaitArgument) { + return Promise.resolve(value.arg).then(function (value) { + invoke("next", value, resolve, reject); + }, function (err) { + invoke("throw", err, resolve, reject); + }); + } + + return Promise.resolve(value).then(function (unwrapped) { + // When a yielded Promise is resolved, its final value becomes + // the .value of the Promise<{value,done}> result for the + // current iteration. If the Promise is rejected, however, the + // result for this iteration will be rejected with the same + // reason. Note that rejections of yielded Promises are not + // thrown back into the generator function, as is the case + // when an awaited Promise is rejected. This difference in + // behavior between yield and await is important, because it + // allows the consumer to decide what to do with the yielded + // rejection (swallow it and continue, manually .throw it back + // into the generator, abandon iteration, whatever). With + // await, by contrast, there is no opportunity to examine the + // rejection reason outside the generator function, so the + // only option is to throw it from the await expression, and + // let the generator function handle the exception. + result.value = unwrapped; + resolve(result); + }, reject); + } + } + + if ((typeof process === "undefined" ? "undefined" : _typeof(process)) === "object" && process.domain) { + invoke = process.domain.bind(invoke); + } + + var previousPromise; + + function enqueue(method, arg) { + function callInvokeWithMethodAndArg() { + return new Promise(function (resolve, reject) { + invoke(method, arg, resolve, reject); + }); + } + + return previousPromise = + // If enqueue has been called before, then we want to wait until + // all previous Promises have been resolved before calling invoke, + // so that results are always delivered in the correct order. If + // enqueue has not been called before, then it is important to + // call invoke immediately, without waiting on a callback to fire, + // so that the async generator function has the opportunity to do + // any necessary setup in a predictable way. This predictability + // is why the Promise constructor synchronously invokes its + // executor callback, and why async functions synchronously + // execute code before the first await. Since we implement simple + // async functions in terms of async generators, it is especially + // important to get this right, even though it requires care. + previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, + // Avoid propagating failures to Promises returned by later + // invocations of the iterator. + callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); + } + + // Define the unified helper method that is used to implement .next, + // .throw, and .return (see defineIteratorMethods). + this._invoke = enqueue; + } + + defineIteratorMethods(AsyncIterator.prototype); + + // Note that simple async functions are implemented on top of + // AsyncIterator objects; they just return a Promise for the value of + // the final result produced by the iterator. + runtime.async = function (innerFn, outerFn, self, tryLocsList) { + var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); + + return runtime.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. + : iter.next().then(function (result) { + return result.done ? result.value : iter.next(); + }); + }; + + function makeInvokeMethod(innerFn, self, context) { + var state = GenStateSuspendedStart; + + return function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + + if (state === GenStateCompleted) { + if (method === "throw") { + throw arg; + } + + // Be forgiving, per 25.3.3.3.3 of the spec: + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume + return doneResult(); + } + + while (true) { + var delegate = context.delegate; + if (delegate) { + if (method === "return" || method === "throw" && delegate.iterator[method] === undefined) { + // A return or throw (when the delegate iterator has no throw + // method) always terminates the yield* loop. + context.delegate = null; + + // If the delegate iterator has a return method, give it a + // chance to clean up. + var returnMethod = delegate.iterator["return"]; + if (returnMethod) { + var record = tryCatch(returnMethod, delegate.iterator, arg); + if (record.type === "throw") { + // If the return method threw an exception, let that + // exception prevail over the original return or throw. + method = "throw"; + arg = record.arg; + continue; + } + } + + if (method === "return") { + // Continue with the outer return, now that the delegate + // iterator has been terminated. + continue; + } + } + + var record = tryCatch(delegate.iterator[method], delegate.iterator, arg); + + if (record.type === "throw") { + context.delegate = null; + + // Like returning generator.throw(uncaught), but without the + // overhead of an extra function call. + method = "throw"; + arg = record.arg; + continue; + } + + // Delegate generator ran and handled its own exceptions so + // regardless of what the method was, we continue as if it is + // "next" with an undefined arg. + method = "next"; + arg = undefined; + + var info = record.arg; + if (info.done) { + context[delegate.resultName] = info.value; + context.next = delegate.nextLoc; + } else { + state = GenStateSuspendedYield; + return info; + } + + context.delegate = null; + } + + if (method === "next") { + if (state === GenStateSuspendedYield) { + context.sent = arg; + } else { + context.sent = undefined; + } + } else if (method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw arg; + } + + if (context.dispatchException(arg)) { + // If the dispatched exception was caught by a catch block, + // then let that catch block handle the exception normally. + method = "next"; + arg = undefined; + } + } else if (method === "return") { + context.abrupt("return", arg); + } + + state = GenStateExecuting; + + var record = tryCatch(innerFn, self, context); + if (record.type === "normal") { + // If an exception is thrown from innerFn, we leave state === + // GenStateExecuting and loop back for another invocation. + state = context.done ? GenStateCompleted : GenStateSuspendedYield; + + var info = { + value: record.arg, + done: context.done + }; + + if (record.arg === ContinueSentinel) { + if (context.delegate && method === "next") { + // Deliberately forget the last sent value so that we don't + // accidentally pass it on to the delegate. + arg = undefined; + } + } else { + return info; + } + } else if (record.type === "throw") { + state = GenStateCompleted; + // Dispatch the exception by looping back around to the + // context.dispatchException(arg) call above. + method = "throw"; + arg = record.arg; + } + } + }; + } + + // Define Generator.prototype.{next,throw,return} in terms of the + // unified ._invoke helper method. + defineIteratorMethods(Gp); + + Gp[iteratorSymbol] = function () { + return this; + }; + + Gp[toStringTagSymbol] = "Generator"; + + Gp.toString = function () { + return "[object Generator]"; + }; + + function pushTryEntry(locs) { + var entry = { tryLoc: locs[0] }; + + if (1 in locs) { + entry.catchLoc = locs[1]; + } + + if (2 in locs) { + entry.finallyLoc = locs[2]; + entry.afterLoc = locs[3]; + } + + this.tryEntries.push(entry); + } + + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal"; + delete record.arg; + entry.completion = record; + } + + function Context(tryLocsList) { + // The root entry object (effectively a try statement without a catch + // or a finally block) gives us a place to store values thrown from + // locations where there is no enclosing try statement. + this.tryEntries = [{ tryLoc: "root" }]; + tryLocsList.forEach(pushTryEntry, this); + this.reset(true); + } + + runtime.keys = function (object) { + var keys = []; + for (var key in object) { + keys.push(key); + } + keys.reverse(); + + // Rather than returning an object with a next method, we keep + // things simple and return the next function itself. + return function next() { + while (keys.length) { + var key = keys.pop(); + if (key in object) { + next.value = key; + next.done = false; + return next; + } + } + + // To avoid creating an additional object, we just hang the .value + // and .done properties off the next function object itself. This + // also ensures that the minifier will not anonymize the function. + next.done = true; + return next; + }; + }; + + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } + + if (typeof iterable.next === "function") { + return iterable; + } + + if (!isNaN(iterable.length)) { + var i = -1, + next = function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } + + next.value = undefined; + next.done = true; + + return next; + }; + + return next.next = next; + } + } + + // Return an iterator with no values. + return { next: doneResult }; + } + runtime.values = values; + + function doneResult() { + return { value: undefined, done: true }; + } + + Context.prototype = { + constructor: Context, + + reset: function reset(skipTempReset) { + this.prev = 0; + this.next = 0; + this.sent = undefined; + this.done = false; + this.delegate = null; + + this.tryEntries.forEach(resetTryEntry); + + if (!skipTempReset) { + for (var name in this) { + // Not sure about the optimal order of these conditions: + if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { + this[name] = undefined; + } + } + } + }, + + stop: function stop() { + this.done = true; + + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } + + return this.rval; + }, + + dispatchException: function dispatchException(exception) { + if (this.done) { + throw exception; + } + + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; + return !!caught; + } + + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; + + if (entry.tryLoc === "root") { + // Exception thrown outside of any try block that could handle + // it, so set the completion value of the entire function to + // throw the exception. + return handle("end"); + } + + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + var hasFinally = hasOwn.call(entry, "finallyLoc"); + + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else { + throw new Error("try statement without catch or finally"); + } + } + } + }, + + abrupt: function abrupt(type, arg) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { + var finallyEntry = entry; + break; + } + } + + if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { + // Ignore the finally entry if control is not jumping to a + // location outside the try/catch block. + finallyEntry = null; + } + + var record = finallyEntry ? finallyEntry.completion : {}; + record.type = type; + record.arg = arg; + + if (finallyEntry) { + this.next = finallyEntry.finallyLoc; + } else { + this.complete(record); + } + + return ContinueSentinel; + }, + + complete: function complete(record, afterLoc) { + if (record.type === "throw") { + throw record.arg; + } + + if (record.type === "break" || record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = record.arg; + this.next = "end"; + } else if (record.type === "normal" && afterLoc) { + this.next = afterLoc; + } + }, + + finish: function finish(finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) { + this.complete(entry.completion, entry.afterLoc); + resetTryEntry(entry); + return ContinueSentinel; + } + } + }, + + "catch": function _catch(tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } + } + + // The context.catch method must only be called with a location + // argument that corresponds to a known catch block. + throw new Error("illegal catch attempt"); + }, + + delegateYield: function delegateYield(iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; + + return ContinueSentinel; + } + }; +}( +// Among the various tricks for obtaining a reference to the global +// object, this seems to be the most reliable technique that does not +// use indirect eval (which violates Content Security Policy). +(typeof global === "undefined" ? "undefined" : _typeof(global)) === "object" ? global : (typeof window === "undefined" ? "undefined" : _typeof(window)) === "object" ? window : (typeof self === "undefined" ? "undefined" : _typeof(self)) === "object" ? self : undefined); + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"_process":1}],3:[function(require,module,exports){ +/* @flow */ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +module.exports = function (Y /* :any */) { + var AbstractConnector = function () { + /* :: + y: YConfig; + role: SyncRole; + connections: Object; + isSynced: boolean; + userEventListeners: Array; + whenSyncedListeners: Array; + currentSyncTarget: ?UserId; + syncingClients: Array; + forwardToSyncingClients: boolean; + debug: boolean; + broadcastedHB: boolean; + syncStep2: Promise; + userId: UserId; + send: Function; + broadcast: Function; + broadcastOpBuffer: Array; + protocolVersion: number; + */ + /* + opts contains the following information: + role : String Role of this client ("master" or "slave") + userId : String Uniquely defines the user. + debug: Boolean Whether to print debug messages (optional) + */ + + function AbstractConnector(y, opts) { + _classCallCheck(this, AbstractConnector); + + this.y = y; + if (opts == null) { + opts = {}; + } + if (opts.role == null || opts.role === 'master') { + this.role = 'master'; + } else if (opts.role === 'slave') { + this.role = 'slave'; + } else { + throw new Error("Role must be either 'master' or 'slave'!"); + } + this.y.db.forwardAppliedOperations = opts.forwardAppliedOperations || false; + this.role = opts.role; + this.connections = {}; + this.isSynced = false; + this.userEventListeners = []; + this.whenSyncedListeners = []; + this.currentSyncTarget = null; + this.syncingClients = []; + this.forwardToSyncingClients = opts.forwardToSyncingClients !== false; + this.debug = opts.debug === true; + this.broadcastedHB = false; + this.syncStep2 = Promise.resolve(); + this.broadcastOpBuffer = []; + this.protocolVersion = 11; + } + + _createClass(AbstractConnector, [{ + key: 'reconnect', + value: function reconnect() {} + }, { + key: 'disconnect', + value: function disconnect() { + this.connections = {}; + this.isSynced = false; + this.currentSyncTarget = null; + this.broadcastedHB = false; + this.syncingClients = []; + this.whenSyncedListeners = []; + return this.y.db.stopGarbageCollector(); + } + }, { + key: 'setUserId', + value: function setUserId(userId) { + if (this.userId == null) { + this.userId = userId; + return this.y.db.setUserId(userId); + } else { + return null; + } + } + }, { + key: 'onUserEvent', + value: function onUserEvent(f) { + this.userEventListeners.push(f); + } + }, { + key: 'userLeft', + value: function userLeft(user) { + if (this.connections[user] != null) { + delete this.connections[user]; + if (user === this.currentSyncTarget) { + this.currentSyncTarget = null; + this.findNextSyncTarget(); + } + this.syncingClients = this.syncingClients.filter(function (cli) { + return cli !== user; + }); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.userEventListeners[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var f = _step.value; + + f({ + action: 'userLeft', + user: user + }); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + } + }, { + key: 'userJoined', + value: function userJoined(user, role) { + if (role == null) { + throw new Error('You must specify the role of the joined user!'); + } + if (this.connections[user] != null) { + throw new Error('This user already joined!'); + } + this.connections[user] = { + isSynced: false, + role: role + }; + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.userEventListeners[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var f = _step2.value; + + f({ + action: 'userJoined', + user: user, + role: role + }); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + if (this.currentSyncTarget == null) { + this.findNextSyncTarget(); + } + } + // Execute a function _when_ we are connected. + // If not connected, wait until connected + + }, { + key: 'whenSynced', + value: function whenSynced(f) { + if (this.isSynced) { + f(); + } else { + this.whenSyncedListeners.push(f); + } + } + /* + returns false, if there is no sync target + true otherwise + */ + + }, { + key: 'findNextSyncTarget', + value: function findNextSyncTarget() { + if (this.currentSyncTarget != null || this.isSynced) { + return; // "The current sync has not finished!" + } + + var syncUser = null; + for (var uid in this.connections) { + if (!this.connections[uid].isSynced) { + syncUser = uid; + break; + } + } + var conn = this; + if (syncUser != null) { + this.currentSyncTarget = syncUser; + this.y.db.requestTransaction(regeneratorRuntime.mark(function _callee() { + var stateSet, deleteSet; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + return _context.delegateYield(this.getStateSet(), 't0', 1); + + case 1: + stateSet = _context.t0; + return _context.delegateYield(this.getDeleteSet(), 't1', 3); + + case 3: + deleteSet = _context.t1; + + conn.send(syncUser, { + type: 'sync step 1', + stateSet: stateSet, + deleteSet: deleteSet, + protocolVersion: conn.protocolVersion + }); + + case 5: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + } else { + this.y.db.requestTransaction(regeneratorRuntime.mark(function _callee2() { + var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, f; + + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + // it is crucial that isSynced is set at the time garbageCollectAfterSync is called + conn.isSynced = true; + return _context2.delegateYield(this.garbageCollectAfterSync(), 't0', 2); + + case 2: + // call whensynced listeners + _iteratorNormalCompletion3 = true; + _didIteratorError3 = false; + _iteratorError3 = undefined; + _context2.prev = 5; + for (_iterator3 = conn.whenSyncedListeners[Symbol.iterator](); !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + f = _step3.value; + + f(); + } + _context2.next = 13; + break; + + case 9: + _context2.prev = 9; + _context2.t1 = _context2['catch'](5); + _didIteratorError3 = true; + _iteratorError3 = _context2.t1; + + case 13: + _context2.prev = 13; + _context2.prev = 14; + + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + + case 16: + _context2.prev = 16; + + if (!_didIteratorError3) { + _context2.next = 19; + break; + } + + throw _iteratorError3; + + case 19: + return _context2.finish(16); + + case 20: + return _context2.finish(13); + + case 21: + conn.whenSyncedListeners = []; + + case 22: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this, [[5, 9, 13, 21], [14,, 16, 20]]); + })); + } + } + }, { + key: 'send', + value: function send(uid, message) { + if (this.debug) { + console.log('send ' + this.userId + ' -> ' + uid + ': ' + message.type, message); // eslint-disable-line + } + } + /* + Buffer operations, and broadcast them when ready. + */ + + }, { + key: 'broadcastOps', + value: function broadcastOps(ops) { + ops = ops.map(function (op) { + return Y.Struct[op.struct].encode(op); + }); + var self = this; + function broadcastOperations() { + if (self.broadcastOpBuffer.length > 0) { + self.broadcast({ + type: 'update', + ops: self.broadcastOpBuffer + }); + self.broadcastOpBuffer = []; + } + } + if (this.broadcastOpBuffer.length === 0) { + this.broadcastOpBuffer = ops; + if (this.y.db.transactionInProgress) { + this.y.db.whenTransactionsFinished().then(broadcastOperations); + } else { + setTimeout(broadcastOperations, 0); + } + } else { + this.broadcastOpBuffer = this.broadcastOpBuffer.concat(ops); + } + } + /* + You received a raw message, and you know that it is intended for Yjs. Then call this function. + */ + + }, { + key: 'receiveMessage', + value: function receiveMessage(sender /* :UserId */, message /* :Message */) { + var _this = this; + + if (sender === this.userId) { + return; + } + if (this.debug) { + console.log('receive ' + sender + ' -> ' + this.userId + ': ' + message.type, JSON.parse(JSON.stringify(message))); // eslint-disable-line + } + if (message.protocolVersion != null && message.protocolVersion !== this.protocolVersion) { + console.error('You tried to sync with a yjs instance that has a different protocol version\n (You: ' + this.protocolVersion + ', Client: ' + message.protocolVersion + ').\n The sync was stopped. You need to upgrade your dependencies (especially Yjs & the Connector)!\n '); + this.send(sender, { + type: 'sync stop', + protocolVersion: this.protocolVersion + }); + return; + } + if (message.type === 'sync step 1') { + (function () { + var conn = _this; + var m = message; + _this.y.db.requestTransaction(regeneratorRuntime.mark(function _callee3() { + var currentStateSet, ds, ops; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + return _context3.delegateYield(this.getStateSet(), 't0', 1); + + case 1: + currentStateSet = _context3.t0; + return _context3.delegateYield(this.applyDeleteSet(m.deleteSet), 't1', 3); + + case 3: + return _context3.delegateYield(this.getDeleteSet(), 't2', 4); + + case 4: + ds = _context3.t2; + return _context3.delegateYield(this.getOperations(m.stateSet), 't3', 6); + + case 6: + ops = _context3.t3; + + conn.send(sender, { + type: 'sync step 2', + os: ops, + stateSet: currentStateSet, + deleteSet: ds, + protocolVersion: this.protocolVersion + }); + if (this.forwardToSyncingClients) { + conn.syncingClients.push(sender); + setTimeout(function () { + conn.syncingClients = conn.syncingClients.filter(function (cli) { + return cli !== sender; + }); + conn.send(sender, { + type: 'sync done' + }); + }, 5000); // TODO: conn.syncingClientDuration) + } else { + conn.send(sender, { + type: 'sync done' + }); + } + conn._setSyncedWith(sender); + + case 10: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + })); + })(); + } else if (message.type === 'sync step 2') { + var broadcastHB; + var db; + var defer; + + (function () { + var conn = _this; + broadcastHB = !_this.broadcastedHB; + + _this.broadcastedHB = true; + db = _this.y.db; + defer = {}; + + defer.promise = new Promise(function (resolve) { + defer.resolve = resolve; + }); + _this.syncStep2 = defer.promise; + var m /* :MessageSyncStep2 */ = message; + db.requestTransaction(regeneratorRuntime.mark(function _callee5() { + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + return _context5.delegateYield(this.applyDeleteSet(m.deleteSet), 't0', 1); + + case 1: + this.store.apply(m.os); + db.requestTransaction(regeneratorRuntime.mark(function _callee4() { + var ops; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + return _context4.delegateYield(this.getOperations(m.stateSet), 't0', 1); + + case 1: + ops = _context4.t0; + + if (ops.length > 0) { + if (!broadcastHB) { + // TODO: consider to broadcast here.. + conn.send(sender, { + type: 'update', + ops: ops + }); + } else { + // broadcast only once! + conn.broadcastOps(ops); + } + } + defer.resolve(); + + case 4: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + })); + + case 3: + case 'end': + return _context5.stop(); + } + } + }, _callee5, this); + })); + })(); + } else if (message.type === 'sync done') { + var self = this; + this.syncStep2.then(function () { + self._setSyncedWith(sender); + }); + } else if (message.type === 'update') { + if (this.forwardToSyncingClients) { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = this.syncingClients[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var client = _step4.value; + + this.send(client, message); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4.return) { + _iterator4.return(); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + } + if (this.y.db.forwardAppliedOperations) { + var delops = message.ops.filter(function (o) { + return o.struct === 'Delete'; + }); + if (delops.length > 0) { + this.broadcastOps(delops); + } + } + this.y.db.apply(message.ops); + } + } + }, { + key: '_setSyncedWith', + value: function _setSyncedWith(user) { + var conn = this.connections[user]; + if (conn != null) { + conn.isSynced = true; + } + if (user === this.currentSyncTarget) { + this.currentSyncTarget = null; + this.findNextSyncTarget(); + } + } + /* + Currently, the HB encodes operations as JSON. For the moment I want to keep it + that way. Maybe we support encoding in the HB as XML in the future, but for now I don't want + too much overhead. Y is very likely to get changed a lot in the future + Because we don't want to encode JSON as string (with character escaping, wich makes it pretty much unreadable) + we encode the JSON as XML. + When the HB support encoding as XML, the format should look pretty much like this. + does not support primitive values as array elements + expects an ltx (less than xml) object + */ + + }, { + key: 'parseMessageFromXml', + value: function parseMessageFromXml(m /* :any */) { + function parseArray(node) { + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = node.children[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var n = _step5.value; + + if (n.getAttribute('isArray') === 'true') { + return parseArray(n); + } else { + return parseObject(n); + } + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5.return) { + _iterator5.return(); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + } + function parseObject(node /* :any */) { + var json = {}; + for (var attrName in node.attrs) { + var value = node.attrs[attrName]; + var int = parseInt(value, 10); + if (isNaN(int) || '' + int !== value) { + json[attrName] = value; + } else { + json[attrName] = int; + } + } + for (var n /* :any */ in node.children) { + var name = n.name; + if (n.getAttribute('isArray') === 'true') { + json[name] = parseArray(n); + } else { + json[name] = parseObject(n); + } + } + return json; + } + parseObject(m); + } + /* + encode message in xml + we use string because Strophe only accepts an "xml-string".. + So {a:4,b:{c:5}} will look like + + + + m - ltx element + json - Object + */ + + }, { + key: 'encodeMessageToXml', + value: function encodeMessageToXml(msg, obj) { + // attributes is optional + function encodeObject(m, json) { + for (var name in json) { + var value = json[name]; + if (name == null) { + // nop + } else if (value.constructor === Object) { + encodeObject(m.c(name), value); + } else if (value.constructor === Array) { + encodeArray(m.c(name), value); + } else { + m.setAttribute(name, value); + } + } + } + function encodeArray(m, array) { + m.setAttribute('isArray', 'true'); + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = array[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var e = _step6.value; + + if (e.constructor === Object) { + encodeObject(m.c('array-element'), e); + } else { + encodeArray(m.c('array-element'), e); + } + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6.return) { + _iterator6.return(); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + } + if (obj.constructor === Object) { + encodeObject(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj); + } else if (obj.constructor === Array) { + encodeArray(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj); + } else { + throw new Error("I can't encode this json!"); + } + } + }]); + + return AbstractConnector; + }(); + + Y.AbstractConnector = AbstractConnector; +}; + +},{}],4:[function(require,module,exports){ +/* global getRandom, async */ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +module.exports = function (Y) { + var globalRoom = { + users: {}, + buffers: {}, // TODO: reimplement this idea. This does not cover all cases!! Here, you have a queue which is unrealistic (i.e. think about multiple incoming connections) + removeUser: function removeUser(user) { + for (var i in this.users) { + this.users[i].userLeft(user); + } + delete this.users[user]; + delete this.buffers[user]; + }, + addUser: function addUser(connector) { + this.users[connector.userId] = connector; + this.buffers[connector.userId] = {}; + for (var uname in this.users) { + if (uname !== connector.userId) { + var u = this.users[uname]; + u.userJoined(connector.userId, 'master'); + connector.userJoined(u.userId, 'master'); + } + } + }, + whenTransactionsFinished: function whenTransactionsFinished() { + var ps = []; + for (var name in this.users) { + ps.push(this.users[name].y.db.whenTransactionsFinished()); + } + return Promise.all(ps); + }, + flushOne: function flushOne() { + var bufs = []; + for (var receiver in globalRoom.buffers) { + var buff = globalRoom.buffers[receiver]; + var push = false; + for (var sender in buff) { + if (buff[sender].length > 0) { + push = true; + break; + } + } + if (push) { + bufs.push(receiver); + } + } + if (bufs.length > 0) { + var userId = getRandom(bufs); + var buff = globalRoom.buffers[userId]; + var sender = getRandom(Object.keys(buff)); + var m = buff[sender].shift(); + if (buff[sender].length === 0) { + delete buff[sender]; + } + var user = globalRoom.users[userId]; + user.receiveMessage(m[0], m[1]); + return user.y.db.whenTransactionsFinished(); + } else { + return false; + } + }, + flushAll: function flushAll() { + return new Promise(function (resolve) { + // flushes may result in more created operations, + // flush until there is nothing more to flush + function nextFlush() { + var c = globalRoom.flushOne(); + if (c) { + while (c) { + c = globalRoom.flushOne(); + } + globalRoom.whenTransactionsFinished().then(nextFlush); + } else { + setTimeout(function () { + var c = globalRoom.flushOne(); + if (c) { + c.then(function () { + globalRoom.whenTransactionsFinished().then(nextFlush); + }); + } else { + resolve(); + } + }, 10); + } + } + globalRoom.whenTransactionsFinished().then(nextFlush); + }); + } + }; + Y.utils.globalRoom = globalRoom; + + var userIdCounter = 0; + + var Test = function (_Y$AbstractConnector) { + _inherits(Test, _Y$AbstractConnector); + + function Test(y, options) { + _classCallCheck(this, Test); + + if (options === undefined) { + throw new Error('Options must not be undefined!'); + } + options.role = 'master'; + options.forwardToSyncingClients = false; + + var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Test).call(this, y, options)); + + _this.setUserId(userIdCounter++ + '').then(function () { + globalRoom.addUser(_this); + }); + _this.globalRoom = globalRoom; + _this.syncingClientDuration = 0; + return _this; + } + + _createClass(Test, [{ + key: 'receiveMessage', + value: function receiveMessage(sender, m) { + _get(Object.getPrototypeOf(Test.prototype), 'receiveMessage', this).call(this, sender, JSON.parse(JSON.stringify(m))); + } + }, { + key: 'send', + value: function send(userId, message) { + var buffer = globalRoom.buffers[userId]; + if (buffer != null) { + if (buffer[this.userId] == null) { + buffer[this.userId] = []; + } + buffer[this.userId].push(JSON.parse(JSON.stringify([this.userId, message]))); + } + } + }, { + key: 'broadcast', + value: function broadcast(message) { + for (var key in globalRoom.buffers) { + var buff = globalRoom.buffers[key]; + if (buff[this.userId] == null) { + buff[this.userId] = []; + } + buff[this.userId].push(JSON.parse(JSON.stringify([this.userId, message]))); + } + } + }, { + key: 'isDisconnected', + value: function isDisconnected() { + return globalRoom.users[this.userId] == null; + } + }, { + key: 'reconnect', + value: function reconnect() { + if (this.isDisconnected()) { + globalRoom.addUser(this); + _get(Object.getPrototypeOf(Test.prototype), 'reconnect', this).call(this); + } + return Y.utils.globalRoom.flushAll(); + } + }, { + key: 'disconnect', + value: function disconnect() { + if (!this.isDisconnected()) { + globalRoom.removeUser(this.userId); + _get(Object.getPrototypeOf(Test.prototype), 'disconnect', this).call(this); + } + return this.y.db.whenTransactionsFinished(); + } + }, { + key: 'flush', + value: function flush() { + var self = this; + return async(regeneratorRuntime.mark(function _callee() { + var buff, sender, m; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + buff = globalRoom.buffers[self.userId]; + + while (Object.keys(buff).length > 0) { + sender = getRandom(Object.keys(buff)); + m = buff[sender].shift(); + + if (buff[sender].length === 0) { + delete buff[sender]; + } + this.receiveMessage(m[0], m[1]); + } + _context.next = 4; + return self.whenTransactionsFinished(); + + case 4: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + } + }]); + + return Test; + }(Y.AbstractConnector); + + Y.Test = Test; +}; + +},{}],5:[function(require,module,exports){ +/* @flow */ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +module.exports = function (Y /* :any */) { + /* + Partial definition of an OperationStore. + TODO: name it Database, operation store only holds operations. + A database definition must alse define the following methods: + * logTable() (optional) + - show relevant information information in a table + * requestTransaction(makeGen) + - request a transaction + * destroy() + - destroy the database + */ + + var AbstractDatabase = function () { + /* :: + y: YConfig; + forwardAppliedOperations: boolean; + listenersById: Object; + listenersByIdExecuteNow: Array; + listenersByIdRequestPending: boolean; + initializedTypes: Object; + whenUserIdSetListener: ?Function; + waitingTransactions: Array; + transactionInProgress: boolean; + executeOrder: Array; + gc1: Array; + gc2: Array; + gcTimeout: number; + gcInterval: any; + garbageCollect: Function; + executeOrder: Array; // for debugging only + userId: UserId; + opClock: number; + transactionsFinished: ?{promise: Promise, resolve: any}; + transact: (x: ?Generator) => any; + */ + + function AbstractDatabase(y, opts) { + _classCallCheck(this, AbstractDatabase); + + this.y = y; + var os = this; + this.userId = null; + var resolve; + this.userIdPromise = new Promise(function (r) { + resolve = r; + }); + this.userIdPromise.resolve = resolve; + // whether to broadcast all applied operations (insert & delete hook) + this.forwardAppliedOperations = false; + // E.g. this.listenersById[id] : Array + this.listenersById = {}; + // Execute the next time a transaction is requested + this.listenersByIdExecuteNow = []; + // A transaction is requested + this.listenersByIdRequestPending = false; + /* To make things more clear, the following naming conventions: + * ls : we put this.listenersById on ls + * l : Array + * id : Id (can't use as property name) + * sid : String (converted from id via JSON.stringify + so we can use it as a property name) + Always remember to first overwrite + a property before you iterate over it! + */ + // TODO: Use ES7 Weak Maps. This way types that are no longer user, + // wont be kept in memory. + this.initializedTypes = {}; + this.waitingTransactions = []; + this.transactionInProgress = false; + this.transactionIsFlushed = false; + if (typeof YConcurrency_TestingMode !== 'undefined') { + this.executeOrder = []; + } + this.gc1 = []; // first stage + this.gc2 = []; // second stage -> after that, remove the op + this.gcTimeout = !opts.gcTimeout ? 50000 : opts.gcTimeoutÅ›; + function garbageCollect() { + return os.whenTransactionsFinished().then(function () { + if (os.gc1.length > 0 || os.gc2.length > 0) { + if (!os.y.isConnected()) { + console.warn('gc should be empty when disconnected!'); + } + return new Promise(function (resolve) { + os.requestTransaction(regeneratorRuntime.mark(function _callee() { + var i, oid; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!(os.y.connector != null && os.y.connector.isSynced)) { + _context.next = 10; + break; + } + + i = 0; + + case 2: + if (!(i < os.gc2.length)) { + _context.next = 8; + break; + } + + oid = os.gc2[i]; + return _context.delegateYield(this.garbageCollectOperation(oid), 't0', 5); + + case 5: + i++; + _context.next = 2; + break; + + case 8: + os.gc2 = os.gc1; + os.gc1 = []; + + case 10: + // TODO: Use setInterval here instead (when garbageCollect is called several times there will be several timeouts..) + if (os.gcTimeout > 0) { + os.gcInterval = setTimeout(garbageCollect, os.gcTimeout); + } + resolve(); + + case 12: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + }); + } else { + // TODO: see above + if (os.gcTimeout > 0) { + os.gcInterval = setTimeout(garbageCollect, os.gcTimeout); + } + return Promise.resolve(); + } + }); + } + this.garbageCollect = garbageCollect; + if (this.gcTimeout > 0) { + garbageCollect(); + } + } + + _createClass(AbstractDatabase, [{ + key: 'queueGarbageCollector', + value: function queueGarbageCollector(id) { + if (this.y.isConnected()) { + this.gc1.push(id); + } + } + }, { + key: 'emptyGarbageCollector', + value: function emptyGarbageCollector() { + var _this = this; + + return new Promise(function (resolve) { + var check = function check() { + if (_this.gc1.length > 0 || _this.gc2.length > 0) { + _this.garbageCollect().then(check); + } else { + resolve(); + } + }; + setTimeout(check, 0); + }); + } + }, { + key: 'addToDebug', + value: function addToDebug() { + if (typeof YConcurrency_TestingMode !== 'undefined') { + var command /* :string */ = Array.prototype.map.call(arguments, function (s) { + if (typeof s === 'string') { + return s; + } else { + return JSON.stringify(s); + } + }).join('').replace(/"/g, "'").replace(/,/g, ', ').replace(/:/g, ': '); + this.executeOrder.push(command); + } + } + }, { + key: 'getDebugData', + value: function getDebugData() { + console.log(this.executeOrder.join('\n')); + } + }, { + key: 'stopGarbageCollector', + value: function stopGarbageCollector() { + var self = this; + return new Promise(function (resolve) { + self.requestTransaction(regeneratorRuntime.mark(function _callee2() { + var ungc /* :Array */, i, op; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + ungc = self.gc1.concat(self.gc2); + + self.gc1 = []; + self.gc2 = []; + i = 0; + + case 4: + if (!(i < ungc.length)) { + _context2.next = 13; + break; + } + + return _context2.delegateYield(this.getOperation(ungc[i]), 't0', 6); + + case 6: + op = _context2.t0; + + if (!(op != null)) { + _context2.next = 10; + break; + } + + delete op.gc; + return _context2.delegateYield(this.setOperation(op), 't1', 10); + + case 10: + i++; + _context2.next = 4; + break; + + case 13: + resolve(); + + case 14: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + }); + } + /* + Try to add to GC. + TODO: rename this function + Rulez: + * Only gc if this user is online + * The most left element in a list must not be gc'd. + => There is at least one element in the list + returns true iff op was added to GC + */ + + }, { + key: 'addToGarbageCollector', + value: regeneratorRuntime.mark(function addToGarbageCollector(op, left) { + var gc; + return regeneratorRuntime.wrap(function addToGarbageCollector$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (!(op.gc == null && op.deleted === true)) { + _context3.next = 15; + break; + } + + gc = false; + + if (!(left != null && left.deleted === true)) { + _context3.next = 6; + break; + } + + gc = true; + _context3.next = 10; + break; + + case 6: + if (!(op.content != null && op.content.length > 1)) { + _context3.next = 10; + break; + } + + return _context3.delegateYield(this.getInsertionCleanStart([op.id[0], op.id[1] + 1]), 't0', 8); + + case 8: + op = _context3.t0; + + gc = true; + + case 10: + if (!gc) { + _context3.next = 15; + break; + } + + op.gc = true; + return _context3.delegateYield(this.setOperation(op), 't1', 13); + + case 13: + this.store.queueGarbageCollector(op.id); + return _context3.abrupt('return', true); + + case 15: + return _context3.abrupt('return', false); + + case 16: + case 'end': + return _context3.stop(); + } + } + }, addToGarbageCollector, this); + }) + }, { + key: 'removeFromGarbageCollector', + value: function removeFromGarbageCollector(op) { + function filter(o) { + return !Y.utils.compareIds(o, op.id); + } + this.gc1 = this.gc1.filter(filter); + this.gc2 = this.gc2.filter(filter); + delete op.gc; + } + }, { + key: 'destroy', + value: regeneratorRuntime.mark(function destroy() { + var key, type; + return regeneratorRuntime.wrap(function destroy$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + clearInterval(this.gcInterval); + this.gcInterval = null; + for (key in this.initializedTypes) { + type = this.initializedTypes[key]; + + if (type._destroy != null) { + type._destroy(); + } else { + console.error('The type you included does not provide destroy functionality, it will remain in memory (updating your packages will help).'); + } + } + + case 3: + case 'end': + return _context4.stop(); + } + } + }, destroy, this); + }) + }, { + key: 'setUserId', + value: function setUserId(userId) { + if (!this.userIdPromise.inProgress) { + this.userIdPromise.inProgress = true; + var self = this; + self.requestTransaction(regeneratorRuntime.mark(function _callee3() { + var state; + return regeneratorRuntime.wrap(function _callee3$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + self.userId = userId; + return _context5.delegateYield(this.getState(userId), 't0', 2); + + case 2: + state = _context5.t0; + + self.opClock = state.clock; + self.userIdPromise.resolve(userId); + + case 5: + case 'end': + return _context5.stop(); + } + } + }, _callee3, this); + })); + } + return this.userIdPromise; + } + }, { + key: 'whenUserIdSet', + value: function whenUserIdSet(f) { + this.userIdPromise.then(f); + } + }, { + key: 'getNextOpId', + value: function getNextOpId(numberOfIds) { + if (numberOfIds == null) { + throw new Error('getNextOpId expects the number of created ids to create!'); + } else if (this.userId == null) { + throw new Error('OperationStore not yet initialized!'); + } else { + var id = [this.userId, this.opClock]; + this.opClock += numberOfIds; + return id; + } + } + /* + Apply a list of operations. + * get a transaction + * check whether all Struct.*.requiredOps are in the OS + * check if it is an expected op (otherwise wait for it) + * check if was deleted, apply a delete operation after op was applied + */ + + }, { + key: 'apply', + value: function apply(ops) { + for (var i = 0; i < ops.length; i++) { + var o = ops[i]; + if (o.id == null || o.id[0] !== this.y.connector.userId) { + var required = Y.Struct[o.struct].requiredOps(o); + if (o.requires != null) { + required = required.concat(o.requires); + } + this.whenOperationsExist(required, o); + } + } + } + /* + op is executed as soon as every operation requested is available. + Note that Transaction can (and should) buffer requests. + */ + + }, { + key: 'whenOperationsExist', + value: function whenOperationsExist(ids, op) { + if (ids.length > 0) { + var listener = { + op: op, + missing: ids.length + }; + + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + var sid = JSON.stringify(id); + var l = this.listenersById[sid]; + if (l == null) { + l = []; + this.listenersById[sid] = l; + } + l.push(listener); + } + } else { + this.listenersByIdExecuteNow.push({ + op: op + }); + } + + if (this.listenersByIdRequestPending) { + return; + } + + this.listenersByIdRequestPending = true; + var store = this; + + this.requestTransaction(regeneratorRuntime.mark(function _callee4() { + var exeNow, ls, key, o, sid, l, id, op, i, listener; + return regeneratorRuntime.wrap(function _callee4$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + exeNow = store.listenersByIdExecuteNow; + + store.listenersByIdExecuteNow = []; + + ls = store.listenersById; + + store.listenersById = {}; + + store.listenersByIdRequestPending = false; + + key = 0; + + case 6: + if (!(key < exeNow.length)) { + _context6.next = 12; + break; + } + + o = exeNow[key].op; + return _context6.delegateYield(store.tryExecute.call(this, o), 't0', 9); + + case 9: + key++; + _context6.next = 6; + break; + + case 12: + _context6.t1 = regeneratorRuntime.keys(ls); + + case 13: + if ((_context6.t2 = _context6.t1()).done) { + _context6.next = 39; + break; + } + + sid = _context6.t2.value; + l = ls[sid]; + id = JSON.parse(sid); + + if (!(typeof id[1] === 'string')) { + _context6.next = 22; + break; + } + + return _context6.delegateYield(this.getOperation(id), 't3', 19); + + case 19: + op = _context6.t3; + _context6.next = 24; + break; + + case 22: + return _context6.delegateYield(this.getInsertion(id), 't4', 23); + + case 23: + op = _context6.t4; + + case 24: + if (!(op == null)) { + _context6.next = 28; + break; + } + + store.listenersById[sid] = l; + _context6.next = 37; + break; + + case 28: + i = 0; + + case 29: + if (!(i < l.length)) { + _context6.next = 37; + break; + } + + listener = l[i]; + o = listener.op; + + if (!(--listener.missing === 0)) { + _context6.next = 34; + break; + } + + return _context6.delegateYield(store.tryExecute.call(this, o), 't5', 34); + + case 34: + i++; + _context6.next = 29; + break; + + case 37: + _context6.next = 13; + break; + + case 39: + case 'end': + return _context6.stop(); + } + } + }, _callee4, this); + })); + } + /* + Actually execute an operation, when all expected operations are available. + */ + /* :: // TODO: this belongs somehow to transaction + store: Object; + getOperation: any; + isGarbageCollected: any; + addOperation: any; + whenOperationsExist: any; + */ + + }, { + key: 'tryExecute', + value: regeneratorRuntime.mark(function tryExecute(op) { + var defined, overlapSize, isGarbageCollected; + return regeneratorRuntime.wrap(function tryExecute$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + this.store.addToDebug('yield* this.store.tryExecute.call(this, ', JSON.stringify(op), ')'); + + if (!(op.struct === 'Delete')) { + _context7.next = 5; + break; + } + + return _context7.delegateYield(Y.Struct.Delete.execute.call(this, op), 't0', 3); + + case 3: + _context7.next = 29; + break; + + case 5: + return _context7.delegateYield(this.getInsertion(op.id), 't1', 6); + + case 6: + defined = _context7.t1; + + case 7: + if (!(defined != null && defined.content != null)) { + _context7.next = 21; + break; + } + + if (!(defined.id[1] + defined.content.length < op.id[1] + op.content.length)) { + _context7.next = 18; + break; + } + + overlapSize = defined.content.length - (op.id[1] - defined.id[1]); + + op.content.splice(0, overlapSize); + op.id = [op.id[0], op.id[1] + overlapSize]; + op.left = Y.utils.getLastId(defined); + op.origin = op.left; + return _context7.delegateYield(this.getOperation(op.id), 't2', 15); + + case 15: + defined = _context7.t2; + _context7.next = 19; + break; + + case 18: + return _context7.abrupt('break', 21); + + case 19: + _context7.next = 7; + break; + + case 21: + if (!(defined == null)) { + _context7.next = 29; + break; + } + + return _context7.delegateYield(this.isGarbageCollected(op.id), 't3', 23); + + case 23: + isGarbageCollected = _context7.t3; + + if (isGarbageCollected) { + _context7.next = 29; + break; + } + + return _context7.delegateYield(Y.Struct[op.struct].execute.call(this, op), 't4', 26); + + case 26: + return _context7.delegateYield(this.addOperation(op), 't5', 27); + + case 27: + return _context7.delegateYield(this.store.operationAdded(this, op), 't6', 28); + + case 28: + return _context7.delegateYield(this.tryCombineWithLeft(op), 't7', 29); + + case 29: + case 'end': + return _context7.stop(); + } + } + }, tryExecute, this); + }) + // called by a transaction when an operation is added + + }, { + key: 'operationAdded', + value: regeneratorRuntime.mark(function operationAdded(transaction, op) { + var opLen, _i, sid, l, key, listener, t, parentIsDeleted, _o, len, startId, _i2, id, opIsDeleted, delop; + + return regeneratorRuntime.wrap(function operationAdded$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + return _context8.delegateYield(transaction.updateState(op.id[0]), 't0', 1); + + case 1: + opLen = op.content != null ? op.content.length : 1; + + for (_i = 0; _i < opLen; _i++) { + // notify whenOperation listeners (by id) + sid = JSON.stringify([op.id[0], op.id[1] + _i]); + l = this.listenersById[sid]; + + delete this.listenersById[sid]; + + if (l != null) { + for (key in l) { + listener = l[key]; + + if (--listener.missing === 0) { + this.whenOperationsExist([], listener.op); + } + } + } + } + t = this.initializedTypes[JSON.stringify(op.parent)]; + + // if parent is deleted, mark as gc'd and return + + if (!(op.parent != null)) { + _context8.next = 10; + break; + } + + return _context8.delegateYield(transaction.isDeleted(op.parent), 't1', 6); + + case 6: + parentIsDeleted = _context8.t1; + + if (!parentIsDeleted) { + _context8.next = 10; + break; + } + + return _context8.delegateYield(transaction.deleteList(op.id), 't2', 9); + + case 9: + return _context8.abrupt('return'); + + case 10: + if (!(t != null)) { + _context8.next = 13; + break; + } + + _o = Y.utils.copyObject(op); + return _context8.delegateYield(t._changed(transaction, _o), 't3', 13); + + case 13: + if (op.deleted) { + _context8.next = 27; + break; + } + + // Delete if DS says this is actually deleted + len = op.content != null ? op.content.length : 1; + startId = op.id; // You must not use op.id in the following loop, because op will change when deleted + + _i2 = 0; + + case 17: + if (!(_i2 < len)) { + _context8.next = 27; + break; + } + + id = [startId[0], startId[1] + _i2]; + return _context8.delegateYield(transaction.isDeleted(id), 't4', 20); + + case 20: + opIsDeleted = _context8.t4; + + if (!opIsDeleted) { + _context8.next = 24; + break; + } + + delop = { + struct: 'Delete', + target: id + }; + return _context8.delegateYield(this.tryExecute.call(transaction, delop), 't5', 24); + + case 24: + _i2++; + _context8.next = 17; + break; + + case 27: + case 'end': + return _context8.stop(); + } + } + }, operationAdded, this); + }) + }, { + key: 'whenTransactionsFinished', + value: function whenTransactionsFinished() { + if (this.transactionInProgress) { + if (this.transactionsFinished == null) { + var resolve; + var promise = new Promise(function (r) { + resolve = r; + }); + this.transactionsFinished = { + resolve: resolve, + promise: promise + }; + return promise; + } else { + return this.transactionsFinished.promise; + } + } else { + return Promise.resolve(); + } + } + // Check if there is another transaction request. + // * the last transaction is always a flush :) + + }, { + key: 'getNextRequest', + value: function getNextRequest() { + if (this.waitingTransactions.length === 0) { + if (this.transactionIsFlushed) { + this.transactionInProgress = false; + this.transactionIsFlushed = false; + if (this.transactionsFinished != null) { + this.transactionsFinished.resolve(); + this.transactionsFinished = null; + } + return null; + } else { + this.transactionIsFlushed = true; + return regeneratorRuntime.mark(function _callee5() { + return regeneratorRuntime.wrap(function _callee5$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + return _context9.delegateYield(this.flush(), 't0', 1); + + case 1: + case 'end': + return _context9.stop(); + } + } + }, _callee5, this); + }); + } + } else { + this.transactionIsFlushed = false; + return this.waitingTransactions.shift(); + } + } + }, { + key: 'requestTransaction', + value: function requestTransaction(makeGen /* :any */, callImmediately) { + this.waitingTransactions.push(makeGen); + if (!this.transactionInProgress) { + this.transactionInProgress = true; + if (false || callImmediately) { + // TODO: decide whether this is ok or not.. + this.transact(this.getNextRequest()); + } else { + var self = this; + setTimeout(function () { + self.transact(self.getNextRequest()); + }, 0); + } + } + } + }]); + + return AbstractDatabase; + }(); + + Y.AbstractDatabase = AbstractDatabase; +}; + +},{}],6:[function(require,module,exports){ +/* @flow */ +'use strict'; + +/* + An operation also defines the structure of a type. This is why operation and + structure are used interchangeably here. + + It must be of the type Object. I hope to achieve some performance + improvements when working on databases that support the json format. + + An operation must have the following properties: + + * encode + - Encode the structure in a readable format (preferably string- todo) + * decode (todo) + - decode structure to json + * execute + - Execute the semantics of an operation. + * requiredOps + - Operations that are required to execute this operation. +*/ + +module.exports = function (Y /* :any */) { + var Struct = { + /* This is the only operation that is actually not a structure, because + it is not stored in the OS. This is why it _does not_ have an id + op = { + target: Id + } + */ + Delete: { + encode: function encode(op) { + return op; + }, + requiredOps: function requiredOps(op) { + return []; // [op.target] + }, + execute: regeneratorRuntime.mark(function execute(op) { + return regeneratorRuntime.wrap(function execute$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + return _context.delegateYield(this.deleteOperation(op.target, op.length || 1), 't0', 1); + + case 1: + return _context.abrupt('return', _context.t0); + + case 2: + case 'end': + return _context.stop(); + } + } + }, execute, this); + }) + }, + Insert: { + /* { + content: [any], + opContent: Id, + id: Id, + left: Id, + origin: Id, + right: Id, + parent: Id, + parentSub: string (optional), // child of Map type + } + */ + encode: function encode(op /* :Insertion */) /* :Insertion */{ + // TODO: you could not send the "left" property, then you also have to + // "op.left = null" in $execute or $decode + var e /* :any */ = { + id: op.id, + left: op.left, + right: op.right, + origin: op.origin, + parent: op.parent, + struct: op.struct + }; + if (op.parentSub != null) { + e.parentSub = op.parentSub; + } + if (op.hasOwnProperty('opContent')) { + e.opContent = op.opContent; + } else { + e.content = op.content.slice(); + } + + return e; + }, + requiredOps: function requiredOps(op) { + var ids = []; + if (op.left != null) { + ids.push(op.left); + } + if (op.right != null) { + ids.push(op.right); + } + if (op.origin != null && !Y.utils.compareIds(op.left, op.origin)) { + ids.push(op.origin); + } + // if (op.right == null && op.left == null) { + ids.push(op.parent); + + if (op.opContent != null) { + ids.push(op.opContent); + } + return ids; + }, + getDistanceToOrigin: regeneratorRuntime.mark(function getDistanceToOrigin(op) { + var d, o; + return regeneratorRuntime.wrap(function getDistanceToOrigin$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (!(op.left == null)) { + _context2.next = 4; + break; + } + + return _context2.abrupt('return', 0); + + case 4: + d = 0; + return _context2.delegateYield(this.getInsertion(op.left), 't0', 6); + + case 6: + o = _context2.t0; + + case 7: + if (Y.utils.matchesId(o, op.origin)) { + _context2.next = 17; + break; + } + + d++; + + if (!(o.left == null)) { + _context2.next = 13; + break; + } + + return _context2.abrupt('break', 17); + + case 13: + return _context2.delegateYield(this.getInsertion(o.left), 't1', 14); + + case 14: + o = _context2.t1; + + case 15: + _context2.next = 7; + break; + + case 17: + return _context2.abrupt('return', d); + + case 18: + case 'end': + return _context2.stop(); + } + } + }, getDistanceToOrigin, this); + }), + /* + # $this has to find a unique position between origin and the next known character + # case 1: $origin equals $o.origin: the $creator parameter decides if left or right + # let $OL= [o1,o2,o3,o4], whereby $this is to be inserted between o1 and o4 + # o2,o3 and o4 origin is 1 (the position of o2) + # there is the case that $this.creator < o2.creator, but o3.creator < $this.creator + # then o2 knows o3. Since on another client $OL could be [o1,o3,o4] the problem is complex + # therefore $this would be always to the right of o3 + # case 2: $origin < $o.origin + # if current $this insert_position > $o origin: $this ins + # else $insert_position will not change + # (maybe we encounter case 1 later, then this will be to the right of $o) + # case 3: $origin > $o.origin + # $this insert_position is to the left of $o (forever!) + */ + execute: regeneratorRuntime.mark(function execute(op) { + var i, tryToRemergeLater, origin, distanceToOrigin, o, parent, start, startId, oOriginDistance, left, right, _i, m; + + return regeneratorRuntime.wrap(function execute$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + // loop counter + + // during this function some ops may get split into two pieces (e.g. with getInsertionCleanEnd) + // We try to merge them later, if possible + tryToRemergeLater = []; + + if (!(op.origin != null)) { + _context3.next = 8; + break; + } + + return _context3.delegateYield(this.getInsertionCleanEnd(op.origin), 't0', 3); + + case 3: + origin = _context3.t0; + + if (origin.originOf == null) { + origin.originOf = []; + } + origin.originOf.push(op.id); + return _context3.delegateYield(this.setOperation(origin), 't1', 7); + + case 7: + if (origin.right != null) { + tryToRemergeLater.push(origin.right); + } + + case 8: + return _context3.delegateYield(Struct.Insert.getDistanceToOrigin.call(this, op), 't2', 9); + + case 9: + distanceToOrigin = i = _context3.t2; + + if (!(op.left != null)) { + _context3.next = 23; + break; + } + + return _context3.delegateYield(this.getInsertionCleanEnd(op.left), 't3', 12); + + case 12: + o = _context3.t3; + + if (!Y.utils.compareIds(op.left, op.origin) && o.right != null) { + // only if not added previously + tryToRemergeLater.push(o.right); + } + + if (!(o.right == null)) { + _context3.next = 18; + break; + } + + _context3.t4 = null; + _context3.next = 20; + break; + + case 18: + return _context3.delegateYield(this.getOperation(o.right), 't5', 19); + + case 19: + _context3.t4 = _context3.t5; + + case 20: + o = _context3.t4; + _context3.next = 34; + break; + + case 23: + return _context3.delegateYield(this.getOperation(op.parent), 't6', 24); + + case 24: + parent = _context3.t6; + startId = op.parentSub ? parent.map[op.parentSub] : parent.start; + + if (!(startId == null)) { + _context3.next = 30; + break; + } + + _context3.t7 = null; + _context3.next = 32; + break; + + case 30: + return _context3.delegateYield(this.getOperation(startId), 't8', 31); + + case 31: + _context3.t7 = _context3.t8; + + case 32: + start = _context3.t7; + + o = start; + + case 34: + if (!(op.right != null)) { + _context3.next = 37; + break; + } + + tryToRemergeLater.push(op.right); + return _context3.delegateYield(this.getInsertionCleanStart(op.right), 't9', 37); + + case 37: + if (!true) { + _context3.next = 62; + break; + } + + if (!(o != null && !Y.utils.compareIds(o.id, op.right))) { + _context3.next = 59; + break; + } + + return _context3.delegateYield(Struct.Insert.getDistanceToOrigin.call(this, o), 't10', 40); + + case 40: + oOriginDistance = _context3.t10; + + if (!(oOriginDistance === i)) { + _context3.next = 45; + break; + } + + // case 1 + if (o.id[0] < op.id[0]) { + op.left = Y.utils.getLastId(o); + distanceToOrigin = i + 1; // just ignore o.content.length, doesn't make a difference + } + _context3.next = 50; + break; + + case 45: + if (!(oOriginDistance < i)) { + _context3.next = 49; + break; + } + + // case 2 + if (i - distanceToOrigin <= oOriginDistance) { + op.left = Y.utils.getLastId(o); + distanceToOrigin = i + 1; // just ignore o.content.length, doesn't make a difference + } + _context3.next = 50; + break; + + case 49: + return _context3.abrupt('break', 62); + + case 50: + i++; + + if (!(o.right != null)) { + _context3.next = 56; + break; + } + + return _context3.delegateYield(this.getInsertion(o.right), 't11', 53); + + case 53: + o = _context3.t11; + _context3.next = 57; + break; + + case 56: + o = null; + + case 57: + _context3.next = 60; + break; + + case 59: + return _context3.abrupt('break', 62); + + case 60: + _context3.next = 37; + break; + + case 62: + + // reconnect.. + left = null; + right = null; + + if (!(parent == null)) { + _context3.next = 67; + break; + } + + return _context3.delegateYield(this.getOperation(op.parent), 't12', 66); + + case 66: + parent = _context3.t12; + + case 67: + if (!(op.left != null)) { + _context3.next = 75; + break; + } + + return _context3.delegateYield(this.getInsertion(op.left), 't13', 69); + + case 69: + left = _context3.t13; + + // link left + op.right = left.right; + left.right = op.id; + + return _context3.delegateYield(this.setOperation(left), 't14', 73); + + case 73: + _context3.next = 76; + break; + + case 75: + // set op.right from parent, if necessary + op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start; + + case 76: + if (!(op.right != null)) { + _context3.next = 86; + break; + } + + return _context3.delegateYield(this.getOperation(op.right), 't15', 78); + + case 78: + right = _context3.t15; + + right.left = Y.utils.getLastId(op); + + // if right exists, and it is supposed to be gc'd. Remove it from the gc + + if (!(right.gc != null)) { + _context3.next = 85; + break; + } + + if (!(right.content != null && right.content.length > 1)) { + _context3.next = 84; + break; + } + + return _context3.delegateYield(this.getInsertionCleanEnd(right.id), 't16', 83); + + case 83: + right = _context3.t16; + + case 84: + this.store.removeFromGarbageCollector(right); + + case 85: + return _context3.delegateYield(this.setOperation(right), 't17', 86); + + case 86: + if (!(op.parentSub != null)) { + _context3.next = 96; + break; + } + + if (!(left == null)) { + _context3.next = 90; + break; + } + + parent.map[op.parentSub] = op.id; + return _context3.delegateYield(this.setOperation(parent), 't18', 90); + + case 90: + if (!(op.right != null)) { + _context3.next = 92; + break; + } + + return _context3.delegateYield(this.deleteOperation(op.right, 1, true), 't19', 92); + + case 92: + if (!(op.left != null)) { + _context3.next = 94; + break; + } + + return _context3.delegateYield(this.deleteOperation(op.id, 1, true), 't20', 94); + + case 94: + _context3.next = 100; + break; + + case 96: + if (!(right == null || left == null)) { + _context3.next = 100; + break; + } + + if (right == null) { + parent.end = Y.utils.getLastId(op); + } + if (left == null) { + parent.start = op.id; + } + return _context3.delegateYield(this.setOperation(parent), 't21', 100); + + case 100: + _i = 0; + + case 101: + if (!(_i < tryToRemergeLater.length)) { + _context3.next = 108; + break; + } + + return _context3.delegateYield(this.getOperation(tryToRemergeLater[_i]), 't22', 103); + + case 103: + m = _context3.t22; + return _context3.delegateYield(this.tryCombineWithLeft(m), 't23', 105); + + case 105: + _i++; + _context3.next = 101; + break; + + case 108: + case 'end': + return _context3.stop(); + } + } + }, execute, this); + }) + }, + List: { + /* + { + start: null, + end: null, + struct: "List", + type: "", + id: this.os.getNextOpId(1) + } + */ + create: function create(id) { + return { + start: null, + end: null, + struct: 'List', + id: id + }; + }, + encode: function encode(op) { + var e = { + struct: 'List', + id: op.id, + type: op.type + }; + if (op.requires != null) { + e.requires = op.requires; + } + if (op.info != null) { + e.info = op.info; + } + return e; + }, + requiredOps: function requiredOps() { + /* + var ids = [] + if (op.start != null) { + ids.push(op.start) + } + if (op.end != null){ + ids.push(op.end) + } + return ids + */ + return []; + }, + execute: regeneratorRuntime.mark(function execute(op) { + return regeneratorRuntime.wrap(function execute$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + op.start = null; + op.end = null; + + case 2: + case 'end': + return _context4.stop(); + } + } + }, execute, this); + }), + ref: regeneratorRuntime.mark(function ref(op, pos) { + var res, o; + return regeneratorRuntime.wrap(function ref$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + if (!(op.start == null)) { + _context5.next = 2; + break; + } + + return _context5.abrupt('return', null); + + case 2: + res = null; + return _context5.delegateYield(this.getOperation(op.start), 't0', 4); + + case 4: + o = _context5.t0; + + case 5: + if (!true) { + _context5.next = 15; + break; + } + + if (!o.deleted) { + res = o; + pos--; + } + + if (!(pos >= 0 && o.right != null)) { + _context5.next = 12; + break; + } + + return _context5.delegateYield(this.getOperation(o.right), 't1', 9); + + case 9: + o = _context5.t1; + _context5.next = 13; + break; + + case 12: + return _context5.abrupt('break', 15); + + case 13: + _context5.next = 5; + break; + + case 15: + return _context5.abrupt('return', res); + + case 16: + case 'end': + return _context5.stop(); + } + } + }, ref, this); + }), + map: regeneratorRuntime.mark(function map(o, f) { + var res, operation; + return regeneratorRuntime.wrap(function map$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + o = o.start; + res = []; + + case 2: + if (!(o != null)) { + _context6.next = 9; + break; + } + + return _context6.delegateYield(this.getOperation(o), 't0', 4); + + case 4: + operation = _context6.t0; + + if (!operation.deleted) { + res.push(f(operation)); + } + o = operation.right; + _context6.next = 2; + break; + + case 9: + return _context6.abrupt('return', res); + + case 10: + case 'end': + return _context6.stop(); + } + } + }, map, this); + }) + }, + Map: { + /* + { + map: {}, + struct: "Map", + type: "", + id: this.os.getNextOpId(1) + } + */ + create: function create(id) { + return { + id: id, + map: {}, + struct: 'Map' + }; + }, + encode: function encode(op) { + var e = { + struct: 'Map', + type: op.type, + id: op.id, + map: {} // overwrite map!! + }; + if (op.requires != null) { + e.requires = op.requires; + } + if (op.info != null) { + e.info = op.info; + } + return e; + }, + requiredOps: function requiredOps() { + return []; + }, + execute: regeneratorRuntime.mark(function execute() { + return regeneratorRuntime.wrap(function execute$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + case 'end': + return _context7.stop(); + } + } + }, execute, this); + }), + /* + Get a property by name + */ + get: regeneratorRuntime.mark(function get(op, name) { + var oid, res; + return regeneratorRuntime.wrap(function get$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + oid = op.map[name]; + + if (!(oid != null)) { + _context8.next = 14; + break; + } + + return _context8.delegateYield(this.getOperation(oid), 't0', 3); + + case 3: + res = _context8.t0; + + if (!(res == null || res.deleted)) { + _context8.next = 8; + break; + } + + return _context8.abrupt('return', void 0); + + case 8: + if (!(res.opContent == null)) { + _context8.next = 12; + break; + } + + return _context8.abrupt('return', res.content[0]); + + case 12: + return _context8.delegateYield(this.getType(res.opContent), 't1', 13); + + case 13: + return _context8.abrupt('return', _context8.t1); + + case 14: + case 'end': + return _context8.stop(); + } + } + }, get, this); + }) + } + }; + Y.Struct = Struct; +}; + +},{}],7:[function(require,module,exports){ +/* @flow */ +'use strict'; + +/* + Partial definition of a transaction + + A transaction provides all the the async functionality on a database. + + By convention, a transaction has the following properties: + * ss for StateSet + * os for OperationStore + * ds for DeleteStore + + A transaction must also define the following methods: + * checkDeleteStoreForState(state) + - When increasing the state of a user, an operation with an higher id + may already be garbage collected, and therefore it will never be received. + update the state to reflect this knowledge. This won't call a method to save the state! + * getDeleteSet(id) + - Get the delete set in a readable format: + { + "userX": [ + [5,1], // starting from position 5, one operations is deleted + [9,4] // starting from position 9, four operations are deleted + ], + "userY": ... + } + * getOpsFromDeleteSet(ds) -- TODO: just call this.deleteOperation(id) here + - get a set of deletions that need to be applied in order to get to + achieve the state of the supplied ds + * setOperation(op) + - write `op` to the database. + Note: this is allowed to return an in-memory object. + E.g. the Memory adapter returns the object that it has in-memory. + Changing values on this object will be stored directly in the database + without calling this function. Therefore, + setOperation may have no functionality in some adapters. This also has + implications on the way we use operations that were served from the database. + We try not to call copyObject, if not necessary. + * addOperation(op) + - add an operation to the database. + This may only be called once for every op.id + Must return a function that returns the next operation in the database (ordered by id) + * getOperation(id) + * removeOperation(id) + - remove an operation from the database. This is called when an operation + is garbage collected. + * setState(state) + - `state` is of the form + { + user: "1", + clock: 4 + } <- meaning that we have four operations from user "1" + (with these id's respectively: 0, 1, 2, and 3) + * getState(user) + * getStateVector() + - Get the state of the OS in the form + [{ + user: "userX", + clock: 11 + }, + .. + ] + * getStateSet() + - Get the state of the OS in the form + { + "userX": 11, + "userY": 22 + } + * getOperations(startSS) + - Get the all the operations that are necessary in order to achive the + stateSet of this user, starting from a stateSet supplied by another user + * makeOperationReady(ss, op) + - this is called only by `getOperations(startSS)`. It makes an operation + applyable on a given SS. +*/ + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +module.exports = function (Y /* :any */) { + var TransactionInterface = function () { + function TransactionInterface() { + _classCallCheck(this, TransactionInterface); + } + + _createClass(TransactionInterface, [{ + key: 'getType', + + /* :: + store: Y.AbstractDatabase; + ds: Store; + os: Store; + ss: Store; + */ + /* + Get a type based on the id of its model. + If it does not exist yes, create it. + TODO: delete type from store.initializedTypes[id] when corresponding id was deleted! + */ + value: regeneratorRuntime.mark(function getType(id, args) { + var sid, t, op /* :MapStruct | ListStruct */; + return regeneratorRuntime.wrap(function getType$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + sid = JSON.stringify(id); + t = this.store.initializedTypes[sid]; + + if (!(t == null)) { + _context.next = 9; + break; + } + + return _context.delegateYield(this.getOperation(id), 't0', 4); + + case 4: + op = _context.t0; + + if (!(op != null)) { + _context.next = 9; + break; + } + + return _context.delegateYield(Y[op.type].typeDefinition.initType.call(this, this.store, op, args), 't1', 7); + + case 7: + t = _context.t1; + + this.store.initializedTypes[sid] = t; + + case 9: + return _context.abrupt('return', t); + + case 10: + case 'end': + return _context.stop(); + } + } + }, getType, this); + }) + }, { + key: 'createType', + value: regeneratorRuntime.mark(function createType(typedefinition, id) { + var structname, op; + return regeneratorRuntime.wrap(function createType$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + structname = typedefinition[0].struct; + + id = id || this.store.getNextOpId(1); + + if (!(id[0] === '_')) { + _context2.next = 7; + break; + } + + return _context2.delegateYield(this.getOperation(id), 't0', 4); + + case 4: + op = _context2.t0; + _context2.next = 9; + break; + + case 7: + op = Y.Struct[structname].create(id); + op.type = typedefinition[0].name; + + case 9: + if (!(typedefinition[0].appendAdditionalInfo != null)) { + _context2.next = 11; + break; + } + + return _context2.delegateYield(typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1]), 't1', 11); + + case 11: + if (!(op[0] === '_')) { + _context2.next = 15; + break; + } + + return _context2.delegateYield(this.setOperation(op), 't2', 13); + + case 13: + _context2.next = 16; + break; + + case 15: + return _context2.delegateYield(this.applyCreatedOperations([op]), 't3', 16); + + case 16: + return _context2.delegateYield(this.getType(id, typedefinition[1]), 't4', 17); + + case 17: + return _context2.abrupt('return', _context2.t4); + + case 18: + case 'end': + return _context2.stop(); + } + } + }, createType, this); + }) + /* createType (typedefinition, id) { + var structname = typedefinition[0].struct + id = id || this.store.getNextOpId(1) + var op = Y.Struct[structname].create(id) + op.type = typedefinition[0].name + if (typedefinition[0].appendAdditionalInfo != null) { + yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1]) + } + // yield* this.applyCreatedOperations([op]) + yield* Y.Struct[op.struct].execute.call(this, op) + yield* this.addOperation(op) + yield* this.store.operationAdded(this, op) + return yield* this.getType(id, typedefinition[1]) + }*/ + /* + Apply operations that this user created (no remote ones!) + * does not check for Struct.*.requiredOps() + * also broadcasts it through the connector + */ + + }, { + key: 'applyCreatedOperations', + value: regeneratorRuntime.mark(function applyCreatedOperations(ops) { + var send, i, op; + return regeneratorRuntime.wrap(function applyCreatedOperations$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + send = []; + i = 0; + + case 2: + if (!(i < ops.length)) { + _context3.next = 9; + break; + } + + op = ops[i]; + return _context3.delegateYield(this.store.tryExecute.call(this, op), 't0', 5); + + case 5: + if (op.id == null || typeof op.id[1] !== 'string') { + send.push(Y.Struct[op.struct].encode(op)); + } + + case 6: + i++; + _context3.next = 2; + break; + + case 9: + if (!this.store.y.connector.isDisconnected() && send.length > 0) { + // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops) + // is connected, and this is not going to be send in addOperation + this.store.y.connector.broadcastOps(send); + } + + case 10: + case 'end': + return _context3.stop(); + } + } + }, applyCreatedOperations, this); + }) + }, { + key: 'deleteList', + value: regeneratorRuntime.mark(function deleteList(start) { + var delLength; + return regeneratorRuntime.wrap(function deleteList$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + if (!(start != null)) { + _context4.next = 15; + break; + } + + return _context4.delegateYield(this.getOperation(start), 't0', 2); + + case 2: + start = _context4.t0; + + if (start.gc) { + _context4.next = 12; + break; + } + + start.gc = true; + start.deleted = true; + return _context4.delegateYield(this.setOperation(start), 't1', 7); + + case 7: + delLength = start.content != null ? start.content.length : 1; + return _context4.delegateYield(this.markDeleted(start.id, delLength), 't2', 9); + + case 9: + if (!(start.opContent != null)) { + _context4.next = 11; + break; + } + + return _context4.delegateYield(this.deleteOperation(start.opContent), 't3', 11); + + case 11: + this.store.queueGarbageCollector(start.id); + + case 12: + start = start.right; + _context4.next = 0; + break; + + case 15: + case 'end': + return _context4.stop(); + } + } + }, deleteList, this); + }) + + /* + Mark an operation as deleted, and add it to the GC, if possible. + */ + + }, { + key: 'deleteOperation', + value: regeneratorRuntime.mark(function deleteOperation(targetId, length, preventCallType) { + var callType, target, targetLength, name, i, left, right, type; + return regeneratorRuntime.wrap(function deleteOperation$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + if (length == null) { + length = 1; + } + return _context5.delegateYield(this.markDeleted(targetId, length), 't0', 2); + + case 2: + if (!(length > 0)) { + _context5.next = 66; + break; + } + + callType = false; + return _context5.delegateYield(this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1]), 't1', 5); + + case 5: + target = _context5.t1; + targetLength = target != null && target.content != null ? target.content.length : 1; + + if (!(target == null || target.id[0] !== targetId[0] || target.id[1] + targetLength <= targetId[1])) { + _context5.next = 12; + break; + } + + // does not exist or is not in the range of the deletion + target = null; + length = 0; + _context5.next = 22; + break; + + case 12: + if (target.deleted) { + _context5.next = 21; + break; + } + + if (!(target.id[1] < targetId[1])) { + _context5.next = 17; + break; + } + + return _context5.delegateYield(this.getInsertionCleanStart(targetId), 't2', 15); + + case 15: + target = _context5.t2; + + targetLength = target.content.length; // must have content property! + + case 17: + if (!(target.id[1] + targetLength > targetId[1] + length)) { + _context5.next = 21; + break; + } + + return _context5.delegateYield(this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1]), 't3', 19); + + case 19: + target = _context5.t3; + + targetLength = target.content.length; + + case 21: + length = target.id[1] - targetId[1]; + + case 22: + if (!(target != null)) { + _context5.next = 64; + break; + } + + if (target.deleted) { + _context5.next = 44; + break; + } + + callType = true; + // set deleted & notify type + target.deleted = true; + // delete containing lists + + if (!(target.start != null)) { + _context5.next = 28; + break; + } + + return _context5.delegateYield(this.deleteList(target.start), 't4', 28); + + case 28: + if (!(target.map != null)) { + _context5.next = 35; + break; + } + + _context5.t5 = regeneratorRuntime.keys(target.map); + + case 30: + if ((_context5.t6 = _context5.t5()).done) { + _context5.next = 35; + break; + } + + name = _context5.t6.value; + return _context5.delegateYield(this.deleteList(target.map[name]), 't7', 33); + + case 33: + _context5.next = 30; + break; + + case 35: + if (!(target.opContent != null)) { + _context5.next = 37; + break; + } + + return _context5.delegateYield(this.deleteOperation(target.opContent), 't8', 37); + + case 37: + if (!(target.requires != null)) { + _context5.next = 44; + break; + } + + i = 0; + + case 39: + if (!(i < target.requires.length)) { + _context5.next = 44; + break; + } + + return _context5.delegateYield(this.deleteOperation(target.requires[i]), 't9', 41); + + case 41: + i++; + _context5.next = 39; + break; + + case 44: + if (!(target.left != null)) { + _context5.next = 49; + break; + } + + return _context5.delegateYield(this.getInsertion(target.left), 't10', 46); + + case 46: + left = _context5.t10; + _context5.next = 50; + break; + + case 49: + left = null; + + case 50: + return _context5.delegateYield(this.setOperation(target), 't11', 51); + + case 51: + if (!(target.right != null)) { + _context5.next = 56; + break; + } + + return _context5.delegateYield(this.getOperation(target.right), 't12', 53); + + case 53: + right = _context5.t12; + _context5.next = 57; + break; + + case 56: + right = null; + + case 57: + if (!(callType && !preventCallType)) { + _context5.next = 61; + break; + } + + type = this.store.initializedTypes[JSON.stringify(target.parent)]; + + if (!(type != null)) { + _context5.next = 61; + break; + } + + return _context5.delegateYield(type._changed(this, { + struct: 'Delete', + target: target.id, + length: targetLength + }), 't13', 61); + + case 61: + return _context5.delegateYield(this.store.addToGarbageCollector.call(this, target, left), 't14', 62); + + case 62: + if (!(right != null)) { + _context5.next = 64; + break; + } + + return _context5.delegateYield(this.store.addToGarbageCollector.call(this, right, target), 't15', 64); + + case 64: + _context5.next = 2; + break; + + case 66: + case 'end': + return _context5.stop(); + } + } + }, deleteOperation, this); + }) + /* + Mark an operation as deleted&gc'd + */ + + }, { + key: 'markGarbageCollected', + value: regeneratorRuntime.mark(function markGarbageCollected(id, len) { + var n, newlen, prev, next; + return regeneratorRuntime.wrap(function markGarbageCollected$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + // this.mem.push(["gc", id]); + this.store.addToDebug('yield* this.markGarbageCollected(', id, ', ', len, ')'); + return _context6.delegateYield(this.markDeleted(id, len), 't0', 2); + + case 2: + n = _context6.t0; + + if (!(n.id[1] < id[1] && !n.gc)) { + _context6.next = 9; + break; + } + + // un-extend left + newlen = n.len - (id[1] - n.id[1]); + + n.len -= newlen; + return _context6.delegateYield(this.ds.put(n), 't1', 7); + + case 7: + n = { id: id, len: newlen, gc: false }; + return _context6.delegateYield(this.ds.put(n), 't2', 9); + + case 9: + return _context6.delegateYield(this.ds.findPrev(id), 't3', 10); + + case 10: + prev = _context6.t3; + return _context6.delegateYield(this.ds.findNext(id), 't4', 12); + + case 12: + next = _context6.t4; + + if (!(id[1] + len < n.id[1] + n.len && !n.gc)) { + _context6.next = 16; + break; + } + + return _context6.delegateYield(this.ds.put({ id: [id[0], id[1] + len], len: n.len - len, gc: false }), 't5', 15); + + case 15: + n.len = len; + + case 16: + // set gc'd + n.gc = true; + // can extend left? + + if (!(prev != null && prev.gc && Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id))) { + _context6.next = 21; + break; + } + + prev.len += n.len; + return _context6.delegateYield(this.ds.delete(n.id), 't6', 20); + + case 20: + n = prev; + // ds.put n here? + + case 21: + if (!(next != null && next.gc && Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id))) { + _context6.next = 24; + break; + } + + n.len += next.len; + return _context6.delegateYield(this.ds.delete(next.id), 't7', 24); + + case 24: + return _context6.delegateYield(this.ds.put(n), 't8', 25); + + case 25: + return _context6.delegateYield(this.updateState(n.id[0]), 't9', 26); + + case 26: + case 'end': + return _context6.stop(); + } + } + }, markGarbageCollected, this); + }) + /* + Mark an operation as deleted. + returns the delete node + */ + + }, { + key: 'markDeleted', + value: regeneratorRuntime.mark(function markDeleted(id, length) { + var n, diff, next, _next; + + return regeneratorRuntime.wrap(function markDeleted$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + if (length == null) { + length = 1; + } + // this.mem.push(["del", id]); + return _context7.delegateYield(this.ds.findWithUpperBound(id), 't0', 2); + + case 2: + n = _context7.t0; + + if (!(n != null && n.id[0] === id[0])) { + _context7.next = 27; + break; + } + + if (!(n.id[1] <= id[1] && id[1] <= n.id[1] + n.len)) { + _context7.next = 23; + break; + } + + // id is in n's range + diff = id[1] + length - (n.id[1] + n.len); // overlapping right + + if (!(diff > 0)) { + _context7.next = 20; + break; + } + + if (n.gc) { + _context7.next = 11; + break; + } + + n.len += diff; + _context7.next = 18; + break; + + case 11: + diff = n.id[1] + n.len - id[1]; // overlapping left (id till n.end) + + if (!(diff < length)) { + _context7.next = 17; + break; + } + + // a partial deletion + n = { id: [id[0], id[1] + diff], len: length - diff, gc: false }; + return _context7.delegateYield(this.ds.put(n), 't1', 15); + + case 15: + _context7.next = 18; + break; + + case 17: + throw new Error('Cannot happen! (it dit though.. :()'); + + case 18: + _context7.next = 21; + break; + + case 20: + return _context7.abrupt('return', n); + + case 21: + _context7.next = 25; + break; + + case 23: + // cannot extend left (there is no left!) + n = { id: id, len: length, gc: false }; + return _context7.delegateYield(this.ds.put(n), 't2', 25); + + case 25: + _context7.next = 29; + break; + + case 27: + // cannot extend left + n = { id: id, len: length, gc: false }; + return _context7.delegateYield(this.ds.put(n), 't3', 29); + + case 29: + return _context7.delegateYield(this.ds.findNext(n.id), 't4', 30); + + case 30: + next = _context7.t4; + + if (!(next != null && n.id[0] === next.id[0] && n.id[1] + n.len >= next.id[1])) { + _context7.next = 61; + break; + } + + diff = n.id[1] + n.len - next.id[1]; // from next.start to n.end + + case 33: + if (!(diff >= 0)) { + _context7.next = 61; + break; + } + + if (!next.gc) { + _context7.next = 44; + break; + } + + // gc is stronger, so reduce length of n + n.len -= diff; + + if (!(diff >= next.len)) { + _context7.next = 41; + break; + } + + // delete the missing range after next + diff = diff - next.len; // missing range after next + + if (!(diff > 0)) { + _context7.next = 41; + break; + } + + return _context7.delegateYield(this.ds.put(n), 't5', 40); + + case 40: + return _context7.delegateYield(this.markDeleted([next.id[0], next.id[1] + next.len], diff), 't6', 41); + + case 41: + return _context7.abrupt('break', 61); + + case 44: + if (!(diff > next.len)) { + _context7.next = 56; + break; + } + + return _context7.delegateYield(this.ds.findNext(next.id), 't7', 46); + + case 46: + _next = _context7.t7; + return _context7.delegateYield(this.ds.delete(next.id), 't8', 48); + + case 48: + if (!(_next == null || n.id[0] !== _next.id[0])) { + _context7.next = 52; + break; + } + + return _context7.abrupt('break', 61); + + case 52: + next = _next; + diff = n.id[1] + n.len - next.id[1]; // from next.start to n.end + // continue! + + case 54: + _context7.next = 59; + break; + + case 56: + // n just partially overlaps with next. extend n, delete next, and break this loop + n.len += next.len - diff; + return _context7.delegateYield(this.ds.delete(next.id), 't9', 58); + + case 58: + return _context7.abrupt('break', 61); + + case 59: + _context7.next = 33; + break; + + case 61: + return _context7.delegateYield(this.ds.put(n), 't10', 62); + + case 62: + return _context7.abrupt('return', n); + + case 63: + case 'end': + return _context7.stop(); + } + } + }, markDeleted, this); + }) + /* + Call this method when the client is connected&synced with the + other clients (e.g. master). This will query the database for + operations that can be gc'd and add them to the garbage collector. + */ + + }, { + key: 'garbageCollectAfterSync', + value: regeneratorRuntime.mark(function garbageCollectAfterSync() { + return regeneratorRuntime.wrap(function garbageCollectAfterSync$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + if (this.store.gc1.length > 0 || this.store.gc2.length > 0) { + console.warn('gc should be empty after sync'); + } + return _context9.delegateYield(this.os.iterate(this, null, null, regeneratorRuntime.mark(function _callee(op) { + var parentDeleted, i, left; + return regeneratorRuntime.wrap(function _callee$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + if (!op.gc) { + _context8.next = 3; + break; + } + + delete op.gc; + return _context8.delegateYield(this.setOperation(op), 't0', 3); + + case 3: + if (!(op.parent != null)) { + _context8.next = 23; + break; + } + + return _context8.delegateYield(this.isDeleted(op.parent), 't1', 5); + + case 5: + parentDeleted = _context8.t1; + + if (!parentDeleted) { + _context8.next = 23; + break; + } + + op.gc = true; + + if (op.deleted) { + _context8.next = 20; + break; + } + + return _context8.delegateYield(this.markDeleted(op.id, op.content != null ? op.content.length : 1), 't2', 10); + + case 10: + op.deleted = true; + + if (!(op.opContent != null)) { + _context8.next = 13; + break; + } + + return _context8.delegateYield(this.deleteOperation(op.opContent), 't3', 13); + + case 13: + if (!(op.requires != null)) { + _context8.next = 20; + break; + } + + i = 0; + + case 15: + if (!(i < op.requires.length)) { + _context8.next = 20; + break; + } + + return _context8.delegateYield(this.deleteOperation(op.requires[i]), 't4', 17); + + case 17: + i++; + _context8.next = 15; + break; + + case 20: + return _context8.delegateYield(this.setOperation(op), 't5', 21); + + case 21: + this.store.gc1.push(op.id); // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!) + return _context8.abrupt('return'); + + case 23: + if (!op.deleted) { + _context8.next = 29; + break; + } + + left = null; + + if (!(op.left != null)) { + _context8.next = 28; + break; + } + + return _context8.delegateYield(this.getInsertion(op.left), 't6', 27); + + case 27: + left = _context8.t6; + + case 28: + return _context8.delegateYield(this.store.addToGarbageCollector.call(this, op, left), 't7', 29); + + case 29: + case 'end': + return _context8.stop(); + } + } + }, _callee, this); + })), 't0', 2); + + case 2: + case 'end': + return _context9.stop(); + } + } + }, garbageCollectAfterSync, this); + }) + /* + Really remove an op and all its effects. + The complicated case here is the Insert operation: + * reset left + * reset right + * reset parent.start + * reset parent.end + * reset origins of all right ops + */ + + }, { + key: 'garbageCollectOperation', + value: regeneratorRuntime.mark(function garbageCollectOperation(id) { + var o, deps, i, dep, left, right, neworigin, neworigin_, _i, originsIn, origin, parent, setParent; + + return regeneratorRuntime.wrap(function garbageCollectOperation$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + this.store.addToDebug('yield* this.garbageCollectOperation(', id, ')'); + return _context10.delegateYield(this.getOperation(id), 't0', 2); + + case 2: + o = _context10.t0; + return _context10.delegateYield(this.markGarbageCollected(id, o != null && o.content != null ? o.content.length : 1), 't1', 4); + + case 4: + if (!(o != null)) { + _context10.next = 76; + break; + } + + deps = []; + + if (o.opContent != null) { + deps.push(o.opContent); + } + if (o.requires != null) { + deps = deps.concat(o.requires); + } + i = 0; + + case 9: + if (!(i < deps.length)) { + _context10.next = 26; + break; + } + + return _context10.delegateYield(this.getOperation(deps[i]), 't2', 11); + + case 11: + dep = _context10.t2; + + if (!(dep != null)) { + _context10.next = 22; + break; + } + + if (dep.deleted) { + _context10.next = 17; + break; + } + + return _context10.delegateYield(this.deleteOperation(dep.id), 't3', 15); + + case 15: + return _context10.delegateYield(this.getOperation(dep.id), 't4', 16); + + case 16: + dep = _context10.t4; + + case 17: + dep.gc = true; + return _context10.delegateYield(this.setOperation(dep), 't5', 19); + + case 19: + this.store.queueGarbageCollector(dep.id); + _context10.next = 23; + break; + + case 22: + return _context10.delegateYield(this.markGarbageCollected(deps[i], 1), 't6', 23); + + case 23: + i++; + _context10.next = 9; + break; + + case 26: + if (!(o.left != null)) { + _context10.next = 31; + break; + } + + return _context10.delegateYield(this.getInsertion(o.left), 't7', 28); + + case 28: + left = _context10.t7; + + left.right = o.right; + return _context10.delegateYield(this.setOperation(left), 't8', 31); + + case 31: + if (!(o.right != null)) { + _context10.next = 62; + break; + } + + return _context10.delegateYield(this.getOperation(o.right), 't9', 33); + + case 33: + right = _context10.t9; + + right.left = o.left; + + if (!(o.originOf != null && o.originOf.length > 0)) { + _context10.next = 61; + break; + } + + // find new origin of right ops + // origin is the first left deleted operation + neworigin = o.left; + neworigin_ = null; + + case 38: + if (!(neworigin != null)) { + _context10.next = 46; + break; + } + + return _context10.delegateYield(this.getInsertion(neworigin), 't10', 40); + + case 40: + neworigin_ = _context10.t10; + + if (!neworigin_.deleted) { + _context10.next = 43; + break; + } + + return _context10.abrupt('break', 46); + + case 43: + neworigin = neworigin_.left; + _context10.next = 38; + break; + + case 46: + _context10.t11 = regeneratorRuntime.keys(o.originOf); + + case 47: + if ((_context10.t12 = _context10.t11()).done) { + _context10.next = 56; + break; + } + + _i = _context10.t12.value; + return _context10.delegateYield(this.getOperation(o.originOf[_i]), 't13', 50); + + case 50: + originsIn = _context10.t13; + + if (!(originsIn != null)) { + _context10.next = 54; + break; + } + + originsIn.origin = neworigin; + return _context10.delegateYield(this.setOperation(originsIn), 't14', 54); + + case 54: + _context10.next = 47; + break; + + case 56: + if (!(neworigin != null)) { + _context10.next = 59; + break; + } + + if (neworigin_.originOf == null) { + neworigin_.originOf = o.originOf; + } else { + neworigin_.originOf = o.originOf.concat(neworigin_.originOf); + } + return _context10.delegateYield(this.setOperation(neworigin_), 't15', 59); + + case 59: + _context10.next = 62; + break; + + case 61: + return _context10.delegateYield(this.setOperation(right), 't16', 62); + + case 62: + if (!(o.origin != null)) { + _context10.next = 67; + break; + } + + return _context10.delegateYield(this.getInsertion(o.origin), 't17', 64); + + case 64: + origin = _context10.t17; + + origin.originOf = origin.originOf.filter(function (_id) { + return !Y.utils.compareIds(id, _id); + }); + return _context10.delegateYield(this.setOperation(origin), 't18', 67); + + case 67: + if (!(o.parent != null)) { + _context10.next = 70; + break; + } + + return _context10.delegateYield(this.getOperation(o.parent), 't19', 69); + + case 69: + parent = _context10.t19; + + case 70: + if (!(parent != null)) { + _context10.next = 75; + break; + } + + setParent = false; // whether to save parent to the os + + if (o.parentSub != null) { + if (Y.utils.compareIds(parent.map[o.parentSub], o.id)) { + setParent = true; + if (o.right != null) { + parent.map[o.parentSub] = o.right; + } else { + delete parent.map[o.parentSub]; + } + } + } else { + if (Y.utils.compareIds(parent.start, o.id)) { + // gc'd op is the start + setParent = true; + parent.start = o.right; + } + if (Y.utils.matchesId(o, parent.end)) { + // gc'd op is the end + setParent = true; + parent.end = o.left; + } + } + + if (!setParent) { + _context10.next = 75; + break; + } + + return _context10.delegateYield(this.setOperation(parent), 't20', 75); + + case 75: + return _context10.delegateYield(this.removeOperation(o.id), 't21', 76); + + case 76: + case 'end': + return _context10.stop(); + } + } + }, garbageCollectOperation, this); + }) + }, { + key: 'checkDeleteStoreForState', + value: regeneratorRuntime.mark(function checkDeleteStoreForState(state) { + var n; + return regeneratorRuntime.wrap(function checkDeleteStoreForState$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + return _context11.delegateYield(this.ds.findWithUpperBound([state.user, state.clock]), 't0', 1); + + case 1: + n = _context11.t0; + + if (n != null && n.id[0] === state.user && n.gc) { + state.clock = Math.max(state.clock, n.id[1] + n.len); + } + + case 3: + case 'end': + return _context11.stop(); + } + } + }, checkDeleteStoreForState, this); + }) + }, { + key: 'updateState', + value: regeneratorRuntime.mark(function updateState(user) { + var state, o, oLength; + return regeneratorRuntime.wrap(function updateState$(_context12) { + while (1) { + switch (_context12.prev = _context12.next) { + case 0: + return _context12.delegateYield(this.getState(user), 't0', 1); + + case 1: + state = _context12.t0; + return _context12.delegateYield(this.checkDeleteStoreForState(state), 't1', 3); + + case 3: + return _context12.delegateYield(this.getInsertion([user, state.clock]), 't2', 4); + + case 4: + o = _context12.t2; + oLength = o != null && o.content != null ? o.content.length : 1; + + case 6: + if (!(o != null && user === o.id[0] && o.id[1] <= state.clock && o.id[1] + oLength > state.clock)) { + _context12.next = 14; + break; + } + + // either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS + state.clock += oLength; + return _context12.delegateYield(this.checkDeleteStoreForState(state), 't3', 9); + + case 9: + return _context12.delegateYield(this.os.findNext(o.id), 't4', 10); + + case 10: + o = _context12.t4; + + oLength = o != null && o.content != null ? o.content.length : 1; + _context12.next = 6; + break; + + case 14: + return _context12.delegateYield(this.setState(state), 't5', 15); + + case 15: + case 'end': + return _context12.stop(); + } + } + }, updateState, this); + }) + /* + apply a delete set in order to get + the state of the supplied ds + */ + + }, { + key: 'applyDeleteSet', + value: regeneratorRuntime.mark(function applyDeleteSet(ds) { + var deletions, user, dv, pos, d, i, del, counter, o, oLen, ops; + return regeneratorRuntime.wrap(function applyDeleteSet$(_context14) { + while (1) { + switch (_context14.prev = _context14.next) { + case 0: + deletions = []; + _context14.t0 = regeneratorRuntime.keys(ds); + + case 2: + if ((_context14.t1 = _context14.t0()).done) { + _context14.next = 11; + break; + } + + user = _context14.t1.value; + dv = ds[user]; + pos = 0; + d = dv[pos]; + return _context14.delegateYield(this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], regeneratorRuntime.mark(function _callee2(n) { + var diff; + return regeneratorRuntime.wrap(function _callee2$(_context13) { + while (1) { + switch (_context13.prev = _context13.next) { + case 0: + if (!(d != null)) { + _context13.next = 10; + break; + } + + diff = 0; // describe the diff of length in 1) and 2) + + if (!(n.id[1] + n.len <= d[0])) { + _context13.next = 6; + break; + } + + return _context13.abrupt('break', 10); + + case 6: + if (d[0] < n.id[1]) { + // 2) + // delete maximum the len of d + // else delete as much as possible + diff = Math.min(n.id[1] - d[0], d[1]); + deletions.push([user, d[0], diff, d[2]]); + } else { + // 3) + diff = n.id[1] + n.len - d[0]; // never null (see 1) + if (d[2] && !n.gc) { + // d marks as gc'd but n does not + // then delete either way + deletions.push([user, d[0], Math.min(diff, d[1]), d[2]]); + } + } + + case 7: + if (d[1] <= diff) { + // d doesn't delete anything anymore + d = dv[++pos]; + } else { + d[0] = d[0] + diff; // reset pos + d[1] = d[1] - diff; // reset length + } + _context13.next = 0; + break; + + case 10: + case 'end': + return _context13.stop(); + } + } + }, _callee2, this); + })), 't2', 8); + + case 8: + // for the rest.. just apply it + for (; pos < dv.length; pos++) { + d = dv[pos]; + deletions.push([user, d[0], d[1], d[2]]); + } + _context14.next = 2; + break; + + case 11: + i = 0; + + case 12: + if (!(i < deletions.length)) { + _context14.next = 40; + break; + } + + del = deletions[i]; + // always try to delete.. + + return _context14.delegateYield(this.deleteOperation([del[0], del[1]], del[2]), 't3', 15); + + case 15: + if (!del[3]) { + _context14.next = 36; + break; + } + + return _context14.delegateYield(this.markGarbageCollected([del[0], del[1]], del[2]), 't4', 17); + + case 17: + // always mark gc'd + // remove operation.. + counter = del[1] + del[2]; + + case 18: + if (!(counter >= del[1])) { + _context14.next = 36; + break; + } + + return _context14.delegateYield(this.os.findWithUpperBound([del[0], counter - 1]), 't5', 20); + + case 20: + o = _context14.t5; + + if (!(o == null)) { + _context14.next = 23; + break; + } + + return _context14.abrupt('break', 36); + + case 23: + oLen = o.content != null ? o.content.length : 1; + + if (!(o.id[0] !== del[0] || o.id[1] + oLen <= del[1])) { + _context14.next = 26; + break; + } + + return _context14.abrupt('break', 36); + + case 26: + if (!(o.id[1] + oLen > del[1] + del[2])) { + _context14.next = 29; + break; + } + + return _context14.delegateYield(this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1]), 't6', 28); + + case 28: + o = _context14.t6; + + case 29: + if (!(o.id[1] < del[1])) { + _context14.next = 32; + break; + } + + return _context14.delegateYield(this.getInsertionCleanStart([del[0], del[1]]), 't7', 31); + + case 31: + o = _context14.t7; + + case 32: + counter = o.id[1]; + return _context14.delegateYield(this.garbageCollectOperation(o.id), 't8', 34); + + case 34: + _context14.next = 18; + break; + + case 36: + if (this.store.forwardAppliedOperations) { + ops = []; + + ops.push({ struct: 'Delete', target: [d[0], d[1]], length: del[2] }); + this.store.y.connector.broadcastOps(ops); + } + + case 37: + i++; + _context14.next = 12; + break; + + case 40: + case 'end': + return _context14.stop(); + } + } + }, applyDeleteSet, this); + }) + }, { + key: 'isGarbageCollected', + value: regeneratorRuntime.mark(function isGarbageCollected(id) { + var n; + return regeneratorRuntime.wrap(function isGarbageCollected$(_context15) { + while (1) { + switch (_context15.prev = _context15.next) { + case 0: + return _context15.delegateYield(this.ds.findWithUpperBound(id), 't0', 1); + + case 1: + n = _context15.t0; + return _context15.abrupt('return', n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len && n.gc); + + case 3: + case 'end': + return _context15.stop(); + } + } + }, isGarbageCollected, this); + }) + /* + A DeleteSet (ds) describes all the deleted ops in the OS + */ + + }, { + key: 'getDeleteSet', + value: regeneratorRuntime.mark(function getDeleteSet() { + var ds; + return regeneratorRuntime.wrap(function getDeleteSet$(_context17) { + while (1) { + switch (_context17.prev = _context17.next) { + case 0: + ds = {}; + return _context17.delegateYield(this.ds.iterate(this, null, null, regeneratorRuntime.mark(function _callee3(n) { + var user, counter, len, gc, dv; + return regeneratorRuntime.wrap(function _callee3$(_context16) { + while (1) { + switch (_context16.prev = _context16.next) { + case 0: + user = n.id[0]; + counter = n.id[1]; + len = n.len; + gc = n.gc; + dv = ds[user]; + + if (dv === void 0) { + dv = []; + ds[user] = dv; + } + dv.push([counter, len, gc]); + + case 7: + case 'end': + return _context16.stop(); + } + } + }, _callee3, this); + })), 't0', 2); + + case 2: + return _context17.abrupt('return', ds); + + case 3: + case 'end': + return _context17.stop(); + } + } + }, getDeleteSet, this); + }) + }, { + key: 'isDeleted', + value: regeneratorRuntime.mark(function isDeleted(id) { + var n; + return regeneratorRuntime.wrap(function isDeleted$(_context18) { + while (1) { + switch (_context18.prev = _context18.next) { + case 0: + return _context18.delegateYield(this.ds.findWithUpperBound(id), 't0', 1); + + case 1: + n = _context18.t0; + return _context18.abrupt('return', n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len); + + case 3: + case 'end': + return _context18.stop(); + } + } + }, isDeleted, this); + }) + }, { + key: 'setOperation', + value: regeneratorRuntime.mark(function setOperation(op) { + return regeneratorRuntime.wrap(function setOperation$(_context19) { + while (1) { + switch (_context19.prev = _context19.next) { + case 0: + return _context19.delegateYield(this.os.put(op), 't0', 1); + + case 1: + return _context19.abrupt('return', op); + + case 2: + case 'end': + return _context19.stop(); + } + } + }, setOperation, this); + }) + }, { + key: 'addOperation', + value: regeneratorRuntime.mark(function addOperation(op) { + return regeneratorRuntime.wrap(function addOperation$(_context20) { + while (1) { + switch (_context20.prev = _context20.next) { + case 0: + return _context20.delegateYield(this.os.put(op), 't0', 1); + + case 1: + if (!this.store.y.connector.isDisconnected() && this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') { + // is connected, and this is not going to be send in addOperation + this.store.y.connector.broadcastOps([op]); + } + + case 2: + case 'end': + return _context20.stop(); + } + } + }, addOperation, this); + }) + // if insertion, try to combine with left insertion (if both have content property) + + }, { + key: 'tryCombineWithLeft', + value: regeneratorRuntime.mark(function tryCombineWithLeft(op) { + var left; + return regeneratorRuntime.wrap(function tryCombineWithLeft$(_context21) { + while (1) { + switch (_context21.prev = _context21.next) { + case 0: + if (!(op != null && op.left != null && op.content != null && op.left[0] === op.id[0] && Y.utils.compareIds(op.left, op.origin))) { + _context21.next = 9; + break; + } + + return _context21.delegateYield(this.getInsertion(op.left), 't0', 2); + + case 2: + left = _context21.t0; + + if (!(left.content != null && left.id[1] + left.content.length === op.id[1] && left.originOf.length === 1 && !left.gc && !left.deleted && !op.gc && !op.deleted)) { + _context21.next = 9; + break; + } + + // combine! + if (op.originOf != null) { + left.originOf = op.originOf; + } else { + delete left.originOf; + } + left.content = left.content.concat(op.content); + left.right = op.right; + return _context21.delegateYield(this.os.delete(op.id), 't1', 8); + + case 8: + return _context21.delegateYield(this.setOperation(left), 't2', 9); + + case 9: + case 'end': + return _context21.stop(); + } + } + }, tryCombineWithLeft, this); + }) + }, { + key: 'getInsertion', + value: regeneratorRuntime.mark(function getInsertion(id) { + var ins, len; + return regeneratorRuntime.wrap(function getInsertion$(_context22) { + while (1) { + switch (_context22.prev = _context22.next) { + case 0: + return _context22.delegateYield(this.os.findWithUpperBound(id), 't0', 1); + + case 1: + ins = _context22.t0; + + if (!(ins == null)) { + _context22.next = 6; + break; + } + + return _context22.abrupt('return', null); + + case 6: + len = ins.content != null ? ins.content.length : 1; // in case of opContent + + if (!(id[0] === ins.id[0] && id[1] < ins.id[1] + len)) { + _context22.next = 11; + break; + } + + return _context22.abrupt('return', ins); + + case 11: + return _context22.abrupt('return', null); + + case 12: + case 'end': + return _context22.stop(); + } + } + }, getInsertion, this); + }) + }, { + key: 'getInsertionCleanStartEnd', + value: regeneratorRuntime.mark(function getInsertionCleanStartEnd(id) { + return regeneratorRuntime.wrap(function getInsertionCleanStartEnd$(_context23) { + while (1) { + switch (_context23.prev = _context23.next) { + case 0: + return _context23.delegateYield(this.getInsertionCleanStart(id), 't0', 1); + + case 1: + return _context23.delegateYield(this.getInsertionCleanEnd(id), 't1', 2); + + case 2: + return _context23.abrupt('return', _context23.t1); + + case 3: + case 'end': + return _context23.stop(); + } + } + }, getInsertionCleanStartEnd, this); + }) + // Return an insertion such that id is the first element of content + // This function manipulates an operation, if necessary + + }, { + key: 'getInsertionCleanStart', + value: regeneratorRuntime.mark(function getInsertionCleanStart(id) { + var ins, left, leftLid; + return regeneratorRuntime.wrap(function getInsertionCleanStart$(_context24) { + while (1) { + switch (_context24.prev = _context24.next) { + case 0: + return _context24.delegateYield(this.getInsertion(id), 't0', 1); + + case 1: + ins = _context24.t0; + + if (!(ins != null)) { + _context24.next = 21; + break; + } + + if (!(ins.id[1] === id[1])) { + _context24.next = 7; + break; + } + + return _context24.abrupt('return', ins); + + case 7: + left = Y.utils.copyObject(ins); + + ins.content = left.content.splice(id[1] - ins.id[1]); + ins.id = id; + leftLid = Y.utils.getLastId(left); + + ins.origin = leftLid; + left.originOf = [ins.id]; + left.right = ins.id; + ins.left = leftLid; + // debugger // check + return _context24.delegateYield(this.setOperation(left), 't1', 16); + + case 16: + return _context24.delegateYield(this.setOperation(ins), 't2', 17); + + case 17: + if (left.gc) { + this.store.queueGarbageCollector(ins.id); + } + return _context24.abrupt('return', ins); + + case 19: + _context24.next = 22; + break; + + case 21: + return _context24.abrupt('return', null); + + case 22: + case 'end': + return _context24.stop(); + } + } + }, getInsertionCleanStart, this); + }) + // Return an insertion such that id is the last element of content + // This function manipulates an operation, if necessary + + }, { + key: 'getInsertionCleanEnd', + value: regeneratorRuntime.mark(function getInsertionCleanEnd(id) { + var ins, right, insLid; + return regeneratorRuntime.wrap(function getInsertionCleanEnd$(_context25) { + while (1) { + switch (_context25.prev = _context25.next) { + case 0: + return _context25.delegateYield(this.getInsertion(id), 't0', 1); + + case 1: + ins = _context25.t0; + + if (!(ins != null)) { + _context25.next = 21; + break; + } + + if (!(ins.content == null || ins.id[1] + ins.content.length - 1 === id[1])) { + _context25.next = 7; + break; + } + + return _context25.abrupt('return', ins); + + case 7: + right = Y.utils.copyObject(ins); + + right.content = ins.content.splice(id[1] - ins.id[1] + 1); // cut off remainder + right.id = [id[0], id[1] + 1]; + insLid = Y.utils.getLastId(ins); + + right.origin = insLid; + ins.originOf = [right.id]; + ins.right = right.id; + right.left = insLid; + // debugger // check + return _context25.delegateYield(this.setOperation(right), 't1', 16); + + case 16: + return _context25.delegateYield(this.setOperation(ins), 't2', 17); + + case 17: + if (ins.gc) { + this.store.queueGarbageCollector(right.id); + } + return _context25.abrupt('return', ins); + + case 19: + _context25.next = 22; + break; + + case 21: + return _context25.abrupt('return', null); + + case 22: + case 'end': + return _context25.stop(); + } + } + }, getInsertionCleanEnd, this); + }) + }, { + key: 'getOperation', + value: regeneratorRuntime.mark(function getOperation(id /* :any */) { + var o, comp, struct, op; + return regeneratorRuntime.wrap(function getOperation$(_context26) { + while (1) { + switch (_context26.prev = _context26.next) { + case 0: + return _context26.delegateYield(this.os.find(id), 't0', 1); + + case 1: + o = _context26.t0; + + if (!(id[0] !== '_' || o != null)) { + _context26.next = 6; + break; + } + + return _context26.abrupt('return', o); + + case 6: + // type is string + // generate this operation? + comp = id[1].split('_'); + + if (!(comp.length > 1)) { + _context26.next = 15; + break; + } + + struct = comp[0]; + op = Y.Struct[struct].create(id); + + op.type = comp[1]; + return _context26.delegateYield(this.setOperation(op), 't1', 12); + + case 12: + return _context26.abrupt('return', op); + + case 15: + // won't be called. but just in case.. + console.error('Unexpected case. How can this happen?'); + debugger; // eslint-disable-line + return _context26.abrupt('return', null); + + case 18: + case 'end': + return _context26.stop(); + } + } + }, getOperation, this); + }) + }, { + key: 'removeOperation', + value: regeneratorRuntime.mark(function removeOperation(id) { + return regeneratorRuntime.wrap(function removeOperation$(_context27) { + while (1) { + switch (_context27.prev = _context27.next) { + case 0: + return _context27.delegateYield(this.os.delete(id), 't0', 1); + + case 1: + case 'end': + return _context27.stop(); + } + } + }, removeOperation, this); + }) + }, { + key: 'setState', + value: regeneratorRuntime.mark(function setState(state) { + var val; + return regeneratorRuntime.wrap(function setState$(_context28) { + while (1) { + switch (_context28.prev = _context28.next) { + case 0: + val = { + id: [state.user], + clock: state.clock + }; + return _context28.delegateYield(this.ss.put(val), 't0', 2); + + case 2: + case 'end': + return _context28.stop(); + } + } + }, setState, this); + }) + }, { + key: 'getState', + value: regeneratorRuntime.mark(function getState(user) { + var n, clock; + return regeneratorRuntime.wrap(function getState$(_context29) { + while (1) { + switch (_context29.prev = _context29.next) { + case 0: + return _context29.delegateYield(this.ss.find([user]), 't0', 1); + + case 1: + n = _context29.t0; + clock = n == null ? null : n.clock; + + if (clock == null) { + clock = 0; + } + return _context29.abrupt('return', { + user: user, + clock: clock + }); + + case 5: + case 'end': + return _context29.stop(); + } + } + }, getState, this); + }) + }, { + key: 'getStateVector', + value: regeneratorRuntime.mark(function getStateVector() { + var stateVector; + return regeneratorRuntime.wrap(function getStateVector$(_context31) { + while (1) { + switch (_context31.prev = _context31.next) { + case 0: + stateVector = []; + return _context31.delegateYield(this.ss.iterate(this, null, null, regeneratorRuntime.mark(function _callee4(n) { + return regeneratorRuntime.wrap(function _callee4$(_context30) { + while (1) { + switch (_context30.prev = _context30.next) { + case 0: + stateVector.push({ + user: n.id[0], + clock: n.clock + }); + + case 1: + case 'end': + return _context30.stop(); + } + } + }, _callee4, this); + })), 't0', 2); + + case 2: + return _context31.abrupt('return', stateVector); + + case 3: + case 'end': + return _context31.stop(); + } + } + }, getStateVector, this); + }) + }, { + key: 'getStateSet', + value: regeneratorRuntime.mark(function getStateSet() { + var ss; + return regeneratorRuntime.wrap(function getStateSet$(_context33) { + while (1) { + switch (_context33.prev = _context33.next) { + case 0: + ss = {}; + return _context33.delegateYield(this.ss.iterate(this, null, null, regeneratorRuntime.mark(function _callee5(n) { + return regeneratorRuntime.wrap(function _callee5$(_context32) { + while (1) { + switch (_context32.prev = _context32.next) { + case 0: + ss[n.id[0]] = n.clock; + + case 1: + case 'end': + return _context32.stop(); + } + } + }, _callee5, this); + })), 't0', 2); + + case 2: + return _context33.abrupt('return', ss); + + case 3: + case 'end': + return _context33.stop(); + } + } + }, getStateSet, this); + }) + /* + Here, we make all missing operations executable for the receiving user. + Notes: + startSS: denotes to the SV that the remote user sent + currSS: denotes to the state vector that the user should have if he + applies all already sent operations (increases is each step) + We face several problems: + * Execute op as is won't work because ops depend on each other + -> find a way so that they do not anymore + * When changing left, must not go more to the left than the origin + * When changing right, you have to consider that other ops may have op + as their origin, this means that you must not set one of these ops + as the new right (interdependencies of ops) + * can't just go to the right until you find the first known operation, + With currSS + -> interdependency of ops is a problem + With startSS + -> leads to inconsistencies when two users join at the same time. + Then the position depends on the order of execution -> error! + Solution: + -> re-create originial situation + -> set op.left = op.origin (which never changes) + -> set op.right + to the first operation that is known (according to startSS) + or to the first operation that has an origin that is not to the + right of op. + -> Enforces unique execution order -> happy user + Improvements: TODO + * Could set left to origin, or the first known operation + (startSS or currSS.. ?) + -> Could be necessary when I turn GC again. + -> Is a bad(ish) idea because it requires more computation + What we do: + * Iterate over all missing operations. + * When there is an operation, where the right op is known, send this op all missing ops to the left to the user + * I explained above what we have to do with each operation. Here is how we do it efficiently: + 1. Go to the left until you find either op.origin, or a known operation (let o denote current operation in the iteration) + 2. Found a known operation -> set op.left = o, and send it to the user. stop + 3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o) + 4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue + */ + + }, { + key: 'getOperations', + value: regeneratorRuntime.mark(function getOperations(startSS) { + var send, endSV, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, endState, user, startPos, firstMissing; + + return regeneratorRuntime.wrap(function getOperations$(_context35) { + while (1) { + switch (_context35.prev = _context35.next) { + case 0: + // TODO: use bounds here! + if (startSS == null) { + startSS = {}; + } + send = []; + return _context35.delegateYield(this.getStateVector(), 't0', 3); + + case 3: + endSV = _context35.t0; + _iteratorNormalCompletion = true; + _didIteratorError = false; + _iteratorError = undefined; + _context35.prev = 7; + _iterator = endSV[Symbol.iterator](); + + case 9: + if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { + _context35.next = 23; + break; + } + + endState = _step.value; + user = endState.user; + + if (!(user === '_')) { + _context35.next = 14; + break; + } + + return _context35.abrupt('continue', 20); + + case 14: + startPos = startSS[user] || 0; + + if (!(startPos > 0)) { + _context35.next = 19; + break; + } + + return _context35.delegateYield(this.getInsertion([user, startPos]), 't1', 17); + + case 17: + firstMissing = _context35.t1; + + if (firstMissing != null) { + // update startPos + startPos = firstMissing.id[1]; + } + + case 19: + return _context35.delegateYield(this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], regeneratorRuntime.mark(function _callee6(op) { + var o, missing_origins, newright, s; + return regeneratorRuntime.wrap(function _callee6$(_context34) { + while (1) { + switch (_context34.prev = _context34.next) { + case 0: + op = Y.Struct[op.struct].encode(op); + + if (!(op.struct !== 'Insert')) { + _context34.next = 5; + break; + } + + send.push(op); + _context34.next = 27; + break; + + case 5: + if (!(op.right == null || op.right[1] < (startSS[op.right[0]] || 0))) { + _context34.next = 27; + break; + } + + // case 1. op.right is known + o = op; + // Remember: ? + // -> set op.right + // 1. to the first operation that is known (according to startSS) + // 2. or to the first operation that has an origin that is not to the + // right of op. + // For this we maintain a list of ops which origins are not found yet. + + missing_origins = [op]; + newright = op.right; + + case 9: + if (!true) { + _context34.next = 27; + break; + } + + if (!(o.left == null)) { + _context34.next = 15; + break; + } + + op.left = null; + send.push(op); + if (!Y.utils.compareIds(o.id, op.id)) { + o = Y.Struct[op.struct].encode(o); + o.right = missing_origins[missing_origins.length - 1].id; + send.push(o); + } + return _context34.abrupt('break', 27); + + case 15: + return _context34.delegateYield(this.getInsertion(o.left), 't0', 16); + + case 16: + o = _context34.t0; + + // we set another o, check if we can reduce $missing_origins + while (missing_origins.length > 0 && Y.utils.matchesId(o, missing_origins[missing_origins.length - 1].origin)) { + missing_origins.pop(); + } + + if (!(o.id[1] < (startSS[o.id[0]] || 0))) { + _context34.next = 24; + break; + } + + // case 2. o is known + op.left = Y.utils.getLastId(o); + send.push(op); + return _context34.abrupt('break', 27); + + case 24: + if (Y.utils.matchesId(o, op.origin)) { + // case 3. o is op.origin + op.left = op.origin; + send.push(op); + op = Y.Struct[op.struct].encode(o); + op.right = newright; + if (missing_origins.length > 0) { + console.log('This should not happen .. :( please report this'); + } + missing_origins = [op]; + } else { + // case 4. send o, continue to find op.origin + s = Y.Struct[op.struct].encode(o); + + s.right = missing_origins[missing_origins.length - 1].id; + s.left = s.origin; + send.push(s); + missing_origins.push(o); + } + + case 25: + _context34.next = 9; + break; + + case 27: + case 'end': + return _context34.stop(); + } + } + }, _callee6, this); + })), 't2', 20); + + case 20: + _iteratorNormalCompletion = true; + _context35.next = 9; + break; + + case 23: + _context35.next = 29; + break; + + case 25: + _context35.prev = 25; + _context35.t3 = _context35['catch'](7); + _didIteratorError = true; + _iteratorError = _context35.t3; + + case 29: + _context35.prev = 29; + _context35.prev = 30; + + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + + case 32: + _context35.prev = 32; + + if (!_didIteratorError) { + _context35.next = 35; + break; + } + + throw _iteratorError; + + case 35: + return _context35.finish(32); + + case 36: + return _context35.finish(29); + + case 37: + return _context35.abrupt('return', send.reverse()); + + case 38: + case 'end': + return _context35.stop(); + } + } + }, getOperations, this, [[7, 25, 29, 37], [30,, 32, 36]]); + }) + /* this is what we used before.. use this as a reference.. + * makeOperationReady (startSS, op) { + op = Y.Struct[op.struct].encode(op) + op = Y.utils.copyObject(op) + var o = op + var ids = [op.id] + // search for the new op.right + // it is either the first known op (according to startSS) + // or the o that has no origin to the right of op + // (this is why we use the ids array) + while (o.right != null) { + var right = yield* this.getOperation(o.right) + if (o.right[1] < (startSS[o.right[0]] || 0) || !ids.some(function (id) { + return Y.utils.compareIds(id, right.origin) + })) { + break + } + ids.push(o.right) + o = right + } + op.right = o.right + op.left = op.origin + return op + } + */ + + }, { + key: 'flush', + value: regeneratorRuntime.mark(function flush() { + return regeneratorRuntime.wrap(function flush$(_context36) { + while (1) { + switch (_context36.prev = _context36.next) { + case 0: + return _context36.delegateYield(this.os.flush(), 't0', 1); + + case 1: + return _context36.delegateYield(this.ss.flush(), 't1', 2); + + case 2: + return _context36.delegateYield(this.ds.flush(), 't2', 3); + + case 3: + case 'end': + return _context36.stop(); + } + } + }, flush, this); + }) + }]); + + return TransactionInterface; + }(); + + Y.Transaction = TransactionInterface; +}; + +},{}],8:[function(require,module,exports){ +/* @flow */ +'use strict'; + +/* + EventHandler is an helper class for constructing custom types. + + Why: When constructing custom types, you sometimes want your types to work + synchronous: E.g. + ``` Synchronous + mytype.setSomething("yay") + mytype.getSomething() === "yay" + ``` + versus + ``` Asynchronous + mytype.setSomething("yay") + mytype.getSomething() === undefined + mytype.waitForSomething().then(function(){ + mytype.getSomething() === "yay" + }) + ``` + + The structures usually work asynchronously (you have to wait for the + database request to finish). EventHandler helps you to make your type + synchronous. +*/ + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +module.exports = function (Y /* : any*/) { + Y.utils = {}; + + var EventListenerHandler = function () { + function EventListenerHandler() { + _classCallCheck(this, EventListenerHandler); + + this.eventListeners = []; + } + + _createClass(EventListenerHandler, [{ + key: 'destroy', + value: function destroy() { + this.eventListeners = null; + } + /* + Basic event listener boilerplate... + */ + + }, { + key: 'addEventListener', + value: function addEventListener(f) { + this.eventListeners.push(f); + } + }, { + key: 'removeEventListener', + value: function removeEventListener(f) { + this.eventListeners = this.eventListeners.filter(function (g) { + return f !== g; + }); + } + }, { + key: 'removeAllEventListeners', + value: function removeAllEventListeners() { + this.eventListeners = []; + } + }, { + key: 'callEventListeners', + value: function callEventListeners(event) { + for (var i = 0; i < this.eventListeners.length; i++) { + try { + this.eventListeners[i](event); + } catch (e) { + console.error('User events must not throw Errors!'); + } + } + } + }]); + + return EventListenerHandler; + }(); + + Y.utils.EventListenerHandler = EventListenerHandler; + + var EventHandler = function (_EventListenerHandler) { + _inherits(EventHandler, _EventListenerHandler); + + /* :: + waiting: Array; + awaiting: number; + onevent: Function; + eventListeners: Array; + */ + /* + onevent: is called when the structure changes. + Note: "awaiting opertations" is used to denote operations that were + prematurely called. Events for received operations can not be executed until + all prematurely called operations were executed ("waiting operations") + */ + + function EventHandler(onevent /* : Function */) { + _classCallCheck(this, EventHandler); + + var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(EventHandler).call(this)); + + _this.waiting = []; + _this.awaiting = 0; + _this.onevent = onevent; + return _this; + } + + _createClass(EventHandler, [{ + key: 'destroy', + value: function destroy() { + _get(Object.getPrototypeOf(EventHandler.prototype), 'destroy', this).call(this); + this.waiting = null; + this.awaiting = null; + this.onevent = null; + } + /* + Call this when a new operation arrives. It will be executed right away if + there are no waiting operations, that you prematurely executed + */ + + }, { + key: 'receivedOp', + value: function receivedOp(op) { + if (this.awaiting <= 0) { + this.onevent(op); + } else { + this.waiting.push(op); + } + } + /* + You created some operations, and you want the `onevent` function to be + called right away. Received operations will not be executed untill all + prematurely called operations are executed + */ + + }, { + key: 'awaitAndPrematurelyCall', + value: function awaitAndPrematurelyCall(ops) { + this.awaiting += ops.length; + ops.forEach(this.onevent); + } + /* + Call this when you successfully awaited the execution of n Insert operations + */ + + }, { + key: 'awaitedInserts', + value: function awaitedInserts(n) { + var ops = this.waiting.splice(this.waiting.length - n); + for (var oid = 0; oid < ops.length; oid++) { + var op = ops[oid]; + if (op.struct === 'Insert') { + for (var i = this.waiting.length - 1; i >= 0; i--) { + var w = this.waiting[i]; + // TODO: do I handle split operations correctly here? Super unlikely, but yeah.. + // Also: can this case happen? Can op be inserted in the middle of a larger op that is in $waiting? + if (w.struct === 'Insert') { + if (Y.utils.matchesId(w, op.left)) { + // include the effect of op in w + w.right = op.id; + // exclude the effect of w in op + op.left = w.left; + } else if (Y.utils.compareIds(w.id, op.right)) { + // similar.. + w.left = Y.utils.getLastId(op); + op.right = w.right; + } + } + } + } else { + throw new Error('Expected Insert Operation!'); + } + } + this._tryCallEvents(n); + } + /* + Call this when you successfully awaited the execution of n Delete operations + */ + + }, { + key: 'awaitedDeletes', + value: function awaitedDeletes(n, newLeft) { + var ops = this.waiting.splice(this.waiting.length - n); + for (var j = 0; j < ops.length; j++) { + var del = ops[j]; + if (del.struct === 'Delete') { + if (newLeft != null) { + for (var i = 0; i < this.waiting.length; i++) { + var w = this.waiting[i]; + // We will just care about w.left + if (w.struct === 'Insert' && Y.utils.compareIds(del.target, w.left)) { + w.left = newLeft; + } + } + } + } else { + throw new Error('Expected Delete Operation!'); + } + } + this._tryCallEvents(n); + } + /* (private) + Try to execute the events for the waiting operations + */ + + }, { + key: '_tryCallEvents', + value: function _tryCallEvents(n) { + this.awaiting -= n; + if (this.awaiting === 0 && this.waiting.length > 0) { + var ops = this.waiting; + this.waiting = []; + ops.forEach(this.onevent); + } + } + }]); + + return EventHandler; + }(EventListenerHandler); + + Y.utils.EventHandler = EventHandler; + + /* + A wrapper for the definition of a custom type. + Every custom type must have three properties: + * struct + - Structname of this type + * initType + - Given a model, creates a custom type + * class + - the constructor of the custom type (e.g. in order to inherit from a type) + */ + + var CustomType = // eslint-disable-line + /* :: + struct: any; + initType: any; + class: Function; + name: String; + */ + function CustomType(def) { + _classCallCheck(this, CustomType); + + if (def.struct == null || def.initType == null || def.class == null || def.name == null) { + throw new Error('Custom type was not initialized correctly!'); + } + this.struct = def.struct; + this.initType = def.initType; + this.class = def.class; + this.name = def.name; + if (def.appendAdditionalInfo != null) { + this.appendAdditionalInfo = def.appendAdditionalInfo; + } + this.parseArguments = (def.parseArguments || function () { + return [this]; + }).bind(this); + this.parseArguments.typeDefinition = this; + }; + + Y.utils.CustomType = CustomType; + + Y.utils.isTypeDefinition = function isTypeDefinition(v) { + if (v != null) { + if (v instanceof Y.utils.CustomType) return [v];else if (v.constructor === Array && v[0] instanceof Y.utils.CustomType) return v;else if (v instanceof Function && v.typeDefinition instanceof Y.utils.CustomType) return [v.typeDefinition]; + } + return false; + }; + + /* + Make a flat copy of an object + (just copy properties) + */ + function copyObject(o) { + var c = {}; + for (var key in o) { + c[key] = o[key]; + } + return c; + } + Y.utils.copyObject = copyObject; + + /* + Defines a smaller relation on Id's + */ + function smaller(a, b) { + return a[0] < b[0] || a[0] === b[0] && (a[1] < b[1] || _typeof(a[1]) < _typeof(b[1])); + } + Y.utils.smaller = smaller; + + function compareIds(id1, id2) { + if (id1 == null || id2 == null) { + return id1 === id2; + } else { + return id1[0] === id2[0] && id1[1] === id2[1]; + } + } + Y.utils.compareIds = compareIds; + + function matchesId(op, id) { + if (id == null || op == null) { + return id === op; + } else { + if (id[0] === op.id[0]) { + if (op.content == null) { + return id[1] === op.id[1]; + } else { + return id[1] >= op.id[1] && id[1] < op.id[1] + op.content.length; + } + } + } + } + Y.utils.matchesId = matchesId; + + function getLastId(op) { + if (op.content == null || op.content.length === 1) { + return op.id; + } else { + return [op.id[0], op.id[1] + op.content.length - 1]; + } + } + Y.utils.getLastId = getLastId; + + function createEmptyOpsArray(n) { + var a = new Array(n); + for (var i = 0; i < a.length; i++) { + a[i] = { + id: [null, null] + }; + } + return a; + } + + function createSmallLookupBuffer(Store) { + /* + This buffer implements a very small buffer that temporarily stores operations + after they are read / before they are written. + The buffer basically implements FIFO. Often requested lookups will be re-queued every time they are looked up / written. + It can speed up lookups on Operation Stores and State Stores. But it does not require notable use of memory or processing power. + Good for os and ss, bot not for ds (because it often uses methods that require a flush) + I tried to optimize this for performance, therefore no highlevel operations. + */ + + var SmallLookupBuffer = function (_Store) { + _inherits(SmallLookupBuffer, _Store); + + function SmallLookupBuffer(arg1, arg2) { + _classCallCheck(this, SmallLookupBuffer); + + var _this2 = _possibleConstructorReturn(this, Object.getPrototypeOf(SmallLookupBuffer).call(this, arg1, arg2)); + // super(...arguments) -- do this when this is supported by stable nodejs + + _this2.writeBuffer = createEmptyOpsArray(5); + _this2.readBuffer = createEmptyOpsArray(10); + return _this2; + } + + _createClass(SmallLookupBuffer, [{ + key: 'find', + value: regeneratorRuntime.mark(function find(id, noSuperCall) { + var i, r, o; + return regeneratorRuntime.wrap(function find$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + i = this.readBuffer.length - 1; + + case 1: + if (!(i >= 0)) { + _context.next = 10; + break; + } + + r = this.readBuffer[i]; + // we don't have to use compareids, because id is always defined! + + if (!(r.id[1] === id[1] && r.id[0] === id[0])) { + _context.next = 7; + break; + } + + // found r + // move r to the end of readBuffer + for (; i < this.readBuffer.length - 1; i++) { + this.readBuffer[i] = this.readBuffer[i + 1]; + } + this.readBuffer[this.readBuffer.length - 1] = r; + return _context.abrupt('return', r); + + case 7: + i--; + _context.next = 1; + break; + + case 10: + i = this.writeBuffer.length - 1; + + case 11: + if (!(i >= 0)) { + _context.next = 19; + break; + } + + r = this.writeBuffer[i]; + + if (!(r.id[1] === id[1] && r.id[0] === id[0])) { + _context.next = 16; + break; + } + + o = r; + return _context.abrupt('break', 19); + + case 16: + i--; + _context.next = 11; + break; + + case 19: + if (!(i < 0 && noSuperCall === undefined)) { + _context.next = 22; + break; + } + + return _context.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'find', this).call(this, id), 't0', 21); + + case 21: + o = _context.t0; + + case 22: + if (o != null) { + for (i = 0; i < this.readBuffer.length - 1; i++) { + this.readBuffer[i] = this.readBuffer[i + 1]; + } + this.readBuffer[this.readBuffer.length - 1] = o; + } + return _context.abrupt('return', o); + + case 24: + case 'end': + return _context.stop(); + } + } + }, find, this); + }) + }, { + key: 'put', + value: regeneratorRuntime.mark(function put(o) { + var id, i, r, write; + return regeneratorRuntime.wrap(function put$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + id = o.id; + i = this.writeBuffer.length - 1; + + case 2: + if (!(i >= 0)) { + _context2.next = 11; + break; + } + + r = this.writeBuffer[i]; + + if (!(r.id[1] === id[1] && r.id[0] === id[0])) { + _context2.next = 8; + break; + } + + // is already in buffer + // forget r, and move o to the end of writeBuffer + for (; i < this.writeBuffer.length - 1; i++) { + this.writeBuffer[i] = this.writeBuffer[i + 1]; + } + this.writeBuffer[this.writeBuffer.length - 1] = o; + return _context2.abrupt('break', 11); + + case 8: + i--; + _context2.next = 2; + break; + + case 11: + if (!(i < 0)) { + _context2.next = 17; + break; + } + + // did not reach break in last loop + // write writeBuffer[0] + write = this.writeBuffer[0]; + + if (!(write.id[0] !== null)) { + _context2.next = 15; + break; + } + + return _context2.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'put', this).call(this, write), 't0', 15); + + case 15: + // put o to the end of writeBuffer + for (i = 0; i < this.writeBuffer.length - 1; i++) { + this.writeBuffer[i] = this.writeBuffer[i + 1]; + } + this.writeBuffer[this.writeBuffer.length - 1] = o; + + case 17: + // check readBuffer for every occurence of o.id, overwrite if found + // whether found or not, we'll append o to the readbuffer + for (i = 0; i < this.readBuffer.length - 1; i++) { + r = this.readBuffer[i + 1]; + if (r.id[1] === id[1] && r.id[0] === id[0]) { + this.readBuffer[i] = o; + } else { + this.readBuffer[i] = r; + } + } + this.readBuffer[this.readBuffer.length - 1] = o; + + case 19: + case 'end': + return _context2.stop(); + } + } + }, put, this); + }) + }, { + key: 'delete', + value: regeneratorRuntime.mark(function _delete(id) { + var i, r; + return regeneratorRuntime.wrap(function _delete$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + for (i = 0; i < this.readBuffer.length; i++) { + r = this.readBuffer[i]; + if (r.id[1] === id[1] && r.id[0] === id[0]) { + this.readBuffer[i] = { + id: [null, null] + }; + } + } + return _context3.delegateYield(this.flush(), 't0', 2); + + case 2: + return _context3.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'delete', this).call(this, id), 't1', 3); + + case 3: + case 'end': + return _context3.stop(); + } + } + }, _delete, this); + }) + }, { + key: 'findWithLowerBound', + value: regeneratorRuntime.mark(function findWithLowerBound(id) { + var o, + _args4 = arguments; + return regeneratorRuntime.wrap(function findWithLowerBound$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + return _context4.delegateYield(this.find(id, true), 't0', 1); + + case 1: + o = _context4.t0; + + if (!(o != null)) { + _context4.next = 6; + break; + } + + return _context4.abrupt('return', o); + + case 6: + return _context4.delegateYield(this.flush(), 't1', 7); + + case 7: + return _context4.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'findWithLowerBound', this).apply(this, _args4), 't2', 8); + + case 8: + return _context4.abrupt('return', _context4.t2); + + case 9: + case 'end': + return _context4.stop(); + } + } + }, findWithLowerBound, this); + }) + }, { + key: 'findWithUpperBound', + value: regeneratorRuntime.mark(function findWithUpperBound(id) { + var o, + _args5 = arguments; + return regeneratorRuntime.wrap(function findWithUpperBound$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + return _context5.delegateYield(this.find(id, true), 't0', 1); + + case 1: + o = _context5.t0; + + if (!(o != null)) { + _context5.next = 6; + break; + } + + return _context5.abrupt('return', o); + + case 6: + return _context5.delegateYield(this.flush(), 't1', 7); + + case 7: + return _context5.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'findWithUpperBound', this).apply(this, _args5), 't2', 8); + + case 8: + return _context5.abrupt('return', _context5.t2); + + case 9: + case 'end': + return _context5.stop(); + } + } + }, findWithUpperBound, this); + }) + }, { + key: 'findNext', + value: regeneratorRuntime.mark(function findNext() { + var _args6 = arguments; + return regeneratorRuntime.wrap(function findNext$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + return _context6.delegateYield(this.flush(), 't0', 1); + + case 1: + return _context6.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'findNext', this).apply(this, _args6), 't1', 2); + + case 2: + return _context6.abrupt('return', _context6.t1); + + case 3: + case 'end': + return _context6.stop(); + } + } + }, findNext, this); + }) + }, { + key: 'findPrev', + value: regeneratorRuntime.mark(function findPrev() { + var _args7 = arguments; + return regeneratorRuntime.wrap(function findPrev$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + return _context7.delegateYield(this.flush(), 't0', 1); + + case 1: + return _context7.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'findPrev', this).apply(this, _args7), 't1', 2); + + case 2: + return _context7.abrupt('return', _context7.t1); + + case 3: + case 'end': + return _context7.stop(); + } + } + }, findPrev, this); + }) + }, { + key: 'iterate', + value: regeneratorRuntime.mark(function iterate() { + var _args8 = arguments; + return regeneratorRuntime.wrap(function iterate$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + return _context8.delegateYield(this.flush(), 't0', 1); + + case 1: + return _context8.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'iterate', this).apply(this, _args8), 't1', 2); + + case 2: + case 'end': + return _context8.stop(); + } + } + }, iterate, this); + }) + }, { + key: 'flush', + value: regeneratorRuntime.mark(function flush() { + var i, write; + return regeneratorRuntime.wrap(function flush$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + i = 0; + + case 1: + if (!(i < this.writeBuffer.length)) { + _context9.next = 9; + break; + } + + write = this.writeBuffer[i]; + + if (!(write.id[0] !== null)) { + _context9.next = 6; + break; + } + + return _context9.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'put', this).call(this, write), 't0', 5); + + case 5: + this.writeBuffer[i] = { + id: [null, null] + }; + + case 6: + i++; + _context9.next = 1; + break; + + case 9: + case 'end': + return _context9.stop(); + } + } + }, flush, this); + }) + }]); + + return SmallLookupBuffer; + }(Store); + + return SmallLookupBuffer; + } + Y.utils.createSmallLookupBuffer = createSmallLookupBuffer; +}; + +},{}],9:[function(require,module,exports){ +/* @flow */ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +require('./Connector.js')(Y); +require('./Database.js')(Y); +require('./Transaction.js')(Y); +require('./Struct.js')(Y); +require('./Utils.js')(Y); +require('./Connectors/Test.js')(Y); + +var requiringModules = {}; + +module.exports = Y; +Y.requiringModules = requiringModules; + +Y.extend = function (name, value) { + if (value instanceof Y.utils.CustomType) { + Y[name] = value.parseArguments; + } else { + Y[name] = value; + } + if (requiringModules[name] != null) { + requiringModules[name].resolve(); + delete requiringModules[name]; + } +}; + +Y.requestModules = requestModules; +function requestModules(modules) { + // determine if this module was compiled for es5 or es6 (y.js vs. y.es6) + // if Insert.execute is a Function, then it isnt a generator.. + // then load the es5(.js) files.. + var extention = typeof regeneratorRuntime !== 'undefined' ? '.js' : '.es6'; + var promises = []; + for (var i = 0; i < modules.length; i++) { + var module = modules[i].split('(')[0]; + var modulename = 'y-' + module.toLowerCase(); + if (Y[module] == null) { + if (requiringModules[module] == null) { + // module does not exist + if (typeof window !== 'undefined' && window.Y !== 'undefined') { + var imported; + + (function () { + imported = document.createElement('script'); + + imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention; + document.head.appendChild(imported); + + var requireModule = {}; + requiringModules[module] = requireModule; + requireModule.promise = new Promise(function (resolve) { + requireModule.resolve = resolve; + }); + promises.push(requireModule.promise); + })(); + } else { + require(modulename)(Y); + } + } else { + promises.push(requiringModules[modules[i]].promise); + } + } + } + return Promise.all(promises); +} + +/* :: +type MemoryOptions = { + name: 'memory' +} +type IndexedDBOptions = { + name: 'indexeddb', + namespace: string +} +type DbOptions = MemoryOptions | IndexedDBOptions + +type WebRTCOptions = { + name: 'webrtc', + room: string +} +type WebsocketsClientOptions = { + name: 'websockets-client', + room: string +} +type ConnectionOptions = WebRTCOptions | WebsocketsClientOptions + +type YOptions = { + connector: ConnectionOptions, + db: DbOptions, + types: Array, + sourceDir: string, + share: {[key: string]: TypeName} +} +*/ + +function Y(opts /* :YOptions */) /* :Promise */{ + opts.types = opts.types != null ? opts.types : []; + var modules = [opts.db.name, opts.connector.name].concat(opts.types); + for (var name in opts.share) { + modules.push(opts.share[name]); + } + Y.sourceDir = opts.sourceDir; + return Y.requestModules(modules).then(function () { + return new Promise(function (resolve, reject) { + if (opts == null) reject('An options object is expected! ');else if (opts.connector == null) reject('You must specify a connector! (missing connector property)');else if (opts.connector.name == null) reject('You must specify connector name! (missing connector.name property)');else if (opts.db == null) reject('You must specify a database! (missing db property)');else if (opts.connector.name == null) reject('You must specify db name! (missing db.name property)');else if (opts.share == null) reject('You must specify a set of shared types!');else { + var yconfig = new YConfig(opts); + yconfig.db.whenUserIdSet(function () { + yconfig.init(function () { + resolve(yconfig); + }); + }); + } + }); + }); +} + +var YConfig = function () { + /* :: + db: Y.AbstractDatabase; + connector: Y.AbstractConnector; + share: {[key: string]: any}; + options: Object; + */ + + function YConfig(opts, callback) { + _classCallCheck(this, YConfig); + + this.options = opts; + this.db = new Y[opts.db.name](this, opts.db); + this.connector = new Y[opts.connector.name](this, opts.connector); + } + + _createClass(YConfig, [{ + key: 'init', + value: function init(callback) { + var opts = this.options; + var share = {}; + this.share = share; + this.db.requestTransaction(regeneratorRuntime.mark(function requestTransaction() { + var propertyname, typeConstructor, typeName, args, type, typedef, id; + return regeneratorRuntime.wrap(function requestTransaction$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.t0 = regeneratorRuntime.keys(opts.share); + + case 1: + if ((_context.t1 = _context.t0()).done) { + _context.next = 21; + break; + } + + propertyname = _context.t1.value; + typeConstructor = opts.share[propertyname].split('('); + typeName = typeConstructor.splice(0, 1); + args = []; + + if (!(typeConstructor.length === 1)) { + _context.next = 14; + break; + } + + _context.prev = 7; + + args = JSON.parse('[' + typeConstructor[0].split(')')[0] + ']'); + _context.next = 14; + break; + + case 11: + _context.prev = 11; + _context.t2 = _context['catch'](7); + throw new Error('Was not able to parse type definition! (share.' + propertyname + ')'); + + case 14: + type = Y[typeName]; + typedef = type.typeDefinition; + id = ['_', typedef.struct + '_' + typeName + '_' + propertyname + '_' + typeConstructor]; + return _context.delegateYield(this.createType(type.apply(typedef, args), id), 't3', 18); + + case 18: + share[propertyname] = _context.t3; + _context.next = 1; + break; + + case 21: + this.store.whenTransactionsFinished().then(callback); + + case 22: + case 'end': + return _context.stop(); + } + } + }, requestTransaction, this, [[7, 11]]); + })); + } + }, { + key: 'isConnected', + value: function isConnected() { + return this.connector.isSynced; + } + }, { + key: 'disconnect', + value: function disconnect() { + return this.connector.disconnect(); + } + }, { + key: 'reconnect', + value: function reconnect() { + return this.connector.reconnect(); + } + }, { + key: 'destroy', + value: function destroy() { + if (this.connector.destroy != null) { + this.connector.destroy(); + } else { + this.connector.disconnect(); + } + var self = this; + this.db.requestTransaction(regeneratorRuntime.mark(function _callee() { + return regeneratorRuntime.wrap(function _callee$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + return _context2.delegateYield(self.db.destroy(), 't0', 1); + + case 1: + self.connector = null; + self.db = null; + + case 3: + case 'end': + return _context2.stop(); + } + } + }, _callee, this); + })); + } + }]); + + return YConfig; +}(); + +if (typeof window !== 'undefined') { + window.Y = Y; +} + +},{"./Connector.js":3,"./Connectors/Test.js":4,"./Database.js":5,"./Struct.js":6,"./Transaction.js":7,"./Utils.js":8}]},{},[2,9]) + + //# sourceMappingURL=y.js.map diff --git a/y.js.map b/y.js.map index 39cf9b57..bdb9af70 100644 --- a/y.js.map +++ b/y.js.map @@ -1 +1 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/process/browser.js","y.js","node_modules/regenerator/node_modules/regenerator/runtime.js","src/Connector.js","src/Connectors/Test.js","src/Database.js","src/Struct.js","src/Transaction.js","src/Utils.js","src/y.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length",1,"module","cleanUpNextTick","draining","currentQueue","queue","concat","queueIndex","drainQueue","timeout","setTimeout","len","run","clearTimeout","Item","fun","array","this","noop","process","nextTick","args","Array","arguments","push","prototype","apply","title","browser","env","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","binding","name","cwd","chdir","dir","umask",2,"global","_typeof","Symbol","iterator","obj","constructor","wrap","innerFn","outerFn","self","tryLocsList","generator","Object","create","Generator","context","Context","_invoke","makeInvokeMethod","tryCatch","fn","arg","type","err","GeneratorFunction","GeneratorFunctionPrototype","defineIteratorMethods","forEach","method","AwaitArgument","AsyncIterator","invoke","resolve","reject","record","result","value","Promise","then","unwrapped","enqueue","callInvokeWithMethodAndArg","previousPromise","domain","bind","state","GenStateSuspendedStart","GenStateExecuting","GenStateCompleted","doneResult","delegate","undefined","returnMethod","info","done","GenStateSuspendedYield","resultName","next","nextLoc","sent","dispatchException","abrupt","ContinueSentinel","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","values","iterable","iteratorMethod","iteratorSymbol","isNaN","hasOwn","hasOwnProperty","$Symbol","toStringTagSymbol","toStringTag","inModule","runtime","regeneratorRuntime","Gp","displayName","isGeneratorFunction","genFun","ctor","mark","setPrototypeOf","__proto__","awrap","async","iter","toString","keys","object","key","reverse","pop","skipTempReset","prev","charAt","slice","stop","rootEntry","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","catch","thrown","delegateYield","window","_process",3,"_classCallCheck","instance","Constructor","TypeError","_createClass","defineProperties","target","props","descriptor","enumerable","configurable","writable","defineProperty","protoProps","staticProps","Y","AbstractConnector","y","opts","role","db","forwardAppliedOperations","connections","isSynced","userEventListeners","whenSyncedListeners","currentSyncTarget","syncingClients","forwardToSyncingClients","debug","broadcastedHB","syncStep2","broadcastOpBuffer","protocolVersion","stopGarbageCollector","userId","setUserId","user","findNextSyncTarget","filter","cli","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_step","_iterator","action","_iteratorNormalCompletion2","_didIteratorError2","_iteratorError2","_step2","_iterator2","syncUser","uid","conn","requestTransaction","_callee","stateSet","deleteSet","_context","getStateSet","t0","getDeleteSet","t1","send","_callee2","_iteratorNormalCompletion3","_didIteratorError3","_iteratorError3","_iterator3","_step3","_context2","garbageCollectAfterSync","message","console","log","ops","broadcastOperations","broadcast","map","op","Struct","struct","encode","transactionInProgress","whenTransactionsFinished","sender","_this","JSON","parse","stringify","error","m","_callee3","currentStateSet","ds","_context3","applyDeleteSet","t2","getOperations","t3","os","_setSyncedWith","broadcastHB","defer","promise","_callee5","_context5","store","_callee4","_context4","broadcastOps","_iteratorNormalCompletion4","_didIteratorError4","_iteratorError4","_step4","_iterator4","client","delops","parseArray","node","_iteratorNormalCompletion5","_didIteratorError5","_iteratorError5","_step5","_iterator5","children","getAttribute","parseObject","json","attrName","attrs","int","parseInt","msg","encodeObject","c","encodeArray","setAttribute","_iteratorNormalCompletion6","_didIteratorError6","_iteratorError6","_step6","_iterator6","xmlns",4,"_possibleConstructorReturn","ReferenceError","_inherits","subClass","superClass","_get","get","property","receiver","Function","desc","getOwnPropertyDescriptor","parent","getPrototypeOf","getter","globalRoom","users","buffers","removeUser","userLeft","addUser","connector","uname","userJoined","ps","all","flushOne","bufs","buff","getRandom","shift","receiveMessage","flushAll","nextFlush","utils","userIdCounter","Test","_Y$AbstractConnector","options","syncingClientDuration","buffer","isDisconnected",5,"AbstractDatabase","garbageCollect","gc1","gc2","isConnected","warn","oid","garbageCollectOperation","gcTimeout","gcInterval","userIdPromise","listenersById","listenersByIdExecuteNow","listenersByIdRequestPending","initializedTypes","waitingTransactions","transactionIsFlushed","YConcurrency_TestingMode","executeOrder","gcTimeoutÅ›","id","check","command","join","replace","ungc","getOperation","gc","setOperation","addToGarbageCollector","left","deleted","content","getInsertionCleanStart","queueGarbageCollector","compareIds","destroy","clearInterval","_destroy","inProgress","getState","opClock","clock","numberOfIds","required","requiredOps","requires","whenOperationsExist","ids","listener","missing","sid","exeNow","ls","_context6","tryExecute","getInsertion","t4","defined","overlapSize","isGarbageCollected","_context7","addToDebug","Delete","execute","splice","getLastId","origin","addOperation","operationAdded","tryCombineWithLeft","transaction","opLen","_i","parentIsDeleted","_o","startId","_i2","opIsDeleted","delop","_context8","updateState","isDeleted","deleteList","copyObject","_changed","transactionsFinished","_context9","flush","makeGen","callImmediately","transact","getNextRequest",6,"deleteOperation","Insert","right","parentSub","opContent","getDistanceToOrigin","d","matchesId","tryToRemergeLater","distanceToOrigin","start","oOriginDistance","getInsertionCleanEnd","originOf","t5","t6","t7","t8","t10","t11","t12","t13","t15","t16","removeFromGarbageCollector","end","t22","List","ref","pos","res","operation","Map","getType",7,"TransactionInterface","typeDefinition","initType","createType","typedefinition","structname","getNextOpId","appendAdditionalInfo","applyCreatedOperations","delLength","markDeleted","targetId","preventCallType","callType","targetLength","findWithUpperBound","markGarbageCollected","newlen","put","findPrev","findNext","diff","_next","iterate","parentDeleted","deps","dep","neworigin","neworigin_","originsIn","setParent","_context10","t9","t17","_id","t19","removeOperation","checkDeleteStoreForState","_context11","Math","max","oLength","_context12","setState","deletions","dv","del","counter","oLen","_context14","Number","MAX_VALUE","_context13","min","_context15","_context17","_context16","_context18","_context19","_context20","_context21","ins","_context22","getInsertionCleanStartEnd","_context23","leftLid","_context24","insLid","_context25","comp","_context26","find","split","_context27","val","_context28","ss","_context29","getStateVector","stateVector","_context31","_context30","_context33","_context32","startSS","endSV","endState","startPos","firstMissing","_context35","_callee6","missing_origins","newright","_context34","_context36","Transaction",8,"smaller","b","id1","id2","createEmptyOpsArray","createSmallLookupBuffer","Store","SmallLookupBuffer","_Store","_this2","writeBuffer","readBuffer","noSuperCall","write","_delete","findWithLowerBound","_args4","_args5","_args6","_args7","_args8","EventListenerHandler","eventListeners","g","event","EventHandler","_EventListenerHandler","onevent","waiting","awaiting","w","_tryCallEvents","newLeft","j","CustomType","def","parseArguments","isTypeDefinition","v",9,"requestModules","modules","extention","promises","modulename","toLowerCase","requiringModules","imported","document","createElement","src","sourceDir","head","appendChild","requireModule","types","share","yconfig","YConfig","whenUserIdSet","init","extend","callback","propertyname","typeConstructor","typeName","typedef","disconnect","reconnect","./Connector.js","./Connectors/Test.js","./Database.js","./Struct.js","./Transaction.js","./Utils.js"],"mappings":"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","file":"y.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n setTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n setTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],2:[function(require,module,exports){\n(function (process,global){\n\"use strict\";\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; };\n\n/**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * https://raw.github.com/facebook/regenerator/master/LICENSE file. An\n * additional grant of patent rights can be found in the PATENTS file in\n * the same directory.\n */\n\n!function (global) {\n \"use strict\";\n\n var hasOwn = Object.prototype.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n var inModule = (typeof module === \"undefined\" ? \"undefined\" : _typeof(module)) === \"object\";\n var runtime = global.regeneratorRuntime;\n if (runtime) {\n if (inModule) {\n // If regeneratorRuntime is defined globally and we're in a module,\n // make the exports object identical to regeneratorRuntime.\n module.exports = runtime;\n }\n // Don't bother evaluating the rest of this file if the runtime was\n // already defined globally.\n return;\n }\n\n // Define the runtime globally (as expected by generated code) as either\n // module.exports (if we're in a module) or a new, empty object.\n runtime = global.regeneratorRuntime = inModule ? module.exports : {};\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided, then outerFn.prototype instanceof Generator.\n var generator = Object.create((outerFn || Generator).prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n runtime.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype;\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = \"GeneratorFunction\";\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function (method) {\n prototype[method] = function (arg) {\n return this._invoke(method, arg);\n };\n });\n }\n\n runtime.isGeneratorFunction = function (genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\" : false;\n };\n\n runtime.mark = function (genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n if (!(toStringTagSymbol in genFun)) {\n genFun[toStringTagSymbol] = \"GeneratorFunction\";\n }\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `value instanceof AwaitArgument` to determine if the yielded value is\n // meant to be awaited. Some may consider the name of this method too\n // cutesy, but they are curmudgeons.\n runtime.awrap = function (arg) {\n return new AwaitArgument(arg);\n };\n\n function AwaitArgument(arg) {\n this.arg = arg;\n }\n\n function AsyncIterator(generator) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value instanceof AwaitArgument) {\n return Promise.resolve(value.arg).then(function (value) {\n invoke(\"next\", value, resolve, reject);\n }, function (err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return Promise.resolve(value).then(function (unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration. If the Promise is rejected, however, the\n // result for this iteration will be rejected with the same\n // reason. Note that rejections of yielded Promises are not\n // thrown back into the generator function, as is the case\n // when an awaited Promise is rejected. This difference in\n // behavior between yield and await is important, because it\n // allows the consumer to decide what to do with the yielded\n // rejection (swallow it and continue, manually .throw it back\n // into the generator, abandon iteration, whatever). With\n // await, by contrast, there is no opportunity to examine the\n // rejection reason outside the generator function, so the\n // only option is to throw it from the await expression, and\n // let the generator function handle the exception.\n result.value = unwrapped;\n resolve(result);\n }, reject);\n }\n }\n\n if ((typeof process === \"undefined\" ? \"undefined\" : _typeof(process)) === \"object\" && process.domain) {\n invoke = process.domain.bind(invoke);\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new Promise(function (resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n runtime.async = function (innerFn, outerFn, self, tryLocsList) {\n var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList));\n\n return runtime.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function (result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n if (method === \"return\" || method === \"throw\" && delegate.iterator[method] === undefined) {\n // A return or throw (when the delegate iterator has no throw\n // method) always terminates the yield* loop.\n context.delegate = null;\n\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n var returnMethod = delegate.iterator[\"return\"];\n if (returnMethod) {\n var record = tryCatch(returnMethod, delegate.iterator, arg);\n if (record.type === \"throw\") {\n // If the return method threw an exception, let that\n // exception prevail over the original return or throw.\n method = \"throw\";\n arg = record.arg;\n continue;\n }\n }\n\n if (method === \"return\") {\n // Continue with the outer return, now that the delegate\n // iterator has been terminated.\n continue;\n }\n }\n\n var record = tryCatch(delegate.iterator[method], delegate.iterator, arg);\n\n if (record.type === \"throw\") {\n context.delegate = null;\n\n // Like returning generator.throw(uncaught), but without the\n // overhead of an extra function call.\n method = \"throw\";\n arg = record.arg;\n continue;\n }\n\n // Delegate generator ran and handled its own exceptions so\n // regardless of what the method was, we continue as if it is\n // \"next\" with an undefined arg.\n method = \"next\";\n arg = undefined;\n\n var info = record.arg;\n if (info.done) {\n context[delegate.resultName] = info.value;\n context.next = delegate.nextLoc;\n } else {\n state = GenStateSuspendedYield;\n return info;\n }\n\n context.delegate = null;\n }\n\n if (method === \"next\") {\n if (state === GenStateSuspendedYield) {\n context.sent = arg;\n } else {\n context.sent = undefined;\n }\n } else if (method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw arg;\n }\n\n if (context.dispatchException(arg)) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n method = \"next\";\n arg = undefined;\n }\n } else if (method === \"return\") {\n context.abrupt(\"return\", arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done ? GenStateCompleted : GenStateSuspendedYield;\n\n var info = {\n value: record.arg,\n done: context.done\n };\n\n if (record.arg === ContinueSentinel) {\n if (context.delegate && method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n arg = undefined;\n }\n } else {\n return info;\n }\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(arg) call above.\n method = \"throw\";\n arg = record.arg;\n }\n }\n };\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n Gp[iteratorSymbol] = function () {\n return this;\n };\n\n Gp[toStringTagSymbol] = \"Generator\";\n\n Gp.toString = function () {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n runtime.keys = function (object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1,\n next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n runtime.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function reset(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n this.sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function stop() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function dispatchException(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n return !!caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function abrupt(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev && hasOwn.call(entry, \"finallyLoc\") && this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry && (type === \"break\" || type === \"continue\") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.next = finallyEntry.finallyLoc;\n } else {\n this.complete(record);\n }\n\n return ContinueSentinel;\n },\n\n complete: function complete(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" || record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = record.arg;\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n },\n\n finish: function finish(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function _catch(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function delegateYield(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n return ContinueSentinel;\n }\n };\n}(\n// Among the various tricks for obtaining a reference to the global\n// object, this seems to be the most reliable technique that does not\n// use indirect eval (which violates Content Security Policy).\n(typeof global === \"undefined\" ? \"undefined\" : _typeof(global)) === \"object\" ? global : (typeof window === \"undefined\" ? \"undefined\" : _typeof(window)) === \"object\" ? window : (typeof self === \"undefined\" ? \"undefined\" : _typeof(self)) === \"object\" ? self : undefined);\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n\n},{\"_process\":1}],3:[function(require,module,exports){\n/* @flow */\n'use strict';\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nmodule.exports = function (Y /* :any */) {\n var AbstractConnector = function () {\n /* ::\n y: YConfig;\n role: SyncRole;\n connections: Object;\n isSynced: boolean;\n userEventListeners: Array;\n whenSyncedListeners: Array;\n currentSyncTarget: ?UserId;\n syncingClients: Array;\n forwardToSyncingClients: boolean;\n debug: boolean;\n broadcastedHB: boolean;\n syncStep2: Promise;\n userId: UserId;\n send: Function;\n broadcast: Function;\n broadcastOpBuffer: Array;\n protocolVersion: number;\n */\n /*\n opts contains the following information:\n role : String Role of this client (\"master\" or \"slave\")\n userId : String Uniquely defines the user.\n debug: Boolean Whether to print debug messages (optional)\n */\n\n function AbstractConnector(y, opts) {\n _classCallCheck(this, AbstractConnector);\n\n this.y = y;\n if (opts == null) {\n opts = {};\n }\n if (opts.role == null || opts.role === 'master') {\n this.role = 'master';\n } else if (opts.role === 'slave') {\n this.role = 'slave';\n } else {\n throw new Error(\"Role must be either 'master' or 'slave'!\");\n }\n this.y.db.forwardAppliedOperations = opts.forwardAppliedOperations || false;\n this.role = opts.role;\n this.connections = {};\n this.isSynced = false;\n this.userEventListeners = [];\n this.whenSyncedListeners = [];\n this.currentSyncTarget = null;\n this.syncingClients = [];\n this.forwardToSyncingClients = opts.forwardToSyncingClients !== false;\n this.debug = opts.debug === true;\n this.broadcastedHB = false;\n this.syncStep2 = Promise.resolve();\n this.broadcastOpBuffer = [];\n this.protocolVersion = 11;\n }\n\n _createClass(AbstractConnector, [{\n key: 'reconnect',\n value: function reconnect() {}\n }, {\n key: 'disconnect',\n value: function disconnect() {\n this.connections = {};\n this.isSynced = false;\n this.currentSyncTarget = null;\n this.broadcastedHB = false;\n this.syncingClients = [];\n this.whenSyncedListeners = [];\n return this.y.db.stopGarbageCollector();\n }\n }, {\n key: 'setUserId',\n value: function setUserId(userId) {\n if (this.userId == null) {\n this.userId = userId;\n return this.y.db.setUserId(userId);\n } else {\n return null;\n }\n }\n }, {\n key: 'onUserEvent',\n value: function onUserEvent(f) {\n this.userEventListeners.push(f);\n }\n }, {\n key: 'userLeft',\n value: function userLeft(user) {\n if (this.connections[user] != null) {\n delete this.connections[user];\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null;\n this.findNextSyncTarget();\n }\n this.syncingClients = this.syncingClients.filter(function (cli) {\n return cli !== user;\n });\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = this.userEventListeners[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var f = _step.value;\n\n f({\n action: 'userLeft',\n user: user\n });\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n }\n }\n }, {\n key: 'userJoined',\n value: function userJoined(user, role) {\n if (role == null) {\n throw new Error('You must specify the role of the joined user!');\n }\n if (this.connections[user] != null) {\n throw new Error('This user already joined!');\n }\n this.connections[user] = {\n isSynced: false,\n role: role\n };\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = this.userEventListeners[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var f = _step2.value;\n\n f({\n action: 'userJoined',\n user: user,\n role: role\n });\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n if (this.currentSyncTarget == null) {\n this.findNextSyncTarget();\n }\n }\n // Execute a function _when_ we are connected.\n // If not connected, wait until connected\n\n }, {\n key: 'whenSynced',\n value: function whenSynced(f) {\n if (this.isSynced) {\n f();\n } else {\n this.whenSyncedListeners.push(f);\n }\n }\n /*\n returns false, if there is no sync target\n true otherwise\n */\n\n }, {\n key: 'findNextSyncTarget',\n value: function findNextSyncTarget() {\n if (this.currentSyncTarget != null || this.isSynced) {\n return; // \"The current sync has not finished!\"\n }\n\n var syncUser = null;\n for (var uid in this.connections) {\n if (!this.connections[uid].isSynced) {\n syncUser = uid;\n break;\n }\n }\n var conn = this;\n if (syncUser != null) {\n this.currentSyncTarget = syncUser;\n this.y.db.requestTransaction(regeneratorRuntime.mark(function _callee() {\n var stateSet, deleteSet;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n return _context.delegateYield(this.getStateSet(), 't0', 1);\n\n case 1:\n stateSet = _context.t0;\n return _context.delegateYield(this.getDeleteSet(), 't1', 3);\n\n case 3:\n deleteSet = _context.t1;\n\n conn.send(syncUser, {\n type: 'sync step 1',\n stateSet: stateSet,\n deleteSet: deleteSet,\n protocolVersion: conn.protocolVersion\n });\n\n case 5:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n } else {\n this.y.db.requestTransaction(regeneratorRuntime.mark(function _callee2() {\n var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, f;\n\n return regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n // it is crucial that isSynced is set at the time garbageCollectAfterSync is called\n conn.isSynced = true;\n return _context2.delegateYield(this.garbageCollectAfterSync(), 't0', 2);\n\n case 2:\n // call whensynced listeners\n _iteratorNormalCompletion3 = true;\n _didIteratorError3 = false;\n _iteratorError3 = undefined;\n _context2.prev = 5;\n for (_iterator3 = conn.whenSyncedListeners[Symbol.iterator](); !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n f = _step3.value;\n\n f();\n }\n _context2.next = 13;\n break;\n\n case 9:\n _context2.prev = 9;\n _context2.t1 = _context2['catch'](5);\n _didIteratorError3 = true;\n _iteratorError3 = _context2.t1;\n\n case 13:\n _context2.prev = 13;\n _context2.prev = 14;\n\n if (!_iteratorNormalCompletion3 && _iterator3.return) {\n _iterator3.return();\n }\n\n case 16:\n _context2.prev = 16;\n\n if (!_didIteratorError3) {\n _context2.next = 19;\n break;\n }\n\n throw _iteratorError3;\n\n case 19:\n return _context2.finish(16);\n\n case 20:\n return _context2.finish(13);\n\n case 21:\n conn.whenSyncedListeners = [];\n\n case 22:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this, [[5, 9, 13, 21], [14,, 16, 20]]);\n }));\n }\n }\n }, {\n key: 'send',\n value: function send(uid, message) {\n if (this.debug) {\n console.log('send ' + this.userId + ' -> ' + uid + ': ' + message.type, message); // eslint-disable-line\n }\n }\n /*\n Buffer operations, and broadcast them when ready.\n */\n\n }, {\n key: 'broadcastOps',\n value: function broadcastOps(ops) {\n ops = ops.map(function (op) {\n return Y.Struct[op.struct].encode(op);\n });\n var self = this;\n function broadcastOperations() {\n if (self.broadcastOpBuffer.length > 0) {\n self.broadcast({\n type: 'update',\n ops: self.broadcastOpBuffer\n });\n self.broadcastOpBuffer = [];\n }\n }\n if (this.broadcastOpBuffer.length === 0) {\n this.broadcastOpBuffer = ops;\n if (this.y.db.transactionInProgress) {\n this.y.db.whenTransactionsFinished().then(broadcastOperations);\n } else {\n setTimeout(broadcastOperations, 0);\n }\n } else {\n this.broadcastOpBuffer = this.broadcastOpBuffer.concat(ops);\n }\n }\n /*\n You received a raw message, and you know that it is intended for Yjs. Then call this function.\n */\n\n }, {\n key: 'receiveMessage',\n value: function receiveMessage(sender /* :UserId */, message /* :Message */) {\n var _this = this;\n\n if (sender === this.userId) {\n return;\n }\n if (this.debug) {\n console.log('receive ' + sender + ' -> ' + this.userId + ': ' + message.type, JSON.parse(JSON.stringify(message))); // eslint-disable-line\n }\n if (message.protocolVersion != null && message.protocolVersion !== this.protocolVersion) {\n console.error('You tried to sync with a yjs instance that has a different protocol version\\n (You: ' + this.protocolVersion + ', Client: ' + message.protocolVersion + ').\\n The sync was stopped. You need to upgrade your dependencies (especially Yjs & the Connector)!\\n ');\n this.send(sender, {\n type: 'sync stop',\n protocolVersion: this.protocolVersion\n });\n return;\n }\n if (message.type === 'sync step 1') {\n (function () {\n var conn = _this;\n var m = message;\n _this.y.db.requestTransaction(regeneratorRuntime.mark(function _callee3() {\n var currentStateSet, ds, ops;\n return regeneratorRuntime.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n return _context3.delegateYield(this.getStateSet(), 't0', 1);\n\n case 1:\n currentStateSet = _context3.t0;\n return _context3.delegateYield(this.applyDeleteSet(m.deleteSet), 't1', 3);\n\n case 3:\n return _context3.delegateYield(this.getDeleteSet(), 't2', 4);\n\n case 4:\n ds = _context3.t2;\n return _context3.delegateYield(this.getOperations(m.stateSet), 't3', 6);\n\n case 6:\n ops = _context3.t3;\n\n conn.send(sender, {\n type: 'sync step 2',\n os: ops,\n stateSet: currentStateSet,\n deleteSet: ds,\n protocolVersion: this.protocolVersion\n });\n if (this.forwardToSyncingClients) {\n conn.syncingClients.push(sender);\n setTimeout(function () {\n conn.syncingClients = conn.syncingClients.filter(function (cli) {\n return cli !== sender;\n });\n conn.send(sender, {\n type: 'sync done'\n });\n }, 5000); // TODO: conn.syncingClientDuration)\n } else {\n conn.send(sender, {\n type: 'sync done'\n });\n }\n conn._setSyncedWith(sender);\n\n case 10:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n })();\n } else if (message.type === 'sync step 2') {\n var broadcastHB;\n var db;\n var defer;\n\n (function () {\n var conn = _this;\n broadcastHB = !_this.broadcastedHB;\n\n _this.broadcastedHB = true;\n db = _this.y.db;\n defer = {};\n\n defer.promise = new Promise(function (resolve) {\n defer.resolve = resolve;\n });\n _this.syncStep2 = defer.promise;\n var m /* :MessageSyncStep2 */ = message;\n db.requestTransaction(regeneratorRuntime.mark(function _callee5() {\n return regeneratorRuntime.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n return _context5.delegateYield(this.applyDeleteSet(m.deleteSet), 't0', 1);\n\n case 1:\n this.store.apply(m.os);\n db.requestTransaction(regeneratorRuntime.mark(function _callee4() {\n var ops;\n return regeneratorRuntime.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n return _context4.delegateYield(this.getOperations(m.stateSet), 't0', 1);\n\n case 1:\n ops = _context4.t0;\n\n if (ops.length > 0) {\n if (!broadcastHB) {\n // TODO: consider to broadcast here..\n conn.send(sender, {\n type: 'update',\n ops: ops\n });\n } else {\n // broadcast only once!\n conn.broadcastOps(ops);\n }\n }\n defer.resolve();\n\n case 4:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n case 3:\n case 'end':\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n })();\n } else if (message.type === 'sync done') {\n var self = this;\n this.syncStep2.then(function () {\n self._setSyncedWith(sender);\n });\n } else if (message.type === 'update') {\n if (this.forwardToSyncingClients) {\n var _iteratorNormalCompletion4 = true;\n var _didIteratorError4 = false;\n var _iteratorError4 = undefined;\n\n try {\n for (var _iterator4 = this.syncingClients[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n var client = _step4.value;\n\n this.send(client, message);\n }\n } catch (err) {\n _didIteratorError4 = true;\n _iteratorError4 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion4 && _iterator4.return) {\n _iterator4.return();\n }\n } finally {\n if (_didIteratorError4) {\n throw _iteratorError4;\n }\n }\n }\n }\n if (this.y.db.forwardAppliedOperations) {\n var delops = message.ops.filter(function (o) {\n return o.struct === 'Delete';\n });\n if (delops.length > 0) {\n this.broadcastOps(delops);\n }\n }\n this.y.db.apply(message.ops);\n }\n }\n }, {\n key: '_setSyncedWith',\n value: function _setSyncedWith(user) {\n var conn = this.connections[user];\n if (conn != null) {\n conn.isSynced = true;\n }\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null;\n this.findNextSyncTarget();\n }\n }\n /*\n Currently, the HB encodes operations as JSON. For the moment I want to keep it\n that way. Maybe we support encoding in the HB as XML in the future, but for now I don't want\n too much overhead. Y is very likely to get changed a lot in the future\n Because we don't want to encode JSON as string (with character escaping, wich makes it pretty much unreadable)\n we encode the JSON as XML.\n When the HB support encoding as XML, the format should look pretty much like this.\n does not support primitive values as array elements\n expects an ltx (less than xml) object\n */\n\n }, {\n key: 'parseMessageFromXml',\n value: function parseMessageFromXml(m /* :any */) {\n function parseArray(node) {\n var _iteratorNormalCompletion5 = true;\n var _didIteratorError5 = false;\n var _iteratorError5 = undefined;\n\n try {\n for (var _iterator5 = node.children[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n var n = _step5.value;\n\n if (n.getAttribute('isArray') === 'true') {\n return parseArray(n);\n } else {\n return parseObject(n);\n }\n }\n } catch (err) {\n _didIteratorError5 = true;\n _iteratorError5 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion5 && _iterator5.return) {\n _iterator5.return();\n }\n } finally {\n if (_didIteratorError5) {\n throw _iteratorError5;\n }\n }\n }\n }\n function parseObject(node /* :any */) {\n var json = {};\n for (var attrName in node.attrs) {\n var value = node.attrs[attrName];\n var int = parseInt(value, 10);\n if (isNaN(int) || '' + int !== value) {\n json[attrName] = value;\n } else {\n json[attrName] = int;\n }\n }\n for (var n /* :any */ in node.children) {\n var name = n.name;\n if (n.getAttribute('isArray') === 'true') {\n json[name] = parseArray(n);\n } else {\n json[name] = parseObject(n);\n }\n }\n return json;\n }\n parseObject(m);\n }\n /*\n encode message in xml\n we use string because Strophe only accepts an \"xml-string\"..\n So {a:4,b:{c:5}} will look like\n \n \n \n m - ltx element\n json - Object\n */\n\n }, {\n key: 'encodeMessageToXml',\n value: function encodeMessageToXml(msg, obj) {\n // attributes is optional\n function encodeObject(m, json) {\n for (var name in json) {\n var value = json[name];\n if (name == null) {\n // nop\n } else if (value.constructor === Object) {\n encodeObject(m.c(name), value);\n } else if (value.constructor === Array) {\n encodeArray(m.c(name), value);\n } else {\n m.setAttribute(name, value);\n }\n }\n }\n function encodeArray(m, array) {\n m.setAttribute('isArray', 'true');\n var _iteratorNormalCompletion6 = true;\n var _didIteratorError6 = false;\n var _iteratorError6 = undefined;\n\n try {\n for (var _iterator6 = array[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {\n var e = _step6.value;\n\n if (e.constructor === Object) {\n encodeObject(m.c('array-element'), e);\n } else {\n encodeArray(m.c('array-element'), e);\n }\n }\n } catch (err) {\n _didIteratorError6 = true;\n _iteratorError6 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion6 && _iterator6.return) {\n _iterator6.return();\n }\n } finally {\n if (_didIteratorError6) {\n throw _iteratorError6;\n }\n }\n }\n }\n if (obj.constructor === Object) {\n encodeObject(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj);\n } else if (obj.constructor === Array) {\n encodeArray(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj);\n } else {\n throw new Error(\"I can't encode this json!\");\n }\n }\n }]);\n\n return AbstractConnector;\n }();\n\n Y.AbstractConnector = AbstractConnector;\n};\n\n},{}],4:[function(require,module,exports){\n/* global getRandom, async */\n'use strict';\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nmodule.exports = function (Y) {\n var globalRoom = {\n users: {},\n buffers: {}, // TODO: reimplement this idea. This does not cover all cases!! Here, you have a queue which is unrealistic (i.e. think about multiple incoming connections)\n removeUser: function removeUser(user) {\n for (var i in this.users) {\n this.users[i].userLeft(user);\n }\n delete this.users[user];\n delete this.buffers[user];\n },\n addUser: function addUser(connector) {\n this.users[connector.userId] = connector;\n this.buffers[connector.userId] = {};\n for (var uname in this.users) {\n if (uname !== connector.userId) {\n var u = this.users[uname];\n u.userJoined(connector.userId, 'master');\n connector.userJoined(u.userId, 'master');\n }\n }\n },\n whenTransactionsFinished: function whenTransactionsFinished() {\n var ps = [];\n for (var name in this.users) {\n ps.push(this.users[name].y.db.whenTransactionsFinished());\n }\n return Promise.all(ps);\n },\n flushOne: function flushOne() {\n var bufs = [];\n for (var receiver in globalRoom.buffers) {\n var buff = globalRoom.buffers[receiver];\n var push = false;\n for (var sender in buff) {\n if (buff[sender].length > 0) {\n push = true;\n break;\n }\n }\n if (push) {\n bufs.push(receiver);\n }\n }\n if (bufs.length > 0) {\n var userId = getRandom(bufs);\n var buff = globalRoom.buffers[userId];\n var sender = getRandom(Object.keys(buff));\n var m = buff[sender].shift();\n if (buff[sender].length === 0) {\n delete buff[sender];\n }\n var user = globalRoom.users[userId];\n user.receiveMessage(m[0], m[1]);\n return user.y.db.whenTransactionsFinished();\n } else {\n return false;\n }\n },\n flushAll: function flushAll() {\n return new Promise(function (resolve) {\n // flushes may result in more created operations,\n // flush until there is nothing more to flush\n function nextFlush() {\n var c = globalRoom.flushOne();\n if (c) {\n while (c) {\n c = globalRoom.flushOne();\n }\n globalRoom.whenTransactionsFinished().then(nextFlush);\n } else {\n setTimeout(function () {\n var c = globalRoom.flushOne();\n if (c) {\n c.then(function () {\n globalRoom.whenTransactionsFinished().then(nextFlush);\n });\n } else {\n resolve();\n }\n }, 10);\n }\n }\n globalRoom.whenTransactionsFinished().then(nextFlush);\n });\n }\n };\n Y.utils.globalRoom = globalRoom;\n\n var userIdCounter = 0;\n\n var Test = function (_Y$AbstractConnector) {\n _inherits(Test, _Y$AbstractConnector);\n\n function Test(y, options) {\n _classCallCheck(this, Test);\n\n if (options === undefined) {\n throw new Error('Options must not be undefined!');\n }\n options.role = 'master';\n options.forwardToSyncingClients = false;\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Test).call(this, y, options));\n\n _this.setUserId(userIdCounter++ + '').then(function () {\n globalRoom.addUser(_this);\n });\n _this.globalRoom = globalRoom;\n _this.syncingClientDuration = 0;\n return _this;\n }\n\n _createClass(Test, [{\n key: 'receiveMessage',\n value: function receiveMessage(sender, m) {\n _get(Object.getPrototypeOf(Test.prototype), 'receiveMessage', this).call(this, sender, JSON.parse(JSON.stringify(m)));\n }\n }, {\n key: 'send',\n value: function send(userId, message) {\n var buffer = globalRoom.buffers[userId];\n if (buffer != null) {\n if (buffer[this.userId] == null) {\n buffer[this.userId] = [];\n }\n buffer[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])));\n }\n }\n }, {\n key: 'broadcast',\n value: function broadcast(message) {\n for (var key in globalRoom.buffers) {\n var buff = globalRoom.buffers[key];\n if (buff[this.userId] == null) {\n buff[this.userId] = [];\n }\n buff[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])));\n }\n }\n }, {\n key: 'isDisconnected',\n value: function isDisconnected() {\n return globalRoom.users[this.userId] == null;\n }\n }, {\n key: 'reconnect',\n value: function reconnect() {\n if (this.isDisconnected()) {\n globalRoom.addUser(this);\n _get(Object.getPrototypeOf(Test.prototype), 'reconnect', this).call(this);\n }\n return Y.utils.globalRoom.flushAll();\n }\n }, {\n key: 'disconnect',\n value: function disconnect() {\n if (!this.isDisconnected()) {\n globalRoom.removeUser(this.userId);\n _get(Object.getPrototypeOf(Test.prototype), 'disconnect', this).call(this);\n }\n return this.y.db.whenTransactionsFinished();\n }\n }, {\n key: 'flush',\n value: function flush() {\n var self = this;\n return async(regeneratorRuntime.mark(function _callee() {\n var buff, sender, m;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n buff = globalRoom.buffers[self.userId];\n\n while (Object.keys(buff).length > 0) {\n sender = getRandom(Object.keys(buff));\n m = buff[sender].shift();\n\n if (buff[sender].length === 0) {\n delete buff[sender];\n }\n this.receiveMessage(m[0], m[1]);\n }\n _context.next = 4;\n return self.whenTransactionsFinished();\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n }\n }]);\n\n return Test;\n }(Y.AbstractConnector);\n\n Y.Test = Test;\n};\n\n},{}],5:[function(require,module,exports){\n/* @flow */\n'use strict';\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nmodule.exports = function (Y /* :any */) {\n /*\n Partial definition of an OperationStore.\n TODO: name it Database, operation store only holds operations.\n A database definition must alse define the following methods:\n * logTable() (optional)\n - show relevant information information in a table\n * requestTransaction(makeGen)\n - request a transaction\n * destroy()\n - destroy the database\n */\n\n var AbstractDatabase = function () {\n /* ::\n y: YConfig;\n forwardAppliedOperations: boolean;\n listenersById: Object;\n listenersByIdExecuteNow: Array;\n listenersByIdRequestPending: boolean;\n initializedTypes: Object;\n whenUserIdSetListener: ?Function;\n waitingTransactions: Array;\n transactionInProgress: boolean;\n executeOrder: Array;\n gc1: Array;\n gc2: Array;\n gcTimeout: number;\n gcInterval: any;\n garbageCollect: Function;\n executeOrder: Array; // for debugging only\n userId: UserId;\n opClock: number;\n transactionsFinished: ?{promise: Promise, resolve: any};\n transact: (x: ?Generator) => any;\n */\n\n function AbstractDatabase(y, opts) {\n _classCallCheck(this, AbstractDatabase);\n\n this.y = y;\n var os = this;\n this.userId = null;\n var resolve;\n this.userIdPromise = new Promise(function (r) {\n resolve = r;\n });\n this.userIdPromise.resolve = resolve;\n // whether to broadcast all applied operations (insert & delete hook)\n this.forwardAppliedOperations = false;\n // E.g. this.listenersById[id] : Array\n this.listenersById = {};\n // Execute the next time a transaction is requested\n this.listenersByIdExecuteNow = [];\n // A transaction is requested\n this.listenersByIdRequestPending = false;\n /* To make things more clear, the following naming conventions:\n * ls : we put this.listenersById on ls\n * l : Array\n * id : Id (can't use as property name)\n * sid : String (converted from id via JSON.stringify\n so we can use it as a property name)\n Always remember to first overwrite\n a property before you iterate over it!\n */\n // TODO: Use ES7 Weak Maps. This way types that are no longer user,\n // wont be kept in memory.\n this.initializedTypes = {};\n this.waitingTransactions = [];\n this.transactionInProgress = false;\n this.transactionIsFlushed = false;\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n this.executeOrder = [];\n }\n this.gc1 = []; // first stage\n this.gc2 = []; // second stage -> after that, remove the op\n this.gcTimeout = !opts.gcTimeout ? 50000 : opts.gcTimeoutÅ›;\n function garbageCollect() {\n return os.whenTransactionsFinished().then(function () {\n if (os.gc1.length > 0 || os.gc2.length > 0) {\n if (!os.y.isConnected()) {\n console.warn('gc should be empty when disconnected!');\n }\n return new Promise(function (resolve) {\n os.requestTransaction(regeneratorRuntime.mark(function _callee() {\n var i, oid;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (!(os.y.connector != null && os.y.connector.isSynced)) {\n _context.next = 10;\n break;\n }\n\n i = 0;\n\n case 2:\n if (!(i < os.gc2.length)) {\n _context.next = 8;\n break;\n }\n\n oid = os.gc2[i];\n return _context.delegateYield(this.garbageCollectOperation(oid), 't0', 5);\n\n case 5:\n i++;\n _context.next = 2;\n break;\n\n case 8:\n os.gc2 = os.gc1;\n os.gc1 = [];\n\n case 10:\n // TODO: Use setInterval here instead (when garbageCollect is called several times there will be several timeouts..)\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout);\n }\n resolve();\n\n case 12:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n });\n } else {\n // TODO: see above\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout);\n }\n return Promise.resolve();\n }\n });\n }\n this.garbageCollect = garbageCollect;\n if (this.gcTimeout > 0) {\n garbageCollect();\n }\n }\n\n _createClass(AbstractDatabase, [{\n key: 'queueGarbageCollector',\n value: function queueGarbageCollector(id) {\n if (this.y.isConnected()) {\n this.gc1.push(id);\n }\n }\n }, {\n key: 'emptyGarbageCollector',\n value: function emptyGarbageCollector() {\n var _this = this;\n\n return new Promise(function (resolve) {\n var check = function check() {\n if (_this.gc1.length > 0 || _this.gc2.length > 0) {\n _this.garbageCollect().then(check);\n } else {\n resolve();\n }\n };\n setTimeout(check, 0);\n });\n }\n }, {\n key: 'addToDebug',\n value: function addToDebug() {\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n var command /* :string */ = Array.prototype.map.call(arguments, function (s) {\n if (typeof s === 'string') {\n return s;\n } else {\n return JSON.stringify(s);\n }\n }).join('').replace(/\"/g, \"'\").replace(/,/g, ', ').replace(/:/g, ': ');\n this.executeOrder.push(command);\n }\n }\n }, {\n key: 'getDebugData',\n value: function getDebugData() {\n console.log(this.executeOrder.join('\\n'));\n }\n }, {\n key: 'stopGarbageCollector',\n value: function stopGarbageCollector() {\n var self = this;\n return new Promise(function (resolve) {\n self.requestTransaction(regeneratorRuntime.mark(function _callee2() {\n var ungc /* :Array */, i, op;\n return regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n ungc = self.gc1.concat(self.gc2);\n\n self.gc1 = [];\n self.gc2 = [];\n i = 0;\n\n case 4:\n if (!(i < ungc.length)) {\n _context2.next = 13;\n break;\n }\n\n return _context2.delegateYield(this.getOperation(ungc[i]), 't0', 6);\n\n case 6:\n op = _context2.t0;\n\n if (!(op != null)) {\n _context2.next = 10;\n break;\n }\n\n delete op.gc;\n return _context2.delegateYield(this.setOperation(op), 't1', 10);\n\n case 10:\n i++;\n _context2.next = 4;\n break;\n\n case 13:\n resolve();\n\n case 14:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n });\n }\n /*\n Try to add to GC.\n TODO: rename this function\n Rulez:\n * Only gc if this user is online\n * The most left element in a list must not be gc'd.\n => There is at least one element in the list\n returns true iff op was added to GC\n */\n\n }, {\n key: 'addToGarbageCollector',\n value: regeneratorRuntime.mark(function addToGarbageCollector(op, left) {\n var gc;\n return regeneratorRuntime.wrap(function addToGarbageCollector$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n if (!(op.gc == null && op.deleted === true)) {\n _context3.next = 15;\n break;\n }\n\n gc = false;\n\n if (!(left != null && left.deleted === true)) {\n _context3.next = 6;\n break;\n }\n\n gc = true;\n _context3.next = 10;\n break;\n\n case 6:\n if (!(op.content != null && op.content.length > 1)) {\n _context3.next = 10;\n break;\n }\n\n return _context3.delegateYield(this.getInsertionCleanStart([op.id[0], op.id[1] + 1]), 't0', 8);\n\n case 8:\n op = _context3.t0;\n\n gc = true;\n\n case 10:\n if (!gc) {\n _context3.next = 15;\n break;\n }\n\n op.gc = true;\n return _context3.delegateYield(this.setOperation(op), 't1', 13);\n\n case 13:\n this.store.queueGarbageCollector(op.id);\n return _context3.abrupt('return', true);\n\n case 15:\n return _context3.abrupt('return', false);\n\n case 16:\n case 'end':\n return _context3.stop();\n }\n }\n }, addToGarbageCollector, this);\n })\n }, {\n key: 'removeFromGarbageCollector',\n value: function removeFromGarbageCollector(op) {\n function filter(o) {\n return !Y.utils.compareIds(o, op.id);\n }\n this.gc1 = this.gc1.filter(filter);\n this.gc2 = this.gc2.filter(filter);\n delete op.gc;\n }\n }, {\n key: 'destroy',\n value: regeneratorRuntime.mark(function destroy() {\n var key, type;\n return regeneratorRuntime.wrap(function destroy$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n clearInterval(this.gcInterval);\n this.gcInterval = null;\n for (key in this.initializedTypes) {\n type = this.initializedTypes[key];\n\n if (type._destroy != null) {\n type._destroy();\n } else {\n console.error('The type you included does not provide destroy functionality, it will remain in memory (updating your packages will help).');\n }\n }\n\n case 3:\n case 'end':\n return _context4.stop();\n }\n }\n }, destroy, this);\n })\n }, {\n key: 'setUserId',\n value: function setUserId(userId) {\n if (!this.userIdPromise.inProgress) {\n this.userIdPromise.inProgress = true;\n var self = this;\n self.requestTransaction(regeneratorRuntime.mark(function _callee3() {\n var state;\n return regeneratorRuntime.wrap(function _callee3$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n self.userId = userId;\n return _context5.delegateYield(this.getState(userId), 't0', 2);\n\n case 2:\n state = _context5.t0;\n\n self.opClock = state.clock;\n self.userIdPromise.resolve(userId);\n\n case 5:\n case 'end':\n return _context5.stop();\n }\n }\n }, _callee3, this);\n }));\n }\n return this.userIdPromise;\n }\n }, {\n key: 'whenUserIdSet',\n value: function whenUserIdSet(f) {\n this.userIdPromise.then(f);\n }\n }, {\n key: 'getNextOpId',\n value: function getNextOpId(numberOfIds) {\n if (numberOfIds == null) {\n throw new Error('getNextOpId expects the number of created ids to create!');\n } else if (this.userId == null) {\n throw new Error('OperationStore not yet initialized!');\n } else {\n var id = [this.userId, this.opClock];\n this.opClock += numberOfIds;\n return id;\n }\n }\n /*\n Apply a list of operations.\n * get a transaction\n * check whether all Struct.*.requiredOps are in the OS\n * check if it is an expected op (otherwise wait for it)\n * check if was deleted, apply a delete operation after op was applied\n */\n\n }, {\n key: 'apply',\n value: function apply(ops) {\n for (var i = 0; i < ops.length; i++) {\n var o = ops[i];\n if (o.id == null || o.id[0] !== this.y.connector.userId) {\n var required = Y.Struct[o.struct].requiredOps(o);\n if (o.requires != null) {\n required = required.concat(o.requires);\n }\n this.whenOperationsExist(required, o);\n }\n }\n }\n /*\n op is executed as soon as every operation requested is available.\n Note that Transaction can (and should) buffer requests.\n */\n\n }, {\n key: 'whenOperationsExist',\n value: function whenOperationsExist(ids, op) {\n if (ids.length > 0) {\n var listener = {\n op: op,\n missing: ids.length\n };\n\n for (var i = 0; i < ids.length; i++) {\n var id = ids[i];\n var sid = JSON.stringify(id);\n var l = this.listenersById[sid];\n if (l == null) {\n l = [];\n this.listenersById[sid] = l;\n }\n l.push(listener);\n }\n } else {\n this.listenersByIdExecuteNow.push({\n op: op\n });\n }\n\n if (this.listenersByIdRequestPending) {\n return;\n }\n\n this.listenersByIdRequestPending = true;\n var store = this;\n\n this.requestTransaction(regeneratorRuntime.mark(function _callee4() {\n var exeNow, ls, key, o, sid, l, id, op, i, listener;\n return regeneratorRuntime.wrap(function _callee4$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n exeNow = store.listenersByIdExecuteNow;\n\n store.listenersByIdExecuteNow = [];\n\n ls = store.listenersById;\n\n store.listenersById = {};\n\n store.listenersByIdRequestPending = false;\n\n key = 0;\n\n case 6:\n if (!(key < exeNow.length)) {\n _context6.next = 12;\n break;\n }\n\n o = exeNow[key].op;\n return _context6.delegateYield(store.tryExecute.call(this, o), 't0', 9);\n\n case 9:\n key++;\n _context6.next = 6;\n break;\n\n case 12:\n _context6.t1 = regeneratorRuntime.keys(ls);\n\n case 13:\n if ((_context6.t2 = _context6.t1()).done) {\n _context6.next = 39;\n break;\n }\n\n sid = _context6.t2.value;\n l = ls[sid];\n id = JSON.parse(sid);\n\n if (!(typeof id[1] === 'string')) {\n _context6.next = 22;\n break;\n }\n\n return _context6.delegateYield(this.getOperation(id), 't3', 19);\n\n case 19:\n op = _context6.t3;\n _context6.next = 24;\n break;\n\n case 22:\n return _context6.delegateYield(this.getInsertion(id), 't4', 23);\n\n case 23:\n op = _context6.t4;\n\n case 24:\n if (!(op == null)) {\n _context6.next = 28;\n break;\n }\n\n store.listenersById[sid] = l;\n _context6.next = 37;\n break;\n\n case 28:\n i = 0;\n\n case 29:\n if (!(i < l.length)) {\n _context6.next = 37;\n break;\n }\n\n listener = l[i];\n o = listener.op;\n\n if (!(--listener.missing === 0)) {\n _context6.next = 34;\n break;\n }\n\n return _context6.delegateYield(store.tryExecute.call(this, o), 't5', 34);\n\n case 34:\n i++;\n _context6.next = 29;\n break;\n\n case 37:\n _context6.next = 13;\n break;\n\n case 39:\n case 'end':\n return _context6.stop();\n }\n }\n }, _callee4, this);\n }));\n }\n /*\n Actually execute an operation, when all expected operations are available.\n */\n /* :: // TODO: this belongs somehow to transaction\n store: Object;\n getOperation: any;\n isGarbageCollected: any;\n addOperation: any;\n whenOperationsExist: any;\n */\n\n }, {\n key: 'tryExecute',\n value: regeneratorRuntime.mark(function tryExecute(op) {\n var defined, overlapSize, isGarbageCollected;\n return regeneratorRuntime.wrap(function tryExecute$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n this.store.addToDebug('yield* this.store.tryExecute.call(this, ', JSON.stringify(op), ')');\n\n if (!(op.struct === 'Delete')) {\n _context7.next = 5;\n break;\n }\n\n return _context7.delegateYield(Y.Struct.Delete.execute.call(this, op), 't0', 3);\n\n case 3:\n _context7.next = 29;\n break;\n\n case 5:\n return _context7.delegateYield(this.getInsertion(op.id), 't1', 6);\n\n case 6:\n defined = _context7.t1;\n\n case 7:\n if (!(defined != null && defined.content != null)) {\n _context7.next = 21;\n break;\n }\n\n if (!(defined.id[1] + defined.content.length < op.id[1] + op.content.length)) {\n _context7.next = 18;\n break;\n }\n\n overlapSize = defined.content.length - (op.id[1] - defined.id[1]);\n\n op.content.splice(0, overlapSize);\n op.id = [op.id[0], op.id[1] + overlapSize];\n op.left = Y.utils.getLastId(defined);\n op.origin = op.left;\n return _context7.delegateYield(this.getOperation(op.id), 't2', 15);\n\n case 15:\n defined = _context7.t2;\n _context7.next = 19;\n break;\n\n case 18:\n return _context7.abrupt('break', 21);\n\n case 19:\n _context7.next = 7;\n break;\n\n case 21:\n if (!(defined == null)) {\n _context7.next = 29;\n break;\n }\n\n return _context7.delegateYield(this.isGarbageCollected(op.id), 't3', 23);\n\n case 23:\n isGarbageCollected = _context7.t3;\n\n if (isGarbageCollected) {\n _context7.next = 29;\n break;\n }\n\n return _context7.delegateYield(Y.Struct[op.struct].execute.call(this, op), 't4', 26);\n\n case 26:\n return _context7.delegateYield(this.addOperation(op), 't5', 27);\n\n case 27:\n return _context7.delegateYield(this.store.operationAdded(this, op), 't6', 28);\n\n case 28:\n return _context7.delegateYield(this.tryCombineWithLeft(op), 't7', 29);\n\n case 29:\n case 'end':\n return _context7.stop();\n }\n }\n }, tryExecute, this);\n })\n // called by a transaction when an operation is added\n\n }, {\n key: 'operationAdded',\n value: regeneratorRuntime.mark(function operationAdded(transaction, op) {\n var opLen, _i, sid, l, key, listener, t, parentIsDeleted, _o, len, startId, _i2, id, opIsDeleted, delop;\n\n return regeneratorRuntime.wrap(function operationAdded$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n return _context8.delegateYield(transaction.updateState(op.id[0]), 't0', 1);\n\n case 1:\n opLen = op.content != null ? op.content.length : 1;\n\n for (_i = 0; _i < opLen; _i++) {\n // notify whenOperation listeners (by id)\n sid = JSON.stringify([op.id[0], op.id[1] + _i]);\n l = this.listenersById[sid];\n\n delete this.listenersById[sid];\n\n if (l != null) {\n for (key in l) {\n listener = l[key];\n\n if (--listener.missing === 0) {\n this.whenOperationsExist([], listener.op);\n }\n }\n }\n }\n t = this.initializedTypes[JSON.stringify(op.parent)];\n\n // if parent is deleted, mark as gc'd and return\n\n if (!(op.parent != null)) {\n _context8.next = 10;\n break;\n }\n\n return _context8.delegateYield(transaction.isDeleted(op.parent), 't1', 6);\n\n case 6:\n parentIsDeleted = _context8.t1;\n\n if (!parentIsDeleted) {\n _context8.next = 10;\n break;\n }\n\n return _context8.delegateYield(transaction.deleteList(op.id), 't2', 9);\n\n case 9:\n return _context8.abrupt('return');\n\n case 10:\n if (!(t != null)) {\n _context8.next = 13;\n break;\n }\n\n _o = Y.utils.copyObject(op);\n return _context8.delegateYield(t._changed(transaction, _o), 't3', 13);\n\n case 13:\n if (op.deleted) {\n _context8.next = 27;\n break;\n }\n\n // Delete if DS says this is actually deleted\n len = op.content != null ? op.content.length : 1;\n startId = op.id; // You must not use op.id in the following loop, because op will change when deleted\n\n _i2 = 0;\n\n case 17:\n if (!(_i2 < len)) {\n _context8.next = 27;\n break;\n }\n\n id = [startId[0], startId[1] + _i2];\n return _context8.delegateYield(transaction.isDeleted(id), 't4', 20);\n\n case 20:\n opIsDeleted = _context8.t4;\n\n if (!opIsDeleted) {\n _context8.next = 24;\n break;\n }\n\n delop = {\n struct: 'Delete',\n target: id\n };\n return _context8.delegateYield(this.tryExecute.call(transaction, delop), 't5', 24);\n\n case 24:\n _i2++;\n _context8.next = 17;\n break;\n\n case 27:\n case 'end':\n return _context8.stop();\n }\n }\n }, operationAdded, this);\n })\n }, {\n key: 'whenTransactionsFinished',\n value: function whenTransactionsFinished() {\n if (this.transactionInProgress) {\n if (this.transactionsFinished == null) {\n var resolve;\n var promise = new Promise(function (r) {\n resolve = r;\n });\n this.transactionsFinished = {\n resolve: resolve,\n promise: promise\n };\n return promise;\n } else {\n return this.transactionsFinished.promise;\n }\n } else {\n return Promise.resolve();\n }\n }\n // Check if there is another transaction request.\n // * the last transaction is always a flush :)\n\n }, {\n key: 'getNextRequest',\n value: function getNextRequest() {\n if (this.waitingTransactions.length === 0) {\n if (this.transactionIsFlushed) {\n this.transactionInProgress = false;\n this.transactionIsFlushed = false;\n if (this.transactionsFinished != null) {\n this.transactionsFinished.resolve();\n this.transactionsFinished = null;\n }\n return null;\n } else {\n this.transactionIsFlushed = true;\n return regeneratorRuntime.mark(function _callee5() {\n return regeneratorRuntime.wrap(function _callee5$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n return _context9.delegateYield(this.flush(), 't0', 1);\n\n case 1:\n case 'end':\n return _context9.stop();\n }\n }\n }, _callee5, this);\n });\n }\n } else {\n this.transactionIsFlushed = false;\n return this.waitingTransactions.shift();\n }\n }\n }, {\n key: 'requestTransaction',\n value: function requestTransaction(makeGen /* :any */, callImmediately) {\n this.waitingTransactions.push(makeGen);\n if (!this.transactionInProgress) {\n this.transactionInProgress = true;\n if (false || callImmediately) {\n // TODO: decide whether this is ok or not..\n this.transact(this.getNextRequest());\n } else {\n var self = this;\n setTimeout(function () {\n self.transact(self.getNextRequest());\n }, 0);\n }\n }\n }\n }]);\n\n return AbstractDatabase;\n }();\n\n Y.AbstractDatabase = AbstractDatabase;\n};\n\n},{}],6:[function(require,module,exports){\n/* @flow */\n'use strict';\n\n/*\n An operation also defines the structure of a type. This is why operation and\n structure are used interchangeably here.\n\n It must be of the type Object. I hope to achieve some performance\n improvements when working on databases that support the json format.\n\n An operation must have the following properties:\n\n * encode\n - Encode the structure in a readable format (preferably string- todo)\n * decode (todo)\n - decode structure to json\n * execute\n - Execute the semantics of an operation.\n * requiredOps\n - Operations that are required to execute this operation.\n*/\n\nmodule.exports = function (Y /* :any */) {\n var Struct = {\n /* This is the only operation that is actually not a structure, because\n it is not stored in the OS. This is why it _does not_ have an id\n op = {\n target: Id\n }\n */\n Delete: {\n encode: function encode(op) {\n return op;\n },\n requiredOps: function requiredOps(op) {\n return []; // [op.target]\n },\n execute: regeneratorRuntime.mark(function execute(op) {\n return regeneratorRuntime.wrap(function execute$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n return _context.delegateYield(this.deleteOperation(op.target, op.length || 1), 't0', 1);\n\n case 1:\n return _context.abrupt('return', _context.t0);\n\n case 2:\n case 'end':\n return _context.stop();\n }\n }\n }, execute, this);\n })\n },\n Insert: {\n /* {\n content: [any],\n opContent: Id,\n id: Id,\n left: Id,\n origin: Id,\n right: Id,\n parent: Id,\n parentSub: string (optional), // child of Map type\n }\n */\n encode: function encode(op /* :Insertion */) /* :Insertion */{\n // TODO: you could not send the \"left\" property, then you also have to\n // \"op.left = null\" in $execute or $decode\n var e /* :any */ = {\n id: op.id,\n left: op.left,\n right: op.right,\n origin: op.origin,\n parent: op.parent,\n struct: op.struct\n };\n if (op.parentSub != null) {\n e.parentSub = op.parentSub;\n }\n if (op.hasOwnProperty('opContent')) {\n e.opContent = op.opContent;\n } else {\n e.content = op.content.slice();\n }\n\n return e;\n },\n requiredOps: function requiredOps(op) {\n var ids = [];\n if (op.left != null) {\n ids.push(op.left);\n }\n if (op.right != null) {\n ids.push(op.right);\n }\n if (op.origin != null && !Y.utils.compareIds(op.left, op.origin)) {\n ids.push(op.origin);\n }\n // if (op.right == null && op.left == null) {\n ids.push(op.parent);\n\n if (op.opContent != null) {\n ids.push(op.opContent);\n }\n return ids;\n },\n getDistanceToOrigin: regeneratorRuntime.mark(function getDistanceToOrigin(op) {\n var d, o;\n return regeneratorRuntime.wrap(function getDistanceToOrigin$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n if (!(op.left == null)) {\n _context2.next = 4;\n break;\n }\n\n return _context2.abrupt('return', 0);\n\n case 4:\n d = 0;\n return _context2.delegateYield(this.getInsertion(op.left), 't0', 6);\n\n case 6:\n o = _context2.t0;\n\n case 7:\n if (Y.utils.matchesId(o, op.origin)) {\n _context2.next = 17;\n break;\n }\n\n d++;\n\n if (!(o.left == null)) {\n _context2.next = 13;\n break;\n }\n\n return _context2.abrupt('break', 17);\n\n case 13:\n return _context2.delegateYield(this.getInsertion(o.left), 't1', 14);\n\n case 14:\n o = _context2.t1;\n\n case 15:\n _context2.next = 7;\n break;\n\n case 17:\n return _context2.abrupt('return', d);\n\n case 18:\n case 'end':\n return _context2.stop();\n }\n }\n }, getDistanceToOrigin, this);\n }),\n /*\n # $this has to find a unique position between origin and the next known character\n # case 1: $origin equals $o.origin: the $creator parameter decides if left or right\n # let $OL= [o1,o2,o3,o4], whereby $this is to be inserted between o1 and o4\n # o2,o3 and o4 origin is 1 (the position of o2)\n # there is the case that $this.creator < o2.creator, but o3.creator < $this.creator\n # then o2 knows o3. Since on another client $OL could be [o1,o3,o4] the problem is complex\n # therefore $this would be always to the right of o3\n # case 2: $origin < $o.origin\n # if current $this insert_position > $o origin: $this ins\n # else $insert_position will not change\n # (maybe we encounter case 1 later, then this will be to the right of $o)\n # case 3: $origin > $o.origin\n # $this insert_position is to the left of $o (forever!)\n */\n execute: regeneratorRuntime.mark(function execute(op) {\n var i, tryToRemergeLater, origin, distanceToOrigin, o, parent, start, startId, oOriginDistance, left, right, _i, m;\n\n return regeneratorRuntime.wrap(function execute$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n // loop counter\n\n // during this function some ops may get split into two pieces (e.g. with getInsertionCleanEnd)\n // We try to merge them later, if possible\n tryToRemergeLater = [];\n\n if (!(op.origin != null)) {\n _context3.next = 8;\n break;\n }\n\n return _context3.delegateYield(this.getInsertionCleanEnd(op.origin), 't0', 3);\n\n case 3:\n origin = _context3.t0;\n\n if (origin.originOf == null) {\n origin.originOf = [];\n }\n origin.originOf.push(op.id);\n return _context3.delegateYield(this.setOperation(origin), 't1', 7);\n\n case 7:\n if (origin.right != null) {\n tryToRemergeLater.push(origin.right);\n }\n\n case 8:\n return _context3.delegateYield(Struct.Insert.getDistanceToOrigin.call(this, op), 't2', 9);\n\n case 9:\n distanceToOrigin = i = _context3.t2;\n\n if (!(op.left != null)) {\n _context3.next = 23;\n break;\n }\n\n return _context3.delegateYield(this.getInsertionCleanEnd(op.left), 't3', 12);\n\n case 12:\n o = _context3.t3;\n\n if (!Y.utils.compareIds(op.left, op.origin) && o.right != null) {\n // only if not added previously\n tryToRemergeLater.push(o.right);\n }\n\n if (!(o.right == null)) {\n _context3.next = 18;\n break;\n }\n\n _context3.t4 = null;\n _context3.next = 20;\n break;\n\n case 18:\n return _context3.delegateYield(this.getOperation(o.right), 't5', 19);\n\n case 19:\n _context3.t4 = _context3.t5;\n\n case 20:\n o = _context3.t4;\n _context3.next = 34;\n break;\n\n case 23:\n return _context3.delegateYield(this.getOperation(op.parent), 't6', 24);\n\n case 24:\n parent = _context3.t6;\n startId = op.parentSub ? parent.map[op.parentSub] : parent.start;\n\n if (!(startId == null)) {\n _context3.next = 30;\n break;\n }\n\n _context3.t7 = null;\n _context3.next = 32;\n break;\n\n case 30:\n return _context3.delegateYield(this.getOperation(startId), 't8', 31);\n\n case 31:\n _context3.t7 = _context3.t8;\n\n case 32:\n start = _context3.t7;\n\n o = start;\n\n case 34:\n if (!(op.right != null)) {\n _context3.next = 37;\n break;\n }\n\n tryToRemergeLater.push(op.right);\n return _context3.delegateYield(this.getInsertionCleanStart(op.right), 't9', 37);\n\n case 37:\n if (!true) {\n _context3.next = 62;\n break;\n }\n\n if (!(o != null && !Y.utils.compareIds(o.id, op.right))) {\n _context3.next = 59;\n break;\n }\n\n return _context3.delegateYield(Struct.Insert.getDistanceToOrigin.call(this, o), 't10', 40);\n\n case 40:\n oOriginDistance = _context3.t10;\n\n if (!(oOriginDistance === i)) {\n _context3.next = 45;\n break;\n }\n\n // case 1\n if (o.id[0] < op.id[0]) {\n op.left = Y.utils.getLastId(o);\n distanceToOrigin = i + 1; // just ignore o.content.length, doesn't make a difference\n }\n _context3.next = 50;\n break;\n\n case 45:\n if (!(oOriginDistance < i)) {\n _context3.next = 49;\n break;\n }\n\n // case 2\n if (i - distanceToOrigin <= oOriginDistance) {\n op.left = Y.utils.getLastId(o);\n distanceToOrigin = i + 1; // just ignore o.content.length, doesn't make a difference\n }\n _context3.next = 50;\n break;\n\n case 49:\n return _context3.abrupt('break', 62);\n\n case 50:\n i++;\n\n if (!(o.right != null)) {\n _context3.next = 56;\n break;\n }\n\n return _context3.delegateYield(this.getInsertion(o.right), 't11', 53);\n\n case 53:\n o = _context3.t11;\n _context3.next = 57;\n break;\n\n case 56:\n o = null;\n\n case 57:\n _context3.next = 60;\n break;\n\n case 59:\n return _context3.abrupt('break', 62);\n\n case 60:\n _context3.next = 37;\n break;\n\n case 62:\n\n // reconnect..\n left = null;\n right = null;\n\n if (!(parent == null)) {\n _context3.next = 67;\n break;\n }\n\n return _context3.delegateYield(this.getOperation(op.parent), 't12', 66);\n\n case 66:\n parent = _context3.t12;\n\n case 67:\n if (!(op.left != null)) {\n _context3.next = 75;\n break;\n }\n\n return _context3.delegateYield(this.getInsertion(op.left), 't13', 69);\n\n case 69:\n left = _context3.t13;\n\n // link left\n op.right = left.right;\n left.right = op.id;\n\n return _context3.delegateYield(this.setOperation(left), 't14', 73);\n\n case 73:\n _context3.next = 76;\n break;\n\n case 75:\n // set op.right from parent, if necessary\n op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start;\n\n case 76:\n if (!(op.right != null)) {\n _context3.next = 86;\n break;\n }\n\n return _context3.delegateYield(this.getOperation(op.right), 't15', 78);\n\n case 78:\n right = _context3.t15;\n\n right.left = Y.utils.getLastId(op);\n\n // if right exists, and it is supposed to be gc'd. Remove it from the gc\n\n if (!(right.gc != null)) {\n _context3.next = 85;\n break;\n }\n\n if (!(right.content != null && right.content.length > 1)) {\n _context3.next = 84;\n break;\n }\n\n return _context3.delegateYield(this.getInsertionCleanEnd(right.id), 't16', 83);\n\n case 83:\n right = _context3.t16;\n\n case 84:\n this.store.removeFromGarbageCollector(right);\n\n case 85:\n return _context3.delegateYield(this.setOperation(right), 't17', 86);\n\n case 86:\n if (!(op.parentSub != null)) {\n _context3.next = 96;\n break;\n }\n\n if (!(left == null)) {\n _context3.next = 90;\n break;\n }\n\n parent.map[op.parentSub] = op.id;\n return _context3.delegateYield(this.setOperation(parent), 't18', 90);\n\n case 90:\n if (!(op.right != null)) {\n _context3.next = 92;\n break;\n }\n\n return _context3.delegateYield(this.deleteOperation(op.right, 1, true), 't19', 92);\n\n case 92:\n if (!(op.left != null)) {\n _context3.next = 94;\n break;\n }\n\n return _context3.delegateYield(this.deleteOperation(op.id, 1, true), 't20', 94);\n\n case 94:\n _context3.next = 100;\n break;\n\n case 96:\n if (!(right == null || left == null)) {\n _context3.next = 100;\n break;\n }\n\n if (right == null) {\n parent.end = Y.utils.getLastId(op);\n }\n if (left == null) {\n parent.start = op.id;\n }\n return _context3.delegateYield(this.setOperation(parent), 't21', 100);\n\n case 100:\n _i = 0;\n\n case 101:\n if (!(_i < tryToRemergeLater.length)) {\n _context3.next = 108;\n break;\n }\n\n return _context3.delegateYield(this.getOperation(tryToRemergeLater[_i]), 't22', 103);\n\n case 103:\n m = _context3.t22;\n return _context3.delegateYield(this.tryCombineWithLeft(m), 't23', 105);\n\n case 105:\n _i++;\n _context3.next = 101;\n break;\n\n case 108:\n case 'end':\n return _context3.stop();\n }\n }\n }, execute, this);\n })\n },\n List: {\n /*\n {\n start: null,\n end: null,\n struct: \"List\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function create(id) {\n return {\n start: null,\n end: null,\n struct: 'List',\n id: id\n };\n },\n encode: function encode(op) {\n var e = {\n struct: 'List',\n id: op.id,\n type: op.type\n };\n if (op.requires != null) {\n e.requires = op.requires;\n }\n if (op.info != null) {\n e.info = op.info;\n }\n return e;\n },\n requiredOps: function requiredOps() {\n /*\n var ids = []\n if (op.start != null) {\n ids.push(op.start)\n }\n if (op.end != null){\n ids.push(op.end)\n }\n return ids\n */\n return [];\n },\n execute: regeneratorRuntime.mark(function execute(op) {\n return regeneratorRuntime.wrap(function execute$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n op.start = null;\n op.end = null;\n\n case 2:\n case 'end':\n return _context4.stop();\n }\n }\n }, execute, this);\n }),\n ref: regeneratorRuntime.mark(function ref(op, pos) {\n var res, o;\n return regeneratorRuntime.wrap(function ref$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n if (!(op.start == null)) {\n _context5.next = 2;\n break;\n }\n\n return _context5.abrupt('return', null);\n\n case 2:\n res = null;\n return _context5.delegateYield(this.getOperation(op.start), 't0', 4);\n\n case 4:\n o = _context5.t0;\n\n case 5:\n if (!true) {\n _context5.next = 15;\n break;\n }\n\n if (!o.deleted) {\n res = o;\n pos--;\n }\n\n if (!(pos >= 0 && o.right != null)) {\n _context5.next = 12;\n break;\n }\n\n return _context5.delegateYield(this.getOperation(o.right), 't1', 9);\n\n case 9:\n o = _context5.t1;\n _context5.next = 13;\n break;\n\n case 12:\n return _context5.abrupt('break', 15);\n\n case 13:\n _context5.next = 5;\n break;\n\n case 15:\n return _context5.abrupt('return', res);\n\n case 16:\n case 'end':\n return _context5.stop();\n }\n }\n }, ref, this);\n }),\n map: regeneratorRuntime.mark(function map(o, f) {\n var res, operation;\n return regeneratorRuntime.wrap(function map$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n o = o.start;\n res = [];\n\n case 2:\n if (!(o != null)) {\n _context6.next = 9;\n break;\n }\n\n return _context6.delegateYield(this.getOperation(o), 't0', 4);\n\n case 4:\n operation = _context6.t0;\n\n if (!operation.deleted) {\n res.push(f(operation));\n }\n o = operation.right;\n _context6.next = 2;\n break;\n\n case 9:\n return _context6.abrupt('return', res);\n\n case 10:\n case 'end':\n return _context6.stop();\n }\n }\n }, map, this);\n })\n },\n Map: {\n /*\n {\n map: {},\n struct: \"Map\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function create(id) {\n return {\n id: id,\n map: {},\n struct: 'Map'\n };\n },\n encode: function encode(op) {\n var e = {\n struct: 'Map',\n type: op.type,\n id: op.id,\n map: {} // overwrite map!!\n };\n if (op.requires != null) {\n e.requires = op.requires;\n }\n if (op.info != null) {\n e.info = op.info;\n }\n return e;\n },\n requiredOps: function requiredOps() {\n return [];\n },\n execute: regeneratorRuntime.mark(function execute() {\n return regeneratorRuntime.wrap(function execute$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n case 'end':\n return _context7.stop();\n }\n }\n }, execute, this);\n }),\n /*\n Get a property by name\n */\n get: regeneratorRuntime.mark(function get(op, name) {\n var oid, res;\n return regeneratorRuntime.wrap(function get$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n oid = op.map[name];\n\n if (!(oid != null)) {\n _context8.next = 14;\n break;\n }\n\n return _context8.delegateYield(this.getOperation(oid), 't0', 3);\n\n case 3:\n res = _context8.t0;\n\n if (!(res == null || res.deleted)) {\n _context8.next = 8;\n break;\n }\n\n return _context8.abrupt('return', void 0);\n\n case 8:\n if (!(res.opContent == null)) {\n _context8.next = 12;\n break;\n }\n\n return _context8.abrupt('return', res.content[0]);\n\n case 12:\n return _context8.delegateYield(this.getType(res.opContent), 't1', 13);\n\n case 13:\n return _context8.abrupt('return', _context8.t1);\n\n case 14:\n case 'end':\n return _context8.stop();\n }\n }\n }, get, this);\n })\n }\n };\n Y.Struct = Struct;\n};\n\n},{}],7:[function(require,module,exports){\n/* @flow */\n'use strict';\n\n/*\n Partial definition of a transaction\n\n A transaction provides all the the async functionality on a database.\n\n By convention, a transaction has the following properties:\n * ss for StateSet\n * os for OperationStore\n * ds for DeleteStore\n\n A transaction must also define the following methods:\n * checkDeleteStoreForState(state)\n - When increasing the state of a user, an operation with an higher id\n may already be garbage collected, and therefore it will never be received.\n update the state to reflect this knowledge. This won't call a method to save the state!\n * getDeleteSet(id)\n - Get the delete set in a readable format:\n {\n \"userX\": [\n [5,1], // starting from position 5, one operations is deleted\n [9,4] // starting from position 9, four operations are deleted\n ],\n \"userY\": ...\n }\n * getOpsFromDeleteSet(ds) -- TODO: just call this.deleteOperation(id) here\n - get a set of deletions that need to be applied in order to get to\n achieve the state of the supplied ds\n * setOperation(op)\n - write `op` to the database.\n Note: this is allowed to return an in-memory object.\n E.g. the Memory adapter returns the object that it has in-memory.\n Changing values on this object will be stored directly in the database\n without calling this function. Therefore,\n setOperation may have no functionality in some adapters. This also has\n implications on the way we use operations that were served from the database.\n We try not to call copyObject, if not necessary.\n * addOperation(op)\n - add an operation to the database.\n This may only be called once for every op.id\n Must return a function that returns the next operation in the database (ordered by id)\n * getOperation(id)\n * removeOperation(id)\n - remove an operation from the database. This is called when an operation\n is garbage collected.\n * setState(state)\n - `state` is of the form\n {\n user: \"1\",\n clock: 4\n } <- meaning that we have four operations from user \"1\"\n (with these id's respectively: 0, 1, 2, and 3)\n * getState(user)\n * getStateVector()\n - Get the state of the OS in the form\n [{\n user: \"userX\",\n clock: 11\n },\n ..\n ]\n * getStateSet()\n - Get the state of the OS in the form\n {\n \"userX\": 11,\n \"userY\": 22\n }\n * getOperations(startSS)\n - Get the all the operations that are necessary in order to achive the\n stateSet of this user, starting from a stateSet supplied by another user\n * makeOperationReady(ss, op)\n - this is called only by `getOperations(startSS)`. It makes an operation\n applyable on a given SS.\n*/\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nmodule.exports = function (Y /* :any */) {\n var TransactionInterface = function () {\n function TransactionInterface() {\n _classCallCheck(this, TransactionInterface);\n }\n\n _createClass(TransactionInterface, [{\n key: 'getType',\n\n /* ::\n store: Y.AbstractDatabase;\n ds: Store;\n os: Store;\n ss: Store;\n */\n /*\n Get a type based on the id of its model.\n If it does not exist yes, create it.\n TODO: delete type from store.initializedTypes[id] when corresponding id was deleted!\n */\n value: regeneratorRuntime.mark(function getType(id, args) {\n var sid, t, op /* :MapStruct | ListStruct */;\n return regeneratorRuntime.wrap(function getType$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n sid = JSON.stringify(id);\n t = this.store.initializedTypes[sid];\n\n if (!(t == null)) {\n _context.next = 9;\n break;\n }\n\n return _context.delegateYield(this.getOperation(id), 't0', 4);\n\n case 4:\n op = _context.t0;\n\n if (!(op != null)) {\n _context.next = 9;\n break;\n }\n\n return _context.delegateYield(Y[op.type].typeDefinition.initType.call(this, this.store, op, args), 't1', 7);\n\n case 7:\n t = _context.t1;\n\n this.store.initializedTypes[sid] = t;\n\n case 9:\n return _context.abrupt('return', t);\n\n case 10:\n case 'end':\n return _context.stop();\n }\n }\n }, getType, this);\n })\n }, {\n key: 'createType',\n value: regeneratorRuntime.mark(function createType(typedefinition, id) {\n var structname, op;\n return regeneratorRuntime.wrap(function createType$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n structname = typedefinition[0].struct;\n\n id = id || this.store.getNextOpId(1);\n\n if (!(id[0] === '_')) {\n _context2.next = 7;\n break;\n }\n\n return _context2.delegateYield(this.getOperation(id), 't0', 4);\n\n case 4:\n op = _context2.t0;\n _context2.next = 9;\n break;\n\n case 7:\n op = Y.Struct[structname].create(id);\n op.type = typedefinition[0].name;\n\n case 9:\n if (!(typedefinition[0].appendAdditionalInfo != null)) {\n _context2.next = 11;\n break;\n }\n\n return _context2.delegateYield(typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1]), 't1', 11);\n\n case 11:\n if (!(op[0] === '_')) {\n _context2.next = 15;\n break;\n }\n\n return _context2.delegateYield(this.setOperation(op), 't2', 13);\n\n case 13:\n _context2.next = 16;\n break;\n\n case 15:\n return _context2.delegateYield(this.applyCreatedOperations([op]), 't3', 16);\n\n case 16:\n return _context2.delegateYield(this.getType(id, typedefinition[1]), 't4', 17);\n\n case 17:\n return _context2.abrupt('return', _context2.t4);\n\n case 18:\n case 'end':\n return _context2.stop();\n }\n }\n }, createType, this);\n })\n /* createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n // yield* this.applyCreatedOperations([op])\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n return yield* this.getType(id, typedefinition[1])\n }*/\n /*\n Apply operations that this user created (no remote ones!)\n * does not check for Struct.*.requiredOps()\n * also broadcasts it through the connector\n */\n\n }, {\n key: 'applyCreatedOperations',\n value: regeneratorRuntime.mark(function applyCreatedOperations(ops) {\n var send, i, op;\n return regeneratorRuntime.wrap(function applyCreatedOperations$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n send = [];\n i = 0;\n\n case 2:\n if (!(i < ops.length)) {\n _context3.next = 9;\n break;\n }\n\n op = ops[i];\n return _context3.delegateYield(this.store.tryExecute.call(this, op), 't0', 5);\n\n case 5:\n if (op.id == null || typeof op.id[1] !== 'string') {\n send.push(Y.Struct[op.struct].encode(op));\n }\n\n case 6:\n i++;\n _context3.next = 2;\n break;\n\n case 9:\n if (!this.store.y.connector.isDisconnected() && send.length > 0) {\n // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops)\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps(send);\n }\n\n case 10:\n case 'end':\n return _context3.stop();\n }\n }\n }, applyCreatedOperations, this);\n })\n }, {\n key: 'deleteList',\n value: regeneratorRuntime.mark(function deleteList(start) {\n var delLength;\n return regeneratorRuntime.wrap(function deleteList$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n if (!(start != null)) {\n _context4.next = 15;\n break;\n }\n\n return _context4.delegateYield(this.getOperation(start), 't0', 2);\n\n case 2:\n start = _context4.t0;\n\n if (start.gc) {\n _context4.next = 12;\n break;\n }\n\n start.gc = true;\n start.deleted = true;\n return _context4.delegateYield(this.setOperation(start), 't1', 7);\n\n case 7:\n delLength = start.content != null ? start.content.length : 1;\n return _context4.delegateYield(this.markDeleted(start.id, delLength), 't2', 9);\n\n case 9:\n if (!(start.opContent != null)) {\n _context4.next = 11;\n break;\n }\n\n return _context4.delegateYield(this.deleteOperation(start.opContent), 't3', 11);\n\n case 11:\n this.store.queueGarbageCollector(start.id);\n\n case 12:\n start = start.right;\n _context4.next = 0;\n break;\n\n case 15:\n case 'end':\n return _context4.stop();\n }\n }\n }, deleteList, this);\n })\n\n /*\n Mark an operation as deleted, and add it to the GC, if possible.\n */\n\n }, {\n key: 'deleteOperation',\n value: regeneratorRuntime.mark(function deleteOperation(targetId, length, preventCallType) {\n var callType, target, targetLength, name, i, left, right, type;\n return regeneratorRuntime.wrap(function deleteOperation$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n if (length == null) {\n length = 1;\n }\n return _context5.delegateYield(this.markDeleted(targetId, length), 't0', 2);\n\n case 2:\n if (!(length > 0)) {\n _context5.next = 66;\n break;\n }\n\n callType = false;\n return _context5.delegateYield(this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1]), 't1', 5);\n\n case 5:\n target = _context5.t1;\n targetLength = target != null && target.content != null ? target.content.length : 1;\n\n if (!(target == null || target.id[0] !== targetId[0] || target.id[1] + targetLength <= targetId[1])) {\n _context5.next = 12;\n break;\n }\n\n // does not exist or is not in the range of the deletion\n target = null;\n length = 0;\n _context5.next = 22;\n break;\n\n case 12:\n if (target.deleted) {\n _context5.next = 21;\n break;\n }\n\n if (!(target.id[1] < targetId[1])) {\n _context5.next = 17;\n break;\n }\n\n return _context5.delegateYield(this.getInsertionCleanStart(targetId), 't2', 15);\n\n case 15:\n target = _context5.t2;\n\n targetLength = target.content.length; // must have content property!\n\n case 17:\n if (!(target.id[1] + targetLength > targetId[1] + length)) {\n _context5.next = 21;\n break;\n }\n\n return _context5.delegateYield(this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1]), 't3', 19);\n\n case 19:\n target = _context5.t3;\n\n targetLength = target.content.length;\n\n case 21:\n length = target.id[1] - targetId[1];\n\n case 22:\n if (!(target != null)) {\n _context5.next = 64;\n break;\n }\n\n if (target.deleted) {\n _context5.next = 44;\n break;\n }\n\n callType = true;\n // set deleted & notify type\n target.deleted = true;\n // delete containing lists\n\n if (!(target.start != null)) {\n _context5.next = 28;\n break;\n }\n\n return _context5.delegateYield(this.deleteList(target.start), 't4', 28);\n\n case 28:\n if (!(target.map != null)) {\n _context5.next = 35;\n break;\n }\n\n _context5.t5 = regeneratorRuntime.keys(target.map);\n\n case 30:\n if ((_context5.t6 = _context5.t5()).done) {\n _context5.next = 35;\n break;\n }\n\n name = _context5.t6.value;\n return _context5.delegateYield(this.deleteList(target.map[name]), 't7', 33);\n\n case 33:\n _context5.next = 30;\n break;\n\n case 35:\n if (!(target.opContent != null)) {\n _context5.next = 37;\n break;\n }\n\n return _context5.delegateYield(this.deleteOperation(target.opContent), 't8', 37);\n\n case 37:\n if (!(target.requires != null)) {\n _context5.next = 44;\n break;\n }\n\n i = 0;\n\n case 39:\n if (!(i < target.requires.length)) {\n _context5.next = 44;\n break;\n }\n\n return _context5.delegateYield(this.deleteOperation(target.requires[i]), 't9', 41);\n\n case 41:\n i++;\n _context5.next = 39;\n break;\n\n case 44:\n if (!(target.left != null)) {\n _context5.next = 49;\n break;\n }\n\n return _context5.delegateYield(this.getInsertion(target.left), 't10', 46);\n\n case 46:\n left = _context5.t10;\n _context5.next = 50;\n break;\n\n case 49:\n left = null;\n\n case 50:\n return _context5.delegateYield(this.setOperation(target), 't11', 51);\n\n case 51:\n if (!(target.right != null)) {\n _context5.next = 56;\n break;\n }\n\n return _context5.delegateYield(this.getOperation(target.right), 't12', 53);\n\n case 53:\n right = _context5.t12;\n _context5.next = 57;\n break;\n\n case 56:\n right = null;\n\n case 57:\n if (!(callType && !preventCallType)) {\n _context5.next = 61;\n break;\n }\n\n type = this.store.initializedTypes[JSON.stringify(target.parent)];\n\n if (!(type != null)) {\n _context5.next = 61;\n break;\n }\n\n return _context5.delegateYield(type._changed(this, {\n struct: 'Delete',\n target: target.id,\n length: targetLength\n }), 't13', 61);\n\n case 61:\n return _context5.delegateYield(this.store.addToGarbageCollector.call(this, target, left), 't14', 62);\n\n case 62:\n if (!(right != null)) {\n _context5.next = 64;\n break;\n }\n\n return _context5.delegateYield(this.store.addToGarbageCollector.call(this, right, target), 't15', 64);\n\n case 64:\n _context5.next = 2;\n break;\n\n case 66:\n case 'end':\n return _context5.stop();\n }\n }\n }, deleteOperation, this);\n })\n /*\n Mark an operation as deleted&gc'd\n */\n\n }, {\n key: 'markGarbageCollected',\n value: regeneratorRuntime.mark(function markGarbageCollected(id, len) {\n var n, newlen, prev, next;\n return regeneratorRuntime.wrap(function markGarbageCollected$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n // this.mem.push([\"gc\", id]);\n this.store.addToDebug('yield* this.markGarbageCollected(', id, ', ', len, ')');\n return _context6.delegateYield(this.markDeleted(id, len), 't0', 2);\n\n case 2:\n n = _context6.t0;\n\n if (!(n.id[1] < id[1] && !n.gc)) {\n _context6.next = 9;\n break;\n }\n\n // un-extend left\n newlen = n.len - (id[1] - n.id[1]);\n\n n.len -= newlen;\n return _context6.delegateYield(this.ds.put(n), 't1', 7);\n\n case 7:\n n = { id: id, len: newlen, gc: false };\n return _context6.delegateYield(this.ds.put(n), 't2', 9);\n\n case 9:\n return _context6.delegateYield(this.ds.findPrev(id), 't3', 10);\n\n case 10:\n prev = _context6.t3;\n return _context6.delegateYield(this.ds.findNext(id), 't4', 12);\n\n case 12:\n next = _context6.t4;\n\n if (!(id[1] + len < n.id[1] + n.len && !n.gc)) {\n _context6.next = 16;\n break;\n }\n\n return _context6.delegateYield(this.ds.put({ id: [id[0], id[1] + len], len: n.len - len, gc: false }), 't5', 15);\n\n case 15:\n n.len = len;\n\n case 16:\n // set gc'd\n n.gc = true;\n // can extend left?\n\n if (!(prev != null && prev.gc && Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id))) {\n _context6.next = 21;\n break;\n }\n\n prev.len += n.len;\n return _context6.delegateYield(this.ds.delete(n.id), 't6', 20);\n\n case 20:\n n = prev;\n // ds.put n here?\n\n case 21:\n if (!(next != null && next.gc && Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id))) {\n _context6.next = 24;\n break;\n }\n\n n.len += next.len;\n return _context6.delegateYield(this.ds.delete(next.id), 't7', 24);\n\n case 24:\n return _context6.delegateYield(this.ds.put(n), 't8', 25);\n\n case 25:\n return _context6.delegateYield(this.updateState(n.id[0]), 't9', 26);\n\n case 26:\n case 'end':\n return _context6.stop();\n }\n }\n }, markGarbageCollected, this);\n })\n /*\n Mark an operation as deleted.\n returns the delete node\n */\n\n }, {\n key: 'markDeleted',\n value: regeneratorRuntime.mark(function markDeleted(id, length) {\n var n, diff, next, _next;\n\n return regeneratorRuntime.wrap(function markDeleted$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n if (length == null) {\n length = 1;\n }\n // this.mem.push([\"del\", id]);\n return _context7.delegateYield(this.ds.findWithUpperBound(id), 't0', 2);\n\n case 2:\n n = _context7.t0;\n\n if (!(n != null && n.id[0] === id[0])) {\n _context7.next = 27;\n break;\n }\n\n if (!(n.id[1] <= id[1] && id[1] <= n.id[1] + n.len)) {\n _context7.next = 23;\n break;\n }\n\n // id is in n's range\n diff = id[1] + length - (n.id[1] + n.len); // overlapping right\n\n if (!(diff > 0)) {\n _context7.next = 20;\n break;\n }\n\n if (n.gc) {\n _context7.next = 11;\n break;\n }\n\n n.len += diff;\n _context7.next = 18;\n break;\n\n case 11:\n diff = n.id[1] + n.len - id[1]; // overlapping left (id till n.end)\n\n if (!(diff < length)) {\n _context7.next = 17;\n break;\n }\n\n // a partial deletion\n n = { id: [id[0], id[1] + diff], len: length - diff, gc: false };\n return _context7.delegateYield(this.ds.put(n), 't1', 15);\n\n case 15:\n _context7.next = 18;\n break;\n\n case 17:\n throw new Error('Cannot happen! (it dit though.. :()');\n\n case 18:\n _context7.next = 21;\n break;\n\n case 20:\n return _context7.abrupt('return', n);\n\n case 21:\n _context7.next = 25;\n break;\n\n case 23:\n // cannot extend left (there is no left!)\n n = { id: id, len: length, gc: false };\n return _context7.delegateYield(this.ds.put(n), 't2', 25);\n\n case 25:\n _context7.next = 29;\n break;\n\n case 27:\n // cannot extend left\n n = { id: id, len: length, gc: false };\n return _context7.delegateYield(this.ds.put(n), 't3', 29);\n\n case 29:\n return _context7.delegateYield(this.ds.findNext(n.id), 't4', 30);\n\n case 30:\n next = _context7.t4;\n\n if (!(next != null && n.id[0] === next.id[0] && n.id[1] + n.len >= next.id[1])) {\n _context7.next = 61;\n break;\n }\n\n diff = n.id[1] + n.len - next.id[1]; // from next.start to n.end\n\n case 33:\n if (!(diff >= 0)) {\n _context7.next = 61;\n break;\n }\n\n if (!next.gc) {\n _context7.next = 44;\n break;\n }\n\n // gc is stronger, so reduce length of n\n n.len -= diff;\n\n if (!(diff >= next.len)) {\n _context7.next = 41;\n break;\n }\n\n // delete the missing range after next\n diff = diff - next.len; // missing range after next\n\n if (!(diff > 0)) {\n _context7.next = 41;\n break;\n }\n\n return _context7.delegateYield(this.ds.put(n), 't5', 40);\n\n case 40:\n return _context7.delegateYield(this.markDeleted([next.id[0], next.id[1] + next.len], diff), 't6', 41);\n\n case 41:\n return _context7.abrupt('break', 61);\n\n case 44:\n if (!(diff > next.len)) {\n _context7.next = 56;\n break;\n }\n\n return _context7.delegateYield(this.ds.findNext(next.id), 't7', 46);\n\n case 46:\n _next = _context7.t7;\n return _context7.delegateYield(this.ds.delete(next.id), 't8', 48);\n\n case 48:\n if (!(_next == null || n.id[0] !== _next.id[0])) {\n _context7.next = 52;\n break;\n }\n\n return _context7.abrupt('break', 61);\n\n case 52:\n next = _next;\n diff = n.id[1] + n.len - next.id[1]; // from next.start to n.end\n // continue!\n\n case 54:\n _context7.next = 59;\n break;\n\n case 56:\n // n just partially overlaps with next. extend n, delete next, and break this loop\n n.len += next.len - diff;\n return _context7.delegateYield(this.ds.delete(next.id), 't9', 58);\n\n case 58:\n return _context7.abrupt('break', 61);\n\n case 59:\n _context7.next = 33;\n break;\n\n case 61:\n return _context7.delegateYield(this.ds.put(n), 't10', 62);\n\n case 62:\n return _context7.abrupt('return', n);\n\n case 63:\n case 'end':\n return _context7.stop();\n }\n }\n }, markDeleted, this);\n })\n /*\n Call this method when the client is connected&synced with the\n other clients (e.g. master). This will query the database for\n operations that can be gc'd and add them to the garbage collector.\n */\n\n }, {\n key: 'garbageCollectAfterSync',\n value: regeneratorRuntime.mark(function garbageCollectAfterSync() {\n return regeneratorRuntime.wrap(function garbageCollectAfterSync$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {\n console.warn('gc should be empty after sync');\n }\n return _context9.delegateYield(this.os.iterate(this, null, null, regeneratorRuntime.mark(function _callee(op) {\n var parentDeleted, i, left;\n return regeneratorRuntime.wrap(function _callee$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n if (!op.gc) {\n _context8.next = 3;\n break;\n }\n\n delete op.gc;\n return _context8.delegateYield(this.setOperation(op), 't0', 3);\n\n case 3:\n if (!(op.parent != null)) {\n _context8.next = 23;\n break;\n }\n\n return _context8.delegateYield(this.isDeleted(op.parent), 't1', 5);\n\n case 5:\n parentDeleted = _context8.t1;\n\n if (!parentDeleted) {\n _context8.next = 23;\n break;\n }\n\n op.gc = true;\n\n if (op.deleted) {\n _context8.next = 20;\n break;\n }\n\n return _context8.delegateYield(this.markDeleted(op.id, op.content != null ? op.content.length : 1), 't2', 10);\n\n case 10:\n op.deleted = true;\n\n if (!(op.opContent != null)) {\n _context8.next = 13;\n break;\n }\n\n return _context8.delegateYield(this.deleteOperation(op.opContent), 't3', 13);\n\n case 13:\n if (!(op.requires != null)) {\n _context8.next = 20;\n break;\n }\n\n i = 0;\n\n case 15:\n if (!(i < op.requires.length)) {\n _context8.next = 20;\n break;\n }\n\n return _context8.delegateYield(this.deleteOperation(op.requires[i]), 't4', 17);\n\n case 17:\n i++;\n _context8.next = 15;\n break;\n\n case 20:\n return _context8.delegateYield(this.setOperation(op), 't5', 21);\n\n case 21:\n this.store.gc1.push(op.id); // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!)\n return _context8.abrupt('return');\n\n case 23:\n if (!op.deleted) {\n _context8.next = 29;\n break;\n }\n\n left = null;\n\n if (!(op.left != null)) {\n _context8.next = 28;\n break;\n }\n\n return _context8.delegateYield(this.getInsertion(op.left), 't6', 27);\n\n case 27:\n left = _context8.t6;\n\n case 28:\n return _context8.delegateYield(this.store.addToGarbageCollector.call(this, op, left), 't7', 29);\n\n case 29:\n case 'end':\n return _context8.stop();\n }\n }\n }, _callee, this);\n })), 't0', 2);\n\n case 2:\n case 'end':\n return _context9.stop();\n }\n }\n }, garbageCollectAfterSync, this);\n })\n /*\n Really remove an op and all its effects.\n The complicated case here is the Insert operation:\n * reset left\n * reset right\n * reset parent.start\n * reset parent.end\n * reset origins of all right ops\n */\n\n }, {\n key: 'garbageCollectOperation',\n value: regeneratorRuntime.mark(function garbageCollectOperation(id) {\n var o, deps, i, dep, left, right, neworigin, neworigin_, _i, originsIn, origin, parent, setParent;\n\n return regeneratorRuntime.wrap(function garbageCollectOperation$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n this.store.addToDebug('yield* this.garbageCollectOperation(', id, ')');\n return _context10.delegateYield(this.getOperation(id), 't0', 2);\n\n case 2:\n o = _context10.t0;\n return _context10.delegateYield(this.markGarbageCollected(id, o != null && o.content != null ? o.content.length : 1), 't1', 4);\n\n case 4:\n if (!(o != null)) {\n _context10.next = 76;\n break;\n }\n\n deps = [];\n\n if (o.opContent != null) {\n deps.push(o.opContent);\n }\n if (o.requires != null) {\n deps = deps.concat(o.requires);\n }\n i = 0;\n\n case 9:\n if (!(i < deps.length)) {\n _context10.next = 26;\n break;\n }\n\n return _context10.delegateYield(this.getOperation(deps[i]), 't2', 11);\n\n case 11:\n dep = _context10.t2;\n\n if (!(dep != null)) {\n _context10.next = 22;\n break;\n }\n\n if (dep.deleted) {\n _context10.next = 17;\n break;\n }\n\n return _context10.delegateYield(this.deleteOperation(dep.id), 't3', 15);\n\n case 15:\n return _context10.delegateYield(this.getOperation(dep.id), 't4', 16);\n\n case 16:\n dep = _context10.t4;\n\n case 17:\n dep.gc = true;\n return _context10.delegateYield(this.setOperation(dep), 't5', 19);\n\n case 19:\n this.store.queueGarbageCollector(dep.id);\n _context10.next = 23;\n break;\n\n case 22:\n return _context10.delegateYield(this.markGarbageCollected(deps[i], 1), 't6', 23);\n\n case 23:\n i++;\n _context10.next = 9;\n break;\n\n case 26:\n if (!(o.left != null)) {\n _context10.next = 31;\n break;\n }\n\n return _context10.delegateYield(this.getInsertion(o.left), 't7', 28);\n\n case 28:\n left = _context10.t7;\n\n left.right = o.right;\n return _context10.delegateYield(this.setOperation(left), 't8', 31);\n\n case 31:\n if (!(o.right != null)) {\n _context10.next = 62;\n break;\n }\n\n return _context10.delegateYield(this.getOperation(o.right), 't9', 33);\n\n case 33:\n right = _context10.t9;\n\n right.left = o.left;\n\n if (!(o.originOf != null && o.originOf.length > 0)) {\n _context10.next = 61;\n break;\n }\n\n // find new origin of right ops\n // origin is the first left deleted operation\n neworigin = o.left;\n neworigin_ = null;\n\n case 38:\n if (!(neworigin != null)) {\n _context10.next = 46;\n break;\n }\n\n return _context10.delegateYield(this.getInsertion(neworigin), 't10', 40);\n\n case 40:\n neworigin_ = _context10.t10;\n\n if (!neworigin_.deleted) {\n _context10.next = 43;\n break;\n }\n\n return _context10.abrupt('break', 46);\n\n case 43:\n neworigin = neworigin_.left;\n _context10.next = 38;\n break;\n\n case 46:\n _context10.t11 = regeneratorRuntime.keys(o.originOf);\n\n case 47:\n if ((_context10.t12 = _context10.t11()).done) {\n _context10.next = 56;\n break;\n }\n\n _i = _context10.t12.value;\n return _context10.delegateYield(this.getOperation(o.originOf[_i]), 't13', 50);\n\n case 50:\n originsIn = _context10.t13;\n\n if (!(originsIn != null)) {\n _context10.next = 54;\n break;\n }\n\n originsIn.origin = neworigin;\n return _context10.delegateYield(this.setOperation(originsIn), 't14', 54);\n\n case 54:\n _context10.next = 47;\n break;\n\n case 56:\n if (!(neworigin != null)) {\n _context10.next = 59;\n break;\n }\n\n if (neworigin_.originOf == null) {\n neworigin_.originOf = o.originOf;\n } else {\n neworigin_.originOf = o.originOf.concat(neworigin_.originOf);\n }\n return _context10.delegateYield(this.setOperation(neworigin_), 't15', 59);\n\n case 59:\n _context10.next = 62;\n break;\n\n case 61:\n return _context10.delegateYield(this.setOperation(right), 't16', 62);\n\n case 62:\n if (!(o.origin != null)) {\n _context10.next = 67;\n break;\n }\n\n return _context10.delegateYield(this.getInsertion(o.origin), 't17', 64);\n\n case 64:\n origin = _context10.t17;\n\n origin.originOf = origin.originOf.filter(function (_id) {\n return !Y.utils.compareIds(id, _id);\n });\n return _context10.delegateYield(this.setOperation(origin), 't18', 67);\n\n case 67:\n if (!(o.parent != null)) {\n _context10.next = 70;\n break;\n }\n\n return _context10.delegateYield(this.getOperation(o.parent), 't19', 69);\n\n case 69:\n parent = _context10.t19;\n\n case 70:\n if (!(parent != null)) {\n _context10.next = 75;\n break;\n }\n\n setParent = false; // whether to save parent to the os\n\n if (o.parentSub != null) {\n if (Y.utils.compareIds(parent.map[o.parentSub], o.id)) {\n setParent = true;\n if (o.right != null) {\n parent.map[o.parentSub] = o.right;\n } else {\n delete parent.map[o.parentSub];\n }\n }\n } else {\n if (Y.utils.compareIds(parent.start, o.id)) {\n // gc'd op is the start\n setParent = true;\n parent.start = o.right;\n }\n if (Y.utils.matchesId(o, parent.end)) {\n // gc'd op is the end\n setParent = true;\n parent.end = o.left;\n }\n }\n\n if (!setParent) {\n _context10.next = 75;\n break;\n }\n\n return _context10.delegateYield(this.setOperation(parent), 't20', 75);\n\n case 75:\n return _context10.delegateYield(this.removeOperation(o.id), 't21', 76);\n\n case 76:\n case 'end':\n return _context10.stop();\n }\n }\n }, garbageCollectOperation, this);\n })\n }, {\n key: 'checkDeleteStoreForState',\n value: regeneratorRuntime.mark(function checkDeleteStoreForState(state) {\n var n;\n return regeneratorRuntime.wrap(function checkDeleteStoreForState$(_context11) {\n while (1) {\n switch (_context11.prev = _context11.next) {\n case 0:\n return _context11.delegateYield(this.ds.findWithUpperBound([state.user, state.clock]), 't0', 1);\n\n case 1:\n n = _context11.t0;\n\n if (n != null && n.id[0] === state.user && n.gc) {\n state.clock = Math.max(state.clock, n.id[1] + n.len);\n }\n\n case 3:\n case 'end':\n return _context11.stop();\n }\n }\n }, checkDeleteStoreForState, this);\n })\n }, {\n key: 'updateState',\n value: regeneratorRuntime.mark(function updateState(user) {\n var state, o, oLength;\n return regeneratorRuntime.wrap(function updateState$(_context12) {\n while (1) {\n switch (_context12.prev = _context12.next) {\n case 0:\n return _context12.delegateYield(this.getState(user), 't0', 1);\n\n case 1:\n state = _context12.t0;\n return _context12.delegateYield(this.checkDeleteStoreForState(state), 't1', 3);\n\n case 3:\n return _context12.delegateYield(this.getInsertion([user, state.clock]), 't2', 4);\n\n case 4:\n o = _context12.t2;\n oLength = o != null && o.content != null ? o.content.length : 1;\n\n case 6:\n if (!(o != null && user === o.id[0] && o.id[1] <= state.clock && o.id[1] + oLength > state.clock)) {\n _context12.next = 14;\n break;\n }\n\n // either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS\n state.clock += oLength;\n return _context12.delegateYield(this.checkDeleteStoreForState(state), 't3', 9);\n\n case 9:\n return _context12.delegateYield(this.os.findNext(o.id), 't4', 10);\n\n case 10:\n o = _context12.t4;\n\n oLength = o != null && o.content != null ? o.content.length : 1;\n _context12.next = 6;\n break;\n\n case 14:\n return _context12.delegateYield(this.setState(state), 't5', 15);\n\n case 15:\n case 'end':\n return _context12.stop();\n }\n }\n }, updateState, this);\n })\n /*\n apply a delete set in order to get\n the state of the supplied ds\n */\n\n }, {\n key: 'applyDeleteSet',\n value: regeneratorRuntime.mark(function applyDeleteSet(ds) {\n var deletions, user, dv, pos, d, i, del, counter, o, oLen, ops;\n return regeneratorRuntime.wrap(function applyDeleteSet$(_context14) {\n while (1) {\n switch (_context14.prev = _context14.next) {\n case 0:\n deletions = [];\n _context14.t0 = regeneratorRuntime.keys(ds);\n\n case 2:\n if ((_context14.t1 = _context14.t0()).done) {\n _context14.next = 11;\n break;\n }\n\n user = _context14.t1.value;\n dv = ds[user];\n pos = 0;\n d = dv[pos];\n return _context14.delegateYield(this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], regeneratorRuntime.mark(function _callee2(n) {\n var diff;\n return regeneratorRuntime.wrap(function _callee2$(_context13) {\n while (1) {\n switch (_context13.prev = _context13.next) {\n case 0:\n if (!(d != null)) {\n _context13.next = 10;\n break;\n }\n\n diff = 0; // describe the diff of length in 1) and 2)\n\n if (!(n.id[1] + n.len <= d[0])) {\n _context13.next = 6;\n break;\n }\n\n return _context13.abrupt('break', 10);\n\n case 6:\n if (d[0] < n.id[1]) {\n // 2)\n // delete maximum the len of d\n // else delete as much as possible\n diff = Math.min(n.id[1] - d[0], d[1]);\n deletions.push([user, d[0], diff, d[2]]);\n } else {\n // 3)\n diff = n.id[1] + n.len - d[0]; // never null (see 1)\n if (d[2] && !n.gc) {\n // d marks as gc'd but n does not\n // then delete either way\n deletions.push([user, d[0], Math.min(diff, d[1]), d[2]]);\n }\n }\n\n case 7:\n if (d[1] <= diff) {\n // d doesn't delete anything anymore\n d = dv[++pos];\n } else {\n d[0] = d[0] + diff; // reset pos\n d[1] = d[1] - diff; // reset length\n }\n _context13.next = 0;\n break;\n\n case 10:\n case 'end':\n return _context13.stop();\n }\n }\n }, _callee2, this);\n })), 't2', 8);\n\n case 8:\n // for the rest.. just apply it\n for (; pos < dv.length; pos++) {\n d = dv[pos];\n deletions.push([user, d[0], d[1], d[2]]);\n }\n _context14.next = 2;\n break;\n\n case 11:\n i = 0;\n\n case 12:\n if (!(i < deletions.length)) {\n _context14.next = 40;\n break;\n }\n\n del = deletions[i];\n // always try to delete..\n\n return _context14.delegateYield(this.deleteOperation([del[0], del[1]], del[2]), 't3', 15);\n\n case 15:\n if (!del[3]) {\n _context14.next = 36;\n break;\n }\n\n return _context14.delegateYield(this.markGarbageCollected([del[0], del[1]], del[2]), 't4', 17);\n\n case 17:\n // always mark gc'd\n // remove operation..\n counter = del[1] + del[2];\n\n case 18:\n if (!(counter >= del[1])) {\n _context14.next = 36;\n break;\n }\n\n return _context14.delegateYield(this.os.findWithUpperBound([del[0], counter - 1]), 't5', 20);\n\n case 20:\n o = _context14.t5;\n\n if (!(o == null)) {\n _context14.next = 23;\n break;\n }\n\n return _context14.abrupt('break', 36);\n\n case 23:\n oLen = o.content != null ? o.content.length : 1;\n\n if (!(o.id[0] !== del[0] || o.id[1] + oLen <= del[1])) {\n _context14.next = 26;\n break;\n }\n\n return _context14.abrupt('break', 36);\n\n case 26:\n if (!(o.id[1] + oLen > del[1] + del[2])) {\n _context14.next = 29;\n break;\n }\n\n return _context14.delegateYield(this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1]), 't6', 28);\n\n case 28:\n o = _context14.t6;\n\n case 29:\n if (!(o.id[1] < del[1])) {\n _context14.next = 32;\n break;\n }\n\n return _context14.delegateYield(this.getInsertionCleanStart([del[0], del[1]]), 't7', 31);\n\n case 31:\n o = _context14.t7;\n\n case 32:\n counter = o.id[1];\n return _context14.delegateYield(this.garbageCollectOperation(o.id), 't8', 34);\n\n case 34:\n _context14.next = 18;\n break;\n\n case 36:\n if (this.store.forwardAppliedOperations) {\n ops = [];\n\n ops.push({ struct: 'Delete', target: [d[0], d[1]], length: del[2] });\n this.store.y.connector.broadcastOps(ops);\n }\n\n case 37:\n i++;\n _context14.next = 12;\n break;\n\n case 40:\n case 'end':\n return _context14.stop();\n }\n }\n }, applyDeleteSet, this);\n })\n }, {\n key: 'isGarbageCollected',\n value: regeneratorRuntime.mark(function isGarbageCollected(id) {\n var n;\n return regeneratorRuntime.wrap(function isGarbageCollected$(_context15) {\n while (1) {\n switch (_context15.prev = _context15.next) {\n case 0:\n return _context15.delegateYield(this.ds.findWithUpperBound(id), 't0', 1);\n\n case 1:\n n = _context15.t0;\n return _context15.abrupt('return', n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len && n.gc);\n\n case 3:\n case 'end':\n return _context15.stop();\n }\n }\n }, isGarbageCollected, this);\n })\n /*\n A DeleteSet (ds) describes all the deleted ops in the OS\n */\n\n }, {\n key: 'getDeleteSet',\n value: regeneratorRuntime.mark(function getDeleteSet() {\n var ds;\n return regeneratorRuntime.wrap(function getDeleteSet$(_context17) {\n while (1) {\n switch (_context17.prev = _context17.next) {\n case 0:\n ds = {};\n return _context17.delegateYield(this.ds.iterate(this, null, null, regeneratorRuntime.mark(function _callee3(n) {\n var user, counter, len, gc, dv;\n return regeneratorRuntime.wrap(function _callee3$(_context16) {\n while (1) {\n switch (_context16.prev = _context16.next) {\n case 0:\n user = n.id[0];\n counter = n.id[1];\n len = n.len;\n gc = n.gc;\n dv = ds[user];\n\n if (dv === void 0) {\n dv = [];\n ds[user] = dv;\n }\n dv.push([counter, len, gc]);\n\n case 7:\n case 'end':\n return _context16.stop();\n }\n }\n }, _callee3, this);\n })), 't0', 2);\n\n case 2:\n return _context17.abrupt('return', ds);\n\n case 3:\n case 'end':\n return _context17.stop();\n }\n }\n }, getDeleteSet, this);\n })\n }, {\n key: 'isDeleted',\n value: regeneratorRuntime.mark(function isDeleted(id) {\n var n;\n return regeneratorRuntime.wrap(function isDeleted$(_context18) {\n while (1) {\n switch (_context18.prev = _context18.next) {\n case 0:\n return _context18.delegateYield(this.ds.findWithUpperBound(id), 't0', 1);\n\n case 1:\n n = _context18.t0;\n return _context18.abrupt('return', n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len);\n\n case 3:\n case 'end':\n return _context18.stop();\n }\n }\n }, isDeleted, this);\n })\n }, {\n key: 'setOperation',\n value: regeneratorRuntime.mark(function setOperation(op) {\n return regeneratorRuntime.wrap(function setOperation$(_context19) {\n while (1) {\n switch (_context19.prev = _context19.next) {\n case 0:\n return _context19.delegateYield(this.os.put(op), 't0', 1);\n\n case 1:\n return _context19.abrupt('return', op);\n\n case 2:\n case 'end':\n return _context19.stop();\n }\n }\n }, setOperation, this);\n })\n }, {\n key: 'addOperation',\n value: regeneratorRuntime.mark(function addOperation(op) {\n return regeneratorRuntime.wrap(function addOperation$(_context20) {\n while (1) {\n switch (_context20.prev = _context20.next) {\n case 0:\n return _context20.delegateYield(this.os.put(op), 't0', 1);\n\n case 1:\n if (!this.store.y.connector.isDisconnected() && this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') {\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps([op]);\n }\n\n case 2:\n case 'end':\n return _context20.stop();\n }\n }\n }, addOperation, this);\n })\n // if insertion, try to combine with left insertion (if both have content property)\n\n }, {\n key: 'tryCombineWithLeft',\n value: regeneratorRuntime.mark(function tryCombineWithLeft(op) {\n var left;\n return regeneratorRuntime.wrap(function tryCombineWithLeft$(_context21) {\n while (1) {\n switch (_context21.prev = _context21.next) {\n case 0:\n if (!(op != null && op.left != null && op.content != null && op.left[0] === op.id[0] && Y.utils.compareIds(op.left, op.origin))) {\n _context21.next = 9;\n break;\n }\n\n return _context21.delegateYield(this.getInsertion(op.left), 't0', 2);\n\n case 2:\n left = _context21.t0;\n\n if (!(left.content != null && left.id[1] + left.content.length === op.id[1] && left.originOf.length === 1 && !left.gc && !left.deleted && !op.gc && !op.deleted)) {\n _context21.next = 9;\n break;\n }\n\n // combine!\n if (op.originOf != null) {\n left.originOf = op.originOf;\n } else {\n delete left.originOf;\n }\n left.content = left.content.concat(op.content);\n left.right = op.right;\n return _context21.delegateYield(this.os.delete(op.id), 't1', 8);\n\n case 8:\n return _context21.delegateYield(this.setOperation(left), 't2', 9);\n\n case 9:\n case 'end':\n return _context21.stop();\n }\n }\n }, tryCombineWithLeft, this);\n })\n }, {\n key: 'getInsertion',\n value: regeneratorRuntime.mark(function getInsertion(id) {\n var ins, len;\n return regeneratorRuntime.wrap(function getInsertion$(_context22) {\n while (1) {\n switch (_context22.prev = _context22.next) {\n case 0:\n return _context22.delegateYield(this.os.findWithUpperBound(id), 't0', 1);\n\n case 1:\n ins = _context22.t0;\n\n if (!(ins == null)) {\n _context22.next = 6;\n break;\n }\n\n return _context22.abrupt('return', null);\n\n case 6:\n len = ins.content != null ? ins.content.length : 1; // in case of opContent\n\n if (!(id[0] === ins.id[0] && id[1] < ins.id[1] + len)) {\n _context22.next = 11;\n break;\n }\n\n return _context22.abrupt('return', ins);\n\n case 11:\n return _context22.abrupt('return', null);\n\n case 12:\n case 'end':\n return _context22.stop();\n }\n }\n }, getInsertion, this);\n })\n }, {\n key: 'getInsertionCleanStartEnd',\n value: regeneratorRuntime.mark(function getInsertionCleanStartEnd(id) {\n return regeneratorRuntime.wrap(function getInsertionCleanStartEnd$(_context23) {\n while (1) {\n switch (_context23.prev = _context23.next) {\n case 0:\n return _context23.delegateYield(this.getInsertionCleanStart(id), 't0', 1);\n\n case 1:\n return _context23.delegateYield(this.getInsertionCleanEnd(id), 't1', 2);\n\n case 2:\n return _context23.abrupt('return', _context23.t1);\n\n case 3:\n case 'end':\n return _context23.stop();\n }\n }\n }, getInsertionCleanStartEnd, this);\n })\n // Return an insertion such that id is the first element of content\n // This function manipulates an operation, if necessary\n\n }, {\n key: 'getInsertionCleanStart',\n value: regeneratorRuntime.mark(function getInsertionCleanStart(id) {\n var ins, left, leftLid;\n return regeneratorRuntime.wrap(function getInsertionCleanStart$(_context24) {\n while (1) {\n switch (_context24.prev = _context24.next) {\n case 0:\n return _context24.delegateYield(this.getInsertion(id), 't0', 1);\n\n case 1:\n ins = _context24.t0;\n\n if (!(ins != null)) {\n _context24.next = 21;\n break;\n }\n\n if (!(ins.id[1] === id[1])) {\n _context24.next = 7;\n break;\n }\n\n return _context24.abrupt('return', ins);\n\n case 7:\n left = Y.utils.copyObject(ins);\n\n ins.content = left.content.splice(id[1] - ins.id[1]);\n ins.id = id;\n leftLid = Y.utils.getLastId(left);\n\n ins.origin = leftLid;\n left.originOf = [ins.id];\n left.right = ins.id;\n ins.left = leftLid;\n // debugger // check\n return _context24.delegateYield(this.setOperation(left), 't1', 16);\n\n case 16:\n return _context24.delegateYield(this.setOperation(ins), 't2', 17);\n\n case 17:\n if (left.gc) {\n this.store.queueGarbageCollector(ins.id);\n }\n return _context24.abrupt('return', ins);\n\n case 19:\n _context24.next = 22;\n break;\n\n case 21:\n return _context24.abrupt('return', null);\n\n case 22:\n case 'end':\n return _context24.stop();\n }\n }\n }, getInsertionCleanStart, this);\n })\n // Return an insertion such that id is the last element of content\n // This function manipulates an operation, if necessary\n\n }, {\n key: 'getInsertionCleanEnd',\n value: regeneratorRuntime.mark(function getInsertionCleanEnd(id) {\n var ins, right, insLid;\n return regeneratorRuntime.wrap(function getInsertionCleanEnd$(_context25) {\n while (1) {\n switch (_context25.prev = _context25.next) {\n case 0:\n return _context25.delegateYield(this.getInsertion(id), 't0', 1);\n\n case 1:\n ins = _context25.t0;\n\n if (!(ins != null)) {\n _context25.next = 21;\n break;\n }\n\n if (!(ins.content == null || ins.id[1] + ins.content.length - 1 === id[1])) {\n _context25.next = 7;\n break;\n }\n\n return _context25.abrupt('return', ins);\n\n case 7:\n right = Y.utils.copyObject(ins);\n\n right.content = ins.content.splice(id[1] - ins.id[1] + 1); // cut off remainder\n right.id = [id[0], id[1] + 1];\n insLid = Y.utils.getLastId(ins);\n\n right.origin = insLid;\n ins.originOf = [right.id];\n ins.right = right.id;\n right.left = insLid;\n // debugger // check\n return _context25.delegateYield(this.setOperation(right), 't1', 16);\n\n case 16:\n return _context25.delegateYield(this.setOperation(ins), 't2', 17);\n\n case 17:\n if (ins.gc) {\n this.store.queueGarbageCollector(right.id);\n }\n return _context25.abrupt('return', ins);\n\n case 19:\n _context25.next = 22;\n break;\n\n case 21:\n return _context25.abrupt('return', null);\n\n case 22:\n case 'end':\n return _context25.stop();\n }\n }\n }, getInsertionCleanEnd, this);\n })\n }, {\n key: 'getOperation',\n value: regeneratorRuntime.mark(function getOperation(id /* :any */) {\n var o, comp, struct, op;\n return regeneratorRuntime.wrap(function getOperation$(_context26) {\n while (1) {\n switch (_context26.prev = _context26.next) {\n case 0:\n return _context26.delegateYield(this.os.find(id), 't0', 1);\n\n case 1:\n o = _context26.t0;\n\n if (!(id[0] !== '_' || o != null)) {\n _context26.next = 6;\n break;\n }\n\n return _context26.abrupt('return', o);\n\n case 6:\n // type is string\n // generate this operation?\n comp = id[1].split('_');\n\n if (!(comp.length > 1)) {\n _context26.next = 15;\n break;\n }\n\n struct = comp[0];\n op = Y.Struct[struct].create(id);\n\n op.type = comp[1];\n return _context26.delegateYield(this.setOperation(op), 't1', 12);\n\n case 12:\n return _context26.abrupt('return', op);\n\n case 15:\n // won't be called. but just in case..\n console.error('Unexpected case. How can this happen?');\n debugger; // eslint-disable-line\n return _context26.abrupt('return', null);\n\n case 18:\n case 'end':\n return _context26.stop();\n }\n }\n }, getOperation, this);\n })\n }, {\n key: 'removeOperation',\n value: regeneratorRuntime.mark(function removeOperation(id) {\n return regeneratorRuntime.wrap(function removeOperation$(_context27) {\n while (1) {\n switch (_context27.prev = _context27.next) {\n case 0:\n return _context27.delegateYield(this.os.delete(id), 't0', 1);\n\n case 1:\n case 'end':\n return _context27.stop();\n }\n }\n }, removeOperation, this);\n })\n }, {\n key: 'setState',\n value: regeneratorRuntime.mark(function setState(state) {\n var val;\n return regeneratorRuntime.wrap(function setState$(_context28) {\n while (1) {\n switch (_context28.prev = _context28.next) {\n case 0:\n val = {\n id: [state.user],\n clock: state.clock\n };\n return _context28.delegateYield(this.ss.put(val), 't0', 2);\n\n case 2:\n case 'end':\n return _context28.stop();\n }\n }\n }, setState, this);\n })\n }, {\n key: 'getState',\n value: regeneratorRuntime.mark(function getState(user) {\n var n, clock;\n return regeneratorRuntime.wrap(function getState$(_context29) {\n while (1) {\n switch (_context29.prev = _context29.next) {\n case 0:\n return _context29.delegateYield(this.ss.find([user]), 't0', 1);\n\n case 1:\n n = _context29.t0;\n clock = n == null ? null : n.clock;\n\n if (clock == null) {\n clock = 0;\n }\n return _context29.abrupt('return', {\n user: user,\n clock: clock\n });\n\n case 5:\n case 'end':\n return _context29.stop();\n }\n }\n }, getState, this);\n })\n }, {\n key: 'getStateVector',\n value: regeneratorRuntime.mark(function getStateVector() {\n var stateVector;\n return regeneratorRuntime.wrap(function getStateVector$(_context31) {\n while (1) {\n switch (_context31.prev = _context31.next) {\n case 0:\n stateVector = [];\n return _context31.delegateYield(this.ss.iterate(this, null, null, regeneratorRuntime.mark(function _callee4(n) {\n return regeneratorRuntime.wrap(function _callee4$(_context30) {\n while (1) {\n switch (_context30.prev = _context30.next) {\n case 0:\n stateVector.push({\n user: n.id[0],\n clock: n.clock\n });\n\n case 1:\n case 'end':\n return _context30.stop();\n }\n }\n }, _callee4, this);\n })), 't0', 2);\n\n case 2:\n return _context31.abrupt('return', stateVector);\n\n case 3:\n case 'end':\n return _context31.stop();\n }\n }\n }, getStateVector, this);\n })\n }, {\n key: 'getStateSet',\n value: regeneratorRuntime.mark(function getStateSet() {\n var ss;\n return regeneratorRuntime.wrap(function getStateSet$(_context33) {\n while (1) {\n switch (_context33.prev = _context33.next) {\n case 0:\n ss = {};\n return _context33.delegateYield(this.ss.iterate(this, null, null, regeneratorRuntime.mark(function _callee5(n) {\n return regeneratorRuntime.wrap(function _callee5$(_context32) {\n while (1) {\n switch (_context32.prev = _context32.next) {\n case 0:\n ss[n.id[0]] = n.clock;\n\n case 1:\n case 'end':\n return _context32.stop();\n }\n }\n }, _callee5, this);\n })), 't0', 2);\n\n case 2:\n return _context33.abrupt('return', ss);\n\n case 3:\n case 'end':\n return _context33.stop();\n }\n }\n }, getStateSet, this);\n })\n /*\n Here, we make all missing operations executable for the receiving user.\n Notes:\n startSS: denotes to the SV that the remote user sent\n currSS: denotes to the state vector that the user should have if he\n applies all already sent operations (increases is each step)\n We face several problems:\n * Execute op as is won't work because ops depend on each other\n -> find a way so that they do not anymore\n * When changing left, must not go more to the left than the origin\n * When changing right, you have to consider that other ops may have op\n as their origin, this means that you must not set one of these ops\n as the new right (interdependencies of ops)\n * can't just go to the right until you find the first known operation,\n With currSS\n -> interdependency of ops is a problem\n With startSS\n -> leads to inconsistencies when two users join at the same time.\n Then the position depends on the order of execution -> error!\n Solution:\n -> re-create originial situation\n -> set op.left = op.origin (which never changes)\n -> set op.right\n to the first operation that is known (according to startSS)\n or to the first operation that has an origin that is not to the\n right of op.\n -> Enforces unique execution order -> happy user\n Improvements: TODO\n * Could set left to origin, or the first known operation\n (startSS or currSS.. ?)\n -> Could be necessary when I turn GC again.\n -> Is a bad(ish) idea because it requires more computation\n What we do:\n * Iterate over all missing operations.\n * When there is an operation, where the right op is known, send this op all missing ops to the left to the user\n * I explained above what we have to do with each operation. Here is how we do it efficiently:\n 1. Go to the left until you find either op.origin, or a known operation (let o denote current operation in the iteration)\n 2. Found a known operation -> set op.left = o, and send it to the user. stop\n 3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o)\n 4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue\n */\n\n }, {\n key: 'getOperations',\n value: regeneratorRuntime.mark(function getOperations(startSS) {\n var send, endSV, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, endState, user, startPos, firstMissing;\n\n return regeneratorRuntime.wrap(function getOperations$(_context35) {\n while (1) {\n switch (_context35.prev = _context35.next) {\n case 0:\n // TODO: use bounds here!\n if (startSS == null) {\n startSS = {};\n }\n send = [];\n return _context35.delegateYield(this.getStateVector(), 't0', 3);\n\n case 3:\n endSV = _context35.t0;\n _iteratorNormalCompletion = true;\n _didIteratorError = false;\n _iteratorError = undefined;\n _context35.prev = 7;\n _iterator = endSV[Symbol.iterator]();\n\n case 9:\n if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {\n _context35.next = 23;\n break;\n }\n\n endState = _step.value;\n user = endState.user;\n\n if (!(user === '_')) {\n _context35.next = 14;\n break;\n }\n\n return _context35.abrupt('continue', 20);\n\n case 14:\n startPos = startSS[user] || 0;\n\n if (!(startPos > 0)) {\n _context35.next = 19;\n break;\n }\n\n return _context35.delegateYield(this.getInsertion([user, startPos]), 't1', 17);\n\n case 17:\n firstMissing = _context35.t1;\n\n if (firstMissing != null) {\n // update startPos\n startPos = firstMissing.id[1];\n }\n\n case 19:\n return _context35.delegateYield(this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], regeneratorRuntime.mark(function _callee6(op) {\n var o, missing_origins, newright, s;\n return regeneratorRuntime.wrap(function _callee6$(_context34) {\n while (1) {\n switch (_context34.prev = _context34.next) {\n case 0:\n op = Y.Struct[op.struct].encode(op);\n\n if (!(op.struct !== 'Insert')) {\n _context34.next = 5;\n break;\n }\n\n send.push(op);\n _context34.next = 27;\n break;\n\n case 5:\n if (!(op.right == null || op.right[1] < (startSS[op.right[0]] || 0))) {\n _context34.next = 27;\n break;\n }\n\n // case 1. op.right is known\n o = op;\n // Remember: ?\n // -> set op.right\n // 1. to the first operation that is known (according to startSS)\n // 2. or to the first operation that has an origin that is not to the\n // right of op.\n // For this we maintain a list of ops which origins are not found yet.\n\n missing_origins = [op];\n newright = op.right;\n\n case 9:\n if (!true) {\n _context34.next = 27;\n break;\n }\n\n if (!(o.left == null)) {\n _context34.next = 15;\n break;\n }\n\n op.left = null;\n send.push(op);\n if (!Y.utils.compareIds(o.id, op.id)) {\n o = Y.Struct[op.struct].encode(o);\n o.right = missing_origins[missing_origins.length - 1].id;\n send.push(o);\n }\n return _context34.abrupt('break', 27);\n\n case 15:\n return _context34.delegateYield(this.getInsertion(o.left), 't0', 16);\n\n case 16:\n o = _context34.t0;\n\n // we set another o, check if we can reduce $missing_origins\n while (missing_origins.length > 0 && Y.utils.matchesId(o, missing_origins[missing_origins.length - 1].origin)) {\n missing_origins.pop();\n }\n\n if (!(o.id[1] < (startSS[o.id[0]] || 0))) {\n _context34.next = 24;\n break;\n }\n\n // case 2. o is known\n op.left = Y.utils.getLastId(o);\n send.push(op);\n return _context34.abrupt('break', 27);\n\n case 24:\n if (Y.utils.matchesId(o, op.origin)) {\n // case 3. o is op.origin\n op.left = op.origin;\n send.push(op);\n op = Y.Struct[op.struct].encode(o);\n op.right = newright;\n if (missing_origins.length > 0) {\n console.log('This should not happen .. :( please report this');\n }\n missing_origins = [op];\n } else {\n // case 4. send o, continue to find op.origin\n s = Y.Struct[op.struct].encode(o);\n\n s.right = missing_origins[missing_origins.length - 1].id;\n s.left = s.origin;\n send.push(s);\n missing_origins.push(o);\n }\n\n case 25:\n _context34.next = 9;\n break;\n\n case 27:\n case 'end':\n return _context34.stop();\n }\n }\n }, _callee6, this);\n })), 't2', 20);\n\n case 20:\n _iteratorNormalCompletion = true;\n _context35.next = 9;\n break;\n\n case 23:\n _context35.next = 29;\n break;\n\n case 25:\n _context35.prev = 25;\n _context35.t3 = _context35['catch'](7);\n _didIteratorError = true;\n _iteratorError = _context35.t3;\n\n case 29:\n _context35.prev = 29;\n _context35.prev = 30;\n\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n\n case 32:\n _context35.prev = 32;\n\n if (!_didIteratorError) {\n _context35.next = 35;\n break;\n }\n\n throw _iteratorError;\n\n case 35:\n return _context35.finish(32);\n\n case 36:\n return _context35.finish(29);\n\n case 37:\n return _context35.abrupt('return', send.reverse());\n\n case 38:\n case 'end':\n return _context35.stop();\n }\n }\n }, getOperations, this, [[7, 25, 29, 37], [30,, 32, 36]]);\n })\n /* this is what we used before.. use this as a reference..\n * makeOperationReady (startSS, op) {\n op = Y.Struct[op.struct].encode(op)\n op = Y.utils.copyObject(op)\n var o = op\n var ids = [op.id]\n // search for the new op.right\n // it is either the first known op (according to startSS)\n // or the o that has no origin to the right of op\n // (this is why we use the ids array)\n while (o.right != null) {\n var right = yield* this.getOperation(o.right)\n if (o.right[1] < (startSS[o.right[0]] || 0) || !ids.some(function (id) {\n return Y.utils.compareIds(id, right.origin)\n })) {\n break\n }\n ids.push(o.right)\n o = right\n }\n op.right = o.right\n op.left = op.origin\n return op\n }\n */\n\n }, {\n key: 'flush',\n value: regeneratorRuntime.mark(function flush() {\n return regeneratorRuntime.wrap(function flush$(_context36) {\n while (1) {\n switch (_context36.prev = _context36.next) {\n case 0:\n return _context36.delegateYield(this.os.flush(), 't0', 1);\n\n case 1:\n return _context36.delegateYield(this.ss.flush(), 't1', 2);\n\n case 2:\n return _context36.delegateYield(this.ds.flush(), 't2', 3);\n\n case 3:\n case 'end':\n return _context36.stop();\n }\n }\n }, flush, this);\n })\n }]);\n\n return TransactionInterface;\n }();\n\n Y.Transaction = TransactionInterface;\n};\n\n},{}],8:[function(require,module,exports){\n/* @flow */\n'use strict';\n\n/*\n EventHandler is an helper class for constructing custom types.\n\n Why: When constructing custom types, you sometimes want your types to work\n synchronous: E.g.\n ``` Synchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === \"yay\"\n ```\n versus\n ``` Asynchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === undefined\n mytype.waitForSomething().then(function(){\n mytype.getSomething() === \"yay\"\n })\n ```\n\n The structures usually work asynchronously (you have to wait for the\n database request to finish). EventHandler helps you to make your type\n synchronous.\n*/\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; };\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nmodule.exports = function (Y /* : any*/) {\n Y.utils = {};\n\n var EventListenerHandler = function () {\n function EventListenerHandler() {\n _classCallCheck(this, EventListenerHandler);\n\n this.eventListeners = [];\n }\n\n _createClass(EventListenerHandler, [{\n key: 'destroy',\n value: function destroy() {\n this.eventListeners = null;\n }\n /*\n Basic event listener boilerplate...\n */\n\n }, {\n key: 'addEventListener',\n value: function addEventListener(f) {\n this.eventListeners.push(f);\n }\n }, {\n key: 'removeEventListener',\n value: function removeEventListener(f) {\n this.eventListeners = this.eventListeners.filter(function (g) {\n return f !== g;\n });\n }\n }, {\n key: 'removeAllEventListeners',\n value: function removeAllEventListeners() {\n this.eventListeners = [];\n }\n }, {\n key: 'callEventListeners',\n value: function callEventListeners(event) {\n for (var i = 0; i < this.eventListeners.length; i++) {\n try {\n this.eventListeners[i](event);\n } catch (e) {\n console.error('User events must not throw Errors!');\n }\n }\n }\n }]);\n\n return EventListenerHandler;\n }();\n\n Y.utils.EventListenerHandler = EventListenerHandler;\n\n var EventHandler = function (_EventListenerHandler) {\n _inherits(EventHandler, _EventListenerHandler);\n\n /* ::\n waiting: Array;\n awaiting: number;\n onevent: Function;\n eventListeners: Array;\n */\n /*\n onevent: is called when the structure changes.\n Note: \"awaiting opertations\" is used to denote operations that were\n prematurely called. Events for received operations can not be executed until\n all prematurely called operations were executed (\"waiting operations\")\n */\n\n function EventHandler(onevent /* : Function */) {\n _classCallCheck(this, EventHandler);\n\n var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(EventHandler).call(this));\n\n _this.waiting = [];\n _this.awaiting = 0;\n _this.onevent = onevent;\n return _this;\n }\n\n _createClass(EventHandler, [{\n key: 'destroy',\n value: function destroy() {\n _get(Object.getPrototypeOf(EventHandler.prototype), 'destroy', this).call(this);\n this.waiting = null;\n this.awaiting = null;\n this.onevent = null;\n }\n /*\n Call this when a new operation arrives. It will be executed right away if\n there are no waiting operations, that you prematurely executed\n */\n\n }, {\n key: 'receivedOp',\n value: function receivedOp(op) {\n if (this.awaiting <= 0) {\n this.onevent(op);\n } else {\n this.waiting.push(op);\n }\n }\n /*\n You created some operations, and you want the `onevent` function to be\n called right away. Received operations will not be executed untill all\n prematurely called operations are executed\n */\n\n }, {\n key: 'awaitAndPrematurelyCall',\n value: function awaitAndPrematurelyCall(ops) {\n this.awaiting += ops.length;\n ops.forEach(this.onevent);\n }\n /*\n Call this when you successfully awaited the execution of n Insert operations\n */\n\n }, {\n key: 'awaitedInserts',\n value: function awaitedInserts(n) {\n var ops = this.waiting.splice(this.waiting.length - n);\n for (var oid = 0; oid < ops.length; oid++) {\n var op = ops[oid];\n if (op.struct === 'Insert') {\n for (var i = this.waiting.length - 1; i >= 0; i--) {\n var w = this.waiting[i];\n // TODO: do I handle split operations correctly here? Super unlikely, but yeah..\n // Also: can this case happen? Can op be inserted in the middle of a larger op that is in $waiting?\n if (w.struct === 'Insert') {\n if (Y.utils.matchesId(w, op.left)) {\n // include the effect of op in w\n w.right = op.id;\n // exclude the effect of w in op\n op.left = w.left;\n } else if (Y.utils.compareIds(w.id, op.right)) {\n // similar..\n w.left = Y.utils.getLastId(op);\n op.right = w.right;\n }\n }\n }\n } else {\n throw new Error('Expected Insert Operation!');\n }\n }\n this._tryCallEvents(n);\n }\n /*\n Call this when you successfully awaited the execution of n Delete operations\n */\n\n }, {\n key: 'awaitedDeletes',\n value: function awaitedDeletes(n, newLeft) {\n var ops = this.waiting.splice(this.waiting.length - n);\n for (var j = 0; j < ops.length; j++) {\n var del = ops[j];\n if (del.struct === 'Delete') {\n if (newLeft != null) {\n for (var i = 0; i < this.waiting.length; i++) {\n var w = this.waiting[i];\n // We will just care about w.left\n if (w.struct === 'Insert' && Y.utils.compareIds(del.target, w.left)) {\n w.left = newLeft;\n }\n }\n }\n } else {\n throw new Error('Expected Delete Operation!');\n }\n }\n this._tryCallEvents(n);\n }\n /* (private)\n Try to execute the events for the waiting operations\n */\n\n }, {\n key: '_tryCallEvents',\n value: function _tryCallEvents(n) {\n this.awaiting -= n;\n if (this.awaiting === 0 && this.waiting.length > 0) {\n var ops = this.waiting;\n this.waiting = [];\n ops.forEach(this.onevent);\n }\n }\n }]);\n\n return EventHandler;\n }(EventListenerHandler);\n\n Y.utils.EventHandler = EventHandler;\n\n /*\n A wrapper for the definition of a custom type.\n Every custom type must have three properties:\n * struct\n - Structname of this type\n * initType\n - Given a model, creates a custom type\n * class\n - the constructor of the custom type (e.g. in order to inherit from a type)\n */\n\n var CustomType = // eslint-disable-line\n /* ::\n struct: any;\n initType: any;\n class: Function;\n name: String;\n */\n function CustomType(def) {\n _classCallCheck(this, CustomType);\n\n if (def.struct == null || def.initType == null || def.class == null || def.name == null) {\n throw new Error('Custom type was not initialized correctly!');\n }\n this.struct = def.struct;\n this.initType = def.initType;\n this.class = def.class;\n this.name = def.name;\n if (def.appendAdditionalInfo != null) {\n this.appendAdditionalInfo = def.appendAdditionalInfo;\n }\n this.parseArguments = (def.parseArguments || function () {\n return [this];\n }).bind(this);\n this.parseArguments.typeDefinition = this;\n };\n\n Y.utils.CustomType = CustomType;\n\n Y.utils.isTypeDefinition = function isTypeDefinition(v) {\n if (v != null) {\n if (v instanceof Y.utils.CustomType) return [v];else if (v.constructor === Array && v[0] instanceof Y.utils.CustomType) return v;else if (v instanceof Function && v.typeDefinition instanceof Y.utils.CustomType) return [v.typeDefinition];\n }\n return false;\n };\n\n /*\n Make a flat copy of an object\n (just copy properties)\n */\n function copyObject(o) {\n var c = {};\n for (var key in o) {\n c[key] = o[key];\n }\n return c;\n }\n Y.utils.copyObject = copyObject;\n\n /*\n Defines a smaller relation on Id's\n */\n function smaller(a, b) {\n return a[0] < b[0] || a[0] === b[0] && (a[1] < b[1] || _typeof(a[1]) < _typeof(b[1]));\n }\n Y.utils.smaller = smaller;\n\n function compareIds(id1, id2) {\n if (id1 == null || id2 == null) {\n return id1 === id2;\n } else {\n return id1[0] === id2[0] && id1[1] === id2[1];\n }\n }\n Y.utils.compareIds = compareIds;\n\n function matchesId(op, id) {\n if (id == null || op == null) {\n return id === op;\n } else {\n if (id[0] === op.id[0]) {\n if (op.content == null) {\n return id[1] === op.id[1];\n } else {\n return id[1] >= op.id[1] && id[1] < op.id[1] + op.content.length;\n }\n }\n }\n }\n Y.utils.matchesId = matchesId;\n\n function getLastId(op) {\n if (op.content == null || op.content.length === 1) {\n return op.id;\n } else {\n return [op.id[0], op.id[1] + op.content.length - 1];\n }\n }\n Y.utils.getLastId = getLastId;\n\n function createEmptyOpsArray(n) {\n var a = new Array(n);\n for (var i = 0; i < a.length; i++) {\n a[i] = {\n id: [null, null]\n };\n }\n return a;\n }\n\n function createSmallLookupBuffer(Store) {\n /*\n This buffer implements a very small buffer that temporarily stores operations\n after they are read / before they are written.\n The buffer basically implements FIFO. Often requested lookups will be re-queued every time they are looked up / written.\n It can speed up lookups on Operation Stores and State Stores. But it does not require notable use of memory or processing power.\n Good for os and ss, bot not for ds (because it often uses methods that require a flush)\n I tried to optimize this for performance, therefore no highlevel operations.\n */\n\n var SmallLookupBuffer = function (_Store) {\n _inherits(SmallLookupBuffer, _Store);\n\n function SmallLookupBuffer(arg) {\n _classCallCheck(this, SmallLookupBuffer);\n\n var _this2 = _possibleConstructorReturn(this, Object.getPrototypeOf(SmallLookupBuffer).call(this, arg));\n // super(...arguments) -- do this when this is supported by stable nodejs\n\n _this2.writeBuffer = createEmptyOpsArray(5);\n _this2.readBuffer = createEmptyOpsArray(10);\n return _this2;\n }\n\n _createClass(SmallLookupBuffer, [{\n key: 'find',\n value: regeneratorRuntime.mark(function find(id, noSuperCall) {\n var i, r, o;\n return regeneratorRuntime.wrap(function find$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n i = this.readBuffer.length - 1;\n\n case 1:\n if (!(i >= 0)) {\n _context.next = 10;\n break;\n }\n\n r = this.readBuffer[i];\n // we don't have to use compareids, because id is always defined!\n\n if (!(r.id[1] === id[1] && r.id[0] === id[0])) {\n _context.next = 7;\n break;\n }\n\n // found r\n // move r to the end of readBuffer\n for (; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1];\n }\n this.readBuffer[this.readBuffer.length - 1] = r;\n return _context.abrupt('return', r);\n\n case 7:\n i--;\n _context.next = 1;\n break;\n\n case 10:\n i = this.writeBuffer.length - 1;\n\n case 11:\n if (!(i >= 0)) {\n _context.next = 19;\n break;\n }\n\n r = this.writeBuffer[i];\n\n if (!(r.id[1] === id[1] && r.id[0] === id[0])) {\n _context.next = 16;\n break;\n }\n\n o = r;\n return _context.abrupt('break', 19);\n\n case 16:\n i--;\n _context.next = 11;\n break;\n\n case 19:\n if (!(i < 0 && noSuperCall === undefined)) {\n _context.next = 22;\n break;\n }\n\n return _context.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'find', this).call(this, id), 't0', 21);\n\n case 21:\n o = _context.t0;\n\n case 22:\n if (o != null) {\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1];\n }\n this.readBuffer[this.readBuffer.length - 1] = o;\n }\n return _context.abrupt('return', o);\n\n case 24:\n case 'end':\n return _context.stop();\n }\n }\n }, find, this);\n })\n }, {\n key: 'put',\n value: regeneratorRuntime.mark(function put(o) {\n var id, i, r, write;\n return regeneratorRuntime.wrap(function put$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n id = o.id;\n i = this.writeBuffer.length - 1;\n\n case 2:\n if (!(i >= 0)) {\n _context2.next = 11;\n break;\n }\n\n r = this.writeBuffer[i];\n\n if (!(r.id[1] === id[1] && r.id[0] === id[0])) {\n _context2.next = 8;\n break;\n }\n\n // is already in buffer\n // forget r, and move o to the end of writeBuffer\n for (; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1];\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o;\n return _context2.abrupt('break', 11);\n\n case 8:\n i--;\n _context2.next = 2;\n break;\n\n case 11:\n if (!(i < 0)) {\n _context2.next = 17;\n break;\n }\n\n // did not reach break in last loop\n // write writeBuffer[0]\n write = this.writeBuffer[0];\n\n if (!(write.id[0] !== null)) {\n _context2.next = 15;\n break;\n }\n\n return _context2.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'put', this).call(this, write), 't0', 15);\n\n case 15:\n // put o to the end of writeBuffer\n for (i = 0; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1];\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o;\n\n case 17:\n // check readBuffer for every occurence of o.id, overwrite if found\n // whether found or not, we'll append o to the readbuffer\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n r = this.readBuffer[i + 1];\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = o;\n } else {\n this.readBuffer[i] = r;\n }\n }\n this.readBuffer[this.readBuffer.length - 1] = o;\n\n case 19:\n case 'end':\n return _context2.stop();\n }\n }\n }, put, this);\n })\n }, {\n key: 'delete',\n value: regeneratorRuntime.mark(function _delete(id) {\n var i, r;\n return regeneratorRuntime.wrap(function _delete$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n for (i = 0; i < this.readBuffer.length; i++) {\n r = this.readBuffer[i];\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = {\n id: [null, null]\n };\n }\n }\n return _context3.delegateYield(this.flush(), 't0', 2);\n\n case 2:\n return _context3.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'delete', this).call(this, id), 't1', 3);\n\n case 3:\n case 'end':\n return _context3.stop();\n }\n }\n }, _delete, this);\n })\n }, {\n key: 'findWithLowerBound',\n value: regeneratorRuntime.mark(function findWithLowerBound(id) {\n var o,\n _args4 = arguments;\n return regeneratorRuntime.wrap(function findWithLowerBound$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n return _context4.delegateYield(this.find(id, true), 't0', 1);\n\n case 1:\n o = _context4.t0;\n\n if (!(o != null)) {\n _context4.next = 6;\n break;\n }\n\n return _context4.abrupt('return', o);\n\n case 6:\n return _context4.delegateYield(this.flush(), 't1', 7);\n\n case 7:\n return _context4.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'findWithLowerBound', this).apply(this, _args4), 't2', 8);\n\n case 8:\n return _context4.abrupt('return', _context4.t2);\n\n case 9:\n case 'end':\n return _context4.stop();\n }\n }\n }, findWithLowerBound, this);\n })\n }, {\n key: 'findWithUpperBound',\n value: regeneratorRuntime.mark(function findWithUpperBound(id) {\n var o,\n _args5 = arguments;\n return regeneratorRuntime.wrap(function findWithUpperBound$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n return _context5.delegateYield(this.find(id, true), 't0', 1);\n\n case 1:\n o = _context5.t0;\n\n if (!(o != null)) {\n _context5.next = 6;\n break;\n }\n\n return _context5.abrupt('return', o);\n\n case 6:\n return _context5.delegateYield(this.flush(), 't1', 7);\n\n case 7:\n return _context5.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'findWithUpperBound', this).apply(this, _args5), 't2', 8);\n\n case 8:\n return _context5.abrupt('return', _context5.t2);\n\n case 9:\n case 'end':\n return _context5.stop();\n }\n }\n }, findWithUpperBound, this);\n })\n }, {\n key: 'findNext',\n value: regeneratorRuntime.mark(function findNext() {\n var _args6 = arguments;\n return regeneratorRuntime.wrap(function findNext$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n return _context6.delegateYield(this.flush(), 't0', 1);\n\n case 1:\n return _context6.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'findNext', this).apply(this, _args6), 't1', 2);\n\n case 2:\n return _context6.abrupt('return', _context6.t1);\n\n case 3:\n case 'end':\n return _context6.stop();\n }\n }\n }, findNext, this);\n })\n }, {\n key: 'findPrev',\n value: regeneratorRuntime.mark(function findPrev() {\n var _args7 = arguments;\n return regeneratorRuntime.wrap(function findPrev$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n return _context7.delegateYield(this.flush(), 't0', 1);\n\n case 1:\n return _context7.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'findPrev', this).apply(this, _args7), 't1', 2);\n\n case 2:\n return _context7.abrupt('return', _context7.t1);\n\n case 3:\n case 'end':\n return _context7.stop();\n }\n }\n }, findPrev, this);\n })\n }, {\n key: 'iterate',\n value: regeneratorRuntime.mark(function iterate() {\n var _args8 = arguments;\n return regeneratorRuntime.wrap(function iterate$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n return _context8.delegateYield(this.flush(), 't0', 1);\n\n case 1:\n return _context8.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'iterate', this).apply(this, _args8), 't1', 2);\n\n case 2:\n case 'end':\n return _context8.stop();\n }\n }\n }, iterate, this);\n })\n }, {\n key: 'flush',\n value: regeneratorRuntime.mark(function flush() {\n var i, write;\n return regeneratorRuntime.wrap(function flush$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n i = 0;\n\n case 1:\n if (!(i < this.writeBuffer.length)) {\n _context9.next = 9;\n break;\n }\n\n write = this.writeBuffer[i];\n\n if (!(write.id[0] !== null)) {\n _context9.next = 6;\n break;\n }\n\n return _context9.delegateYield(_get(Object.getPrototypeOf(SmallLookupBuffer.prototype), 'put', this).call(this, write), 't0', 5);\n\n case 5:\n this.writeBuffer[i] = {\n id: [null, null]\n };\n\n case 6:\n i++;\n _context9.next = 1;\n break;\n\n case 9:\n case 'end':\n return _context9.stop();\n }\n }\n }, flush, this);\n })\n }]);\n\n return SmallLookupBuffer;\n }(Store);\n\n return SmallLookupBuffer;\n }\n Y.utils.createSmallLookupBuffer = createSmallLookupBuffer;\n};\n\n},{}],9:[function(require,module,exports){\n/* @flow */\n'use strict';\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nrequire('./Connector.js')(Y);\nrequire('./Database.js')(Y);\nrequire('./Transaction.js')(Y);\nrequire('./Struct.js')(Y);\nrequire('./Utils.js')(Y);\nrequire('./Connectors/Test.js')(Y);\n\nvar requiringModules = {};\n\nmodule.exports = Y;\nY.requiringModules = requiringModules;\n\nY.extend = function (name, value) {\n if (value instanceof Y.utils.CustomType) {\n Y[name] = value.parseArguments;\n } else {\n Y[name] = value;\n }\n if (requiringModules[name] != null) {\n requiringModules[name].resolve();\n delete requiringModules[name];\n }\n};\n\nY.requestModules = requestModules;\nfunction requestModules(modules) {\n // determine if this module was compiled for es5 or es6 (y.js vs. y.es6)\n // if Insert.execute is a Function, then it isnt a generator..\n // then load the es5(.js) files..\n var extention = typeof regeneratorRuntime !== 'undefined' ? '.js' : '.es6';\n var promises = [];\n for (var i = 0; i < modules.length; i++) {\n var module = modules[i].split('(')[0];\n var modulename = 'y-' + module.toLowerCase();\n if (Y[module] == null) {\n if (requiringModules[module] == null) {\n // module does not exist\n if (typeof window !== 'undefined' && window.Y !== 'undefined') {\n var imported;\n\n (function () {\n imported = document.createElement('script');\n\n imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention;\n document.head.appendChild(imported);\n\n var requireModule = {};\n requiringModules[module] = requireModule;\n requireModule.promise = new Promise(function (resolve) {\n requireModule.resolve = resolve;\n });\n promises.push(requireModule.promise);\n })();\n } else {\n require(modulename)(Y);\n }\n } else {\n promises.push(requiringModules[modules[i]].promise);\n }\n }\n }\n return Promise.all(promises);\n}\n\n/* ::\r\ntype MemoryOptions = {\r\n name: 'memory'\r\n}\r\ntype IndexedDBOptions = {\r\n name: 'indexeddb',\r\n namespace: string\r\n}\r\ntype DbOptions = MemoryOptions | IndexedDBOptions\r\n\r\ntype WebRTCOptions = {\r\n name: 'webrtc',\r\n room: string\r\n}\r\ntype WebsocketsClientOptions = {\r\n name: 'websockets-client',\r\n room: string\r\n}\r\ntype ConnectionOptions = WebRTCOptions | WebsocketsClientOptions\r\n\r\ntype YOptions = {\r\n connector: ConnectionOptions,\r\n db: DbOptions,\r\n types: Array,\r\n sourceDir: string,\r\n share: {[key: string]: TypeName}\r\n}\r\n*/\n\nfunction Y(opts /* :YOptions */) /* :Promise */{\n opts.types = opts.types != null ? opts.types : [];\n var modules = [opts.db.name, opts.connector.name].concat(opts.types);\n for (var name in opts.share) {\n modules.push(opts.share[name]);\n }\n Y.sourceDir = opts.sourceDir;\n return Y.requestModules(modules).then(function () {\n return new Promise(function (resolve, reject) {\n if (opts == null) reject('An options object is expected! ');else if (opts.connector == null) reject('You must specify a connector! (missing connector property)');else if (opts.connector.name == null) reject('You must specify connector name! (missing connector.name property)');else if (opts.db == null) reject('You must specify a database! (missing db property)');else if (opts.connector.name == null) reject('You must specify db name! (missing db.name property)');else if (opts.share == null) reject('You must specify a set of shared types!');else {\n var yconfig = new YConfig(opts);\n yconfig.db.whenUserIdSet(function () {\n yconfig.init(function () {\n resolve(yconfig);\n });\n });\n }\n });\n });\n}\n\nvar YConfig = function () {\n /* ::\r\n db: Y.AbstractDatabase;\r\n connector: Y.AbstractConnector;\r\n share: {[key: string]: any};\r\n options: Object;\r\n */\n\n function YConfig(opts, callback) {\n _classCallCheck(this, YConfig);\n\n this.options = opts;\n this.db = new Y[opts.db.name](this, opts.db);\n this.connector = new Y[opts.connector.name](this, opts.connector);\n }\n\n _createClass(YConfig, [{\n key: 'init',\n value: function init(callback) {\n var opts = this.options;\n var share = {};\n this.share = share;\n this.db.requestTransaction(regeneratorRuntime.mark(function requestTransaction() {\n var propertyname, typeConstructor, typeName, args, type, typedef, id;\n return regeneratorRuntime.wrap(function requestTransaction$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _context.t0 = regeneratorRuntime.keys(opts.share);\n\n case 1:\n if ((_context.t1 = _context.t0()).done) {\n _context.next = 21;\n break;\n }\n\n propertyname = _context.t1.value;\n typeConstructor = opts.share[propertyname].split('(');\n typeName = typeConstructor.splice(0, 1);\n args = [];\n\n if (!(typeConstructor.length === 1)) {\n _context.next = 14;\n break;\n }\n\n _context.prev = 7;\n\n args = JSON.parse('[' + typeConstructor[0].split(')')[0] + ']');\n _context.next = 14;\n break;\n\n case 11:\n _context.prev = 11;\n _context.t2 = _context['catch'](7);\n throw new Error('Was not able to parse type definition! (share.' + propertyname + ')');\n\n case 14:\n type = Y[typeName];\n typedef = type.typeDefinition;\n id = ['_', typedef.struct + '_' + typeName + '_' + propertyname + '_' + typeConstructor];\n return _context.delegateYield(this.createType(type.apply(typedef, args), id), 't3', 18);\n\n case 18:\n share[propertyname] = _context.t3;\n _context.next = 1;\n break;\n\n case 21:\n this.store.whenTransactionsFinished().then(callback);\n\n case 22:\n case 'end':\n return _context.stop();\n }\n }\n }, requestTransaction, this, [[7, 11]]);\n }));\n }\n }, {\n key: 'isConnected',\n value: function isConnected() {\n return this.connector.isSynced;\n }\n }, {\n key: 'disconnect',\n value: function disconnect() {\n return this.connector.disconnect();\n }\n }, {\n key: 'reconnect',\n value: function reconnect() {\n return this.connector.reconnect();\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n if (this.connector.destroy != null) {\n this.connector.destroy();\n } else {\n this.connector.disconnect();\n }\n var self = this;\n this.db.requestTransaction(regeneratorRuntime.mark(function _callee() {\n return regeneratorRuntime.wrap(function _callee$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n return _context2.delegateYield(self.db.destroy(), 't0', 1);\n\n case 1:\n self.connector = null;\n self.db = null;\n\n case 3:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee, this);\n }));\n }\n }]);\n\n return YConfig;\n}();\n\nif (typeof window !== 'undefined') {\n window.Y = Y;\n}\n\n},{\"./Connector.js\":3,\"./Connectors/Test.js\":4,\"./Database.js\":5,\"./Struct.js\":6,\"./Transaction.js\":7,\"./Utils.js\":8}]},{},[2,9])\n\n","/**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * https://raw.github.com/facebook/regenerator/master/LICENSE file. An\n * additional grant of patent rights can be found in the PATENTS file in\n * the same directory.\n */\n\n!(function(global) {\n \"use strict\";\n\n var hasOwn = Object.prototype.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n var inModule = typeof module === \"object\";\n var runtime = global.regeneratorRuntime;\n if (runtime) {\n if (inModule) {\n // If regeneratorRuntime is defined globally and we're in a module,\n // make the exports object identical to regeneratorRuntime.\n module.exports = runtime;\n }\n // Don't bother evaluating the rest of this file if the runtime was\n // already defined globally.\n return;\n }\n\n // Define the runtime globally (as expected by generated code) as either\n // module.exports (if we're in a module) or a new, empty object.\n runtime = global.regeneratorRuntime = inModule ? module.exports : {};\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided, then outerFn.prototype instanceof Generator.\n var generator = Object.create((outerFn || Generator).prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n runtime.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype;\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = \"GeneratorFunction\";\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n prototype[method] = function(arg) {\n return this._invoke(method, arg);\n };\n });\n }\n\n runtime.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n runtime.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n if (!(toStringTagSymbol in genFun)) {\n genFun[toStringTagSymbol] = \"GeneratorFunction\";\n }\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `value instanceof AwaitArgument` to determine if the yielded value is\n // meant to be awaited. Some may consider the name of this method too\n // cutesy, but they are curmudgeons.\n runtime.awrap = function(arg) {\n return new AwaitArgument(arg);\n };\n\n function AwaitArgument(arg) {\n this.arg = arg;\n }\n\n function AsyncIterator(generator) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value instanceof AwaitArgument) {\n return Promise.resolve(value.arg).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return Promise.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration. If the Promise is rejected, however, the\n // result for this iteration will be rejected with the same\n // reason. Note that rejections of yielded Promises are not\n // thrown back into the generator function, as is the case\n // when an awaited Promise is rejected. This difference in\n // behavior between yield and await is important, because it\n // allows the consumer to decide what to do with the yielded\n // rejection (swallow it and continue, manually .throw it back\n // into the generator, abandon iteration, whatever). With\n // await, by contrast, there is no opportunity to examine the\n // rejection reason outside the generator function, so the\n // only option is to throw it from the await expression, and\n // let the generator function handle the exception.\n result.value = unwrapped;\n resolve(result);\n }, reject);\n }\n }\n\n if (typeof process === \"object\" && process.domain) {\n invoke = process.domain.bind(invoke);\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new Promise(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n runtime.async = function(innerFn, outerFn, self, tryLocsList) {\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList)\n );\n\n return runtime.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n if (method === \"return\" ||\n (method === \"throw\" && delegate.iterator[method] === undefined)) {\n // A return or throw (when the delegate iterator has no throw\n // method) always terminates the yield* loop.\n context.delegate = null;\n\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n var returnMethod = delegate.iterator[\"return\"];\n if (returnMethod) {\n var record = tryCatch(returnMethod, delegate.iterator, arg);\n if (record.type === \"throw\") {\n // If the return method threw an exception, let that\n // exception prevail over the original return or throw.\n method = \"throw\";\n arg = record.arg;\n continue;\n }\n }\n\n if (method === \"return\") {\n // Continue with the outer return, now that the delegate\n // iterator has been terminated.\n continue;\n }\n }\n\n var record = tryCatch(\n delegate.iterator[method],\n delegate.iterator,\n arg\n );\n\n if (record.type === \"throw\") {\n context.delegate = null;\n\n // Like returning generator.throw(uncaught), but without the\n // overhead of an extra function call.\n method = \"throw\";\n arg = record.arg;\n continue;\n }\n\n // Delegate generator ran and handled its own exceptions so\n // regardless of what the method was, we continue as if it is\n // \"next\" with an undefined arg.\n method = \"next\";\n arg = undefined;\n\n var info = record.arg;\n if (info.done) {\n context[delegate.resultName] = info.value;\n context.next = delegate.nextLoc;\n } else {\n state = GenStateSuspendedYield;\n return info;\n }\n\n context.delegate = null;\n }\n\n if (method === \"next\") {\n if (state === GenStateSuspendedYield) {\n context.sent = arg;\n } else {\n context.sent = undefined;\n }\n\n } else if (method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw arg;\n }\n\n if (context.dispatchException(arg)) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n method = \"next\";\n arg = undefined;\n }\n\n } else if (method === \"return\") {\n context.abrupt(\"return\", arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n var info = {\n value: record.arg,\n done: context.done\n };\n\n if (record.arg === ContinueSentinel) {\n if (context.delegate && method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n arg = undefined;\n }\n } else {\n return info;\n }\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(arg) call above.\n method = \"throw\";\n arg = record.arg;\n }\n }\n };\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp[toStringTagSymbol] = \"Generator\";\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n runtime.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n runtime.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n this.sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n return !!caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.next = finallyEntry.finallyLoc;\n } else {\n this.complete(record);\n }\n\n return ContinueSentinel;\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = record.arg;\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n return ContinueSentinel;\n }\n };\n})(\n // Among the various tricks for obtaining a reference to the global\n // object, this seems to be the most reliable technique that does not\n // use indirect eval (which violates Content Security Policy).\n typeof global === \"object\" ? global :\n typeof window === \"object\" ? window :\n typeof self === \"object\" ? self : this\n);\n","/* @flow */\n'use strict'\n\nmodule.exports = function (Y/* :any */) {\n class AbstractConnector {\n /* ::\n y: YConfig;\n role: SyncRole;\n connections: Object;\n isSynced: boolean;\n userEventListeners: Array;\n whenSyncedListeners: Array;\n currentSyncTarget: ?UserId;\n syncingClients: Array;\n forwardToSyncingClients: boolean;\n debug: boolean;\n broadcastedHB: boolean;\n syncStep2: Promise;\n userId: UserId;\n send: Function;\n broadcast: Function;\n broadcastOpBuffer: Array;\n protocolVersion: number;\n */\n /*\n opts contains the following information:\n role : String Role of this client (\"master\" or \"slave\")\n userId : String Uniquely defines the user.\n debug: Boolean Whether to print debug messages (optional)\n */\n constructor (y, opts) {\n this.y = y\n if (opts == null) {\n opts = {}\n }\n if (opts.role == null || opts.role === 'master') {\n this.role = 'master'\n } else if (opts.role === 'slave') {\n this.role = 'slave'\n } else {\n throw new Error(\"Role must be either 'master' or 'slave'!\")\n }\n this.y.db.forwardAppliedOperations = opts.forwardAppliedOperations || false\n this.role = opts.role\n this.connections = {}\n this.isSynced = false\n this.userEventListeners = []\n this.whenSyncedListeners = []\n this.currentSyncTarget = null\n this.syncingClients = []\n this.forwardToSyncingClients = opts.forwardToSyncingClients !== false\n this.debug = opts.debug === true\n this.broadcastedHB = false\n this.syncStep2 = Promise.resolve()\n this.broadcastOpBuffer = []\n this.protocolVersion = 11\n }\n reconnect () {\n }\n disconnect () {\n this.connections = {}\n this.isSynced = false\n this.currentSyncTarget = null\n this.broadcastedHB = false\n this.syncingClients = []\n this.whenSyncedListeners = []\n return this.y.db.stopGarbageCollector()\n }\n setUserId (userId) {\n if (this.userId == null) {\n this.userId = userId\n return this.y.db.setUserId(userId)\n } else {\n return null\n }\n }\n onUserEvent (f) {\n this.userEventListeners.push(f)\n }\n userLeft (user) {\n if (this.connections[user] != null) {\n delete this.connections[user]\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null\n this.findNextSyncTarget()\n }\n this.syncingClients = this.syncingClients.filter(function (cli) {\n return cli !== user\n })\n for (var f of this.userEventListeners) {\n f({\n action: 'userLeft',\n user: user\n })\n }\n }\n }\n userJoined (user, role) {\n if (role == null) {\n throw new Error('You must specify the role of the joined user!')\n }\n if (this.connections[user] != null) {\n throw new Error('This user already joined!')\n }\n this.connections[user] = {\n isSynced: false,\n role: role\n }\n for (var f of this.userEventListeners) {\n f({\n action: 'userJoined',\n user: user,\n role: role\n })\n }\n if (this.currentSyncTarget == null) {\n this.findNextSyncTarget()\n }\n }\n // Execute a function _when_ we are connected.\n // If not connected, wait until connected\n whenSynced (f) {\n if (this.isSynced) {\n f()\n } else {\n this.whenSyncedListeners.push(f)\n }\n }\n /*\n\n returns false, if there is no sync target\n true otherwise\n */\n findNextSyncTarget () {\n if (this.currentSyncTarget != null || this.isSynced) {\n return // \"The current sync has not finished!\"\n }\n\n var syncUser = null\n for (var uid in this.connections) {\n if (!this.connections[uid].isSynced) {\n syncUser = uid\n break\n }\n }\n var conn = this\n if (syncUser != null) {\n this.currentSyncTarget = syncUser\n this.y.db.requestTransaction(function *() {\n var stateSet = yield* this.getStateSet()\n var deleteSet = yield* this.getDeleteSet()\n conn.send(syncUser, {\n type: 'sync step 1',\n stateSet: stateSet,\n deleteSet: deleteSet,\n protocolVersion: conn.protocolVersion\n })\n })\n } else {\n this.y.db.requestTransaction(function *() {\n // it is crucial that isSynced is set at the time garbageCollectAfterSync is called\n conn.isSynced = true\n yield* this.garbageCollectAfterSync()\n // call whensynced listeners\n for (var f of conn.whenSyncedListeners) {\n f()\n }\n conn.whenSyncedListeners = []\n })\n }\n }\n send (uid, message) {\n if (this.debug) {\n console.log(`send ${this.userId} -> ${uid}: ${message.type}`, message) // eslint-disable-line\n }\n }\n /*\n Buffer operations, and broadcast them when ready.\n */\n broadcastOps (ops) {\n ops = ops.map(function (op) {\n return Y.Struct[op.struct].encode(op)\n })\n var self = this\n function broadcastOperations () {\n if (self.broadcastOpBuffer.length > 0) {\n self.broadcast({\n type: 'update',\n ops: self.broadcastOpBuffer\n })\n self.broadcastOpBuffer = []\n }\n }\n if (this.broadcastOpBuffer.length === 0) {\n this.broadcastOpBuffer = ops\n if (this.y.db.transactionInProgress) {\n this.y.db.whenTransactionsFinished().then(broadcastOperations)\n } else {\n setTimeout(broadcastOperations, 0)\n }\n } else {\n this.broadcastOpBuffer = this.broadcastOpBuffer.concat(ops)\n }\n }\n /*\n You received a raw message, and you know that it is intended for Yjs. Then call this function.\n */\n receiveMessage (sender/* :UserId */, message/* :Message */) {\n if (sender === this.userId) {\n return\n }\n if (this.debug) {\n console.log(`receive ${sender} -> ${this.userId}: ${message.type}`, JSON.parse(JSON.stringify(message))) // eslint-disable-line\n }\n if (message.protocolVersion != null && message.protocolVersion !== this.protocolVersion) {\n console.error(\n `You tried to sync with a yjs instance that has a different protocol version\n (You: ${this.protocolVersion}, Client: ${message.protocolVersion}).\n The sync was stopped. You need to upgrade your dependencies (especially Yjs & the Connector)!\n `)\n this.send(sender, {\n type: 'sync stop',\n protocolVersion: this.protocolVersion\n })\n return\n }\n if (message.type === 'sync step 1') {\n let conn = this\n let m = message\n this.y.db.requestTransaction(function *() {\n var currentStateSet = yield* this.getStateSet()\n yield* this.applyDeleteSet(m.deleteSet)\n\n var ds = yield* this.getDeleteSet()\n var ops = yield* this.getOperations(m.stateSet)\n conn.send(sender, {\n type: 'sync step 2',\n os: ops,\n stateSet: currentStateSet,\n deleteSet: ds,\n protocolVersion: this.protocolVersion\n })\n if (this.forwardToSyncingClients) {\n conn.syncingClients.push(sender)\n setTimeout(function () {\n conn.syncingClients = conn.syncingClients.filter(function (cli) {\n return cli !== sender\n })\n conn.send(sender, {\n type: 'sync done'\n })\n }, 5000) // TODO: conn.syncingClientDuration)\n } else {\n conn.send(sender, {\n type: 'sync done'\n })\n }\n conn._setSyncedWith(sender)\n })\n } else if (message.type === 'sync step 2') {\n let conn = this\n var broadcastHB = !this.broadcastedHB\n this.broadcastedHB = true\n var db = this.y.db\n var defer = {}\n defer.promise = new Promise(function (resolve) {\n defer.resolve = resolve\n })\n this.syncStep2 = defer.promise\n let m /* :MessageSyncStep2 */ = message\n db.requestTransaction(function * () {\n yield* this.applyDeleteSet(m.deleteSet)\n this.store.apply(m.os)\n db.requestTransaction(function * () {\n var ops = yield* this.getOperations(m.stateSet)\n if (ops.length > 0) {\n if (!broadcastHB) { // TODO: consider to broadcast here..\n conn.send(sender, {\n type: 'update',\n ops: ops\n })\n } else {\n // broadcast only once!\n conn.broadcastOps(ops)\n }\n }\n defer.resolve()\n })\n })\n } else if (message.type === 'sync done') {\n var self = this\n this.syncStep2.then(function () {\n self._setSyncedWith(sender)\n })\n } else if (message.type === 'update') {\n if (this.forwardToSyncingClients) {\n for (var client of this.syncingClients) {\n this.send(client, message)\n }\n }\n if (this.y.db.forwardAppliedOperations) {\n var delops = message.ops.filter(function (o) {\n return o.struct === 'Delete'\n })\n if (delops.length > 0) {\n this.broadcastOps(delops)\n }\n }\n this.y.db.apply(message.ops)\n }\n }\n _setSyncedWith (user) {\n var conn = this.connections[user]\n if (conn != null) {\n conn.isSynced = true\n }\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null\n this.findNextSyncTarget()\n }\n }\n /*\n Currently, the HB encodes operations as JSON. For the moment I want to keep it\n that way. Maybe we support encoding in the HB as XML in the future, but for now I don't want\n too much overhead. Y is very likely to get changed a lot in the future\n\n Because we don't want to encode JSON as string (with character escaping, wich makes it pretty much unreadable)\n we encode the JSON as XML.\n\n When the HB support encoding as XML, the format should look pretty much like this.\n\n does not support primitive values as array elements\n expects an ltx (less than xml) object\n */\n parseMessageFromXml (m/* :any */) {\n function parseArray (node) {\n for (var n of node.children) {\n if (n.getAttribute('isArray') === 'true') {\n return parseArray(n)\n } else {\n return parseObject(n)\n }\n }\n }\n function parseObject (node/* :any */) {\n var json = {}\n for (var attrName in node.attrs) {\n var value = node.attrs[attrName]\n var int = parseInt(value, 10)\n if (isNaN(int) || ('' + int) !== value) {\n json[attrName] = value\n } else {\n json[attrName] = int\n }\n }\n for (var n/* :any */ in node.children) {\n var name = n.name\n if (n.getAttribute('isArray') === 'true') {\n json[name] = parseArray(n)\n } else {\n json[name] = parseObject(n)\n }\n }\n return json\n }\n parseObject(m)\n }\n /*\n encode message in xml\n we use string because Strophe only accepts an \"xml-string\"..\n So {a:4,b:{c:5}} will look like\n \n \n \n m - ltx element\n json - Object\n */\n encodeMessageToXml (msg, obj) {\n // attributes is optional\n function encodeObject (m, json) {\n for (var name in json) {\n var value = json[name]\n if (name == null) {\n // nop\n } else if (value.constructor === Object) {\n encodeObject(m.c(name), value)\n } else if (value.constructor === Array) {\n encodeArray(m.c(name), value)\n } else {\n m.setAttribute(name, value)\n }\n }\n }\n function encodeArray (m, array) {\n m.setAttribute('isArray', 'true')\n for (var e of array) {\n if (e.constructor === Object) {\n encodeObject(m.c('array-element'), e)\n } else {\n encodeArray(m.c('array-element'), e)\n }\n }\n }\n if (obj.constructor === Object) {\n encodeObject(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj)\n } else if (obj.constructor === Array) {\n encodeArray(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj)\n } else {\n throw new Error(\"I can't encode this json!\")\n }\n }\n }\n Y.AbstractConnector = AbstractConnector\n}\n","/* global getRandom, async */\n'use strict'\n\nmodule.exports = function (Y) {\n var globalRoom = {\n users: {},\n buffers: {}, // TODO: reimplement this idea. This does not cover all cases!! Here, you have a queue which is unrealistic (i.e. think about multiple incoming connections)\n removeUser: function (user) {\n for (var i in this.users) {\n this.users[i].userLeft(user)\n }\n delete this.users[user]\n delete this.buffers[user]\n },\n addUser: function (connector) {\n this.users[connector.userId] = connector\n this.buffers[connector.userId] = {}\n for (var uname in this.users) {\n if (uname !== connector.userId) {\n var u = this.users[uname]\n u.userJoined(connector.userId, 'master')\n connector.userJoined(u.userId, 'master')\n }\n }\n },\n whenTransactionsFinished: function () {\n var ps = []\n for (var name in this.users) {\n ps.push(this.users[name].y.db.whenTransactionsFinished())\n }\n return Promise.all(ps)\n },\n flushOne: function flushOne () {\n var bufs = []\n for (var receiver in globalRoom.buffers) {\n let buff = globalRoom.buffers[receiver]\n var push = false\n for (let sender in buff) {\n if (buff[sender].length > 0) {\n push = true\n break\n }\n }\n if (push) {\n bufs.push(receiver)\n }\n }\n if (bufs.length > 0) {\n var userId = getRandom(bufs)\n let buff = globalRoom.buffers[userId]\n let sender = getRandom(Object.keys(buff))\n var m = buff[sender].shift()\n if (buff[sender].length === 0) {\n delete buff[sender]\n }\n var user = globalRoom.users[userId]\n user.receiveMessage(m[0], m[1])\n return user.y.db.whenTransactionsFinished()\n } else {\n return false\n }\n },\n flushAll: function () {\n return new Promise(function (resolve) {\n // flushes may result in more created operations,\n // flush until there is nothing more to flush\n function nextFlush () {\n var c = globalRoom.flushOne()\n if (c) {\n while (c) {\n c = globalRoom.flushOne()\n }\n globalRoom.whenTransactionsFinished().then(nextFlush)\n } else {\n setTimeout(function () {\n var c = globalRoom.flushOne()\n if (c) {\n c.then(function () {\n globalRoom.whenTransactionsFinished().then(nextFlush)\n })\n } else {\n resolve()\n }\n }, 10)\n }\n }\n globalRoom.whenTransactionsFinished().then(nextFlush)\n })\n }\n }\n Y.utils.globalRoom = globalRoom\n\n var userIdCounter = 0\n\n class Test extends Y.AbstractConnector {\n constructor (y, options) {\n if (options === undefined) {\n throw new Error('Options must not be undefined!')\n }\n options.role = 'master'\n options.forwardToSyncingClients = false\n super(y, options)\n this.setUserId((userIdCounter++) + '').then(() => {\n globalRoom.addUser(this)\n })\n this.globalRoom = globalRoom\n this.syncingClientDuration = 0\n }\n receiveMessage (sender, m) {\n super.receiveMessage(sender, JSON.parse(JSON.stringify(m)))\n }\n send (userId, message) {\n var buffer = globalRoom.buffers[userId]\n if (buffer != null) {\n if (buffer[this.userId] == null) {\n buffer[this.userId] = []\n }\n buffer[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n broadcast (message) {\n for (var key in globalRoom.buffers) {\n var buff = globalRoom.buffers[key]\n if (buff[this.userId] == null) {\n buff[this.userId] = []\n }\n buff[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n isDisconnected () {\n return globalRoom.users[this.userId] == null\n }\n reconnect () {\n if (this.isDisconnected()) {\n globalRoom.addUser(this)\n super.reconnect()\n }\n return Y.utils.globalRoom.flushAll()\n }\n disconnect () {\n if (!this.isDisconnected()) {\n globalRoom.removeUser(this.userId)\n super.disconnect()\n }\n return this.y.db.whenTransactionsFinished()\n }\n flush () {\n var self = this\n return async(function * () {\n var buff = globalRoom.buffers[self.userId]\n while (Object.keys(buff).length > 0) {\n var sender = getRandom(Object.keys(buff))\n var m = buff[sender].shift()\n if (buff[sender].length === 0) {\n delete buff[sender]\n }\n this.receiveMessage(m[0], m[1])\n }\n yield self.whenTransactionsFinished()\n })\n }\n }\n\n Y.Test = Test\n}\n","/* @flow */\n'use strict'\n\nmodule.exports = function (Y /* :any */) {\n /*\n Partial definition of an OperationStore.\n TODO: name it Database, operation store only holds operations.\n\n A database definition must alse define the following methods:\n * logTable() (optional)\n - show relevant information information in a table\n * requestTransaction(makeGen)\n - request a transaction\n * destroy()\n - destroy the database\n */\n class AbstractDatabase {\n /* ::\n y: YConfig;\n forwardAppliedOperations: boolean;\n listenersById: Object;\n listenersByIdExecuteNow: Array;\n listenersByIdRequestPending: boolean;\n initializedTypes: Object;\n whenUserIdSetListener: ?Function;\n waitingTransactions: Array;\n transactionInProgress: boolean;\n executeOrder: Array;\n gc1: Array;\n gc2: Array;\n gcTimeout: number;\n gcInterval: any;\n garbageCollect: Function;\n executeOrder: Array; // for debugging only\n userId: UserId;\n opClock: number;\n transactionsFinished: ?{promise: Promise, resolve: any};\n transact: (x: ?Generator) => any;\n */\n constructor (y, opts) {\n this.y = y\n var os = this\n this.userId = null\n var resolve\n this.userIdPromise = new Promise(function (r) {\n resolve = r\n })\n this.userIdPromise.resolve = resolve\n // whether to broadcast all applied operations (insert & delete hook)\n this.forwardAppliedOperations = false\n // E.g. this.listenersById[id] : Array\n this.listenersById = {}\n // Execute the next time a transaction is requested\n this.listenersByIdExecuteNow = []\n // A transaction is requested\n this.listenersByIdRequestPending = false\n /* To make things more clear, the following naming conventions:\n * ls : we put this.listenersById on ls\n * l : Array\n * id : Id (can't use as property name)\n * sid : String (converted from id via JSON.stringify\n so we can use it as a property name)\n\n Always remember to first overwrite\n a property before you iterate over it!\n */\n // TODO: Use ES7 Weak Maps. This way types that are no longer user,\n // wont be kept in memory.\n this.initializedTypes = {}\n this.waitingTransactions = []\n this.transactionInProgress = false\n this.transactionIsFlushed = false\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n this.executeOrder = []\n }\n this.gc1 = [] // first stage\n this.gc2 = [] // second stage -> after that, remove the op\n this.gcTimeout = !opts.gcTimeout ? 50000 : opts.gcTimeoutÅ›\n function garbageCollect () {\n return os.whenTransactionsFinished().then(function () {\n if (os.gc1.length > 0 || os.gc2.length > 0) {\n if (!os.y.isConnected()) {\n console.warn('gc should be empty when disconnected!')\n }\n return new Promise((resolve) => {\n os.requestTransaction(function * () {\n if (os.y.connector != null && os.y.connector.isSynced) {\n for (var i = 0; i < os.gc2.length; i++) {\n var oid = os.gc2[i]\n yield* this.garbageCollectOperation(oid)\n }\n os.gc2 = os.gc1\n os.gc1 = []\n }\n // TODO: Use setInterval here instead (when garbageCollect is called several times there will be several timeouts..)\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout)\n }\n resolve()\n })\n })\n } else {\n // TODO: see above\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout)\n }\n return Promise.resolve()\n }\n })\n }\n this.garbageCollect = garbageCollect\n if (this.gcTimeout > 0) {\n garbageCollect()\n }\n }\n queueGarbageCollector (id) {\n if (this.y.isConnected()) {\n this.gc1.push(id)\n }\n }\n emptyGarbageCollector () {\n return new Promise(resolve => {\n var check = () => {\n if (this.gc1.length > 0 || this.gc2.length > 0) {\n this.garbageCollect().then(check)\n } else {\n resolve()\n }\n }\n setTimeout(check, 0)\n })\n }\n addToDebug () {\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n var command /* :string */ = Array.prototype.map.call(arguments, function (s) {\n if (typeof s === 'string') {\n return s\n } else {\n return JSON.stringify(s)\n }\n }).join('').replace(/\"/g, \"'\").replace(/,/g, ', ').replace(/:/g, ': ')\n this.executeOrder.push(command)\n }\n }\n getDebugData () {\n console.log(this.executeOrder.join('\\n'))\n }\n stopGarbageCollector () {\n var self = this\n return new Promise(function (resolve) {\n self.requestTransaction(function * () {\n var ungc /* :Array */ = self.gc1.concat(self.gc2)\n self.gc1 = []\n self.gc2 = []\n for (var i = 0; i < ungc.length; i++) {\n var op = yield* this.getOperation(ungc[i])\n if (op != null) {\n delete op.gc\n yield* this.setOperation(op)\n }\n }\n resolve()\n })\n })\n }\n /*\n Try to add to GC.\n\n TODO: rename this function\n\n Rulez:\n * Only gc if this user is online\n * The most left element in a list must not be gc'd.\n => There is at least one element in the list\n\n returns true iff op was added to GC\n */\n * addToGarbageCollector (op, left) {\n if (\n op.gc == null &&\n op.deleted === true\n ) {\n var gc = false\n if (left != null && left.deleted === true) {\n gc = true\n } else if (op.content != null && op.content.length > 1) {\n op = yield* this.getInsertionCleanStart([op.id[0], op.id[1] + 1])\n gc = true\n }\n if (gc) {\n op.gc = true\n yield* this.setOperation(op)\n this.store.queueGarbageCollector(op.id)\n return true\n }\n }\n return false\n }\n removeFromGarbageCollector (op) {\n function filter (o) {\n return !Y.utils.compareIds(o, op.id)\n }\n this.gc1 = this.gc1.filter(filter)\n this.gc2 = this.gc2.filter(filter)\n delete op.gc\n }\n * destroy () {\n clearInterval(this.gcInterval)\n this.gcInterval = null\n for (var key in this.initializedTypes) {\n var type = this.initializedTypes[key]\n if (type._destroy != null) {\n type._destroy()\n } else {\n console.error('The type you included does not provide destroy functionality, it will remain in memory (updating your packages will help).')\n }\n }\n }\n setUserId (userId) {\n if (!this.userIdPromise.inProgress) {\n this.userIdPromise.inProgress = true\n var self = this\n self.requestTransaction(function * () {\n self.userId = userId\n var state = yield* this.getState(userId)\n self.opClock = state.clock\n self.userIdPromise.resolve(userId)\n })\n }\n return this.userIdPromise\n }\n whenUserIdSet (f) {\n this.userIdPromise.then(f)\n }\n getNextOpId (numberOfIds) {\n if (numberOfIds == null) {\n throw new Error('getNextOpId expects the number of created ids to create!')\n } else if (this.userId == null) {\n throw new Error('OperationStore not yet initialized!')\n } else {\n var id = [this.userId, this.opClock]\n this.opClock += numberOfIds\n return id\n }\n }\n /*\n Apply a list of operations.\n\n * get a transaction\n * check whether all Struct.*.requiredOps are in the OS\n * check if it is an expected op (otherwise wait for it)\n * check if was deleted, apply a delete operation after op was applied\n */\n apply (ops) {\n for (var i = 0; i < ops.length; i++) {\n var o = ops[i]\n if (o.id == null || o.id[0] !== this.y.connector.userId) {\n var required = Y.Struct[o.struct].requiredOps(o)\n if (o.requires != null) {\n required = required.concat(o.requires)\n }\n this.whenOperationsExist(required, o)\n }\n }\n }\n /*\n op is executed as soon as every operation requested is available.\n Note that Transaction can (and should) buffer requests.\n */\n whenOperationsExist (ids, op) {\n if (ids.length > 0) {\n let listener = {\n op: op,\n missing: ids.length\n }\n\n for (let i = 0; i < ids.length; i++) {\n let id = ids[i]\n let sid = JSON.stringify(id)\n let l = this.listenersById[sid]\n if (l == null) {\n l = []\n this.listenersById[sid] = l\n }\n l.push(listener)\n }\n } else {\n this.listenersByIdExecuteNow.push({\n op: op\n })\n }\n\n if (this.listenersByIdRequestPending) {\n return\n }\n\n this.listenersByIdRequestPending = true\n var store = this\n\n this.requestTransaction(function * () {\n var exeNow = store.listenersByIdExecuteNow\n store.listenersByIdExecuteNow = []\n\n var ls = store.listenersById\n store.listenersById = {}\n\n store.listenersByIdRequestPending = false\n\n for (let key = 0; key < exeNow.length; key++) {\n let o = exeNow[key].op\n yield* store.tryExecute.call(this, o)\n }\n\n for (var sid in ls) {\n var l = ls[sid]\n var id = JSON.parse(sid)\n var op\n if (typeof id[1] === 'string') {\n op = yield* this.getOperation(id)\n } else {\n op = yield* this.getInsertion(id)\n }\n if (op == null) {\n store.listenersById[sid] = l\n } else {\n for (let i = 0; i < l.length; i++) {\n let listener = l[i]\n let o = listener.op\n if (--listener.missing === 0) {\n yield* store.tryExecute.call(this, o)\n }\n }\n }\n }\n })\n }\n /*\n Actually execute an operation, when all expected operations are available.\n */\n /* :: // TODO: this belongs somehow to transaction\n store: Object;\n getOperation: any;\n isGarbageCollected: any;\n addOperation: any;\n whenOperationsExist: any;\n */\n * tryExecute (op) {\n this.store.addToDebug('yield* this.store.tryExecute.call(this, ', JSON.stringify(op), ')')\n if (op.struct === 'Delete') {\n yield* Y.Struct.Delete.execute.call(this, op)\n // this is now called in Transaction.deleteOperation!\n // yield* this.store.operationAdded(this, op)\n } else {\n // check if this op was defined\n var defined = yield* this.getInsertion(op.id)\n while (defined != null && defined.content != null) {\n // check if this op has a longer content in the case it is defined\n if (defined.id[1] + defined.content.length < op.id[1] + op.content.length) {\n var overlapSize = defined.content.length - (op.id[1] - defined.id[1])\n op.content.splice(0, overlapSize)\n op.id = [op.id[0], op.id[1] + overlapSize]\n op.left = Y.utils.getLastId(defined)\n op.origin = op.left\n defined = yield* this.getOperation(op.id) // getOperation suffices here\n } else {\n break\n }\n }\n if (defined == null) {\n var isGarbageCollected = yield* this.isGarbageCollected(op.id)\n if (!isGarbageCollected) {\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n\n // if insertion, try to combine with left\n yield* this.tryCombineWithLeft(op)\n }\n }\n }\n }\n // called by a transaction when an operation is added\n * operationAdded (transaction, op) {\n // increase SS\n yield* transaction.updateState(op.id[0])\n\n var opLen = op.content != null ? op.content.length : 1\n for (let i = 0; i < opLen; i++) {\n // notify whenOperation listeners (by id)\n var sid = JSON.stringify([op.id[0], op.id[1] + i])\n var l = this.listenersById[sid]\n delete this.listenersById[sid]\n\n if (l != null) {\n for (var key in l) {\n var listener = l[key]\n if (--listener.missing === 0) {\n this.whenOperationsExist([], listener.op)\n }\n }\n }\n }\n var t = this.initializedTypes[JSON.stringify(op.parent)]\n\n // if parent is deleted, mark as gc'd and return\n if (op.parent != null) {\n var parentIsDeleted = yield* transaction.isDeleted(op.parent)\n if (parentIsDeleted) {\n yield* transaction.deleteList(op.id)\n return\n }\n }\n\n // notify parent, if it was instanciated as a custom type\n if (t != null) {\n let o = Y.utils.copyObject(op)\n yield* t._changed(transaction, o)\n }\n if (!op.deleted) {\n // Delete if DS says this is actually deleted\n var len = op.content != null ? op.content.length : 1\n var startId = op.id // You must not use op.id in the following loop, because op will change when deleted\n for (let i = 0; i < len; i++) {\n var id = [startId[0], startId[1] + i]\n var opIsDeleted = yield* transaction.isDeleted(id)\n if (opIsDeleted) {\n var delop = {\n struct: 'Delete',\n target: id\n }\n yield* this.tryExecute.call(transaction, delop)\n }\n }\n }\n }\n whenTransactionsFinished () {\n if (this.transactionInProgress) {\n if (this.transactionsFinished == null) {\n var resolve\n var promise = new Promise(function (r) {\n resolve = r\n })\n this.transactionsFinished = {\n resolve: resolve,\n promise: promise\n }\n return promise\n } else {\n return this.transactionsFinished.promise\n }\n } else {\n return Promise.resolve()\n }\n }\n // Check if there is another transaction request.\n // * the last transaction is always a flush :)\n getNextRequest () {\n if (this.waitingTransactions.length === 0) {\n if (this.transactionIsFlushed) {\n this.transactionInProgress = false\n this.transactionIsFlushed = false\n if (this.transactionsFinished != null) {\n this.transactionsFinished.resolve()\n this.transactionsFinished = null\n }\n return null\n } else {\n this.transactionIsFlushed = true\n return function * () {\n yield* this.flush()\n }\n }\n } else {\n this.transactionIsFlushed = false\n return this.waitingTransactions.shift()\n }\n }\n requestTransaction (makeGen/* :any */, callImmediately) {\n this.waitingTransactions.push(makeGen)\n if (!this.transactionInProgress) {\n this.transactionInProgress = true\n if (false || callImmediately) { // TODO: decide whether this is ok or not..\n this.transact(this.getNextRequest())\n } else {\n var self = this\n setTimeout(function () {\n self.transact(self.getNextRequest())\n }, 0)\n }\n }\n }\n }\n Y.AbstractDatabase = AbstractDatabase\n}\n","/* @flow */\n'use strict'\n\n/*\n An operation also defines the structure of a type. This is why operation and\n structure are used interchangeably here.\n\n It must be of the type Object. I hope to achieve some performance\n improvements when working on databases that support the json format.\n\n An operation must have the following properties:\n\n * encode\n - Encode the structure in a readable format (preferably string- todo)\n * decode (todo)\n - decode structure to json\n * execute\n - Execute the semantics of an operation.\n * requiredOps\n - Operations that are required to execute this operation.\n*/\nmodule.exports = function (Y/* :any */) {\n var Struct = {\n /* This is the only operation that is actually not a structure, because\n it is not stored in the OS. This is why it _does not_ have an id\n\n op = {\n target: Id\n }\n */\n Delete: {\n encode: function (op) {\n return op\n },\n requiredOps: function (op) {\n return [] // [op.target]\n },\n execute: function * (op) {\n return yield* this.deleteOperation(op.target, op.length || 1)\n }\n },\n Insert: {\n /* {\n content: [any],\n opContent: Id,\n id: Id,\n left: Id,\n origin: Id,\n right: Id,\n parent: Id,\n parentSub: string (optional), // child of Map type\n }\n */\n encode: function (op/* :Insertion */) /* :Insertion */ {\n // TODO: you could not send the \"left\" property, then you also have to\n // \"op.left = null\" in $execute or $decode\n var e/* :any */ = {\n id: op.id,\n left: op.left,\n right: op.right,\n origin: op.origin,\n parent: op.parent,\n struct: op.struct\n }\n if (op.parentSub != null) {\n e.parentSub = op.parentSub\n }\n if (op.hasOwnProperty('opContent')) {\n e.opContent = op.opContent\n } else {\n e.content = op.content.slice()\n }\n\n return e\n },\n requiredOps: function (op) {\n var ids = []\n if (op.left != null) {\n ids.push(op.left)\n }\n if (op.right != null) {\n ids.push(op.right)\n }\n if (op.origin != null && !Y.utils.compareIds(op.left, op.origin)) {\n ids.push(op.origin)\n }\n // if (op.right == null && op.left == null) {\n ids.push(op.parent)\n\n if (op.opContent != null) {\n ids.push(op.opContent)\n }\n return ids\n },\n getDistanceToOrigin: function * (op) {\n if (op.left == null) {\n return 0\n } else {\n var d = 0\n var o = yield* this.getInsertion(op.left)\n while (!Y.utils.matchesId(o, op.origin)) {\n d++\n if (o.left == null) {\n break\n } else {\n o = yield* this.getInsertion(o.left)\n }\n }\n return d\n }\n },\n /*\n # $this has to find a unique position between origin and the next known character\n # case 1: $origin equals $o.origin: the $creator parameter decides if left or right\n # let $OL= [o1,o2,o3,o4], whereby $this is to be inserted between o1 and o4\n # o2,o3 and o4 origin is 1 (the position of o2)\n # there is the case that $this.creator < o2.creator, but o3.creator < $this.creator\n # then o2 knows o3. Since on another client $OL could be [o1,o3,o4] the problem is complex\n # therefore $this would be always to the right of o3\n # case 2: $origin < $o.origin\n # if current $this insert_position > $o origin: $this ins\n # else $insert_position will not change\n # (maybe we encounter case 1 later, then this will be to the right of $o)\n # case 3: $origin > $o.origin\n # $this insert_position is to the left of $o (forever!)\n */\n execute: function * (op) {\n var i // loop counter\n\n // during this function some ops may get split into two pieces (e.g. with getInsertionCleanEnd)\n // We try to merge them later, if possible\n var tryToRemergeLater = []\n\n if (op.origin != null) { // TODO: !== instead of !=\n // we save in origin that op originates in it\n // we need that later when we eventually garbage collect origin (see transaction)\n var origin = yield* this.getInsertionCleanEnd(op.origin)\n if (origin.originOf == null) {\n origin.originOf = []\n }\n origin.originOf.push(op.id)\n yield* this.setOperation(origin)\n if (origin.right != null) {\n tryToRemergeLater.push(origin.right)\n }\n }\n var distanceToOrigin = i = yield* Struct.Insert.getDistanceToOrigin.call(this, op) // most cases: 0 (starts from 0)\n\n // now we begin to insert op in the list of insertions..\n var o\n var parent\n var start\n\n // find o. o is the first conflicting operation\n if (op.left != null) {\n o = yield* this.getInsertionCleanEnd(op.left)\n if (!Y.utils.compareIds(op.left, op.origin) && o.right != null) {\n // only if not added previously\n tryToRemergeLater.push(o.right)\n }\n o = (o.right == null) ? null : yield* this.getOperation(o.right)\n } else { // left == null\n parent = yield* this.getOperation(op.parent)\n let startId = op.parentSub ? parent.map[op.parentSub] : parent.start\n start = startId == null ? null : yield* this.getOperation(startId)\n o = start\n }\n\n // make sure to split op.right if necessary (also add to tryCombineWithLeft)\n if (op.right != null) {\n tryToRemergeLater.push(op.right)\n yield* this.getInsertionCleanStart(op.right)\n }\n\n // handle conflicts\n while (true) {\n if (o != null && !Y.utils.compareIds(o.id, op.right)) {\n var oOriginDistance = yield* Struct.Insert.getDistanceToOrigin.call(this, o)\n if (oOriginDistance === i) {\n // case 1\n if (o.id[0] < op.id[0]) {\n op.left = Y.utils.getLastId(o)\n distanceToOrigin = i + 1 // just ignore o.content.length, doesn't make a difference\n }\n } else if (oOriginDistance < i) {\n // case 2\n if (i - distanceToOrigin <= oOriginDistance) {\n op.left = Y.utils.getLastId(o)\n distanceToOrigin = i + 1 // just ignore o.content.length, doesn't make a difference\n }\n } else {\n break\n }\n i++\n if (o.right != null) {\n o = yield* this.getInsertion(o.right)\n } else {\n o = null\n }\n } else {\n break\n }\n }\n\n // reconnect..\n var left = null\n var right = null\n if (parent == null) {\n parent = yield* this.getOperation(op.parent)\n }\n\n // reconnect left and set right of op\n if (op.left != null) {\n left = yield* this.getInsertion(op.left)\n // link left\n op.right = left.right\n left.right = op.id\n\n yield* this.setOperation(left)\n } else {\n // set op.right from parent, if necessary\n op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start\n }\n // reconnect right\n if (op.right != null) {\n // TODO: wanna connect right too?\n right = yield* this.getOperation(op.right)\n right.left = Y.utils.getLastId(op)\n\n // if right exists, and it is supposed to be gc'd. Remove it from the gc\n if (right.gc != null) {\n if (right.content != null && right.content.length > 1) {\n right = yield* this.getInsertionCleanEnd(right.id)\n }\n this.store.removeFromGarbageCollector(right)\n }\n yield* this.setOperation(right)\n }\n\n // update parents .map/start/end properties\n if (op.parentSub != null) {\n if (left == null) {\n parent.map[op.parentSub] = op.id\n yield* this.setOperation(parent)\n }\n // is a child of a map struct.\n // Then also make sure that only the most left element is not deleted\n // We do not call the type in this case (this is what the third parameter is for)\n if (op.right != null) {\n yield* this.deleteOperation(op.right, 1, true)\n }\n if (op.left != null) {\n yield* this.deleteOperation(op.id, 1, true)\n }\n } else {\n if (right == null || left == null) {\n if (right == null) {\n parent.end = Y.utils.getLastId(op)\n }\n if (left == null) {\n parent.start = op.id\n }\n yield* this.setOperation(parent)\n }\n }\n\n // try to merge original op.left and op.origin\n for (let i = 0; i < tryToRemergeLater.length; i++) {\n var m = yield* this.getOperation(tryToRemergeLater[i])\n yield* this.tryCombineWithLeft(m)\n }\n }\n },\n List: {\n /*\n {\n start: null,\n end: null,\n struct: \"List\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function (id) {\n return {\n start: null,\n end: null,\n struct: 'List',\n id: id\n }\n },\n encode: function (op) {\n var e = {\n struct: 'List',\n id: op.id,\n type: op.type\n }\n if (op.requires != null) {\n e.requires = op.requires\n }\n if (op.info != null) {\n e.info = op.info\n }\n return e\n },\n requiredOps: function () {\n /*\n var ids = []\n if (op.start != null) {\n ids.push(op.start)\n }\n if (op.end != null){\n ids.push(op.end)\n }\n return ids\n */\n return []\n },\n execute: function * (op) {\n op.start = null\n op.end = null\n },\n ref: function * (op, pos) {\n if (op.start == null) {\n return null\n }\n var res = null\n var o = yield* this.getOperation(op.start)\n\n while (true) {\n if (!o.deleted) {\n res = o\n pos--\n }\n if (pos >= 0 && o.right != null) {\n o = yield* this.getOperation(o.right)\n } else {\n break\n }\n }\n return res\n },\n map: function * (o, f) {\n o = o.start\n var res = []\n while (o != null) { // TODO: change to != (at least some convention)\n var operation = yield* this.getOperation(o)\n if (!operation.deleted) {\n res.push(f(operation))\n }\n o = operation.right\n }\n return res\n }\n },\n Map: {\n /*\n {\n map: {},\n struct: \"Map\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function (id) {\n return {\n id: id,\n map: {},\n struct: 'Map'\n }\n },\n encode: function (op) {\n var e = {\n struct: 'Map',\n type: op.type,\n id: op.id,\n map: {} // overwrite map!!\n }\n if (op.requires != null) {\n e.requires = op.requires\n }\n if (op.info != null) {\n e.info = op.info\n }\n return e\n },\n requiredOps: function () {\n return []\n },\n execute: function * () {},\n /*\n Get a property by name\n */\n get: function * (op, name) {\n var oid = op.map[name]\n if (oid != null) {\n var res = yield* this.getOperation(oid)\n if (res == null || res.deleted) {\n return void 0\n } else if (res.opContent == null) {\n return res.content[0]\n } else {\n return yield* this.getType(res.opContent)\n }\n }\n }\n }\n }\n Y.Struct = Struct\n}\n","/* @flow */\n'use strict'\n\n/*\n Partial definition of a transaction\n\n A transaction provides all the the async functionality on a database.\n\n By convention, a transaction has the following properties:\n * ss for StateSet\n * os for OperationStore\n * ds for DeleteStore\n\n A transaction must also define the following methods:\n * checkDeleteStoreForState(state)\n - When increasing the state of a user, an operation with an higher id\n may already be garbage collected, and therefore it will never be received.\n update the state to reflect this knowledge. This won't call a method to save the state!\n * getDeleteSet(id)\n - Get the delete set in a readable format:\n {\n \"userX\": [\n [5,1], // starting from position 5, one operations is deleted\n [9,4] // starting from position 9, four operations are deleted\n ],\n \"userY\": ...\n }\n * getOpsFromDeleteSet(ds) -- TODO: just call this.deleteOperation(id) here\n - get a set of deletions that need to be applied in order to get to\n achieve the state of the supplied ds\n * setOperation(op)\n - write `op` to the database.\n Note: this is allowed to return an in-memory object.\n E.g. the Memory adapter returns the object that it has in-memory.\n Changing values on this object will be stored directly in the database\n without calling this function. Therefore,\n setOperation may have no functionality in some adapters. This also has\n implications on the way we use operations that were served from the database.\n We try not to call copyObject, if not necessary.\n * addOperation(op)\n - add an operation to the database.\n This may only be called once for every op.id\n Must return a function that returns the next operation in the database (ordered by id)\n * getOperation(id)\n * removeOperation(id)\n - remove an operation from the database. This is called when an operation\n is garbage collected.\n * setState(state)\n - `state` is of the form\n {\n user: \"1\",\n clock: 4\n } <- meaning that we have four operations from user \"1\"\n (with these id's respectively: 0, 1, 2, and 3)\n * getState(user)\n * getStateVector()\n - Get the state of the OS in the form\n [{\n user: \"userX\",\n clock: 11\n },\n ..\n ]\n * getStateSet()\n - Get the state of the OS in the form\n {\n \"userX\": 11,\n \"userY\": 22\n }\n * getOperations(startSS)\n - Get the all the operations that are necessary in order to achive the\n stateSet of this user, starting from a stateSet supplied by another user\n * makeOperationReady(ss, op)\n - this is called only by `getOperations(startSS)`. It makes an operation\n applyable on a given SS.\n*/\nmodule.exports = function (Y/* :any */) {\n class TransactionInterface {\n /* ::\n store: Y.AbstractDatabase;\n ds: Store;\n os: Store;\n ss: Store;\n */\n /*\n Get a type based on the id of its model.\n If it does not exist yes, create it.\n TODO: delete type from store.initializedTypes[id] when corresponding id was deleted!\n */\n * getType (id, args) {\n var sid = JSON.stringify(id)\n var t = this.store.initializedTypes[sid]\n if (t == null) {\n var op/* :MapStruct | ListStruct */ = yield* this.getOperation(id)\n if (op != null) {\n t = yield* Y[op.type].typeDefinition.initType.call(this, this.store, op, args)\n this.store.initializedTypes[sid] = t\n }\n }\n return t\n }\n * createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op\n if (id[0] === '_') {\n op = yield* this.getOperation(id)\n } else {\n op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n }\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n if (op[0] === '_') {\n yield* this.setOperation(op)\n } else {\n yield* this.applyCreatedOperations([op])\n }\n return yield* this.getType(id, typedefinition[1])\n }\n /* createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n // yield* this.applyCreatedOperations([op])\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n return yield* this.getType(id, typedefinition[1])\n }*/\n /*\n Apply operations that this user created (no remote ones!)\n * does not check for Struct.*.requiredOps()\n * also broadcasts it through the connector\n */\n * applyCreatedOperations (ops) {\n var send = []\n for (var i = 0; i < ops.length; i++) {\n var op = ops[i]\n yield* this.store.tryExecute.call(this, op)\n if (op.id == null || typeof op.id[1] !== 'string') {\n send.push(Y.Struct[op.struct].encode(op))\n }\n }\n if (!this.store.y.connector.isDisconnected() && send.length > 0) { // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops)\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps(send)\n }\n }\n\n * deleteList (start) {\n while (start != null) {\n start = yield* this.getOperation(start)\n if (!start.gc) {\n start.gc = true\n start.deleted = true\n yield* this.setOperation(start)\n var delLength = start.content != null ? start.content.length : 1\n yield* this.markDeleted(start.id, delLength)\n if (start.opContent != null) {\n yield* this.deleteOperation(start.opContent)\n }\n this.store.queueGarbageCollector(start.id)\n }\n start = start.right\n }\n }\n\n /*\n Mark an operation as deleted, and add it to the GC, if possible.\n */\n * deleteOperation (targetId, length, preventCallType) /* :Generator */ {\n if (length == null) {\n length = 1\n }\n yield* this.markDeleted(targetId, length)\n while (length > 0) {\n var callType = false\n var target = yield* this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1])\n var targetLength = target != null && target.content != null ? target.content.length : 1\n if (target == null || target.id[0] !== targetId[0] || target.id[1] + targetLength <= targetId[1]) {\n // does not exist or is not in the range of the deletion\n target = null\n length = 0\n } else {\n // does exist, check if it is too long\n if (!target.deleted) {\n if (target.id[1] < targetId[1]) {\n // starts to the left of the deletion range\n target = yield* this.getInsertionCleanStart(targetId)\n targetLength = target.content.length // must have content property!\n }\n if (target.id[1] + targetLength > targetId[1] + length) {\n // ends to the right of the deletion range\n target = yield* this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1])\n targetLength = target.content.length\n }\n }\n length = target.id[1] - targetId[1]\n }\n\n if (target != null) {\n if (!target.deleted) {\n callType = true\n // set deleted & notify type\n target.deleted = true\n // delete containing lists\n if (target.start != null) {\n // TODO: don't do it like this .. -.-\n yield* this.deleteList(target.start)\n // yield* this.deleteList(target.id) -- do not gc itself because this may still get referenced\n }\n if (target.map != null) {\n for (var name in target.map) {\n yield* this.deleteList(target.map[name])\n }\n // TODO: here to.. (see above)\n // yield* this.deleteList(target.id) -- see above\n }\n if (target.opContent != null) {\n yield* this.deleteOperation(target.opContent)\n // target.opContent = null\n }\n if (target.requires != null) {\n for (var i = 0; i < target.requires.length; i++) {\n yield* this.deleteOperation(target.requires[i])\n }\n }\n }\n var left\n if (target.left != null) {\n left = yield* this.getInsertion(target.left)\n } else {\n left = null\n }\n\n // set here because it was deleted and/or gc'd\n yield* this.setOperation(target)\n\n /*\n Check if it is possible to add right to the gc.\n Because this delete can't be responsible for left being gc'd,\n we don't have to add left to the gc..\n */\n var right\n if (target.right != null) {\n right = yield* this.getOperation(target.right)\n } else {\n right = null\n }\n if (callType && !preventCallType) {\n var type = this.store.initializedTypes[JSON.stringify(target.parent)]\n if (type != null) {\n yield* type._changed(this, {\n struct: 'Delete',\n target: target.id,\n length: targetLength\n })\n }\n }\n // need to gc in the end!\n yield* this.store.addToGarbageCollector.call(this, target, left)\n if (right != null) {\n yield* this.store.addToGarbageCollector.call(this, right, target)\n }\n }\n }\n }\n /*\n Mark an operation as deleted&gc'd\n */\n * markGarbageCollected (id, len) {\n // this.mem.push([\"gc\", id]);\n this.store.addToDebug('yield* this.markGarbageCollected(', id, ', ', len, ')')\n var n = yield* this.markDeleted(id, len)\n if (n.id[1] < id[1] && !n.gc) {\n // un-extend left\n var newlen = n.len - (id[1] - n.id[1])\n n.len -= newlen\n yield* this.ds.put(n)\n n = {id: id, len: newlen, gc: false}\n yield* this.ds.put(n)\n }\n // get prev&next before adding a new operation\n var prev = yield* this.ds.findPrev(id)\n var next = yield* this.ds.findNext(id)\n\n if (id[1] + len < n.id[1] + n.len && !n.gc) {\n // un-extend right\n yield* this.ds.put({id: [id[0], id[1] + len], len: n.len - len, gc: false})\n n.len = len\n }\n // set gc'd\n n.gc = true\n // can extend left?\n if (\n prev != null &&\n prev.gc &&\n Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id)\n ) {\n prev.len += n.len\n yield* this.ds.delete(n.id)\n n = prev\n // ds.put n here?\n }\n // can extend right?\n if (\n next != null &&\n next.gc &&\n Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id)\n ) {\n n.len += next.len\n yield* this.ds.delete(next.id)\n }\n yield* this.ds.put(n)\n yield* this.updateState(n.id[0])\n }\n /*\n Mark an operation as deleted.\n\n returns the delete node\n */\n * markDeleted (id, length) {\n if (length == null) {\n length = 1\n }\n // this.mem.push([\"del\", id]);\n var n = yield* this.ds.findWithUpperBound(id)\n if (n != null && n.id[0] === id[0]) {\n if (n.id[1] <= id[1] && id[1] <= n.id[1] + n.len) {\n // id is in n's range\n var diff = id[1] + length - (n.id[1] + n.len) // overlapping right\n if (diff > 0) {\n // id+length overlaps n\n if (!n.gc) {\n n.len += diff\n } else {\n diff = n.id[1] + n.len - id[1] // overlapping left (id till n.end)\n if (diff < length) {\n // a partial deletion\n n = {id: [id[0], id[1] + diff], len: length - diff, gc: false}\n yield* this.ds.put(n)\n } else {\n // already gc'd\n throw new Error('Cannot happen! (it dit though.. :()')\n // return n\n }\n }\n } else {\n // no overlapping, already deleted\n return n\n }\n } else {\n // cannot extend left (there is no left!)\n n = {id: id, len: length, gc: false}\n yield* this.ds.put(n) // TODO: you double-put !!\n }\n } else {\n // cannot extend left\n n = {id: id, len: length, gc: false}\n yield* this.ds.put(n)\n }\n // can extend right?\n var next = yield* this.ds.findNext(n.id)\n if (\n next != null &&\n n.id[0] === next.id[0] &&\n n.id[1] + n.len >= next.id[1]\n ) {\n diff = n.id[1] + n.len - next.id[1] // from next.start to n.end\n while (diff >= 0) {\n // n overlaps with next\n if (next.gc) {\n // gc is stronger, so reduce length of n\n n.len -= diff\n if (diff >= next.len) {\n // delete the missing range after next\n diff = diff - next.len // missing range after next\n if (diff > 0) {\n yield* this.ds.put(n) // unneccessary? TODO!\n yield* this.markDeleted([next.id[0], next.id[1] + next.len], diff)\n }\n }\n break\n } else {\n // we can extend n with next\n if (diff > next.len) {\n // n is even longer than next\n // get next.next, and try to extend it\n var _next = yield* this.ds.findNext(next.id)\n yield* this.ds.delete(next.id)\n if (_next == null || n.id[0] !== _next.id[0]) {\n break\n } else {\n next = _next\n diff = n.id[1] + n.len - next.id[1] // from next.start to n.end\n // continue!\n }\n } else {\n // n just partially overlaps with next. extend n, delete next, and break this loop\n n.len += next.len - diff\n yield* this.ds.delete(next.id)\n break\n }\n }\n }\n }\n yield* this.ds.put(n)\n return n\n }\n /*\n Call this method when the client is connected&synced with the\n other clients (e.g. master). This will query the database for\n operations that can be gc'd and add them to the garbage collector.\n */\n * garbageCollectAfterSync () {\n if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {\n console.warn('gc should be empty after sync')\n }\n yield* this.os.iterate(this, null, null, function * (op) {\n if (op.gc) {\n delete op.gc\n yield* this.setOperation(op)\n }\n if (op.parent != null) {\n var parentDeleted = yield* this.isDeleted(op.parent)\n if (parentDeleted) {\n op.gc = true\n if (!op.deleted) {\n yield* this.markDeleted(op.id, op.content != null ? op.content.length : 1)\n op.deleted = true\n if (op.opContent != null) {\n yield* this.deleteOperation(op.opContent)\n }\n if (op.requires != null) {\n for (var i = 0; i < op.requires.length; i++) {\n yield* this.deleteOperation(op.requires[i])\n }\n }\n }\n yield* this.setOperation(op)\n this.store.gc1.push(op.id) // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!)\n return\n }\n }\n if (op.deleted) {\n var left = null\n if (op.left != null) {\n left = yield* this.getInsertion(op.left)\n }\n yield* this.store.addToGarbageCollector.call(this, op, left)\n }\n })\n }\n /*\n Really remove an op and all its effects.\n The complicated case here is the Insert operation:\n * reset left\n * reset right\n * reset parent.start\n * reset parent.end\n * reset origins of all right ops\n */\n * garbageCollectOperation (id) {\n this.store.addToDebug('yield* this.garbageCollectOperation(', id, ')')\n var o = yield* this.getOperation(id)\n yield* this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd\n // if op exists, then clean that mess up..\n if (o != null) {\n var deps = []\n if (o.opContent != null) {\n deps.push(o.opContent)\n }\n if (o.requires != null) {\n deps = deps.concat(o.requires)\n }\n for (var i = 0; i < deps.length; i++) {\n var dep = yield* this.getOperation(deps[i])\n if (dep != null) {\n if (!dep.deleted) {\n yield* this.deleteOperation(dep.id)\n dep = yield* this.getOperation(dep.id)\n }\n dep.gc = true\n yield* this.setOperation(dep)\n this.store.queueGarbageCollector(dep.id)\n } else {\n yield* this.markGarbageCollected(deps[i], 1)\n }\n }\n\n // remove gc'd op from the left op, if it exists\n if (o.left != null) {\n var left = yield* this.getInsertion(o.left)\n left.right = o.right\n yield* this.setOperation(left)\n }\n // remove gc'd op from the right op, if it exists\n // also reset origins of right ops\n if (o.right != null) {\n var right = yield* this.getOperation(o.right)\n right.left = o.left\n\n if (o.originOf != null && o.originOf.length > 0) {\n // find new origin of right ops\n // origin is the first left deleted operation\n var neworigin = o.left\n var neworigin_ = null\n while (neworigin != null) {\n neworigin_ = yield* this.getInsertion(neworigin)\n if (neworigin_.deleted) {\n break\n }\n neworigin = neworigin_.left\n }\n\n // reset origin of all right ops (except first right - duh!),\n\n /* ** The following code does not rely on the the originOf property **\n I recently added originOf to all Insert Operations (see Struct.Insert.execute),\n which saves which operations originate in a Insert operation.\n Garbage collecting without originOf is more memory efficient, but is nearly impossible for large texts, or lists!\n But I keep this code for now\n ```\n // reset origin of right\n right.origin = neworigin\n // search until you find origin pointer to the left of o\n if (right.right != null) {\n var i = yield* this.getOperation(right.right)\n var ids = [o.id, o.right]\n while (ids.some(function (id) {\n return Y.utils.compareIds(id, i.origin)\n })) {\n if (Y.utils.compareIds(i.origin, o.id)) {\n // reset origin of i\n i.origin = neworigin\n yield* this.setOperation(i)\n }\n // get next i\n if (i.right == null) {\n break\n } else {\n ids.push(i.id)\n i = yield* this.getOperation(i.right)\n }\n }\n }\n ```\n */\n // ** Now the new implementation starts **\n // reset neworigin of all originOf[*]\n for (var _i in o.originOf) {\n var originsIn = yield* this.getOperation(o.originOf[_i])\n if (originsIn != null) {\n originsIn.origin = neworigin\n yield* this.setOperation(originsIn)\n }\n }\n if (neworigin != null) {\n if (neworigin_.originOf == null) {\n neworigin_.originOf = o.originOf\n } else {\n neworigin_.originOf = o.originOf.concat(neworigin_.originOf)\n }\n yield* this.setOperation(neworigin_)\n }\n // we don't need to set right here, because\n // right should be in o.originOf => it is set it the previous for loop\n } else {\n // we didn't need to reset the origin of right\n // so we have to set right here\n yield* this.setOperation(right)\n }\n }\n // o may originate in another operation.\n // Since o is deleted, we have to reset o.origin's `originOf` property\n if (o.origin != null) {\n var origin = yield* this.getInsertion(o.origin)\n origin.originOf = origin.originOf.filter(function (_id) {\n return !Y.utils.compareIds(id, _id)\n })\n yield* this.setOperation(origin)\n }\n var parent\n if (o.parent != null) {\n parent = yield* this.getOperation(o.parent)\n }\n // remove gc'd op from parent, if it exists\n if (parent != null) {\n var setParent = false // whether to save parent to the os\n if (o.parentSub != null) {\n if (Y.utils.compareIds(parent.map[o.parentSub], o.id)) {\n setParent = true\n if (o.right != null) {\n parent.map[o.parentSub] = o.right\n } else {\n delete parent.map[o.parentSub]\n }\n }\n } else {\n if (Y.utils.compareIds(parent.start, o.id)) {\n // gc'd op is the start\n setParent = true\n parent.start = o.right\n }\n if (Y.utils.matchesId(o, parent.end)) {\n // gc'd op is the end\n setParent = true\n parent.end = o.left\n }\n }\n if (setParent) {\n yield* this.setOperation(parent)\n }\n }\n // finally remove it from the os\n yield* this.removeOperation(o.id)\n }\n }\n * checkDeleteStoreForState (state) {\n var n = yield* this.ds.findWithUpperBound([state.user, state.clock])\n if (n != null && n.id[0] === state.user && n.gc) {\n state.clock = Math.max(state.clock, n.id[1] + n.len)\n }\n }\n * updateState (user) {\n var state = yield* this.getState(user)\n yield* this.checkDeleteStoreForState(state)\n var o = yield* this.getInsertion([user, state.clock])\n var oLength = (o != null && o.content != null) ? o.content.length : 1\n while (o != null && user === o.id[0] && o.id[1] <= state.clock && o.id[1] + oLength > state.clock) {\n // either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS\n state.clock += oLength\n yield* this.checkDeleteStoreForState(state)\n o = yield* this.os.findNext(o.id)\n oLength = (o != null && o.content != null) ? o.content.length : 1\n }\n yield* this.setState(state)\n }\n /*\n apply a delete set in order to get\n the state of the supplied ds\n */\n * applyDeleteSet (ds) {\n var deletions = []\n\n for (var user in ds) {\n var dv = ds[user]\n var pos = 0\n var d = dv[pos]\n yield* this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], function * (n) {\n // cases:\n // 1. d deletes something to the right of n\n // => go to next n (break)\n // 2. d deletes something to the left of n\n // => create deletions\n // => reset d accordingly\n // *)=> if d doesn't delete anything anymore, go to next d (continue)\n // 3. not 2) and d deletes something that also n deletes\n // => reset d so that it doesn't contain n's deletion\n // *)=> if d does not delete anything anymore, go to next d (continue)\n while (d != null) {\n var diff = 0 // describe the diff of length in 1) and 2)\n if (n.id[1] + n.len <= d[0]) {\n // 1)\n break\n } else if (d[0] < n.id[1]) {\n // 2)\n // delete maximum the len of d\n // else delete as much as possible\n diff = Math.min(n.id[1] - d[0], d[1])\n deletions.push([user, d[0], diff, d[2]])\n } else {\n // 3)\n diff = n.id[1] + n.len - d[0] // never null (see 1)\n if (d[2] && !n.gc) {\n // d marks as gc'd but n does not\n // then delete either way\n deletions.push([user, d[0], Math.min(diff, d[1]), d[2]])\n }\n }\n if (d[1] <= diff) {\n // d doesn't delete anything anymore\n d = dv[++pos]\n } else {\n d[0] = d[0] + diff // reset pos\n d[1] = d[1] - diff // reset length\n }\n }\n })\n // for the rest.. just apply it\n for (; pos < dv.length; pos++) {\n d = dv[pos]\n deletions.push([user, d[0], d[1], d[2]])\n }\n }\n for (var i = 0; i < deletions.length; i++) {\n var del = deletions[i]\n // always try to delete..\n yield* this.deleteOperation([del[0], del[1]], del[2])\n if (del[3]) {\n // gc..\n yield* this.markGarbageCollected([del[0], del[1]], del[2]) // always mark gc'd\n // remove operation..\n var counter = del[1] + del[2]\n while (counter >= del[1]) {\n var o = yield* this.os.findWithUpperBound([del[0], counter - 1])\n if (o == null) {\n break\n }\n var oLen = o.content != null ? o.content.length : 1\n if (o.id[0] !== del[0] || o.id[1] + oLen <= del[1]) {\n // not in range\n break\n }\n if (o.id[1] + oLen > del[1] + del[2]) {\n // overlaps right\n o = yield* this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1])\n }\n if (o.id[1] < del[1]) {\n // overlaps left\n o = yield* this.getInsertionCleanStart([del[0], del[1]])\n }\n counter = o.id[1]\n yield* this.garbageCollectOperation(o.id)\n }\n }\n if (this.store.forwardAppliedOperations) {\n var ops = []\n ops.push({struct: 'Delete', target: [d[0], d[1]], length: del[2]})\n this.store.y.connector.broadcastOps(ops)\n }\n }\n }\n * isGarbageCollected (id) {\n var n = yield* this.ds.findWithUpperBound(id)\n return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len && n.gc\n }\n /*\n A DeleteSet (ds) describes all the deleted ops in the OS\n */\n * getDeleteSet () {\n var ds = {}\n yield* this.ds.iterate(this, null, null, function * (n) {\n var user = n.id[0]\n var counter = n.id[1]\n var len = n.len\n var gc = n.gc\n var dv = ds[user]\n if (dv === void 0) {\n dv = []\n ds[user] = dv\n }\n dv.push([counter, len, gc])\n })\n return ds\n }\n * isDeleted (id) {\n var n = yield* this.ds.findWithUpperBound(id)\n return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len\n }\n * setOperation (op) {\n yield* this.os.put(op)\n return op\n }\n * addOperation (op) {\n yield* this.os.put(op)\n if (!this.store.y.connector.isDisconnected() && this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') {\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps([op])\n }\n }\n // if insertion, try to combine with left insertion (if both have content property)\n * tryCombineWithLeft (op) {\n if (\n op != null &&\n op.left != null &&\n op.content != null &&\n op.left[0] === op.id[0] &&\n Y.utils.compareIds(op.left, op.origin)\n ) {\n var left = yield* this.getInsertion(op.left)\n if (left.content != null &&\n left.id[1] + left.content.length === op.id[1] &&\n left.originOf.length === 1 &&\n !left.gc && !left.deleted &&\n !op.gc && !op.deleted\n ) {\n // combine!\n if (op.originOf != null) {\n left.originOf = op.originOf\n } else {\n delete left.originOf\n }\n left.content = left.content.concat(op.content)\n left.right = op.right\n yield* this.os.delete(op.id)\n yield* this.setOperation(left)\n }\n }\n }\n * getInsertion (id) {\n var ins = yield* this.os.findWithUpperBound(id)\n if (ins == null) {\n return null\n } else {\n var len = ins.content != null ? ins.content.length : 1 // in case of opContent\n if (id[0] === ins.id[0] && id[1] < ins.id[1] + len) {\n return ins\n } else {\n return null\n }\n }\n }\n * getInsertionCleanStartEnd (id) {\n yield* this.getInsertionCleanStart(id)\n return yield* this.getInsertionCleanEnd(id)\n }\n // Return an insertion such that id is the first element of content\n // This function manipulates an operation, if necessary\n * getInsertionCleanStart (id) {\n var ins = yield* this.getInsertion(id)\n if (ins != null) {\n if (ins.id[1] === id[1]) {\n return ins\n } else {\n var left = Y.utils.copyObject(ins)\n ins.content = left.content.splice(id[1] - ins.id[1])\n ins.id = id\n var leftLid = Y.utils.getLastId(left)\n ins.origin = leftLid\n left.originOf = [ins.id]\n left.right = ins.id\n ins.left = leftLid\n // debugger // check\n yield* this.setOperation(left)\n yield* this.setOperation(ins)\n if (left.gc) {\n this.store.queueGarbageCollector(ins.id)\n }\n return ins\n }\n } else {\n return null\n }\n }\n // Return an insertion such that id is the last element of content\n // This function manipulates an operation, if necessary\n * getInsertionCleanEnd (id) {\n var ins = yield* this.getInsertion(id)\n if (ins != null) {\n if (ins.content == null || (ins.id[1] + ins.content.length - 1 === id[1])) {\n return ins\n } else {\n var right = Y.utils.copyObject(ins)\n right.content = ins.content.splice(id[1] - ins.id[1] + 1) // cut off remainder\n right.id = [id[0], id[1] + 1]\n var insLid = Y.utils.getLastId(ins)\n right.origin = insLid\n ins.originOf = [right.id]\n ins.right = right.id\n right.left = insLid\n // debugger // check\n yield* this.setOperation(right)\n yield* this.setOperation(ins)\n if (ins.gc) {\n this.store.queueGarbageCollector(right.id)\n }\n return ins\n }\n } else {\n return null\n }\n }\n * getOperation (id/* :any */)/* :Transaction */ {\n var o = yield* this.os.find(id)\n if (id[0] !== '_' || o != null) {\n return o\n } else { // type is string\n // generate this operation?\n var comp = id[1].split('_')\n if (comp.length > 1) {\n var struct = comp[0]\n var op = Y.Struct[struct].create(id)\n op.type = comp[1]\n yield* this.setOperation(op)\n return op\n } else {\n // won't be called. but just in case..\n console.error('Unexpected case. How can this happen?')\n debugger // eslint-disable-line\n return null\n }\n }\n }\n * removeOperation (id) {\n yield* this.os.delete(id)\n }\n * setState (state) {\n var val = {\n id: [state.user],\n clock: state.clock\n }\n yield* this.ss.put(val)\n }\n * getState (user) {\n var n = yield* this.ss.find([user])\n var clock = n == null ? null : n.clock\n if (clock == null) {\n clock = 0\n }\n return {\n user: user,\n clock: clock\n }\n }\n * getStateVector () {\n var stateVector = []\n yield* this.ss.iterate(this, null, null, function * (n) {\n stateVector.push({\n user: n.id[0],\n clock: n.clock\n })\n })\n return stateVector\n }\n * getStateSet () {\n var ss = {}\n yield* this.ss.iterate(this, null, null, function * (n) {\n ss[n.id[0]] = n.clock\n })\n return ss\n }\n /*\n Here, we make all missing operations executable for the receiving user.\n\n Notes:\n startSS: denotes to the SV that the remote user sent\n currSS: denotes to the state vector that the user should have if he\n applies all already sent operations (increases is each step)\n\n We face several problems:\n * Execute op as is won't work because ops depend on each other\n -> find a way so that they do not anymore\n * When changing left, must not go more to the left than the origin\n * When changing right, you have to consider that other ops may have op\n as their origin, this means that you must not set one of these ops\n as the new right (interdependencies of ops)\n * can't just go to the right until you find the first known operation,\n With currSS\n -> interdependency of ops is a problem\n With startSS\n -> leads to inconsistencies when two users join at the same time.\n Then the position depends on the order of execution -> error!\n\n Solution:\n -> re-create originial situation\n -> set op.left = op.origin (which never changes)\n -> set op.right\n to the first operation that is known (according to startSS)\n or to the first operation that has an origin that is not to the\n right of op.\n -> Enforces unique execution order -> happy user\n\n Improvements: TODO\n * Could set left to origin, or the first known operation\n (startSS or currSS.. ?)\n -> Could be necessary when I turn GC again.\n -> Is a bad(ish) idea because it requires more computation\n\n What we do:\n * Iterate over all missing operations.\n * When there is an operation, where the right op is known, send this op all missing ops to the left to the user\n * I explained above what we have to do with each operation. Here is how we do it efficiently:\n 1. Go to the left until you find either op.origin, or a known operation (let o denote current operation in the iteration)\n 2. Found a known operation -> set op.left = o, and send it to the user. stop\n 3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o)\n 4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue\n */\n * getOperations (startSS) {\n // TODO: use bounds here!\n if (startSS == null) {\n startSS = {}\n }\n var send = []\n\n var endSV = yield* this.getStateVector()\n for (var endState of endSV) {\n var user = endState.user\n if (user === '_') {\n continue\n }\n var startPos = startSS[user] || 0\n if (startPos > 0) {\n // There is a change that [user, startPos] is in a composed Insertion (with a smaller counter)\n // find out if that is the case\n var firstMissing = yield* this.getInsertion([user, startPos])\n if (firstMissing != null) {\n // update startPos\n startPos = firstMissing.id[1]\n }\n }\n yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {\n op = Y.Struct[op.struct].encode(op)\n if (op.struct !== 'Insert') {\n send.push(op)\n } else if (op.right == null || op.right[1] < (startSS[op.right[0]] || 0)) {\n // case 1. op.right is known\n var o = op\n // Remember: ?\n // -> set op.right\n // 1. to the first operation that is known (according to startSS)\n // 2. or to the first operation that has an origin that is not to the\n // right of op.\n // For this we maintain a list of ops which origins are not found yet.\n var missing_origins = [op]\n var newright = op.right\n while (true) {\n if (o.left == null) {\n op.left = null\n send.push(op)\n if (!Y.utils.compareIds(o.id, op.id)) {\n o = Y.Struct[op.struct].encode(o)\n o.right = missing_origins[missing_origins.length - 1].id\n send.push(o)\n }\n break\n }\n o = yield* this.getInsertion(o.left)\n // we set another o, check if we can reduce $missing_origins\n while (missing_origins.length > 0 && Y.utils.matchesId(o, missing_origins[missing_origins.length - 1].origin)) {\n missing_origins.pop()\n }\n if (o.id[1] < (startSS[o.id[0]] || 0)) {\n // case 2. o is known\n op.left = Y.utils.getLastId(o)\n send.push(op)\n break\n } else if (Y.utils.matchesId(o, op.origin)) {\n // case 3. o is op.origin\n op.left = op.origin\n send.push(op)\n op = Y.Struct[op.struct].encode(o)\n op.right = newright\n if (missing_origins.length > 0) {\n console.log('This should not happen .. :( please report this')\n }\n missing_origins = [op]\n } else {\n // case 4. send o, continue to find op.origin\n var s = Y.Struct[op.struct].encode(o)\n s.right = missing_origins[missing_origins.length - 1].id\n s.left = s.origin\n send.push(s)\n missing_origins.push(o)\n }\n }\n }\n })\n }\n return send.reverse()\n }\n /* this is what we used before.. use this as a reference..\n * makeOperationReady (startSS, op) {\n op = Y.Struct[op.struct].encode(op)\n op = Y.utils.copyObject(op)\n var o = op\n var ids = [op.id]\n // search for the new op.right\n // it is either the first known op (according to startSS)\n // or the o that has no origin to the right of op\n // (this is why we use the ids array)\n while (o.right != null) {\n var right = yield* this.getOperation(o.right)\n if (o.right[1] < (startSS[o.right[0]] || 0) || !ids.some(function (id) {\n return Y.utils.compareIds(id, right.origin)\n })) {\n break\n }\n ids.push(o.right)\n o = right\n }\n op.right = o.right\n op.left = op.origin\n return op\n }\n */\n * flush () {\n yield* this.os.flush()\n yield* this.ss.flush()\n yield* this.ds.flush()\n }\n }\n Y.Transaction = TransactionInterface\n}\n","/* @flow */\n'use strict'\n\n/*\n EventHandler is an helper class for constructing custom types.\n\n Why: When constructing custom types, you sometimes want your types to work\n synchronous: E.g.\n ``` Synchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === \"yay\"\n ```\n versus\n ``` Asynchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === undefined\n mytype.waitForSomething().then(function(){\n mytype.getSomething() === \"yay\"\n })\n ```\n\n The structures usually work asynchronously (you have to wait for the\n database request to finish). EventHandler helps you to make your type\n synchronous.\n*/\nmodule.exports = function (Y /* : any*/) {\n Y.utils = {}\n\n class EventListenerHandler {\n constructor () {\n this.eventListeners = []\n }\n destroy () {\n this.eventListeners = null\n }\n /*\n Basic event listener boilerplate...\n */\n addEventListener (f) {\n this.eventListeners.push(f)\n }\n removeEventListener (f) {\n this.eventListeners = this.eventListeners.filter(function (g) {\n return f !== g\n })\n }\n removeAllEventListeners () {\n this.eventListeners = []\n }\n callEventListeners (event) {\n for (var i = 0; i < this.eventListeners.length; i++) {\n try {\n this.eventListeners[i](event)\n } catch (e) {\n console.error('User events must not throw Errors!')\n }\n }\n }\n }\n Y.utils.EventListenerHandler = EventListenerHandler\n\n class EventHandler extends EventListenerHandler {\n /* ::\n waiting: Array;\n awaiting: number;\n onevent: Function;\n eventListeners: Array;\n */\n /*\n onevent: is called when the structure changes.\n\n Note: \"awaiting opertations\" is used to denote operations that were\n prematurely called. Events for received operations can not be executed until\n all prematurely called operations were executed (\"waiting operations\")\n */\n constructor (onevent /* : Function */) {\n super()\n this.waiting = []\n this.awaiting = 0\n this.onevent = onevent\n }\n destroy () {\n super.destroy()\n this.waiting = null\n this.awaiting = null\n this.onevent = null\n }\n /*\n Call this when a new operation arrives. It will be executed right away if\n there are no waiting operations, that you prematurely executed\n */\n receivedOp (op) {\n if (this.awaiting <= 0) {\n this.onevent(op)\n } else {\n this.waiting.push(op)\n }\n }\n /*\n You created some operations, and you want the `onevent` function to be\n called right away. Received operations will not be executed untill all\n prematurely called operations are executed\n */\n awaitAndPrematurelyCall (ops) {\n this.awaiting += ops.length\n ops.forEach(this.onevent)\n }\n /*\n Call this when you successfully awaited the execution of n Insert operations\n */\n awaitedInserts (n) {\n var ops = this.waiting.splice(this.waiting.length - n)\n for (var oid = 0; oid < ops.length; oid++) {\n var op = ops[oid]\n if (op.struct === 'Insert') {\n for (var i = this.waiting.length - 1; i >= 0; i--) {\n let w = this.waiting[i]\n // TODO: do I handle split operations correctly here? Super unlikely, but yeah..\n // Also: can this case happen? Can op be inserted in the middle of a larger op that is in $waiting?\n if (w.struct === 'Insert') {\n if (Y.utils.matchesId(w, op.left)) {\n // include the effect of op in w\n w.right = op.id\n // exclude the effect of w in op\n op.left = w.left\n } else if (Y.utils.compareIds(w.id, op.right)) {\n // similar..\n w.left = Y.utils.getLastId(op)\n op.right = w.right\n }\n }\n }\n } else {\n throw new Error('Expected Insert Operation!')\n }\n }\n this._tryCallEvents(n)\n }\n /*\n Call this when you successfully awaited the execution of n Delete operations\n */\n awaitedDeletes (n, newLeft) {\n var ops = this.waiting.splice(this.waiting.length - n)\n for (var j = 0; j < ops.length; j++) {\n var del = ops[j]\n if (del.struct === 'Delete') {\n if (newLeft != null) {\n for (var i = 0; i < this.waiting.length; i++) {\n let w = this.waiting[i]\n // We will just care about w.left\n if (w.struct === 'Insert' && Y.utils.compareIds(del.target, w.left)) {\n w.left = newLeft\n }\n }\n }\n } else {\n throw new Error('Expected Delete Operation!')\n }\n }\n this._tryCallEvents(n)\n }\n /* (private)\n Try to execute the events for the waiting operations\n */\n _tryCallEvents (n) {\n this.awaiting -= n\n if (this.awaiting === 0 && this.waiting.length > 0) {\n var ops = this.waiting\n this.waiting = []\n ops.forEach(this.onevent)\n }\n }\n }\n Y.utils.EventHandler = EventHandler\n\n /*\n A wrapper for the definition of a custom type.\n Every custom type must have three properties:\n\n * struct\n - Structname of this type\n * initType\n - Given a model, creates a custom type\n * class\n - the constructor of the custom type (e.g. in order to inherit from a type)\n */\n class CustomType { // eslint-disable-line\n /* ::\n struct: any;\n initType: any;\n class: Function;\n name: String;\n */\n constructor (def) {\n if (def.struct == null ||\n def.initType == null ||\n def.class == null ||\n def.name == null\n ) {\n throw new Error('Custom type was not initialized correctly!')\n }\n this.struct = def.struct\n this.initType = def.initType\n this.class = def.class\n this.name = def.name\n if (def.appendAdditionalInfo != null) {\n this.appendAdditionalInfo = def.appendAdditionalInfo\n }\n this.parseArguments = (def.parseArguments || function () {\n return [this]\n }).bind(this)\n this.parseArguments.typeDefinition = this\n }\n }\n Y.utils.CustomType = CustomType\n\n Y.utils.isTypeDefinition = function isTypeDefinition (v) {\n if (v != null) {\n if (v instanceof Y.utils.CustomType) return [v]\n else if (v.constructor === Array && v[0] instanceof Y.utils.CustomType) return v\n else if (v instanceof Function && v.typeDefinition instanceof Y.utils.CustomType) return [v.typeDefinition]\n }\n return false\n }\n\n /*\n Make a flat copy of an object\n (just copy properties)\n */\n function copyObject (o) {\n var c = {}\n for (var key in o) {\n c[key] = o[key]\n }\n return c\n }\n Y.utils.copyObject = copyObject\n\n /*\n Defines a smaller relation on Id's\n */\n function smaller (a, b) {\n return a[0] < b[0] || (a[0] === b[0] && (a[1] < b[1] || typeof a[1] < typeof b[1]))\n }\n Y.utils.smaller = smaller\n\n function compareIds (id1, id2) {\n if (id1 == null || id2 == null) {\n return id1 === id2\n } else {\n return id1[0] === id2[0] && id1[1] === id2[1]\n }\n }\n Y.utils.compareIds = compareIds\n\n function matchesId (op, id) {\n if (id == null || op == null) {\n return id === op\n } else {\n if (id[0] === op.id[0]) {\n if (op.content == null) {\n return id[1] === op.id[1]\n } else {\n return id[1] >= op.id[1] && id[1] < op.id[1] + op.content.length\n }\n }\n }\n }\n Y.utils.matchesId = matchesId\n\n function getLastId (op) {\n if (op.content == null || op.content.length === 1) {\n return op.id\n } else {\n return [op.id[0], op.id[1] + op.content.length - 1]\n }\n }\n Y.utils.getLastId = getLastId\n\n function createEmptyOpsArray (n) {\n var a = new Array(n)\n for (var i = 0; i < a.length; i++) {\n a[i] = {\n id: [null, null]\n }\n }\n return a\n }\n\n function createSmallLookupBuffer (Store) {\n /*\n This buffer implements a very small buffer that temporarily stores operations\n after they are read / before they are written.\n The buffer basically implements FIFO. Often requested lookups will be re-queued every time they are looked up / written.\n\n It can speed up lookups on Operation Stores and State Stores. But it does not require notable use of memory or processing power.\n\n Good for os and ss, bot not for ds (because it often uses methods that require a flush)\n\n I tried to optimize this for performance, therefore no highlevel operations.\n */\n class SmallLookupBuffer extends Store {\n constructor (arg) {\n // super(...arguments) -- do this when this is supported by stable nodejs\n super(arg)\n this.writeBuffer = createEmptyOpsArray(5)\n this.readBuffer = createEmptyOpsArray(10)\n }\n * find (id, noSuperCall) {\n var i, r\n for (i = this.readBuffer.length - 1; i >= 0; i--) {\n r = this.readBuffer[i]\n // we don't have to use compareids, because id is always defined!\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n // found r\n // move r to the end of readBuffer\n for (; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1]\n }\n this.readBuffer[this.readBuffer.length - 1] = r\n return r\n }\n }\n var o\n for (i = this.writeBuffer.length - 1; i >= 0; i--) {\n r = this.writeBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n o = r\n break\n }\n }\n if (i < 0 && noSuperCall === undefined) {\n // did not reach break in last loop\n // read id and put it to the end of readBuffer\n o = yield* super.find(id)\n }\n if (o != null) {\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1]\n }\n this.readBuffer[this.readBuffer.length - 1] = o\n }\n return o\n }\n * put (o) {\n var id = o.id\n var i, r // helper variables\n for (i = this.writeBuffer.length - 1; i >= 0; i--) {\n r = this.writeBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n // is already in buffer\n // forget r, and move o to the end of writeBuffer\n for (; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1]\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o\n break\n }\n }\n if (i < 0) {\n // did not reach break in last loop\n // write writeBuffer[0]\n var write = this.writeBuffer[0]\n if (write.id[0] !== null) {\n yield* super.put(write)\n }\n // put o to the end of writeBuffer\n for (i = 0; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1]\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o\n }\n // check readBuffer for every occurence of o.id, overwrite if found\n // whether found or not, we'll append o to the readbuffer\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n r = this.readBuffer[i + 1]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = o\n } else {\n this.readBuffer[i] = r\n }\n }\n this.readBuffer[this.readBuffer.length - 1] = o\n }\n * delete (id) {\n var i, r\n for (i = 0; i < this.readBuffer.length; i++) {\n r = this.readBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = {\n id: [null, null]\n }\n }\n }\n yield* this.flush()\n yield* super.delete(id)\n }\n * findWithLowerBound (id) {\n var o = yield* this.find(id, true)\n if (o != null) {\n return o\n } else {\n yield* this.flush()\n return yield* super.findWithLowerBound.apply(this, arguments)\n }\n }\n * findWithUpperBound (id) {\n var o = yield* this.find(id, true)\n if (o != null) {\n return o\n } else {\n yield* this.flush()\n return yield* super.findWithUpperBound.apply(this, arguments)\n }\n }\n * findNext () {\n yield* this.flush()\n return yield* super.findNext.apply(this, arguments)\n }\n * findPrev () {\n yield* this.flush()\n return yield* super.findPrev.apply(this, arguments)\n }\n * iterate () {\n yield* this.flush()\n yield* super.iterate.apply(this, arguments)\n }\n * flush () {\n for (var i = 0; i < this.writeBuffer.length; i++) {\n var write = this.writeBuffer[i]\n if (write.id[0] !== null) {\n yield* super.put(write)\n this.writeBuffer[i] = {\n id: [null, null]\n }\n }\n }\n }\n }\n return SmallLookupBuffer\n }\n Y.utils.createSmallLookupBuffer = createSmallLookupBuffer\n}\n","/* @flow */\r\n'use strict'\r\n\r\nrequire('./Connector.js')(Y)\r\nrequire('./Database.js')(Y)\r\nrequire('./Transaction.js')(Y)\r\nrequire('./Struct.js')(Y)\r\nrequire('./Utils.js')(Y)\r\nrequire('./Connectors/Test.js')(Y)\r\n\r\nvar requiringModules = {}\r\n\r\nmodule.exports = Y\r\nY.requiringModules = requiringModules\r\n\r\nY.extend = function (name, value) {\r\n if (value instanceof Y.utils.CustomType) {\r\n Y[name] = value.parseArguments\r\n } else {\r\n Y[name] = value\r\n }\r\n if (requiringModules[name] != null) {\r\n requiringModules[name].resolve()\r\n delete requiringModules[name]\r\n }\r\n}\r\n\r\nY.requestModules = requestModules\r\nfunction requestModules (modules) {\r\n // determine if this module was compiled for es5 or es6 (y.js vs. y.es6)\r\n // if Insert.execute is a Function, then it isnt a generator..\r\n // then load the es5(.js) files..\r\n var extention = typeof regeneratorRuntime !== 'undefined' ? '.js' : '.es6'\r\n var promises = []\r\n for (var i = 0; i < modules.length; i++) {\r\n var module = modules[i].split('(')[0]\r\n var modulename = 'y-' + module.toLowerCase()\r\n if (Y[module] == null) {\r\n if (requiringModules[module] == null) {\r\n // module does not exist\r\n if (typeof window !== 'undefined' && window.Y !== 'undefined') {\r\n var imported = document.createElement('script')\r\n imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention\r\n document.head.appendChild(imported)\r\n\r\n let requireModule = {}\r\n requiringModules[module] = requireModule\r\n requireModule.promise = new Promise(function (resolve) {\r\n requireModule.resolve = resolve\r\n })\r\n promises.push(requireModule.promise)\r\n } else {\r\n require(modulename)(Y)\r\n }\r\n } else {\r\n promises.push(requiringModules[modules[i]].promise)\r\n }\r\n }\r\n }\r\n return Promise.all(promises)\r\n}\r\n\r\n/* ::\r\ntype MemoryOptions = {\r\n name: 'memory'\r\n}\r\ntype IndexedDBOptions = {\r\n name: 'indexeddb',\r\n namespace: string\r\n}\r\ntype DbOptions = MemoryOptions | IndexedDBOptions\r\n\r\ntype WebRTCOptions = {\r\n name: 'webrtc',\r\n room: string\r\n}\r\ntype WebsocketsClientOptions = {\r\n name: 'websockets-client',\r\n room: string\r\n}\r\ntype ConnectionOptions = WebRTCOptions | WebsocketsClientOptions\r\n\r\ntype YOptions = {\r\n connector: ConnectionOptions,\r\n db: DbOptions,\r\n types: Array,\r\n sourceDir: string,\r\n share: {[key: string]: TypeName}\r\n}\r\n*/\r\n\r\nfunction Y (opts/* :YOptions */) /* :Promise */ {\r\n opts.types = opts.types != null ? opts.types : []\r\n var modules = [opts.db.name, opts.connector.name].concat(opts.types)\r\n for (var name in opts.share) {\r\n modules.push(opts.share[name])\r\n }\r\n Y.sourceDir = opts.sourceDir\r\n return Y.requestModules(modules).then(function () {\r\n return new Promise(function (resolve, reject) {\r\n if (opts == null) reject('An options object is expected! ')\r\n else if (opts.connector == null) reject('You must specify a connector! (missing connector property)')\r\n else if (opts.connector.name == null) reject('You must specify connector name! (missing connector.name property)')\r\n else if (opts.db == null) reject('You must specify a database! (missing db property)')\r\n else if (opts.connector.name == null) reject('You must specify db name! (missing db.name property)')\r\n else if (opts.share == null) reject('You must specify a set of shared types!')\r\n else {\r\n var yconfig = new YConfig(opts)\r\n yconfig.db.whenUserIdSet(function () {\r\n yconfig.init(function () {\r\n resolve(yconfig)\r\n })\r\n })\r\n }\r\n })\r\n })\r\n}\r\n\r\nclass YConfig {\r\n /* ::\r\n db: Y.AbstractDatabase;\r\n connector: Y.AbstractConnector;\r\n share: {[key: string]: any};\r\n options: Object;\r\n */\r\n constructor (opts, callback) {\r\n this.options = opts\r\n this.db = new Y[opts.db.name](this, opts.db)\r\n this.connector = new Y[opts.connector.name](this, opts.connector)\r\n }\r\n init (callback) {\r\n var opts = this.options\r\n var share = {}\r\n this.share = share\r\n this.db.requestTransaction(function * requestTransaction () {\r\n // create shared object\r\n for (var propertyname in opts.share) {\r\n var typeConstructor = opts.share[propertyname].split('(')\r\n var typeName = typeConstructor.splice(0, 1)\r\n var args = []\r\n if (typeConstructor.length === 1) {\r\n try {\r\n args = JSON.parse('[' + typeConstructor[0].split(')')[0] + ']')\r\n } catch (e) {\r\n throw new Error('Was not able to parse type definition! (share.' + propertyname + ')')\r\n }\r\n }\r\n var type = Y[typeName]\r\n var typedef = type.typeDefinition\r\n var id = ['_', typedef.struct + '_' + typeName + '_' + propertyname + '_' + typeConstructor]\r\n share[propertyname] = yield* this.createType(type.apply(typedef, args), id)\r\n }\r\n this.store.whenTransactionsFinished()\r\n .then(callback)\r\n })\r\n }\r\n isConnected () {\r\n return this.connector.isSynced\r\n }\r\n disconnect () {\r\n return this.connector.disconnect()\r\n }\r\n reconnect () {\r\n return this.connector.reconnect()\r\n }\r\n destroy () {\r\n if (this.connector.destroy != null) {\r\n this.connector.destroy()\r\n } else {\r\n this.connector.disconnect()\r\n }\r\n var self = this\r\n this.db.requestTransaction(function * () {\r\n yield* self.db.destroy()\r\n self.connector = null\r\n self.db = null\r\n })\r\n }\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n window.Y = Y\r\n}\r\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/process/browser.js","node_modules/regenerator/node_modules/regenerator/runtime.js","src/Connector.js","src/Connectors/Test.js","src/Database.js","src/Struct.js","src/Transaction.js","src/Utils.js","src/y.js"],"names":[],"mappings":"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","file":"y.js","sourceRoot":"/source/","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n setTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","/**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * https://raw.github.com/facebook/regenerator/master/LICENSE file. An\n * additional grant of patent rights can be found in the PATENTS file in\n * the same directory.\n */\n\n!(function(global) {\n \"use strict\";\n\n var hasOwn = Object.prototype.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n var inModule = typeof module === \"object\";\n var runtime = global.regeneratorRuntime;\n if (runtime) {\n if (inModule) {\n // If regeneratorRuntime is defined globally and we're in a module,\n // make the exports object identical to regeneratorRuntime.\n module.exports = runtime;\n }\n // Don't bother evaluating the rest of this file if the runtime was\n // already defined globally.\n return;\n }\n\n // Define the runtime globally (as expected by generated code) as either\n // module.exports (if we're in a module) or a new, empty object.\n runtime = global.regeneratorRuntime = inModule ? module.exports : {};\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided, then outerFn.prototype instanceof Generator.\n var generator = Object.create((outerFn || Generator).prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n runtime.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype;\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = \"GeneratorFunction\";\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n prototype[method] = function(arg) {\n return this._invoke(method, arg);\n };\n });\n }\n\n runtime.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n runtime.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n if (!(toStringTagSymbol in genFun)) {\n genFun[toStringTagSymbol] = \"GeneratorFunction\";\n }\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `value instanceof AwaitArgument` to determine if the yielded value is\n // meant to be awaited. Some may consider the name of this method too\n // cutesy, but they are curmudgeons.\n runtime.awrap = function(arg) {\n return new AwaitArgument(arg);\n };\n\n function AwaitArgument(arg) {\n this.arg = arg;\n }\n\n function AsyncIterator(generator) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value instanceof AwaitArgument) {\n return Promise.resolve(value.arg).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return Promise.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration. If the Promise is rejected, however, the\n // result for this iteration will be rejected with the same\n // reason. Note that rejections of yielded Promises are not\n // thrown back into the generator function, as is the case\n // when an awaited Promise is rejected. This difference in\n // behavior between yield and await is important, because it\n // allows the consumer to decide what to do with the yielded\n // rejection (swallow it and continue, manually .throw it back\n // into the generator, abandon iteration, whatever). With\n // await, by contrast, there is no opportunity to examine the\n // rejection reason outside the generator function, so the\n // only option is to throw it from the await expression, and\n // let the generator function handle the exception.\n result.value = unwrapped;\n resolve(result);\n }, reject);\n }\n }\n\n if (typeof process === \"object\" && process.domain) {\n invoke = process.domain.bind(invoke);\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new Promise(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n runtime.async = function(innerFn, outerFn, self, tryLocsList) {\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList)\n );\n\n return runtime.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n if (method === \"return\" ||\n (method === \"throw\" && delegate.iterator[method] === undefined)) {\n // A return or throw (when the delegate iterator has no throw\n // method) always terminates the yield* loop.\n context.delegate = null;\n\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n var returnMethod = delegate.iterator[\"return\"];\n if (returnMethod) {\n var record = tryCatch(returnMethod, delegate.iterator, arg);\n if (record.type === \"throw\") {\n // If the return method threw an exception, let that\n // exception prevail over the original return or throw.\n method = \"throw\";\n arg = record.arg;\n continue;\n }\n }\n\n if (method === \"return\") {\n // Continue with the outer return, now that the delegate\n // iterator has been terminated.\n continue;\n }\n }\n\n var record = tryCatch(\n delegate.iterator[method],\n delegate.iterator,\n arg\n );\n\n if (record.type === \"throw\") {\n context.delegate = null;\n\n // Like returning generator.throw(uncaught), but without the\n // overhead of an extra function call.\n method = \"throw\";\n arg = record.arg;\n continue;\n }\n\n // Delegate generator ran and handled its own exceptions so\n // regardless of what the method was, we continue as if it is\n // \"next\" with an undefined arg.\n method = \"next\";\n arg = undefined;\n\n var info = record.arg;\n if (info.done) {\n context[delegate.resultName] = info.value;\n context.next = delegate.nextLoc;\n } else {\n state = GenStateSuspendedYield;\n return info;\n }\n\n context.delegate = null;\n }\n\n if (method === \"next\") {\n if (state === GenStateSuspendedYield) {\n context.sent = arg;\n } else {\n context.sent = undefined;\n }\n\n } else if (method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw arg;\n }\n\n if (context.dispatchException(arg)) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n method = \"next\";\n arg = undefined;\n }\n\n } else if (method === \"return\") {\n context.abrupt(\"return\", arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n var info = {\n value: record.arg,\n done: context.done\n };\n\n if (record.arg === ContinueSentinel) {\n if (context.delegate && method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n arg = undefined;\n }\n } else {\n return info;\n }\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(arg) call above.\n method = \"throw\";\n arg = record.arg;\n }\n }\n };\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp[toStringTagSymbol] = \"Generator\";\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n runtime.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n runtime.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n this.sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n return !!caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.next = finallyEntry.finallyLoc;\n } else {\n this.complete(record);\n }\n\n return ContinueSentinel;\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = record.arg;\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n return ContinueSentinel;\n }\n };\n})(\n // Among the various tricks for obtaining a reference to the global\n // object, this seems to be the most reliable technique that does not\n // use indirect eval (which violates Content Security Policy).\n typeof global === \"object\" ? global :\n typeof window === \"object\" ? window :\n typeof self === \"object\" ? self : this\n);\n","/* @flow */\n'use strict'\n\nmodule.exports = function (Y/* :any */) {\n class AbstractConnector {\n /* ::\n y: YConfig;\n role: SyncRole;\n connections: Object;\n isSynced: boolean;\n userEventListeners: Array;\n whenSyncedListeners: Array;\n currentSyncTarget: ?UserId;\n syncingClients: Array;\n forwardToSyncingClients: boolean;\n debug: boolean;\n broadcastedHB: boolean;\n syncStep2: Promise;\n userId: UserId;\n send: Function;\n broadcast: Function;\n broadcastOpBuffer: Array;\n protocolVersion: number;\n */\n /*\n opts contains the following information:\n role : String Role of this client (\"master\" or \"slave\")\n userId : String Uniquely defines the user.\n debug: Boolean Whether to print debug messages (optional)\n */\n constructor (y, opts) {\n this.y = y\n if (opts == null) {\n opts = {}\n }\n if (opts.role == null || opts.role === 'master') {\n this.role = 'master'\n } else if (opts.role === 'slave') {\n this.role = 'slave'\n } else {\n throw new Error(\"Role must be either 'master' or 'slave'!\")\n }\n this.y.db.forwardAppliedOperations = opts.forwardAppliedOperations || false\n this.role = opts.role\n this.connections = {}\n this.isSynced = false\n this.userEventListeners = []\n this.whenSyncedListeners = []\n this.currentSyncTarget = null\n this.syncingClients = []\n this.forwardToSyncingClients = opts.forwardToSyncingClients !== false\n this.debug = opts.debug === true\n this.broadcastedHB = false\n this.syncStep2 = Promise.resolve()\n this.broadcastOpBuffer = []\n this.protocolVersion = 11\n }\n reconnect () {\n }\n disconnect () {\n this.connections = {}\n this.isSynced = false\n this.currentSyncTarget = null\n this.broadcastedHB = false\n this.syncingClients = []\n this.whenSyncedListeners = []\n return this.y.db.stopGarbageCollector()\n }\n setUserId (userId) {\n if (this.userId == null) {\n this.userId = userId\n return this.y.db.setUserId(userId)\n } else {\n return null\n }\n }\n onUserEvent (f) {\n this.userEventListeners.push(f)\n }\n userLeft (user) {\n if (this.connections[user] != null) {\n delete this.connections[user]\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null\n this.findNextSyncTarget()\n }\n this.syncingClients = this.syncingClients.filter(function (cli) {\n return cli !== user\n })\n for (var f of this.userEventListeners) {\n f({\n action: 'userLeft',\n user: user\n })\n }\n }\n }\n userJoined (user, role) {\n if (role == null) {\n throw new Error('You must specify the role of the joined user!')\n }\n if (this.connections[user] != null) {\n throw new Error('This user already joined!')\n }\n this.connections[user] = {\n isSynced: false,\n role: role\n }\n for (var f of this.userEventListeners) {\n f({\n action: 'userJoined',\n user: user,\n role: role\n })\n }\n if (this.currentSyncTarget == null) {\n this.findNextSyncTarget()\n }\n }\n // Execute a function _when_ we are connected.\n // If not connected, wait until connected\n whenSynced (f) {\n if (this.isSynced) {\n f()\n } else {\n this.whenSyncedListeners.push(f)\n }\n }\n /*\n\n returns false, if there is no sync target\n true otherwise\n */\n findNextSyncTarget () {\n if (this.currentSyncTarget != null || this.isSynced) {\n return // \"The current sync has not finished!\"\n }\n\n var syncUser = null\n for (var uid in this.connections) {\n if (!this.connections[uid].isSynced) {\n syncUser = uid\n break\n }\n }\n var conn = this\n if (syncUser != null) {\n this.currentSyncTarget = syncUser\n this.y.db.requestTransaction(function *() {\n var stateSet = yield* this.getStateSet()\n var deleteSet = yield* this.getDeleteSet()\n conn.send(syncUser, {\n type: 'sync step 1',\n stateSet: stateSet,\n deleteSet: deleteSet,\n protocolVersion: conn.protocolVersion\n })\n })\n } else {\n this.y.db.requestTransaction(function *() {\n // it is crucial that isSynced is set at the time garbageCollectAfterSync is called\n conn.isSynced = true\n yield* this.garbageCollectAfterSync()\n // call whensynced listeners\n for (var f of conn.whenSyncedListeners) {\n f()\n }\n conn.whenSyncedListeners = []\n })\n }\n }\n send (uid, message) {\n if (this.debug) {\n console.log(`send ${this.userId} -> ${uid}: ${message.type}`, message) // eslint-disable-line\n }\n }\n /*\n Buffer operations, and broadcast them when ready.\n */\n broadcastOps (ops) {\n ops = ops.map(function (op) {\n return Y.Struct[op.struct].encode(op)\n })\n var self = this\n function broadcastOperations () {\n if (self.broadcastOpBuffer.length > 0) {\n self.broadcast({\n type: 'update',\n ops: self.broadcastOpBuffer\n })\n self.broadcastOpBuffer = []\n }\n }\n if (this.broadcastOpBuffer.length === 0) {\n this.broadcastOpBuffer = ops\n if (this.y.db.transactionInProgress) {\n this.y.db.whenTransactionsFinished().then(broadcastOperations)\n } else {\n setTimeout(broadcastOperations, 0)\n }\n } else {\n this.broadcastOpBuffer = this.broadcastOpBuffer.concat(ops)\n }\n }\n /*\n You received a raw message, and you know that it is intended for Yjs. Then call this function.\n */\n receiveMessage (sender/* :UserId */, message/* :Message */) {\n if (sender === this.userId) {\n return\n }\n if (this.debug) {\n console.log(`receive ${sender} -> ${this.userId}: ${message.type}`, JSON.parse(JSON.stringify(message))) // eslint-disable-line\n }\n if (message.protocolVersion != null && message.protocolVersion !== this.protocolVersion) {\n console.error(\n `You tried to sync with a yjs instance that has a different protocol version\n (You: ${this.protocolVersion}, Client: ${message.protocolVersion}).\n The sync was stopped. You need to upgrade your dependencies (especially Yjs & the Connector)!\n `)\n this.send(sender, {\n type: 'sync stop',\n protocolVersion: this.protocolVersion\n })\n return\n }\n if (message.type === 'sync step 1') {\n let conn = this\n let m = message\n this.y.db.requestTransaction(function *() {\n var currentStateSet = yield* this.getStateSet()\n yield* this.applyDeleteSet(m.deleteSet)\n\n var ds = yield* this.getDeleteSet()\n var ops = yield* this.getOperations(m.stateSet)\n conn.send(sender, {\n type: 'sync step 2',\n os: ops,\n stateSet: currentStateSet,\n deleteSet: ds,\n protocolVersion: this.protocolVersion\n })\n if (this.forwardToSyncingClients) {\n conn.syncingClients.push(sender)\n setTimeout(function () {\n conn.syncingClients = conn.syncingClients.filter(function (cli) {\n return cli !== sender\n })\n conn.send(sender, {\n type: 'sync done'\n })\n }, 5000) // TODO: conn.syncingClientDuration)\n } else {\n conn.send(sender, {\n type: 'sync done'\n })\n }\n conn._setSyncedWith(sender)\n })\n } else if (message.type === 'sync step 2') {\n let conn = this\n var broadcastHB = !this.broadcastedHB\n this.broadcastedHB = true\n var db = this.y.db\n var defer = {}\n defer.promise = new Promise(function (resolve) {\n defer.resolve = resolve\n })\n this.syncStep2 = defer.promise\n let m /* :MessageSyncStep2 */ = message\n db.requestTransaction(function * () {\n yield* this.applyDeleteSet(m.deleteSet)\n this.store.apply(m.os)\n db.requestTransaction(function * () {\n var ops = yield* this.getOperations(m.stateSet)\n if (ops.length > 0) {\n if (!broadcastHB) { // TODO: consider to broadcast here..\n conn.send(sender, {\n type: 'update',\n ops: ops\n })\n } else {\n // broadcast only once!\n conn.broadcastOps(ops)\n }\n }\n defer.resolve()\n })\n })\n } else if (message.type === 'sync done') {\n var self = this\n this.syncStep2.then(function () {\n self._setSyncedWith(sender)\n })\n } else if (message.type === 'update') {\n if (this.forwardToSyncingClients) {\n for (var client of this.syncingClients) {\n this.send(client, message)\n }\n }\n if (this.y.db.forwardAppliedOperations) {\n var delops = message.ops.filter(function (o) {\n return o.struct === 'Delete'\n })\n if (delops.length > 0) {\n this.broadcastOps(delops)\n }\n }\n this.y.db.apply(message.ops)\n }\n }\n _setSyncedWith (user) {\n var conn = this.connections[user]\n if (conn != null) {\n conn.isSynced = true\n }\n if (user === this.currentSyncTarget) {\n this.currentSyncTarget = null\n this.findNextSyncTarget()\n }\n }\n /*\n Currently, the HB encodes operations as JSON. For the moment I want to keep it\n that way. Maybe we support encoding in the HB as XML in the future, but for now I don't want\n too much overhead. Y is very likely to get changed a lot in the future\n\n Because we don't want to encode JSON as string (with character escaping, wich makes it pretty much unreadable)\n we encode the JSON as XML.\n\n When the HB support encoding as XML, the format should look pretty much like this.\n\n does not support primitive values as array elements\n expects an ltx (less than xml) object\n */\n parseMessageFromXml (m/* :any */) {\n function parseArray (node) {\n for (var n of node.children) {\n if (n.getAttribute('isArray') === 'true') {\n return parseArray(n)\n } else {\n return parseObject(n)\n }\n }\n }\n function parseObject (node/* :any */) {\n var json = {}\n for (var attrName in node.attrs) {\n var value = node.attrs[attrName]\n var int = parseInt(value, 10)\n if (isNaN(int) || ('' + int) !== value) {\n json[attrName] = value\n } else {\n json[attrName] = int\n }\n }\n for (var n/* :any */ in node.children) {\n var name = n.name\n if (n.getAttribute('isArray') === 'true') {\n json[name] = parseArray(n)\n } else {\n json[name] = parseObject(n)\n }\n }\n return json\n }\n parseObject(m)\n }\n /*\n encode message in xml\n we use string because Strophe only accepts an \"xml-string\"..\n So {a:4,b:{c:5}} will look like\n \n \n \n m - ltx element\n json - Object\n */\n encodeMessageToXml (msg, obj) {\n // attributes is optional\n function encodeObject (m, json) {\n for (var name in json) {\n var value = json[name]\n if (name == null) {\n // nop\n } else if (value.constructor === Object) {\n encodeObject(m.c(name), value)\n } else if (value.constructor === Array) {\n encodeArray(m.c(name), value)\n } else {\n m.setAttribute(name, value)\n }\n }\n }\n function encodeArray (m, array) {\n m.setAttribute('isArray', 'true')\n for (var e of array) {\n if (e.constructor === Object) {\n encodeObject(m.c('array-element'), e)\n } else {\n encodeArray(m.c('array-element'), e)\n }\n }\n }\n if (obj.constructor === Object) {\n encodeObject(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj)\n } else if (obj.constructor === Array) {\n encodeArray(msg.c('y', { xmlns: 'http://y.ninja/connector-stanza' }), obj)\n } else {\n throw new Error(\"I can't encode this json!\")\n }\n }\n }\n Y.AbstractConnector = AbstractConnector\n}\n","/* global getRandom, async */\n'use strict'\n\nmodule.exports = function (Y) {\n var globalRoom = {\n users: {},\n buffers: {}, // TODO: reimplement this idea. This does not cover all cases!! Here, you have a queue which is unrealistic (i.e. think about multiple incoming connections)\n removeUser: function (user) {\n for (var i in this.users) {\n this.users[i].userLeft(user)\n }\n delete this.users[user]\n delete this.buffers[user]\n },\n addUser: function (connector) {\n this.users[connector.userId] = connector\n this.buffers[connector.userId] = {}\n for (var uname in this.users) {\n if (uname !== connector.userId) {\n var u = this.users[uname]\n u.userJoined(connector.userId, 'master')\n connector.userJoined(u.userId, 'master')\n }\n }\n },\n whenTransactionsFinished: function () {\n var ps = []\n for (var name in this.users) {\n ps.push(this.users[name].y.db.whenTransactionsFinished())\n }\n return Promise.all(ps)\n },\n flushOne: function flushOne () {\n var bufs = []\n for (var receiver in globalRoom.buffers) {\n let buff = globalRoom.buffers[receiver]\n var push = false\n for (let sender in buff) {\n if (buff[sender].length > 0) {\n push = true\n break\n }\n }\n if (push) {\n bufs.push(receiver)\n }\n }\n if (bufs.length > 0) {\n var userId = getRandom(bufs)\n let buff = globalRoom.buffers[userId]\n let sender = getRandom(Object.keys(buff))\n var m = buff[sender].shift()\n if (buff[sender].length === 0) {\n delete buff[sender]\n }\n var user = globalRoom.users[userId]\n user.receiveMessage(m[0], m[1])\n return user.y.db.whenTransactionsFinished()\n } else {\n return false\n }\n },\n flushAll: function () {\n return new Promise(function (resolve) {\n // flushes may result in more created operations,\n // flush until there is nothing more to flush\n function nextFlush () {\n var c = globalRoom.flushOne()\n if (c) {\n while (c) {\n c = globalRoom.flushOne()\n }\n globalRoom.whenTransactionsFinished().then(nextFlush)\n } else {\n setTimeout(function () {\n var c = globalRoom.flushOne()\n if (c) {\n c.then(function () {\n globalRoom.whenTransactionsFinished().then(nextFlush)\n })\n } else {\n resolve()\n }\n }, 10)\n }\n }\n globalRoom.whenTransactionsFinished().then(nextFlush)\n })\n }\n }\n Y.utils.globalRoom = globalRoom\n\n var userIdCounter = 0\n\n class Test extends Y.AbstractConnector {\n constructor (y, options) {\n if (options === undefined) {\n throw new Error('Options must not be undefined!')\n }\n options.role = 'master'\n options.forwardToSyncingClients = false\n super(y, options)\n this.setUserId((userIdCounter++) + '').then(() => {\n globalRoom.addUser(this)\n })\n this.globalRoom = globalRoom\n this.syncingClientDuration = 0\n }\n receiveMessage (sender, m) {\n super.receiveMessage(sender, JSON.parse(JSON.stringify(m)))\n }\n send (userId, message) {\n var buffer = globalRoom.buffers[userId]\n if (buffer != null) {\n if (buffer[this.userId] == null) {\n buffer[this.userId] = []\n }\n buffer[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n broadcast (message) {\n for (var key in globalRoom.buffers) {\n var buff = globalRoom.buffers[key]\n if (buff[this.userId] == null) {\n buff[this.userId] = []\n }\n buff[this.userId].push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n isDisconnected () {\n return globalRoom.users[this.userId] == null\n }\n reconnect () {\n if (this.isDisconnected()) {\n globalRoom.addUser(this)\n super.reconnect()\n }\n return Y.utils.globalRoom.flushAll()\n }\n disconnect () {\n if (!this.isDisconnected()) {\n globalRoom.removeUser(this.userId)\n super.disconnect()\n }\n return this.y.db.whenTransactionsFinished()\n }\n flush () {\n var self = this\n return async(function * () {\n var buff = globalRoom.buffers[self.userId]\n while (Object.keys(buff).length > 0) {\n var sender = getRandom(Object.keys(buff))\n var m = buff[sender].shift()\n if (buff[sender].length === 0) {\n delete buff[sender]\n }\n this.receiveMessage(m[0], m[1])\n }\n yield self.whenTransactionsFinished()\n })\n }\n }\n\n Y.Test = Test\n}\n","/* @flow */\n'use strict'\n\nmodule.exports = function (Y /* :any */) {\n /*\n Partial definition of an OperationStore.\n TODO: name it Database, operation store only holds operations.\n\n A database definition must alse define the following methods:\n * logTable() (optional)\n - show relevant information information in a table\n * requestTransaction(makeGen)\n - request a transaction\n * destroy()\n - destroy the database\n */\n class AbstractDatabase {\n /* ::\n y: YConfig;\n forwardAppliedOperations: boolean;\n listenersById: Object;\n listenersByIdExecuteNow: Array;\n listenersByIdRequestPending: boolean;\n initializedTypes: Object;\n whenUserIdSetListener: ?Function;\n waitingTransactions: Array;\n transactionInProgress: boolean;\n executeOrder: Array;\n gc1: Array;\n gc2: Array;\n gcTimeout: number;\n gcInterval: any;\n garbageCollect: Function;\n executeOrder: Array; // for debugging only\n userId: UserId;\n opClock: number;\n transactionsFinished: ?{promise: Promise, resolve: any};\n transact: (x: ?Generator) => any;\n */\n constructor (y, opts) {\n this.y = y\n var os = this\n this.userId = null\n var resolve\n this.userIdPromise = new Promise(function (r) {\n resolve = r\n })\n this.userIdPromise.resolve = resolve\n // whether to broadcast all applied operations (insert & delete hook)\n this.forwardAppliedOperations = false\n // E.g. this.listenersById[id] : Array\n this.listenersById = {}\n // Execute the next time a transaction is requested\n this.listenersByIdExecuteNow = []\n // A transaction is requested\n this.listenersByIdRequestPending = false\n /* To make things more clear, the following naming conventions:\n * ls : we put this.listenersById on ls\n * l : Array\n * id : Id (can't use as property name)\n * sid : String (converted from id via JSON.stringify\n so we can use it as a property name)\n\n Always remember to first overwrite\n a property before you iterate over it!\n */\n // TODO: Use ES7 Weak Maps. This way types that are no longer user,\n // wont be kept in memory.\n this.initializedTypes = {}\n this.waitingTransactions = []\n this.transactionInProgress = false\n this.transactionIsFlushed = false\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n this.executeOrder = []\n }\n this.gc1 = [] // first stage\n this.gc2 = [] // second stage -> after that, remove the op\n this.gcTimeout = !opts.gcTimeout ? 50000 : opts.gcTimeoutÅ›\n function garbageCollect () {\n return os.whenTransactionsFinished().then(function () {\n if (os.gc1.length > 0 || os.gc2.length > 0) {\n if (!os.y.isConnected()) {\n console.warn('gc should be empty when disconnected!')\n }\n return new Promise((resolve) => {\n os.requestTransaction(function * () {\n if (os.y.connector != null && os.y.connector.isSynced) {\n for (var i = 0; i < os.gc2.length; i++) {\n var oid = os.gc2[i]\n yield* this.garbageCollectOperation(oid)\n }\n os.gc2 = os.gc1\n os.gc1 = []\n }\n // TODO: Use setInterval here instead (when garbageCollect is called several times there will be several timeouts..)\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout)\n }\n resolve()\n })\n })\n } else {\n // TODO: see above\n if (os.gcTimeout > 0) {\n os.gcInterval = setTimeout(garbageCollect, os.gcTimeout)\n }\n return Promise.resolve()\n }\n })\n }\n this.garbageCollect = garbageCollect\n if (this.gcTimeout > 0) {\n garbageCollect()\n }\n }\n queueGarbageCollector (id) {\n if (this.y.isConnected()) {\n this.gc1.push(id)\n }\n }\n emptyGarbageCollector () {\n return new Promise(resolve => {\n var check = () => {\n if (this.gc1.length > 0 || this.gc2.length > 0) {\n this.garbageCollect().then(check)\n } else {\n resolve()\n }\n }\n setTimeout(check, 0)\n })\n }\n addToDebug () {\n if (typeof YConcurrency_TestingMode !== 'undefined') {\n var command /* :string */ = Array.prototype.map.call(arguments, function (s) {\n if (typeof s === 'string') {\n return s\n } else {\n return JSON.stringify(s)\n }\n }).join('').replace(/\"/g, \"'\").replace(/,/g, ', ').replace(/:/g, ': ')\n this.executeOrder.push(command)\n }\n }\n getDebugData () {\n console.log(this.executeOrder.join('\\n'))\n }\n stopGarbageCollector () {\n var self = this\n return new Promise(function (resolve) {\n self.requestTransaction(function * () {\n var ungc /* :Array */ = self.gc1.concat(self.gc2)\n self.gc1 = []\n self.gc2 = []\n for (var i = 0; i < ungc.length; i++) {\n var op = yield* this.getOperation(ungc[i])\n if (op != null) {\n delete op.gc\n yield* this.setOperation(op)\n }\n }\n resolve()\n })\n })\n }\n /*\n Try to add to GC.\n\n TODO: rename this function\n\n Rulez:\n * Only gc if this user is online\n * The most left element in a list must not be gc'd.\n => There is at least one element in the list\n\n returns true iff op was added to GC\n */\n * addToGarbageCollector (op, left) {\n if (\n op.gc == null &&\n op.deleted === true\n ) {\n var gc = false\n if (left != null && left.deleted === true) {\n gc = true\n } else if (op.content != null && op.content.length > 1) {\n op = yield* this.getInsertionCleanStart([op.id[0], op.id[1] + 1])\n gc = true\n }\n if (gc) {\n op.gc = true\n yield* this.setOperation(op)\n this.store.queueGarbageCollector(op.id)\n return true\n }\n }\n return false\n }\n removeFromGarbageCollector (op) {\n function filter (o) {\n return !Y.utils.compareIds(o, op.id)\n }\n this.gc1 = this.gc1.filter(filter)\n this.gc2 = this.gc2.filter(filter)\n delete op.gc\n }\n * destroy () {\n clearInterval(this.gcInterval)\n this.gcInterval = null\n for (var key in this.initializedTypes) {\n var type = this.initializedTypes[key]\n if (type._destroy != null) {\n type._destroy()\n } else {\n console.error('The type you included does not provide destroy functionality, it will remain in memory (updating your packages will help).')\n }\n }\n }\n setUserId (userId) {\n if (!this.userIdPromise.inProgress) {\n this.userIdPromise.inProgress = true\n var self = this\n self.requestTransaction(function * () {\n self.userId = userId\n var state = yield* this.getState(userId)\n self.opClock = state.clock\n self.userIdPromise.resolve(userId)\n })\n }\n return this.userIdPromise\n }\n whenUserIdSet (f) {\n this.userIdPromise.then(f)\n }\n getNextOpId (numberOfIds) {\n if (numberOfIds == null) {\n throw new Error('getNextOpId expects the number of created ids to create!')\n } else if (this.userId == null) {\n throw new Error('OperationStore not yet initialized!')\n } else {\n var id = [this.userId, this.opClock]\n this.opClock += numberOfIds\n return id\n }\n }\n /*\n Apply a list of operations.\n\n * get a transaction\n * check whether all Struct.*.requiredOps are in the OS\n * check if it is an expected op (otherwise wait for it)\n * check if was deleted, apply a delete operation after op was applied\n */\n apply (ops) {\n for (var i = 0; i < ops.length; i++) {\n var o = ops[i]\n if (o.id == null || o.id[0] !== this.y.connector.userId) {\n var required = Y.Struct[o.struct].requiredOps(o)\n if (o.requires != null) {\n required = required.concat(o.requires)\n }\n this.whenOperationsExist(required, o)\n }\n }\n }\n /*\n op is executed as soon as every operation requested is available.\n Note that Transaction can (and should) buffer requests.\n */\n whenOperationsExist (ids, op) {\n if (ids.length > 0) {\n let listener = {\n op: op,\n missing: ids.length\n }\n\n for (let i = 0; i < ids.length; i++) {\n let id = ids[i]\n let sid = JSON.stringify(id)\n let l = this.listenersById[sid]\n if (l == null) {\n l = []\n this.listenersById[sid] = l\n }\n l.push(listener)\n }\n } else {\n this.listenersByIdExecuteNow.push({\n op: op\n })\n }\n\n if (this.listenersByIdRequestPending) {\n return\n }\n\n this.listenersByIdRequestPending = true\n var store = this\n\n this.requestTransaction(function * () {\n var exeNow = store.listenersByIdExecuteNow\n store.listenersByIdExecuteNow = []\n\n var ls = store.listenersById\n store.listenersById = {}\n\n store.listenersByIdRequestPending = false\n\n for (let key = 0; key < exeNow.length; key++) {\n let o = exeNow[key].op\n yield* store.tryExecute.call(this, o)\n }\n\n for (var sid in ls) {\n var l = ls[sid]\n var id = JSON.parse(sid)\n var op\n if (typeof id[1] === 'string') {\n op = yield* this.getOperation(id)\n } else {\n op = yield* this.getInsertion(id)\n }\n if (op == null) {\n store.listenersById[sid] = l\n } else {\n for (let i = 0; i < l.length; i++) {\n let listener = l[i]\n let o = listener.op\n if (--listener.missing === 0) {\n yield* store.tryExecute.call(this, o)\n }\n }\n }\n }\n })\n }\n /*\n Actually execute an operation, when all expected operations are available.\n */\n /* :: // TODO: this belongs somehow to transaction\n store: Object;\n getOperation: any;\n isGarbageCollected: any;\n addOperation: any;\n whenOperationsExist: any;\n */\n * tryExecute (op) {\n this.store.addToDebug('yield* this.store.tryExecute.call(this, ', JSON.stringify(op), ')')\n if (op.struct === 'Delete') {\n yield* Y.Struct.Delete.execute.call(this, op)\n // this is now called in Transaction.deleteOperation!\n // yield* this.store.operationAdded(this, op)\n } else {\n // check if this op was defined\n var defined = yield* this.getInsertion(op.id)\n while (defined != null && defined.content != null) {\n // check if this op has a longer content in the case it is defined\n if (defined.id[1] + defined.content.length < op.id[1] + op.content.length) {\n var overlapSize = defined.content.length - (op.id[1] - defined.id[1])\n op.content.splice(0, overlapSize)\n op.id = [op.id[0], op.id[1] + overlapSize]\n op.left = Y.utils.getLastId(defined)\n op.origin = op.left\n defined = yield* this.getOperation(op.id) // getOperation suffices here\n } else {\n break\n }\n }\n if (defined == null) {\n var isGarbageCollected = yield* this.isGarbageCollected(op.id)\n if (!isGarbageCollected) {\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n\n // if insertion, try to combine with left\n yield* this.tryCombineWithLeft(op)\n }\n }\n }\n }\n // called by a transaction when an operation is added\n * operationAdded (transaction, op) {\n // increase SS\n yield* transaction.updateState(op.id[0])\n\n var opLen = op.content != null ? op.content.length : 1\n for (let i = 0; i < opLen; i++) {\n // notify whenOperation listeners (by id)\n var sid = JSON.stringify([op.id[0], op.id[1] + i])\n var l = this.listenersById[sid]\n delete this.listenersById[sid]\n\n if (l != null) {\n for (var key in l) {\n var listener = l[key]\n if (--listener.missing === 0) {\n this.whenOperationsExist([], listener.op)\n }\n }\n }\n }\n var t = this.initializedTypes[JSON.stringify(op.parent)]\n\n // if parent is deleted, mark as gc'd and return\n if (op.parent != null) {\n var parentIsDeleted = yield* transaction.isDeleted(op.parent)\n if (parentIsDeleted) {\n yield* transaction.deleteList(op.id)\n return\n }\n }\n\n // notify parent, if it was instanciated as a custom type\n if (t != null) {\n let o = Y.utils.copyObject(op)\n yield* t._changed(transaction, o)\n }\n if (!op.deleted) {\n // Delete if DS says this is actually deleted\n var len = op.content != null ? op.content.length : 1\n var startId = op.id // You must not use op.id in the following loop, because op will change when deleted\n for (let i = 0; i < len; i++) {\n var id = [startId[0], startId[1] + i]\n var opIsDeleted = yield* transaction.isDeleted(id)\n if (opIsDeleted) {\n var delop = {\n struct: 'Delete',\n target: id\n }\n yield* this.tryExecute.call(transaction, delop)\n }\n }\n }\n }\n whenTransactionsFinished () {\n if (this.transactionInProgress) {\n if (this.transactionsFinished == null) {\n var resolve\n var promise = new Promise(function (r) {\n resolve = r\n })\n this.transactionsFinished = {\n resolve: resolve,\n promise: promise\n }\n return promise\n } else {\n return this.transactionsFinished.promise\n }\n } else {\n return Promise.resolve()\n }\n }\n // Check if there is another transaction request.\n // * the last transaction is always a flush :)\n getNextRequest () {\n if (this.waitingTransactions.length === 0) {\n if (this.transactionIsFlushed) {\n this.transactionInProgress = false\n this.transactionIsFlushed = false\n if (this.transactionsFinished != null) {\n this.transactionsFinished.resolve()\n this.transactionsFinished = null\n }\n return null\n } else {\n this.transactionIsFlushed = true\n return function * () {\n yield* this.flush()\n }\n }\n } else {\n this.transactionIsFlushed = false\n return this.waitingTransactions.shift()\n }\n }\n requestTransaction (makeGen/* :any */, callImmediately) {\n this.waitingTransactions.push(makeGen)\n if (!this.transactionInProgress) {\n this.transactionInProgress = true\n if (false || callImmediately) { // TODO: decide whether this is ok or not..\n this.transact(this.getNextRequest())\n } else {\n var self = this\n setTimeout(function () {\n self.transact(self.getNextRequest())\n }, 0)\n }\n }\n }\n }\n Y.AbstractDatabase = AbstractDatabase\n}\n","/* @flow */\n'use strict'\n\n/*\n An operation also defines the structure of a type. This is why operation and\n structure are used interchangeably here.\n\n It must be of the type Object. I hope to achieve some performance\n improvements when working on databases that support the json format.\n\n An operation must have the following properties:\n\n * encode\n - Encode the structure in a readable format (preferably string- todo)\n * decode (todo)\n - decode structure to json\n * execute\n - Execute the semantics of an operation.\n * requiredOps\n - Operations that are required to execute this operation.\n*/\nmodule.exports = function (Y/* :any */) {\n var Struct = {\n /* This is the only operation that is actually not a structure, because\n it is not stored in the OS. This is why it _does not_ have an id\n\n op = {\n target: Id\n }\n */\n Delete: {\n encode: function (op) {\n return op\n },\n requiredOps: function (op) {\n return [] // [op.target]\n },\n execute: function * (op) {\n return yield* this.deleteOperation(op.target, op.length || 1)\n }\n },\n Insert: {\n /* {\n content: [any],\n opContent: Id,\n id: Id,\n left: Id,\n origin: Id,\n right: Id,\n parent: Id,\n parentSub: string (optional), // child of Map type\n }\n */\n encode: function (op/* :Insertion */) /* :Insertion */ {\n // TODO: you could not send the \"left\" property, then you also have to\n // \"op.left = null\" in $execute or $decode\n var e/* :any */ = {\n id: op.id,\n left: op.left,\n right: op.right,\n origin: op.origin,\n parent: op.parent,\n struct: op.struct\n }\n if (op.parentSub != null) {\n e.parentSub = op.parentSub\n }\n if (op.hasOwnProperty('opContent')) {\n e.opContent = op.opContent\n } else {\n e.content = op.content.slice()\n }\n\n return e\n },\n requiredOps: function (op) {\n var ids = []\n if (op.left != null) {\n ids.push(op.left)\n }\n if (op.right != null) {\n ids.push(op.right)\n }\n if (op.origin != null && !Y.utils.compareIds(op.left, op.origin)) {\n ids.push(op.origin)\n }\n // if (op.right == null && op.left == null) {\n ids.push(op.parent)\n\n if (op.opContent != null) {\n ids.push(op.opContent)\n }\n return ids\n },\n getDistanceToOrigin: function * (op) {\n if (op.left == null) {\n return 0\n } else {\n var d = 0\n var o = yield* this.getInsertion(op.left)\n while (!Y.utils.matchesId(o, op.origin)) {\n d++\n if (o.left == null) {\n break\n } else {\n o = yield* this.getInsertion(o.left)\n }\n }\n return d\n }\n },\n /*\n # $this has to find a unique position between origin and the next known character\n # case 1: $origin equals $o.origin: the $creator parameter decides if left or right\n # let $OL= [o1,o2,o3,o4], whereby $this is to be inserted between o1 and o4\n # o2,o3 and o4 origin is 1 (the position of o2)\n # there is the case that $this.creator < o2.creator, but o3.creator < $this.creator\n # then o2 knows o3. Since on another client $OL could be [o1,o3,o4] the problem is complex\n # therefore $this would be always to the right of o3\n # case 2: $origin < $o.origin\n # if current $this insert_position > $o origin: $this ins\n # else $insert_position will not change\n # (maybe we encounter case 1 later, then this will be to the right of $o)\n # case 3: $origin > $o.origin\n # $this insert_position is to the left of $o (forever!)\n */\n execute: function * (op) {\n var i // loop counter\n\n // during this function some ops may get split into two pieces (e.g. with getInsertionCleanEnd)\n // We try to merge them later, if possible\n var tryToRemergeLater = []\n\n if (op.origin != null) { // TODO: !== instead of !=\n // we save in origin that op originates in it\n // we need that later when we eventually garbage collect origin (see transaction)\n var origin = yield* this.getInsertionCleanEnd(op.origin)\n if (origin.originOf == null) {\n origin.originOf = []\n }\n origin.originOf.push(op.id)\n yield* this.setOperation(origin)\n if (origin.right != null) {\n tryToRemergeLater.push(origin.right)\n }\n }\n var distanceToOrigin = i = yield* Struct.Insert.getDistanceToOrigin.call(this, op) // most cases: 0 (starts from 0)\n\n // now we begin to insert op in the list of insertions..\n var o\n var parent\n var start\n\n // find o. o is the first conflicting operation\n if (op.left != null) {\n o = yield* this.getInsertionCleanEnd(op.left)\n if (!Y.utils.compareIds(op.left, op.origin) && o.right != null) {\n // only if not added previously\n tryToRemergeLater.push(o.right)\n }\n o = (o.right == null) ? null : yield* this.getOperation(o.right)\n } else { // left == null\n parent = yield* this.getOperation(op.parent)\n let startId = op.parentSub ? parent.map[op.parentSub] : parent.start\n start = startId == null ? null : yield* this.getOperation(startId)\n o = start\n }\n\n // make sure to split op.right if necessary (also add to tryCombineWithLeft)\n if (op.right != null) {\n tryToRemergeLater.push(op.right)\n yield* this.getInsertionCleanStart(op.right)\n }\n\n // handle conflicts\n while (true) {\n if (o != null && !Y.utils.compareIds(o.id, op.right)) {\n var oOriginDistance = yield* Struct.Insert.getDistanceToOrigin.call(this, o)\n if (oOriginDistance === i) {\n // case 1\n if (o.id[0] < op.id[0]) {\n op.left = Y.utils.getLastId(o)\n distanceToOrigin = i + 1 // just ignore o.content.length, doesn't make a difference\n }\n } else if (oOriginDistance < i) {\n // case 2\n if (i - distanceToOrigin <= oOriginDistance) {\n op.left = Y.utils.getLastId(o)\n distanceToOrigin = i + 1 // just ignore o.content.length, doesn't make a difference\n }\n } else {\n break\n }\n i++\n if (o.right != null) {\n o = yield* this.getInsertion(o.right)\n } else {\n o = null\n }\n } else {\n break\n }\n }\n\n // reconnect..\n var left = null\n var right = null\n if (parent == null) {\n parent = yield* this.getOperation(op.parent)\n }\n\n // reconnect left and set right of op\n if (op.left != null) {\n left = yield* this.getInsertion(op.left)\n // link left\n op.right = left.right\n left.right = op.id\n\n yield* this.setOperation(left)\n } else {\n // set op.right from parent, if necessary\n op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start\n }\n // reconnect right\n if (op.right != null) {\n // TODO: wanna connect right too?\n right = yield* this.getOperation(op.right)\n right.left = Y.utils.getLastId(op)\n\n // if right exists, and it is supposed to be gc'd. Remove it from the gc\n if (right.gc != null) {\n if (right.content != null && right.content.length > 1) {\n right = yield* this.getInsertionCleanEnd(right.id)\n }\n this.store.removeFromGarbageCollector(right)\n }\n yield* this.setOperation(right)\n }\n\n // update parents .map/start/end properties\n if (op.parentSub != null) {\n if (left == null) {\n parent.map[op.parentSub] = op.id\n yield* this.setOperation(parent)\n }\n // is a child of a map struct.\n // Then also make sure that only the most left element is not deleted\n // We do not call the type in this case (this is what the third parameter is for)\n if (op.right != null) {\n yield* this.deleteOperation(op.right, 1, true)\n }\n if (op.left != null) {\n yield* this.deleteOperation(op.id, 1, true)\n }\n } else {\n if (right == null || left == null) {\n if (right == null) {\n parent.end = Y.utils.getLastId(op)\n }\n if (left == null) {\n parent.start = op.id\n }\n yield* this.setOperation(parent)\n }\n }\n\n // try to merge original op.left and op.origin\n for (let i = 0; i < tryToRemergeLater.length; i++) {\n var m = yield* this.getOperation(tryToRemergeLater[i])\n yield* this.tryCombineWithLeft(m)\n }\n }\n },\n List: {\n /*\n {\n start: null,\n end: null,\n struct: \"List\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function (id) {\n return {\n start: null,\n end: null,\n struct: 'List',\n id: id\n }\n },\n encode: function (op) {\n var e = {\n struct: 'List',\n id: op.id,\n type: op.type\n }\n if (op.requires != null) {\n e.requires = op.requires\n }\n if (op.info != null) {\n e.info = op.info\n }\n return e\n },\n requiredOps: function () {\n /*\n var ids = []\n if (op.start != null) {\n ids.push(op.start)\n }\n if (op.end != null){\n ids.push(op.end)\n }\n return ids\n */\n return []\n },\n execute: function * (op) {\n op.start = null\n op.end = null\n },\n ref: function * (op, pos) {\n if (op.start == null) {\n return null\n }\n var res = null\n var o = yield* this.getOperation(op.start)\n\n while (true) {\n if (!o.deleted) {\n res = o\n pos--\n }\n if (pos >= 0 && o.right != null) {\n o = yield* this.getOperation(o.right)\n } else {\n break\n }\n }\n return res\n },\n map: function * (o, f) {\n o = o.start\n var res = []\n while (o != null) { // TODO: change to != (at least some convention)\n var operation = yield* this.getOperation(o)\n if (!operation.deleted) {\n res.push(f(operation))\n }\n o = operation.right\n }\n return res\n }\n },\n Map: {\n /*\n {\n map: {},\n struct: \"Map\",\n type: \"\",\n id: this.os.getNextOpId(1)\n }\n */\n create: function (id) {\n return {\n id: id,\n map: {},\n struct: 'Map'\n }\n },\n encode: function (op) {\n var e = {\n struct: 'Map',\n type: op.type,\n id: op.id,\n map: {} // overwrite map!!\n }\n if (op.requires != null) {\n e.requires = op.requires\n }\n if (op.info != null) {\n e.info = op.info\n }\n return e\n },\n requiredOps: function () {\n return []\n },\n execute: function * () {},\n /*\n Get a property by name\n */\n get: function * (op, name) {\n var oid = op.map[name]\n if (oid != null) {\n var res = yield* this.getOperation(oid)\n if (res == null || res.deleted) {\n return void 0\n } else if (res.opContent == null) {\n return res.content[0]\n } else {\n return yield* this.getType(res.opContent)\n }\n }\n }\n }\n }\n Y.Struct = Struct\n}\n","/* @flow */\n'use strict'\n\n/*\n Partial definition of a transaction\n\n A transaction provides all the the async functionality on a database.\n\n By convention, a transaction has the following properties:\n * ss for StateSet\n * os for OperationStore\n * ds for DeleteStore\n\n A transaction must also define the following methods:\n * checkDeleteStoreForState(state)\n - When increasing the state of a user, an operation with an higher id\n may already be garbage collected, and therefore it will never be received.\n update the state to reflect this knowledge. This won't call a method to save the state!\n * getDeleteSet(id)\n - Get the delete set in a readable format:\n {\n \"userX\": [\n [5,1], // starting from position 5, one operations is deleted\n [9,4] // starting from position 9, four operations are deleted\n ],\n \"userY\": ...\n }\n * getOpsFromDeleteSet(ds) -- TODO: just call this.deleteOperation(id) here\n - get a set of deletions that need to be applied in order to get to\n achieve the state of the supplied ds\n * setOperation(op)\n - write `op` to the database.\n Note: this is allowed to return an in-memory object.\n E.g. the Memory adapter returns the object that it has in-memory.\n Changing values on this object will be stored directly in the database\n without calling this function. Therefore,\n setOperation may have no functionality in some adapters. This also has\n implications on the way we use operations that were served from the database.\n We try not to call copyObject, if not necessary.\n * addOperation(op)\n - add an operation to the database.\n This may only be called once for every op.id\n Must return a function that returns the next operation in the database (ordered by id)\n * getOperation(id)\n * removeOperation(id)\n - remove an operation from the database. This is called when an operation\n is garbage collected.\n * setState(state)\n - `state` is of the form\n {\n user: \"1\",\n clock: 4\n } <- meaning that we have four operations from user \"1\"\n (with these id's respectively: 0, 1, 2, and 3)\n * getState(user)\n * getStateVector()\n - Get the state of the OS in the form\n [{\n user: \"userX\",\n clock: 11\n },\n ..\n ]\n * getStateSet()\n - Get the state of the OS in the form\n {\n \"userX\": 11,\n \"userY\": 22\n }\n * getOperations(startSS)\n - Get the all the operations that are necessary in order to achive the\n stateSet of this user, starting from a stateSet supplied by another user\n * makeOperationReady(ss, op)\n - this is called only by `getOperations(startSS)`. It makes an operation\n applyable on a given SS.\n*/\nmodule.exports = function (Y/* :any */) {\n class TransactionInterface {\n /* ::\n store: Y.AbstractDatabase;\n ds: Store;\n os: Store;\n ss: Store;\n */\n /*\n Get a type based on the id of its model.\n If it does not exist yes, create it.\n TODO: delete type from store.initializedTypes[id] when corresponding id was deleted!\n */\n * getType (id, args) {\n var sid = JSON.stringify(id)\n var t = this.store.initializedTypes[sid]\n if (t == null) {\n var op/* :MapStruct | ListStruct */ = yield* this.getOperation(id)\n if (op != null) {\n t = yield* Y[op.type].typeDefinition.initType.call(this, this.store, op, args)\n this.store.initializedTypes[sid] = t\n }\n }\n return t\n }\n * createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op\n if (id[0] === '_') {\n op = yield* this.getOperation(id)\n } else {\n op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n }\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n if (op[0] === '_') {\n yield* this.setOperation(op)\n } else {\n yield* this.applyCreatedOperations([op])\n }\n return yield* this.getType(id, typedefinition[1])\n }\n /* createType (typedefinition, id) {\n var structname = typedefinition[0].struct\n id = id || this.store.getNextOpId(1)\n var op = Y.Struct[structname].create(id)\n op.type = typedefinition[0].name\n if (typedefinition[0].appendAdditionalInfo != null) {\n yield* typedefinition[0].appendAdditionalInfo.call(this, op, typedefinition[1])\n }\n // yield* this.applyCreatedOperations([op])\n yield* Y.Struct[op.struct].execute.call(this, op)\n yield* this.addOperation(op)\n yield* this.store.operationAdded(this, op)\n return yield* this.getType(id, typedefinition[1])\n }*/\n /*\n Apply operations that this user created (no remote ones!)\n * does not check for Struct.*.requiredOps()\n * also broadcasts it through the connector\n */\n * applyCreatedOperations (ops) {\n var send = []\n for (var i = 0; i < ops.length; i++) {\n var op = ops[i]\n yield* this.store.tryExecute.call(this, op)\n if (op.id == null || typeof op.id[1] !== 'string') {\n send.push(Y.Struct[op.struct].encode(op))\n }\n }\n if (!this.store.y.connector.isDisconnected() && send.length > 0) { // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops)\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps(send)\n }\n }\n\n * deleteList (start) {\n while (start != null) {\n start = yield* this.getOperation(start)\n if (!start.gc) {\n start.gc = true\n start.deleted = true\n yield* this.setOperation(start)\n var delLength = start.content != null ? start.content.length : 1\n yield* this.markDeleted(start.id, delLength)\n if (start.opContent != null) {\n yield* this.deleteOperation(start.opContent)\n }\n this.store.queueGarbageCollector(start.id)\n }\n start = start.right\n }\n }\n\n /*\n Mark an operation as deleted, and add it to the GC, if possible.\n */\n * deleteOperation (targetId, length, preventCallType) /* :Generator */ {\n if (length == null) {\n length = 1\n }\n yield* this.markDeleted(targetId, length)\n while (length > 0) {\n var callType = false\n var target = yield* this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1])\n var targetLength = target != null && target.content != null ? target.content.length : 1\n if (target == null || target.id[0] !== targetId[0] || target.id[1] + targetLength <= targetId[1]) {\n // does not exist or is not in the range of the deletion\n target = null\n length = 0\n } else {\n // does exist, check if it is too long\n if (!target.deleted) {\n if (target.id[1] < targetId[1]) {\n // starts to the left of the deletion range\n target = yield* this.getInsertionCleanStart(targetId)\n targetLength = target.content.length // must have content property!\n }\n if (target.id[1] + targetLength > targetId[1] + length) {\n // ends to the right of the deletion range\n target = yield* this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1])\n targetLength = target.content.length\n }\n }\n length = target.id[1] - targetId[1]\n }\n\n if (target != null) {\n if (!target.deleted) {\n callType = true\n // set deleted & notify type\n target.deleted = true\n // delete containing lists\n if (target.start != null) {\n // TODO: don't do it like this .. -.-\n yield* this.deleteList(target.start)\n // yield* this.deleteList(target.id) -- do not gc itself because this may still get referenced\n }\n if (target.map != null) {\n for (var name in target.map) {\n yield* this.deleteList(target.map[name])\n }\n // TODO: here to.. (see above)\n // yield* this.deleteList(target.id) -- see above\n }\n if (target.opContent != null) {\n yield* this.deleteOperation(target.opContent)\n // target.opContent = null\n }\n if (target.requires != null) {\n for (var i = 0; i < target.requires.length; i++) {\n yield* this.deleteOperation(target.requires[i])\n }\n }\n }\n var left\n if (target.left != null) {\n left = yield* this.getInsertion(target.left)\n } else {\n left = null\n }\n\n // set here because it was deleted and/or gc'd\n yield* this.setOperation(target)\n\n /*\n Check if it is possible to add right to the gc.\n Because this delete can't be responsible for left being gc'd,\n we don't have to add left to the gc..\n */\n var right\n if (target.right != null) {\n right = yield* this.getOperation(target.right)\n } else {\n right = null\n }\n if (callType && !preventCallType) {\n var type = this.store.initializedTypes[JSON.stringify(target.parent)]\n if (type != null) {\n yield* type._changed(this, {\n struct: 'Delete',\n target: target.id,\n length: targetLength\n })\n }\n }\n // need to gc in the end!\n yield* this.store.addToGarbageCollector.call(this, target, left)\n if (right != null) {\n yield* this.store.addToGarbageCollector.call(this, right, target)\n }\n }\n }\n }\n /*\n Mark an operation as deleted&gc'd\n */\n * markGarbageCollected (id, len) {\n // this.mem.push([\"gc\", id]);\n this.store.addToDebug('yield* this.markGarbageCollected(', id, ', ', len, ')')\n var n = yield* this.markDeleted(id, len)\n if (n.id[1] < id[1] && !n.gc) {\n // un-extend left\n var newlen = n.len - (id[1] - n.id[1])\n n.len -= newlen\n yield* this.ds.put(n)\n n = {id: id, len: newlen, gc: false}\n yield* this.ds.put(n)\n }\n // get prev&next before adding a new operation\n var prev = yield* this.ds.findPrev(id)\n var next = yield* this.ds.findNext(id)\n\n if (id[1] + len < n.id[1] + n.len && !n.gc) {\n // un-extend right\n yield* this.ds.put({id: [id[0], id[1] + len], len: n.len - len, gc: false})\n n.len = len\n }\n // set gc'd\n n.gc = true\n // can extend left?\n if (\n prev != null &&\n prev.gc &&\n Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id)\n ) {\n prev.len += n.len\n yield* this.ds.delete(n.id)\n n = prev\n // ds.put n here?\n }\n // can extend right?\n if (\n next != null &&\n next.gc &&\n Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id)\n ) {\n n.len += next.len\n yield* this.ds.delete(next.id)\n }\n yield* this.ds.put(n)\n yield* this.updateState(n.id[0])\n }\n /*\n Mark an operation as deleted.\n\n returns the delete node\n */\n * markDeleted (id, length) {\n if (length == null) {\n length = 1\n }\n // this.mem.push([\"del\", id]);\n var n = yield* this.ds.findWithUpperBound(id)\n if (n != null && n.id[0] === id[0]) {\n if (n.id[1] <= id[1] && id[1] <= n.id[1] + n.len) {\n // id is in n's range\n var diff = id[1] + length - (n.id[1] + n.len) // overlapping right\n if (diff > 0) {\n // id+length overlaps n\n if (!n.gc) {\n n.len += diff\n } else {\n diff = n.id[1] + n.len - id[1] // overlapping left (id till n.end)\n if (diff < length) {\n // a partial deletion\n n = {id: [id[0], id[1] + diff], len: length - diff, gc: false}\n yield* this.ds.put(n)\n } else {\n // already gc'd\n throw new Error('Cannot happen! (it dit though.. :()')\n // return n\n }\n }\n } else {\n // no overlapping, already deleted\n return n\n }\n } else {\n // cannot extend left (there is no left!)\n n = {id: id, len: length, gc: false}\n yield* this.ds.put(n) // TODO: you double-put !!\n }\n } else {\n // cannot extend left\n n = {id: id, len: length, gc: false}\n yield* this.ds.put(n)\n }\n // can extend right?\n var next = yield* this.ds.findNext(n.id)\n if (\n next != null &&\n n.id[0] === next.id[0] &&\n n.id[1] + n.len >= next.id[1]\n ) {\n diff = n.id[1] + n.len - next.id[1] // from next.start to n.end\n while (diff >= 0) {\n // n overlaps with next\n if (next.gc) {\n // gc is stronger, so reduce length of n\n n.len -= diff\n if (diff >= next.len) {\n // delete the missing range after next\n diff = diff - next.len // missing range after next\n if (diff > 0) {\n yield* this.ds.put(n) // unneccessary? TODO!\n yield* this.markDeleted([next.id[0], next.id[1] + next.len], diff)\n }\n }\n break\n } else {\n // we can extend n with next\n if (diff > next.len) {\n // n is even longer than next\n // get next.next, and try to extend it\n var _next = yield* this.ds.findNext(next.id)\n yield* this.ds.delete(next.id)\n if (_next == null || n.id[0] !== _next.id[0]) {\n break\n } else {\n next = _next\n diff = n.id[1] + n.len - next.id[1] // from next.start to n.end\n // continue!\n }\n } else {\n // n just partially overlaps with next. extend n, delete next, and break this loop\n n.len += next.len - diff\n yield* this.ds.delete(next.id)\n break\n }\n }\n }\n }\n yield* this.ds.put(n)\n return n\n }\n /*\n Call this method when the client is connected&synced with the\n other clients (e.g. master). This will query the database for\n operations that can be gc'd and add them to the garbage collector.\n */\n * garbageCollectAfterSync () {\n if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {\n console.warn('gc should be empty after sync')\n }\n yield* this.os.iterate(this, null, null, function * (op) {\n if (op.gc) {\n delete op.gc\n yield* this.setOperation(op)\n }\n if (op.parent != null) {\n var parentDeleted = yield* this.isDeleted(op.parent)\n if (parentDeleted) {\n op.gc = true\n if (!op.deleted) {\n yield* this.markDeleted(op.id, op.content != null ? op.content.length : 1)\n op.deleted = true\n if (op.opContent != null) {\n yield* this.deleteOperation(op.opContent)\n }\n if (op.requires != null) {\n for (var i = 0; i < op.requires.length; i++) {\n yield* this.deleteOperation(op.requires[i])\n }\n }\n }\n yield* this.setOperation(op)\n this.store.gc1.push(op.id) // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!)\n return\n }\n }\n if (op.deleted) {\n var left = null\n if (op.left != null) {\n left = yield* this.getInsertion(op.left)\n }\n yield* this.store.addToGarbageCollector.call(this, op, left)\n }\n })\n }\n /*\n Really remove an op and all its effects.\n The complicated case here is the Insert operation:\n * reset left\n * reset right\n * reset parent.start\n * reset parent.end\n * reset origins of all right ops\n */\n * garbageCollectOperation (id) {\n this.store.addToDebug('yield* this.garbageCollectOperation(', id, ')')\n var o = yield* this.getOperation(id)\n yield* this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd\n // if op exists, then clean that mess up..\n if (o != null) {\n var deps = []\n if (o.opContent != null) {\n deps.push(o.opContent)\n }\n if (o.requires != null) {\n deps = deps.concat(o.requires)\n }\n for (var i = 0; i < deps.length; i++) {\n var dep = yield* this.getOperation(deps[i])\n if (dep != null) {\n if (!dep.deleted) {\n yield* this.deleteOperation(dep.id)\n dep = yield* this.getOperation(dep.id)\n }\n dep.gc = true\n yield* this.setOperation(dep)\n this.store.queueGarbageCollector(dep.id)\n } else {\n yield* this.markGarbageCollected(deps[i], 1)\n }\n }\n\n // remove gc'd op from the left op, if it exists\n if (o.left != null) {\n var left = yield* this.getInsertion(o.left)\n left.right = o.right\n yield* this.setOperation(left)\n }\n // remove gc'd op from the right op, if it exists\n // also reset origins of right ops\n if (o.right != null) {\n var right = yield* this.getOperation(o.right)\n right.left = o.left\n\n if (o.originOf != null && o.originOf.length > 0) {\n // find new origin of right ops\n // origin is the first left deleted operation\n var neworigin = o.left\n var neworigin_ = null\n while (neworigin != null) {\n neworigin_ = yield* this.getInsertion(neworigin)\n if (neworigin_.deleted) {\n break\n }\n neworigin = neworigin_.left\n }\n\n // reset origin of all right ops (except first right - duh!),\n\n /* ** The following code does not rely on the the originOf property **\n I recently added originOf to all Insert Operations (see Struct.Insert.execute),\n which saves which operations originate in a Insert operation.\n Garbage collecting without originOf is more memory efficient, but is nearly impossible for large texts, or lists!\n But I keep this code for now\n ```\n // reset origin of right\n right.origin = neworigin\n // search until you find origin pointer to the left of o\n if (right.right != null) {\n var i = yield* this.getOperation(right.right)\n var ids = [o.id, o.right]\n while (ids.some(function (id) {\n return Y.utils.compareIds(id, i.origin)\n })) {\n if (Y.utils.compareIds(i.origin, o.id)) {\n // reset origin of i\n i.origin = neworigin\n yield* this.setOperation(i)\n }\n // get next i\n if (i.right == null) {\n break\n } else {\n ids.push(i.id)\n i = yield* this.getOperation(i.right)\n }\n }\n }\n ```\n */\n // ** Now the new implementation starts **\n // reset neworigin of all originOf[*]\n for (var _i in o.originOf) {\n var originsIn = yield* this.getOperation(o.originOf[_i])\n if (originsIn != null) {\n originsIn.origin = neworigin\n yield* this.setOperation(originsIn)\n }\n }\n if (neworigin != null) {\n if (neworigin_.originOf == null) {\n neworigin_.originOf = o.originOf\n } else {\n neworigin_.originOf = o.originOf.concat(neworigin_.originOf)\n }\n yield* this.setOperation(neworigin_)\n }\n // we don't need to set right here, because\n // right should be in o.originOf => it is set it the previous for loop\n } else {\n // we didn't need to reset the origin of right\n // so we have to set right here\n yield* this.setOperation(right)\n }\n }\n // o may originate in another operation.\n // Since o is deleted, we have to reset o.origin's `originOf` property\n if (o.origin != null) {\n var origin = yield* this.getInsertion(o.origin)\n origin.originOf = origin.originOf.filter(function (_id) {\n return !Y.utils.compareIds(id, _id)\n })\n yield* this.setOperation(origin)\n }\n var parent\n if (o.parent != null) {\n parent = yield* this.getOperation(o.parent)\n }\n // remove gc'd op from parent, if it exists\n if (parent != null) {\n var setParent = false // whether to save parent to the os\n if (o.parentSub != null) {\n if (Y.utils.compareIds(parent.map[o.parentSub], o.id)) {\n setParent = true\n if (o.right != null) {\n parent.map[o.parentSub] = o.right\n } else {\n delete parent.map[o.parentSub]\n }\n }\n } else {\n if (Y.utils.compareIds(parent.start, o.id)) {\n // gc'd op is the start\n setParent = true\n parent.start = o.right\n }\n if (Y.utils.matchesId(o, parent.end)) {\n // gc'd op is the end\n setParent = true\n parent.end = o.left\n }\n }\n if (setParent) {\n yield* this.setOperation(parent)\n }\n }\n // finally remove it from the os\n yield* this.removeOperation(o.id)\n }\n }\n * checkDeleteStoreForState (state) {\n var n = yield* this.ds.findWithUpperBound([state.user, state.clock])\n if (n != null && n.id[0] === state.user && n.gc) {\n state.clock = Math.max(state.clock, n.id[1] + n.len)\n }\n }\n * updateState (user) {\n var state = yield* this.getState(user)\n yield* this.checkDeleteStoreForState(state)\n var o = yield* this.getInsertion([user, state.clock])\n var oLength = (o != null && o.content != null) ? o.content.length : 1\n while (o != null && user === o.id[0] && o.id[1] <= state.clock && o.id[1] + oLength > state.clock) {\n // either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS\n state.clock += oLength\n yield* this.checkDeleteStoreForState(state)\n o = yield* this.os.findNext(o.id)\n oLength = (o != null && o.content != null) ? o.content.length : 1\n }\n yield* this.setState(state)\n }\n /*\n apply a delete set in order to get\n the state of the supplied ds\n */\n * applyDeleteSet (ds) {\n var deletions = []\n\n for (var user in ds) {\n var dv = ds[user]\n var pos = 0\n var d = dv[pos]\n yield* this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], function * (n) {\n // cases:\n // 1. d deletes something to the right of n\n // => go to next n (break)\n // 2. d deletes something to the left of n\n // => create deletions\n // => reset d accordingly\n // *)=> if d doesn't delete anything anymore, go to next d (continue)\n // 3. not 2) and d deletes something that also n deletes\n // => reset d so that it doesn't contain n's deletion\n // *)=> if d does not delete anything anymore, go to next d (continue)\n while (d != null) {\n var diff = 0 // describe the diff of length in 1) and 2)\n if (n.id[1] + n.len <= d[0]) {\n // 1)\n break\n } else if (d[0] < n.id[1]) {\n // 2)\n // delete maximum the len of d\n // else delete as much as possible\n diff = Math.min(n.id[1] - d[0], d[1])\n deletions.push([user, d[0], diff, d[2]])\n } else {\n // 3)\n diff = n.id[1] + n.len - d[0] // never null (see 1)\n if (d[2] && !n.gc) {\n // d marks as gc'd but n does not\n // then delete either way\n deletions.push([user, d[0], Math.min(diff, d[1]), d[2]])\n }\n }\n if (d[1] <= diff) {\n // d doesn't delete anything anymore\n d = dv[++pos]\n } else {\n d[0] = d[0] + diff // reset pos\n d[1] = d[1] - diff // reset length\n }\n }\n })\n // for the rest.. just apply it\n for (; pos < dv.length; pos++) {\n d = dv[pos]\n deletions.push([user, d[0], d[1], d[2]])\n }\n }\n for (var i = 0; i < deletions.length; i++) {\n var del = deletions[i]\n // always try to delete..\n yield* this.deleteOperation([del[0], del[1]], del[2])\n if (del[3]) {\n // gc..\n yield* this.markGarbageCollected([del[0], del[1]], del[2]) // always mark gc'd\n // remove operation..\n var counter = del[1] + del[2]\n while (counter >= del[1]) {\n var o = yield* this.os.findWithUpperBound([del[0], counter - 1])\n if (o == null) {\n break\n }\n var oLen = o.content != null ? o.content.length : 1\n if (o.id[0] !== del[0] || o.id[1] + oLen <= del[1]) {\n // not in range\n break\n }\n if (o.id[1] + oLen > del[1] + del[2]) {\n // overlaps right\n o = yield* this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1])\n }\n if (o.id[1] < del[1]) {\n // overlaps left\n o = yield* this.getInsertionCleanStart([del[0], del[1]])\n }\n counter = o.id[1]\n yield* this.garbageCollectOperation(o.id)\n }\n }\n if (this.store.forwardAppliedOperations) {\n var ops = []\n ops.push({struct: 'Delete', target: [d[0], d[1]], length: del[2]})\n this.store.y.connector.broadcastOps(ops)\n }\n }\n }\n * isGarbageCollected (id) {\n var n = yield* this.ds.findWithUpperBound(id)\n return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len && n.gc\n }\n /*\n A DeleteSet (ds) describes all the deleted ops in the OS\n */\n * getDeleteSet () {\n var ds = {}\n yield* this.ds.iterate(this, null, null, function * (n) {\n var user = n.id[0]\n var counter = n.id[1]\n var len = n.len\n var gc = n.gc\n var dv = ds[user]\n if (dv === void 0) {\n dv = []\n ds[user] = dv\n }\n dv.push([counter, len, gc])\n })\n return ds\n }\n * isDeleted (id) {\n var n = yield* this.ds.findWithUpperBound(id)\n return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len\n }\n * setOperation (op) {\n yield* this.os.put(op)\n return op\n }\n * addOperation (op) {\n yield* this.os.put(op)\n if (!this.store.y.connector.isDisconnected() && this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') {\n // is connected, and this is not going to be send in addOperation\n this.store.y.connector.broadcastOps([op])\n }\n }\n // if insertion, try to combine with left insertion (if both have content property)\n * tryCombineWithLeft (op) {\n if (\n op != null &&\n op.left != null &&\n op.content != null &&\n op.left[0] === op.id[0] &&\n Y.utils.compareIds(op.left, op.origin)\n ) {\n var left = yield* this.getInsertion(op.left)\n if (left.content != null &&\n left.id[1] + left.content.length === op.id[1] &&\n left.originOf.length === 1 &&\n !left.gc && !left.deleted &&\n !op.gc && !op.deleted\n ) {\n // combine!\n if (op.originOf != null) {\n left.originOf = op.originOf\n } else {\n delete left.originOf\n }\n left.content = left.content.concat(op.content)\n left.right = op.right\n yield* this.os.delete(op.id)\n yield* this.setOperation(left)\n }\n }\n }\n * getInsertion (id) {\n var ins = yield* this.os.findWithUpperBound(id)\n if (ins == null) {\n return null\n } else {\n var len = ins.content != null ? ins.content.length : 1 // in case of opContent\n if (id[0] === ins.id[0] && id[1] < ins.id[1] + len) {\n return ins\n } else {\n return null\n }\n }\n }\n * getInsertionCleanStartEnd (id) {\n yield* this.getInsertionCleanStart(id)\n return yield* this.getInsertionCleanEnd(id)\n }\n // Return an insertion such that id is the first element of content\n // This function manipulates an operation, if necessary\n * getInsertionCleanStart (id) {\n var ins = yield* this.getInsertion(id)\n if (ins != null) {\n if (ins.id[1] === id[1]) {\n return ins\n } else {\n var left = Y.utils.copyObject(ins)\n ins.content = left.content.splice(id[1] - ins.id[1])\n ins.id = id\n var leftLid = Y.utils.getLastId(left)\n ins.origin = leftLid\n left.originOf = [ins.id]\n left.right = ins.id\n ins.left = leftLid\n // debugger // check\n yield* this.setOperation(left)\n yield* this.setOperation(ins)\n if (left.gc) {\n this.store.queueGarbageCollector(ins.id)\n }\n return ins\n }\n } else {\n return null\n }\n }\n // Return an insertion such that id is the last element of content\n // This function manipulates an operation, if necessary\n * getInsertionCleanEnd (id) {\n var ins = yield* this.getInsertion(id)\n if (ins != null) {\n if (ins.content == null || (ins.id[1] + ins.content.length - 1 === id[1])) {\n return ins\n } else {\n var right = Y.utils.copyObject(ins)\n right.content = ins.content.splice(id[1] - ins.id[1] + 1) // cut off remainder\n right.id = [id[0], id[1] + 1]\n var insLid = Y.utils.getLastId(ins)\n right.origin = insLid\n ins.originOf = [right.id]\n ins.right = right.id\n right.left = insLid\n // debugger // check\n yield* this.setOperation(right)\n yield* this.setOperation(ins)\n if (ins.gc) {\n this.store.queueGarbageCollector(right.id)\n }\n return ins\n }\n } else {\n return null\n }\n }\n * getOperation (id/* :any */)/* :Transaction */ {\n var o = yield* this.os.find(id)\n if (id[0] !== '_' || o != null) {\n return o\n } else { // type is string\n // generate this operation?\n var comp = id[1].split('_')\n if (comp.length > 1) {\n var struct = comp[0]\n var op = Y.Struct[struct].create(id)\n op.type = comp[1]\n yield* this.setOperation(op)\n return op\n } else {\n // won't be called. but just in case..\n console.error('Unexpected case. How can this happen?')\n debugger // eslint-disable-line\n return null\n }\n }\n }\n * removeOperation (id) {\n yield* this.os.delete(id)\n }\n * setState (state) {\n var val = {\n id: [state.user],\n clock: state.clock\n }\n yield* this.ss.put(val)\n }\n * getState (user) {\n var n = yield* this.ss.find([user])\n var clock = n == null ? null : n.clock\n if (clock == null) {\n clock = 0\n }\n return {\n user: user,\n clock: clock\n }\n }\n * getStateVector () {\n var stateVector = []\n yield* this.ss.iterate(this, null, null, function * (n) {\n stateVector.push({\n user: n.id[0],\n clock: n.clock\n })\n })\n return stateVector\n }\n * getStateSet () {\n var ss = {}\n yield* this.ss.iterate(this, null, null, function * (n) {\n ss[n.id[0]] = n.clock\n })\n return ss\n }\n /*\n Here, we make all missing operations executable for the receiving user.\n\n Notes:\n startSS: denotes to the SV that the remote user sent\n currSS: denotes to the state vector that the user should have if he\n applies all already sent operations (increases is each step)\n\n We face several problems:\n * Execute op as is won't work because ops depend on each other\n -> find a way so that they do not anymore\n * When changing left, must not go more to the left than the origin\n * When changing right, you have to consider that other ops may have op\n as their origin, this means that you must not set one of these ops\n as the new right (interdependencies of ops)\n * can't just go to the right until you find the first known operation,\n With currSS\n -> interdependency of ops is a problem\n With startSS\n -> leads to inconsistencies when two users join at the same time.\n Then the position depends on the order of execution -> error!\n\n Solution:\n -> re-create originial situation\n -> set op.left = op.origin (which never changes)\n -> set op.right\n to the first operation that is known (according to startSS)\n or to the first operation that has an origin that is not to the\n right of op.\n -> Enforces unique execution order -> happy user\n\n Improvements: TODO\n * Could set left to origin, or the first known operation\n (startSS or currSS.. ?)\n -> Could be necessary when I turn GC again.\n -> Is a bad(ish) idea because it requires more computation\n\n What we do:\n * Iterate over all missing operations.\n * When there is an operation, where the right op is known, send this op all missing ops to the left to the user\n * I explained above what we have to do with each operation. Here is how we do it efficiently:\n 1. Go to the left until you find either op.origin, or a known operation (let o denote current operation in the iteration)\n 2. Found a known operation -> set op.left = o, and send it to the user. stop\n 3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o)\n 4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue\n */\n * getOperations (startSS) {\n // TODO: use bounds here!\n if (startSS == null) {\n startSS = {}\n }\n var send = []\n\n var endSV = yield* this.getStateVector()\n for (var endState of endSV) {\n var user = endState.user\n if (user === '_') {\n continue\n }\n var startPos = startSS[user] || 0\n if (startPos > 0) {\n // There is a change that [user, startPos] is in a composed Insertion (with a smaller counter)\n // find out if that is the case\n var firstMissing = yield* this.getInsertion([user, startPos])\n if (firstMissing != null) {\n // update startPos\n startPos = firstMissing.id[1]\n }\n }\n yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {\n op = Y.Struct[op.struct].encode(op)\n if (op.struct !== 'Insert') {\n send.push(op)\n } else if (op.right == null || op.right[1] < (startSS[op.right[0]] || 0)) {\n // case 1. op.right is known\n var o = op\n // Remember: ?\n // -> set op.right\n // 1. to the first operation that is known (according to startSS)\n // 2. or to the first operation that has an origin that is not to the\n // right of op.\n // For this we maintain a list of ops which origins are not found yet.\n var missing_origins = [op]\n var newright = op.right\n while (true) {\n if (o.left == null) {\n op.left = null\n send.push(op)\n if (!Y.utils.compareIds(o.id, op.id)) {\n o = Y.Struct[op.struct].encode(o)\n o.right = missing_origins[missing_origins.length - 1].id\n send.push(o)\n }\n break\n }\n o = yield* this.getInsertion(o.left)\n // we set another o, check if we can reduce $missing_origins\n while (missing_origins.length > 0 && Y.utils.matchesId(o, missing_origins[missing_origins.length - 1].origin)) {\n missing_origins.pop()\n }\n if (o.id[1] < (startSS[o.id[0]] || 0)) {\n // case 2. o is known\n op.left = Y.utils.getLastId(o)\n send.push(op)\n break\n } else if (Y.utils.matchesId(o, op.origin)) {\n // case 3. o is op.origin\n op.left = op.origin\n send.push(op)\n op = Y.Struct[op.struct].encode(o)\n op.right = newright\n if (missing_origins.length > 0) {\n console.log('This should not happen .. :( please report this')\n }\n missing_origins = [op]\n } else {\n // case 4. send o, continue to find op.origin\n var s = Y.Struct[op.struct].encode(o)\n s.right = missing_origins[missing_origins.length - 1].id\n s.left = s.origin\n send.push(s)\n missing_origins.push(o)\n }\n }\n }\n })\n }\n return send.reverse()\n }\n /* this is what we used before.. use this as a reference..\n * makeOperationReady (startSS, op) {\n op = Y.Struct[op.struct].encode(op)\n op = Y.utils.copyObject(op)\n var o = op\n var ids = [op.id]\n // search for the new op.right\n // it is either the first known op (according to startSS)\n // or the o that has no origin to the right of op\n // (this is why we use the ids array)\n while (o.right != null) {\n var right = yield* this.getOperation(o.right)\n if (o.right[1] < (startSS[o.right[0]] || 0) || !ids.some(function (id) {\n return Y.utils.compareIds(id, right.origin)\n })) {\n break\n }\n ids.push(o.right)\n o = right\n }\n op.right = o.right\n op.left = op.origin\n return op\n }\n */\n * flush () {\n yield* this.os.flush()\n yield* this.ss.flush()\n yield* this.ds.flush()\n }\n }\n Y.Transaction = TransactionInterface\n}\n","/* @flow */\n'use strict'\n\n/*\n EventHandler is an helper class for constructing custom types.\n\n Why: When constructing custom types, you sometimes want your types to work\n synchronous: E.g.\n ``` Synchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === \"yay\"\n ```\n versus\n ``` Asynchronous\n mytype.setSomething(\"yay\")\n mytype.getSomething() === undefined\n mytype.waitForSomething().then(function(){\n mytype.getSomething() === \"yay\"\n })\n ```\n\n The structures usually work asynchronously (you have to wait for the\n database request to finish). EventHandler helps you to make your type\n synchronous.\n*/\nmodule.exports = function (Y /* : any*/) {\n Y.utils = {}\n\n class EventListenerHandler {\n constructor () {\n this.eventListeners = []\n }\n destroy () {\n this.eventListeners = null\n }\n /*\n Basic event listener boilerplate...\n */\n addEventListener (f) {\n this.eventListeners.push(f)\n }\n removeEventListener (f) {\n this.eventListeners = this.eventListeners.filter(function (g) {\n return f !== g\n })\n }\n removeAllEventListeners () {\n this.eventListeners = []\n }\n callEventListeners (event) {\n for (var i = 0; i < this.eventListeners.length; i++) {\n try {\n this.eventListeners[i](event)\n } catch (e) {\n console.error('User events must not throw Errors!')\n }\n }\n }\n }\n Y.utils.EventListenerHandler = EventListenerHandler\n\n class EventHandler extends EventListenerHandler {\n /* ::\n waiting: Array;\n awaiting: number;\n onevent: Function;\n eventListeners: Array;\n */\n /*\n onevent: is called when the structure changes.\n\n Note: \"awaiting opertations\" is used to denote operations that were\n prematurely called. Events for received operations can not be executed until\n all prematurely called operations were executed (\"waiting operations\")\n */\n constructor (onevent /* : Function */) {\n super()\n this.waiting = []\n this.awaiting = 0\n this.onevent = onevent\n }\n destroy () {\n super.destroy()\n this.waiting = null\n this.awaiting = null\n this.onevent = null\n }\n /*\n Call this when a new operation arrives. It will be executed right away if\n there are no waiting operations, that you prematurely executed\n */\n receivedOp (op) {\n if (this.awaiting <= 0) {\n this.onevent(op)\n } else {\n this.waiting.push(op)\n }\n }\n /*\n You created some operations, and you want the `onevent` function to be\n called right away. Received operations will not be executed untill all\n prematurely called operations are executed\n */\n awaitAndPrematurelyCall (ops) {\n this.awaiting += ops.length\n ops.forEach(this.onevent)\n }\n /*\n Call this when you successfully awaited the execution of n Insert operations\n */\n awaitedInserts (n) {\n var ops = this.waiting.splice(this.waiting.length - n)\n for (var oid = 0; oid < ops.length; oid++) {\n var op = ops[oid]\n if (op.struct === 'Insert') {\n for (var i = this.waiting.length - 1; i >= 0; i--) {\n let w = this.waiting[i]\n // TODO: do I handle split operations correctly here? Super unlikely, but yeah..\n // Also: can this case happen? Can op be inserted in the middle of a larger op that is in $waiting?\n if (w.struct === 'Insert') {\n if (Y.utils.matchesId(w, op.left)) {\n // include the effect of op in w\n w.right = op.id\n // exclude the effect of w in op\n op.left = w.left\n } else if (Y.utils.compareIds(w.id, op.right)) {\n // similar..\n w.left = Y.utils.getLastId(op)\n op.right = w.right\n }\n }\n }\n } else {\n throw new Error('Expected Insert Operation!')\n }\n }\n this._tryCallEvents(n)\n }\n /*\n Call this when you successfully awaited the execution of n Delete operations\n */\n awaitedDeletes (n, newLeft) {\n var ops = this.waiting.splice(this.waiting.length - n)\n for (var j = 0; j < ops.length; j++) {\n var del = ops[j]\n if (del.struct === 'Delete') {\n if (newLeft != null) {\n for (var i = 0; i < this.waiting.length; i++) {\n let w = this.waiting[i]\n // We will just care about w.left\n if (w.struct === 'Insert' && Y.utils.compareIds(del.target, w.left)) {\n w.left = newLeft\n }\n }\n }\n } else {\n throw new Error('Expected Delete Operation!')\n }\n }\n this._tryCallEvents(n)\n }\n /* (private)\n Try to execute the events for the waiting operations\n */\n _tryCallEvents (n) {\n this.awaiting -= n\n if (this.awaiting === 0 && this.waiting.length > 0) {\n var ops = this.waiting\n this.waiting = []\n ops.forEach(this.onevent)\n }\n }\n }\n Y.utils.EventHandler = EventHandler\n\n /*\n A wrapper for the definition of a custom type.\n Every custom type must have three properties:\n\n * struct\n - Structname of this type\n * initType\n - Given a model, creates a custom type\n * class\n - the constructor of the custom type (e.g. in order to inherit from a type)\n */\n class CustomType { // eslint-disable-line\n /* ::\n struct: any;\n initType: any;\n class: Function;\n name: String;\n */\n constructor (def) {\n if (def.struct == null ||\n def.initType == null ||\n def.class == null ||\n def.name == null\n ) {\n throw new Error('Custom type was not initialized correctly!')\n }\n this.struct = def.struct\n this.initType = def.initType\n this.class = def.class\n this.name = def.name\n if (def.appendAdditionalInfo != null) {\n this.appendAdditionalInfo = def.appendAdditionalInfo\n }\n this.parseArguments = (def.parseArguments || function () {\n return [this]\n }).bind(this)\n this.parseArguments.typeDefinition = this\n }\n }\n Y.utils.CustomType = CustomType\n\n Y.utils.isTypeDefinition = function isTypeDefinition (v) {\n if (v != null) {\n if (v instanceof Y.utils.CustomType) return [v]\n else if (v.constructor === Array && v[0] instanceof Y.utils.CustomType) return v\n else if (v instanceof Function && v.typeDefinition instanceof Y.utils.CustomType) return [v.typeDefinition]\n }\n return false\n }\n\n /*\n Make a flat copy of an object\n (just copy properties)\n */\n function copyObject (o) {\n var c = {}\n for (var key in o) {\n c[key] = o[key]\n }\n return c\n }\n Y.utils.copyObject = copyObject\n\n /*\n Defines a smaller relation on Id's\n */\n function smaller (a, b) {\n return a[0] < b[0] || (a[0] === b[0] && (a[1] < b[1] || typeof a[1] < typeof b[1]))\n }\n Y.utils.smaller = smaller\n\n function compareIds (id1, id2) {\n if (id1 == null || id2 == null) {\n return id1 === id2\n } else {\n return id1[0] === id2[0] && id1[1] === id2[1]\n }\n }\n Y.utils.compareIds = compareIds\n\n function matchesId (op, id) {\n if (id == null || op == null) {\n return id === op\n } else {\n if (id[0] === op.id[0]) {\n if (op.content == null) {\n return id[1] === op.id[1]\n } else {\n return id[1] >= op.id[1] && id[1] < op.id[1] + op.content.length\n }\n }\n }\n }\n Y.utils.matchesId = matchesId\n\n function getLastId (op) {\n if (op.content == null || op.content.length === 1) {\n return op.id\n } else {\n return [op.id[0], op.id[1] + op.content.length - 1]\n }\n }\n Y.utils.getLastId = getLastId\n\n function createEmptyOpsArray (n) {\n var a = new Array(n)\n for (var i = 0; i < a.length; i++) {\n a[i] = {\n id: [null, null]\n }\n }\n return a\n }\n\n function createSmallLookupBuffer (Store) {\n /*\n This buffer implements a very small buffer that temporarily stores operations\n after they are read / before they are written.\n The buffer basically implements FIFO. Often requested lookups will be re-queued every time they are looked up / written.\n\n It can speed up lookups on Operation Stores and State Stores. But it does not require notable use of memory or processing power.\n\n Good for os and ss, bot not for ds (because it often uses methods that require a flush)\n\n I tried to optimize this for performance, therefore no highlevel operations.\n */\n class SmallLookupBuffer extends Store {\n constructor (arg1, arg2) {\n // super(...arguments) -- do this when this is supported by stable nodejs\n super(arg1, arg2)\n this.writeBuffer = createEmptyOpsArray(5)\n this.readBuffer = createEmptyOpsArray(10)\n }\n * find (id, noSuperCall) {\n var i, r\n for (i = this.readBuffer.length - 1; i >= 0; i--) {\n r = this.readBuffer[i]\n // we don't have to use compareids, because id is always defined!\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n // found r\n // move r to the end of readBuffer\n for (; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1]\n }\n this.readBuffer[this.readBuffer.length - 1] = r\n return r\n }\n }\n var o\n for (i = this.writeBuffer.length - 1; i >= 0; i--) {\n r = this.writeBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n o = r\n break\n }\n }\n if (i < 0 && noSuperCall === undefined) {\n // did not reach break in last loop\n // read id and put it to the end of readBuffer\n o = yield* super.find(id)\n }\n if (o != null) {\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n this.readBuffer[i] = this.readBuffer[i + 1]\n }\n this.readBuffer[this.readBuffer.length - 1] = o\n }\n return o\n }\n * put (o) {\n var id = o.id\n var i, r // helper variables\n for (i = this.writeBuffer.length - 1; i >= 0; i--) {\n r = this.writeBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n // is already in buffer\n // forget r, and move o to the end of writeBuffer\n for (; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1]\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o\n break\n }\n }\n if (i < 0) {\n // did not reach break in last loop\n // write writeBuffer[0]\n var write = this.writeBuffer[0]\n if (write.id[0] !== null) {\n yield* super.put(write)\n }\n // put o to the end of writeBuffer\n for (i = 0; i < this.writeBuffer.length - 1; i++) {\n this.writeBuffer[i] = this.writeBuffer[i + 1]\n }\n this.writeBuffer[this.writeBuffer.length - 1] = o\n }\n // check readBuffer for every occurence of o.id, overwrite if found\n // whether found or not, we'll append o to the readbuffer\n for (i = 0; i < this.readBuffer.length - 1; i++) {\n r = this.readBuffer[i + 1]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = o\n } else {\n this.readBuffer[i] = r\n }\n }\n this.readBuffer[this.readBuffer.length - 1] = o\n }\n * delete (id) {\n var i, r\n for (i = 0; i < this.readBuffer.length; i++) {\n r = this.readBuffer[i]\n if (r.id[1] === id[1] && r.id[0] === id[0]) {\n this.readBuffer[i] = {\n id: [null, null]\n }\n }\n }\n yield* this.flush()\n yield* super.delete(id)\n }\n * findWithLowerBound (id) {\n var o = yield* this.find(id, true)\n if (o != null) {\n return o\n } else {\n yield* this.flush()\n return yield* super.findWithLowerBound.apply(this, arguments)\n }\n }\n * findWithUpperBound (id) {\n var o = yield* this.find(id, true)\n if (o != null) {\n return o\n } else {\n yield* this.flush()\n return yield* super.findWithUpperBound.apply(this, arguments)\n }\n }\n * findNext () {\n yield* this.flush()\n return yield* super.findNext.apply(this, arguments)\n }\n * findPrev () {\n yield* this.flush()\n return yield* super.findPrev.apply(this, arguments)\n }\n * iterate () {\n yield* this.flush()\n yield* super.iterate.apply(this, arguments)\n }\n * flush () {\n for (var i = 0; i < this.writeBuffer.length; i++) {\n var write = this.writeBuffer[i]\n if (write.id[0] !== null) {\n yield* super.put(write)\n this.writeBuffer[i] = {\n id: [null, null]\n }\n }\n }\n }\n }\n return SmallLookupBuffer\n }\n Y.utils.createSmallLookupBuffer = createSmallLookupBuffer\n}\n","/* @flow */\r\n'use strict'\r\n\r\nrequire('./Connector.js')(Y)\r\nrequire('./Database.js')(Y)\r\nrequire('./Transaction.js')(Y)\r\nrequire('./Struct.js')(Y)\r\nrequire('./Utils.js')(Y)\r\nrequire('./Connectors/Test.js')(Y)\r\n\r\nvar requiringModules = {}\r\n\r\nmodule.exports = Y\r\nY.requiringModules = requiringModules\r\n\r\nY.extend = function (name, value) {\r\n if (value instanceof Y.utils.CustomType) {\r\n Y[name] = value.parseArguments\r\n } else {\r\n Y[name] = value\r\n }\r\n if (requiringModules[name] != null) {\r\n requiringModules[name].resolve()\r\n delete requiringModules[name]\r\n }\r\n}\r\n\r\nY.requestModules = requestModules\r\nfunction requestModules (modules) {\r\n // determine if this module was compiled for es5 or es6 (y.js vs. y.es6)\r\n // if Insert.execute is a Function, then it isnt a generator..\r\n // then load the es5(.js) files..\r\n var extention = typeof regeneratorRuntime !== 'undefined' ? '.js' : '.es6'\r\n var promises = []\r\n for (var i = 0; i < modules.length; i++) {\r\n var module = modules[i].split('(')[0]\r\n var modulename = 'y-' + module.toLowerCase()\r\n if (Y[module] == null) {\r\n if (requiringModules[module] == null) {\r\n // module does not exist\r\n if (typeof window !== 'undefined' && window.Y !== 'undefined') {\r\n var imported = document.createElement('script')\r\n imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention\r\n document.head.appendChild(imported)\r\n\r\n let requireModule = {}\r\n requiringModules[module] = requireModule\r\n requireModule.promise = new Promise(function (resolve) {\r\n requireModule.resolve = resolve\r\n })\r\n promises.push(requireModule.promise)\r\n } else {\r\n require(modulename)(Y)\r\n }\r\n } else {\r\n promises.push(requiringModules[modules[i]].promise)\r\n }\r\n }\r\n }\r\n return Promise.all(promises)\r\n}\r\n\r\n/* ::\r\ntype MemoryOptions = {\r\n name: 'memory'\r\n}\r\ntype IndexedDBOptions = {\r\n name: 'indexeddb',\r\n namespace: string\r\n}\r\ntype DbOptions = MemoryOptions | IndexedDBOptions\r\n\r\ntype WebRTCOptions = {\r\n name: 'webrtc',\r\n room: string\r\n}\r\ntype WebsocketsClientOptions = {\r\n name: 'websockets-client',\r\n room: string\r\n}\r\ntype ConnectionOptions = WebRTCOptions | WebsocketsClientOptions\r\n\r\ntype YOptions = {\r\n connector: ConnectionOptions,\r\n db: DbOptions,\r\n types: Array,\r\n sourceDir: string,\r\n share: {[key: string]: TypeName}\r\n}\r\n*/\r\n\r\nfunction Y (opts/* :YOptions */) /* :Promise */ {\r\n opts.types = opts.types != null ? opts.types : []\r\n var modules = [opts.db.name, opts.connector.name].concat(opts.types)\r\n for (var name in opts.share) {\r\n modules.push(opts.share[name])\r\n }\r\n Y.sourceDir = opts.sourceDir\r\n return Y.requestModules(modules).then(function () {\r\n return new Promise(function (resolve, reject) {\r\n if (opts == null) reject('An options object is expected! ')\r\n else if (opts.connector == null) reject('You must specify a connector! (missing connector property)')\r\n else if (opts.connector.name == null) reject('You must specify connector name! (missing connector.name property)')\r\n else if (opts.db == null) reject('You must specify a database! (missing db property)')\r\n else if (opts.connector.name == null) reject('You must specify db name! (missing db.name property)')\r\n else if (opts.share == null) reject('You must specify a set of shared types!')\r\n else {\r\n var yconfig = new YConfig(opts)\r\n yconfig.db.whenUserIdSet(function () {\r\n yconfig.init(function () {\r\n resolve(yconfig)\r\n })\r\n })\r\n }\r\n })\r\n })\r\n}\r\n\r\nclass YConfig {\r\n /* ::\r\n db: Y.AbstractDatabase;\r\n connector: Y.AbstractConnector;\r\n share: {[key: string]: any};\r\n options: Object;\r\n */\r\n constructor (opts, callback) {\r\n this.options = opts\r\n this.db = new Y[opts.db.name](this, opts.db)\r\n this.connector = new Y[opts.connector.name](this, opts.connector)\r\n }\r\n init (callback) {\r\n var opts = this.options\r\n var share = {}\r\n this.share = share\r\n this.db.requestTransaction(function * requestTransaction () {\r\n // create shared object\r\n for (var propertyname in opts.share) {\r\n var typeConstructor = opts.share[propertyname].split('(')\r\n var typeName = typeConstructor.splice(0, 1)\r\n var args = []\r\n if (typeConstructor.length === 1) {\r\n try {\r\n args = JSON.parse('[' + typeConstructor[0].split(')')[0] + ']')\r\n } catch (e) {\r\n throw new Error('Was not able to parse type definition! (share.' + propertyname + ')')\r\n }\r\n }\r\n var type = Y[typeName]\r\n var typedef = type.typeDefinition\r\n var id = ['_', typedef.struct + '_' + typeName + '_' + propertyname + '_' + typeConstructor]\r\n share[propertyname] = yield* this.createType(type.apply(typedef, args), id)\r\n }\r\n this.store.whenTransactionsFinished()\r\n .then(callback)\r\n })\r\n }\r\n isConnected () {\r\n return this.connector.isSynced\r\n }\r\n disconnect () {\r\n return this.connector.disconnect()\r\n }\r\n reconnect () {\r\n return this.connector.reconnect()\r\n }\r\n destroy () {\r\n if (this.connector.destroy != null) {\r\n this.connector.destroy()\r\n } else {\r\n this.connector.disconnect()\r\n }\r\n var self = this\r\n this.db.requestTransaction(function * () {\r\n yield* self.db.destroy()\r\n self.connector = null\r\n self.db = null\r\n })\r\n }\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n window.Y = Y\r\n}\r\n"]} \ No newline at end of file