diff --git a/Examples/Jigsaw/index.html b/Examples/Jigsaw/index.html
new file mode 100644
index 00000000..f1ce439e
--- /dev/null
+++ b/Examples/Jigsaw/index.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Examples/Jigsaw/index.js b/Examples/Jigsaw/index.js
new file mode 100644
index 00000000..148f01c3
--- /dev/null
+++ b/Examples/Jigsaw/index.js
@@ -0,0 +1,70 @@
+/* @flow */
+/* global Y, d3 */
+
+// initialize a shared object. This function call returns a promise!
+Y({
+ db: {
+ name: 'memory'
+ },
+ connector: {
+ url: 'http://127.0.0.1:1234',
+ name: 'websockets-client',
+ room: 'Puzzle-example2',
+ debug: true
+ },
+ sourceDir: '/bower_components',
+ share: {
+ piece1: 'Map',
+ piece2: 'Map',
+ piece3: 'Map',
+ piece4: 'Map'
+ }
+}).then(function (y) {
+ var origin // mouse start position - translation of piece
+ var drag = d3.behavior.drag()
+ .on('dragstart', function (params) {
+ // get the translation of the element
+ var translation = d3.select(this).attr('transform').slice(10,-1).split(',').map(Number)
+ // mouse coordinates
+ var mouse = d3.mouse(this.parentNode)
+ origin = {
+ x: mouse[0] - translation[0],
+ y: mouse[1] - translation[1]
+ }
+ })
+ .on("drag", function(){
+ var mouse = d3.mouse(this.parentNode)
+ var x = mouse[0] - origin.x // =^= mouse - mouse at dragstart + translation at dragstart
+ var y = mouse[1] - origin.y
+ d3.select(this).attr("transform", "translate(" + x + "," + y + ")")
+ })
+ .on('dragend', function (piece, i) {
+ // save the current translation of the puzzle piece
+ var mouse = d3.mouse(this.parentNode)
+ var x = mouse[0] - origin.x
+ var y = mouse[1] - origin.y
+ piece.set('translation', {x, y})
+ })
+
+ var data = [y.share.piece1, y.share.piece2, y.share.piece3, y.share.piece4]
+ var pieces = d3.select(document.querySelector("#puzzle-example")).selectAll("path").data(data)
+
+ pieces
+ .classed('draggable', true)
+ .attr("transform", function (piece) {
+ var translation = piece.get('translation') || {x: 0, y: 0}
+ return "translate(" + translation.x + "," + translation.y + ")"
+ }).call(drag)
+
+ data.forEach(function(piece){
+ piece.observe(function () {
+ // whenever a property of a piece changes, update the translation of the pieces
+ pieces
+ .transition()
+ .attr("transform", function (piece) {
+ var translation = piece.get('translation') || {x: 0, y: 0}
+ return "translate(" + translation.x + "," + translation.y + ")"
+ })
+ })
+ })
+})
\ No newline at end of file
diff --git a/Examples/Puzzle/index.html b/Examples/Puzzle/index.html
deleted file mode 100644
index 80d1fb49..00000000
--- a/Examples/Puzzle/index.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Examples/Puzzle/index.js b/Examples/Puzzle/index.js
deleted file mode 100644
index f5bce78b..00000000
--- a/Examples/Puzzle/index.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* @flow */
-/* global Y, d3 */
-
-// initialize a shared object. This function call returns a promise!
-Y({
- db: {
- name: 'memory'
- },
- connector: {
- name: 'websockets-client',
- room: 'Puzzle-example'
- },
- sourceDir: '/bower_components',
- share: {
- piece1: 'Map',
- piece2: 'Map',
- piece3: 'Map'
- }
-}).then(function (y) {
- window.y = y
-
- var dragX, dragY // x,y coordinates of drag event
- var drag = d3.behavior.drag()
- .on("drag", function(){
- dragX = d3.event.x-0.05
- dragY = d3.event.y-0.05
- d3.select(this)
- //.transition()
- .attr("transform", "translate(" + dragX + "," + dragY+ ")")
- })
- .on('dragend', function (piece) {
- // change the shared model of the puzzle
- piece.set('x', dragX)
- piece.set('y', dragY)
- })
-
- var data = [y.share.piece1, y.share.piece2, y.share.piece3]
- var nodes = d3.select(document.querySelector("#puzzle-example")).append('g').selectAll("rect").data(data)
- nodes
- .enter()
- .append('rect')
- .attr('width', 0.1)
- .attr('height', 0.1)
- .attr("class", "cell")
- .attr("transform", function (piece, i) {
- var x = piece.get('x') || i/3
- var y = piece.get('y') || i/3
- return "translate(" + x + "," + y + ")"
- }).call(drag)
-
- function repaint () {
- nodes
- .transition()
- .attr("transform", function (piece, i) {
- var x = piece.get('x') || i/3
- var y = piece.get('y') || i/3
- return "translate(" + x + "," + y + ")"
- })
- }
- data.forEach(function(piece){
- piece.observe(repaint)
- })
-})
\ No newline at end of file
diff --git a/y.es6 b/y.es6
index 2e444882..ea639514 100644
--- a/y.es6
+++ b/y.es6
@@ -1824,12 +1824,12 @@ module.exports = function (Y/* :any */) {
}
* getOperation (id/* :any */)/* :Transaction */ {
var o = yield* this.os.find(id)
- if (o != null || id[0] != '_') {
+ if (o != null || id[0] !== '_') {
return o
} else {
// need to generate this operation
if (this.store._nextUserId == null) {
- var typename= id[1].split('_')[0]
+ var typename = id[1].split('_')[0]
this.store._nextUserId = id
yield* Y[typename].createType.call(this)
delete this.store._nextUserId
@@ -2536,6 +2536,10 @@ Y.extend = function (name, value) {
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 = Y.Struct.Insert.execute.constructor === Function ? '.js' : '.es6'
var promises = []
for (var i = 0; i < modules.length; i++) {
var modulename = 'y-' + modules[i].toLowerCase()
@@ -2547,7 +2551,6 @@ function requestModules (modules) {
// module does not exist
if (typeof window !== 'undefined') {
var imported = document.createElement('script')
- var extention = typeof regeneratorRuntime === "undefined" ? '.es6' : '.js'
imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention
document.head.appendChild(imported)
@@ -2584,7 +2587,7 @@ type DbOptions = MemoryOptions | IndexedDBOptions
type WebRTCOptions = {
name: 'webrtc',
room: string
-}
+}
type WebsocketsClientOptions = {
name: 'websockets-client',
room: string
diff --git a/y.es6.map b/y.es6.map
index cff31c35..ea6c9a1c 100644
--- a/y.es6.map
+++ b/y.es6.map
@@ -1 +1 @@
-{"version":3,"sources":["node_modules/browserify/node_modules/browser-pack/_prelude.js","src/Connector.js","src/Connectors/Test.js","src/Database.js","src/Struct.js","src/Transaction.js","src/Types/Map.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;;AC9WA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1TA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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 */\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 }\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 this.userId = userId\n return this.y.db.setUserId(userId)\n }\n onUserEvent (f) {\n this.userEventListeners.push(f)\n }\n userLeft (user) {\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 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 if (syncUser != null) {\n var conn = this\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 })\n })\n } else {\n this.isSynced = true\n // call when synced listeners\n for (var f of this.whenSyncedListeners) {\n f()\n }\n this.whenSyncedListeners = []\n this.y.db.requestTransaction(function *() {\n yield* this.garbageCollectAfterSync()\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 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.type === 'sync step 1') {\n // TODO: make transaction, stream the ops\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 })\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 var update /* :MessageUpdate */ = {\n type: 'update',\n ops: ops\n }\n if (!broadcastHB) { // TODO: consider to broadcast here..\n conn.send(sender, update)\n } else {\n // broadcast only once!\n conn.broadcast(update)\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.broadcast({\n type: 'update',\n ops: delops\n })\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: {},\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 i in globalRoom.buffers) {\n if (globalRoom.buffers[i].length > 0) {\n bufs.push(i)\n }\n }\n if (bufs.length > 0) {\n var userId = getRandom(bufs)\n var m = globalRoom.buffers[userId].shift()\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 buffer.push(JSON.parse(JSON.stringify([this.userId, message])))\n }\n }\n broadcast (message) {\n for (var key in globalRoom.buffers) {\n globalRoom.buffers[key].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 while (globalRoom.buffers[self.userId].length > 0) {\n var m = globalRoom.buffers[self.userId].shift()\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