node-inspector
This commit is contained in:
		
							parent
							
								
									b9e21665e2
								
							
						
					
					
						commit
						4bfe484fc2
					
				@ -128,8 +128,8 @@ gulp.task('build_jasmine_browser', function () {
 | 
				
			|||||||
      loose: 'all',
 | 
					      loose: 'all',
 | 
				
			||||||
      modules: 'ignore',
 | 
					      modules: 'ignore',
 | 
				
			||||||
      // optional: ['es7.asyncFunctions'],
 | 
					      // optional: ['es7.asyncFunctions'],
 | 
				
			||||||
      blacklist: "regenerator",
 | 
					      blacklist: 'regenerator'
 | 
				
			||||||
      //experimental: true
 | 
					      // experimental: true
 | 
				
			||||||
    }))
 | 
					    }))
 | 
				
			||||||
    .pipe(sourcemaps.write())
 | 
					    .pipe(sourcemaps.write())
 | 
				
			||||||
    .pipe(gulp.dest('build'))
 | 
					    .pipe(gulp.dest('build'))
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										16
									
								
								spec/support/jasmine.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								spec/support/jasmine.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "spec_dir": "src",
 | 
				
			||||||
 | 
					    "spec_files": [
 | 
				
			||||||
 | 
					        "**/**.spec.js"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "helpers": [
 | 
				
			||||||
 | 
					       "Helper.spec.js",
 | 
				
			||||||
 | 
					       "y.js",
 | 
				
			||||||
 | 
					       "Connector.js",
 | 
				
			||||||
 | 
					       "OperationStore.js",
 | 
				
			||||||
 | 
					       "Struct.js",
 | 
				
			||||||
 | 
					       "Utils.js",
 | 
				
			||||||
 | 
					       "OperationStores/RedBlackTree.js",
 | 
				
			||||||
 | 
					       "OperationStores/Memory.js"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					'use strict'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AbstractConnector { // eslint-disable-line no-unused-vars
 | 
					class AbstractConnector { // eslint-disable-line no-unused-vars
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
    opts
 | 
					    opts
 | 
				
			||||||
@ -125,7 +127,6 @@ class AbstractConnector { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
    if (this.debug) {
 | 
					    if (this.debug) {
 | 
				
			||||||
      console.log(`me -> ${uid}: ${message.type}`, m);// eslint-disable-line
 | 
					      console.log(`me -> ${uid}: ${message.type}`, m);// eslint-disable-line
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    super(uid, message)
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // You received a raw message, and you know that it is intended for to Yjs. Then call this function.
 | 
					  // You received a raw message, and you know that it is intended for to Yjs. Then call this function.
 | 
				
			||||||
  receiveMessage (sender, m) {
 | 
					  receiveMessage (sender, m) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
/* global getRandom, AbstractConnector, Y, wait */
 | 
					/* global getRandom, AbstractConnector, Y, wait */
 | 
				
			||||||
 | 
					'use strict'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var globalRoom = {
 | 
					var globalRoom = {
 | 
				
			||||||
  users: {},
 | 
					  users: {},
 | 
				
			||||||
@ -66,11 +67,11 @@ class Test extends AbstractConnector {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  reconnect () {
 | 
					  reconnect () {
 | 
				
			||||||
    globalRoom.addUser(this)
 | 
					    globalRoom.addUser(this)
 | 
				
			||||||
    super()
 | 
					    super.reconnect()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  disconnect () {
 | 
					  disconnect () {
 | 
				
			||||||
    globalRoom.removeUser(this.userId)
 | 
					    globalRoom.removeUser(this.userId)
 | 
				
			||||||
    super()
 | 
					    super.disconnect()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  flush () {
 | 
					  flush () {
 | 
				
			||||||
    var buff = globalRoom.buffers[this.userId]
 | 
					    var buff = globalRoom.buffers[this.userId]
 | 
				
			||||||
 | 
				
			|||||||
@ -5,13 +5,23 @@
 | 
				
			|||||||
  This is just a compilation of functions that help to test this library!
 | 
					  This is just a compilation of functions that help to test this library!
 | 
				
			||||||
***/
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function wait(t = 10) {//eslint-disable-line
 | 
					var g = global || window
 | 
				
			||||||
 | 
					g.g = g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var co = require('co')
 | 
				
			||||||
 | 
					g.co = co
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function wait (t) {
 | 
				
			||||||
 | 
					  if (t == null) {
 | 
				
			||||||
 | 
					    t = 10
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  var def = Promise.defer()
 | 
					  var def = Promise.defer()
 | 
				
			||||||
  setTimeout(function () {
 | 
					  setTimeout(function () {
 | 
				
			||||||
    def.resolve()
 | 
					    def.resolve()
 | 
				
			||||||
  }, t)
 | 
					  }, t)
 | 
				
			||||||
  return def.promise
 | 
					  return def.promise
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					g.wait = wait
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// returns a random element of o
 | 
					// returns a random element of o
 | 
				
			||||||
// works on Object, and Array
 | 
					// works on Object, and Array
 | 
				
			||||||
@ -26,14 +36,17 @@ function getRandom (o) {
 | 
				
			|||||||
    return o[getRandom(ks)]
 | 
					    return o[getRandom(ks)]
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					g.getRandom = getRandom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getRandomNumber(n) {//eslint-disable-line
 | 
					function getRandomNumber(n) {//eslint-disable-line
 | 
				
			||||||
  if (n == null) {
 | 
					  if (n == null) {
 | 
				
			||||||
    n = 9999
 | 
					    n = 9999
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return Math.floor(Math.random() * n)
 | 
					  return Math.floor(Math.random() * n)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					g.getRandomNumber = getRandomNumber
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function applyRandomTransactions (users, objects, transactions, numberOfTransactions) {//eslint-disable-line
 | 
					g.applyRandomTransactions = co.wrap(function * applyRandomTransactions (users, objects, transactions, numberOfTransactions) { //eslint-disable-line
 | 
				
			||||||
  function randomTransaction (root) {
 | 
					  function randomTransaction (root) {
 | 
				
			||||||
    var f = getRandom(transactions)
 | 
					    var f = getRandom(transactions)
 | 
				
			||||||
    f(root)
 | 
					    f(root)
 | 
				
			||||||
@ -51,24 +64,24 @@ async function applyRandomTransactions (users, objects, transactions, numberOfTr
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  applyTransactions()
 | 
					  applyTransactions()
 | 
				
			||||||
  await users[0].connector.flushAll()
 | 
					  yield users[0].connector.flushAll()
 | 
				
			||||||
  users[0].disconnect()
 | 
					  users[0].disconnect()
 | 
				
			||||||
  await wait()
 | 
					  yield wait()
 | 
				
			||||||
  applyTransactions()
 | 
					  applyTransactions()
 | 
				
			||||||
  await users[0].connector.flushAll()
 | 
					  yield users[0].connector.flushAll()
 | 
				
			||||||
  users[0].reconnect()
 | 
					  users[0].reconnect()
 | 
				
			||||||
  await wait()
 | 
					  yield wait()
 | 
				
			||||||
  await users[0].connector.flushAll()
 | 
					  yield users[0].connector.flushAll()
 | 
				
			||||||
}
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function garbageCollectAllUsers (users) {
 | 
					g.garbageCollectAllUsers = co.wrap(function * garbageCollectAllUsers (users) {
 | 
				
			||||||
  for (var i in users) {
 | 
					  for (var i in users) {
 | 
				
			||||||
    await users[i].db.garbageCollect()
 | 
					    yield users[i].db.garbageCollect()
 | 
				
			||||||
    await users[i].db.garbageCollect()
 | 
					    yield users[i].db.garbageCollect()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function compareAllUsers(users){//eslint-disable-line
 | 
					g.compareAllUsers = co.wrap(function * compareAllUsers (users) { //eslint-disable-line
 | 
				
			||||||
  var s1, s2, ds1, ds2, allDels1, allDels2
 | 
					  var s1, s2, ds1, ds2, allDels1, allDels2
 | 
				
			||||||
  var db1 = []
 | 
					  var db1 = []
 | 
				
			||||||
  function * t1 () {
 | 
					  function * t1 () {
 | 
				
			||||||
@ -87,11 +100,11 @@ async function compareAllUsers(users){//eslint-disable-line
 | 
				
			|||||||
      allDels2.push(d)
 | 
					      allDels2.push(d)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  await users[0].connector.flushAll()
 | 
					  yield users[0].connector.flushAll()
 | 
				
			||||||
  await garbageCollectAllUsers(users)
 | 
					  yield g.garbageCollectAllUsers(users)
 | 
				
			||||||
  await wait(200)
 | 
					  yield wait(200)
 | 
				
			||||||
  await garbageCollectAllUsers(users)
 | 
					  yield g.garbageCollectAllUsers(users)
 | 
				
			||||||
  await wait(200)
 | 
					  yield wait(200)
 | 
				
			||||||
  for (var uid = 0; uid < users.length; uid++) {
 | 
					  for (var uid = 0; uid < users.length; uid++) {
 | 
				
			||||||
    var u = users[uid]
 | 
					    var u = users[uid]
 | 
				
			||||||
    // compare deleted ops against deleteStore
 | 
					    // compare deleted ops against deleteStore
 | 
				
			||||||
@ -116,16 +129,16 @@ async function compareAllUsers(users){//eslint-disable-line
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    // compare allDels tree
 | 
					    // compare allDels tree
 | 
				
			||||||
    await wait()
 | 
					    yield wait()
 | 
				
			||||||
    if (s1 == null) {
 | 
					    if (s1 == null) {
 | 
				
			||||||
      u.db.requestTransaction(t1)
 | 
					      u.db.requestTransaction(t1)
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      u.db.os.iterate(null, null, function(o){//eslint-disable-line
 | 
					      u.db.os.iterate(null, null, function(o){//eslint-disable-line
 | 
				
			||||||
        db1.push(o)
 | 
					        db1.push(o)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      u.db.requestTransaction(t2)
 | 
					      u.db.requestTransaction(t2)
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      expect(s1).toEqual(s2)
 | 
					      expect(s1).toEqual(s2)
 | 
				
			||||||
      expect(allDels1).toEqual(allDels2) // inner structure
 | 
					      expect(allDels1).toEqual(allDels2) // inner structure
 | 
				
			||||||
      expect(ds1).toEqual(ds2) // exported structure
 | 
					      expect(ds1).toEqual(ds2) // exported structure
 | 
				
			||||||
@ -135,11 +148,11 @@ async function compareAllUsers(users){//eslint-disable-line
 | 
				
			|||||||
      })
 | 
					      })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function createUsers(self, numberOfUsers) {//eslint-disable-line
 | 
					g.createUsers = co.wrap(function * createUsers (self, numberOfUsers) { //eslint-disable-line
 | 
				
			||||||
  if (globalRoom.users[0] != null) {//eslint-disable-line
 | 
					  if (globalRoom.users[0] != null) {//eslint-disable-line
 | 
				
			||||||
    await globalRoom.users[0].flushAll()//eslint-disable-line
 | 
					    yield globalRoom.users[0].flushAll()//eslint-disable-line
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // destroy old users
 | 
					  // destroy old users
 | 
				
			||||||
  for (var u in globalRoom.users) {//eslint-disable-line
 | 
					  for (var u in globalRoom.users) {//eslint-disable-line
 | 
				
			||||||
@ -160,5 +173,5 @@ async function createUsers(self, numberOfUsers) {//eslint-disable-line
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }))
 | 
					    }))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  self.users = await Promise.all(promises)
 | 
					  self.users = yield Promise.all(promises)
 | 
				
			||||||
}
 | 
					})
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,10 @@
 | 
				
			|||||||
/* global Y, copyObject, Struct, RBTree */
 | 
					/* global Y */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					'use strict'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var RBTree = Y.RBTree
 | 
				
			||||||
 | 
					var Struct = Y.Struct
 | 
				
			||||||
 | 
					var copyObject = Y.copyObject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AbstractTransaction { // eslint-disable-line no-unused-vars
 | 
					class AbstractTransaction { // eslint-disable-line no-unused-vars
 | 
				
			||||||
  constructor (store) {
 | 
					  constructor (store) {
 | 
				
			||||||
@ -37,6 +43,7 @@ class AbstractTransaction { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					Y.AbstractTransaction = AbstractTransaction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AbstractOperationStore { // eslint-disable-line no-unused-vars
 | 
					class AbstractOperationStore { // eslint-disable-line no-unused-vars
 | 
				
			||||||
  constructor (y, opts) {
 | 
					  constructor (y, opts) {
 | 
				
			||||||
@ -216,7 +223,7 @@ class AbstractOperationStore { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
          yield* this.store.operationAdded(this, op)
 | 
					          yield* this.store.operationAdded(this, op)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (isDeleted) {
 | 
					          if (isDeleted) {
 | 
				
			||||||
            yield* Struct["Delete"].execute.call(this, {target: op.id})
 | 
					            yield* Struct['Delete'].execute.call(this, {target: op.id})
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          // find next operation to execute
 | 
					          // find next operation to execute
 | 
				
			||||||
@ -272,3 +279,4 @@ class AbstractOperationStore { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
    ls.push(f)
 | 
					    ls.push(f)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					Y.AbstractOperationStore = AbstractOperationStore
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
/* global Struct, RBTree, Y, compareIds */
 | 
					/* global Struct, RBTree, Y, compareIds */
 | 
				
			||||||
 | 
					'use strict'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function copyObject (o) {
 | 
					function copyObject (o) {
 | 
				
			||||||
  var c = {}
 | 
					  var c = {}
 | 
				
			||||||
@ -8,7 +9,7 @@ function copyObject (o) {
 | 
				
			|||||||
  return c
 | 
					  return c
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DeleteStore extends RBTree { // eslint-disable-line
 | 
					class DeleteStore extends Y.RBTree {
 | 
				
			||||||
  constructor () {
 | 
					  constructor () {
 | 
				
			||||||
    super()
 | 
					    super()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -116,8 +117,10 @@ class DeleteStore extends RBTree { // eslint-disable-line
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Y.DeleteStore = DeleteStore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Y.Memory = (function () { // eslint-disable-line no-unused-vars
 | 
					Y.Memory = (function () { // eslint-disable-line no-unused-vars
 | 
				
			||||||
  class Transaction extends AbstractTransaction { // eslint-disable-line
 | 
					  class Transaction extends Y.AbstractTransaction { // eslint-disable-line
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor (store) {
 | 
					    constructor (store) {
 | 
				
			||||||
      super(store)
 | 
					      super(store)
 | 
				
			||||||
@ -245,7 +248,7 @@ Y.Memory = (function () { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
      return op
 | 
					      return op
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  class OperationStore extends AbstractOperationStore { // eslint-disable-line no-undef
 | 
					  class OperationStore extends Y.AbstractOperationStore { // eslint-disable-line no-undef
 | 
				
			||||||
    constructor (y, opts) {
 | 
					    constructor (y, opts) {
 | 
				
			||||||
      super(y, opts)
 | 
					      super(y, opts)
 | 
				
			||||||
      this.os = new RBTree()
 | 
					      this.os = new RBTree()
 | 
				
			||||||
@ -257,10 +260,11 @@ Y.Memory = (function () { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
    logTable () {
 | 
					    logTable () {
 | 
				
			||||||
      this.os.logTable()
 | 
					      this.os.logTable()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    requestTransaction (_makeGen, requestNow = false) {
 | 
					    requestTransaction (_makeGen, requestNow) {
 | 
				
			||||||
 | 
					      if (requestNow == null) { requestNow = false }
 | 
				
			||||||
      if (!this.transactionInProgress) {
 | 
					      if (!this.transactionInProgress) {
 | 
				
			||||||
        this.transactionInProgress = true
 | 
					        this.transactionInProgress = true
 | 
				
			||||||
        var transact = () => {
 | 
					        var transact = (xxxx) => {
 | 
				
			||||||
          var makeGen = _makeGen
 | 
					          var makeGen = _makeGen
 | 
				
			||||||
          while (makeGen != null) {
 | 
					          while (makeGen != null) {
 | 
				
			||||||
            var t = new Transaction(this)
 | 
					            var t = new Transaction(this)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,8 @@
 | 
				
			|||||||
/* global DeleteStore */
 | 
					/* global Y */
 | 
				
			||||||
/* eslint-env browser,jasmine,console */
 | 
					/* eslint-env browser,jasmine,console */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var DeleteStore = Y.DeleteStore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Memory', function () {
 | 
					describe('Memory', function () {
 | 
				
			||||||
  describe('DeleteStore', function () {
 | 
					  describe('DeleteStore', function () {
 | 
				
			||||||
    var ds
 | 
					    var ds
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,8 @@
 | 
				
			|||||||
/* global compareIds, copyObject */
 | 
					/* global Y, copyObject */
 | 
				
			||||||
 | 
					'use strict'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var compareIds = Y.compareIds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function smaller (a, b) {
 | 
					function smaller (a, b) {
 | 
				
			||||||
  return a[0] < b[0] || (a[0] === b[0] && a[1] < b[1])
 | 
					  return a[0] < b[0] || (a[0] === b[0] && a[1] < b[1])
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -26,8 +30,8 @@ class N {
 | 
				
			|||||||
    return this._parent
 | 
					    return this._parent
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  get sibling () {
 | 
					  get sibling () {
 | 
				
			||||||
    return (this === this.parent.left) ?
 | 
					    return (this === this.parent.left)
 | 
				
			||||||
      this.parent.right : this.parent.left
 | 
					      ? this.parent.right : this.parent.left
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  get left () {
 | 
					  get left () {
 | 
				
			||||||
    return this._left
 | 
					    return this._left
 | 
				
			||||||
@ -192,7 +196,9 @@ class RBTree { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return true
 | 
					    return true
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  logTable (from = null, to = null) {
 | 
					  logTable (from, to) {
 | 
				
			||||||
 | 
					    if (from == null) { from = null }
 | 
				
			||||||
 | 
					    if (to == null) { to = null }
 | 
				
			||||||
    var os = []
 | 
					    var os = []
 | 
				
			||||||
    this.iterate(from, to, function (o) {
 | 
					    this.iterate(from, to, function (o) {
 | 
				
			||||||
      var o_ = copyObject(o)
 | 
					      var o_ = copyObject(o)
 | 
				
			||||||
@ -453,3 +459,5 @@ class RBTree { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Y.RBTree = RBTree
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,9 @@
 | 
				
			|||||||
/* global RBTree, smaller, compareIds */
 | 
					/* global Y */
 | 
				
			||||||
/* eslint-env browser,jasmine,console */
 | 
					/* eslint-env browser,jasmine,console */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var RBTree = Y.RBTree
 | 
				
			||||||
 | 
					var compareIds = Y.compareIds
 | 
				
			||||||
 | 
					var smaller = Y.smaller
 | 
				
			||||||
var numberOfRBTreeTests = 1000
 | 
					var numberOfRBTreeTests = 1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function itRedNodesDoNotHaveBlackChildren (tree) {
 | 
					function itRedNodesDoNotHaveBlackChildren (tree) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,7 @@
 | 
				
			|||||||
/* global copyObject, Y*/
 | 
					/* global Y */
 | 
				
			||||||
 | 
					'use strict'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var copyObject = Y.copyObject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function compareIds (id1, id2) {
 | 
					function compareIds (id1, id2) {
 | 
				
			||||||
  if (id1 == null || id2 == null) {
 | 
					  if (id1 == null || id2 == null) {
 | 
				
			||||||
@ -13,6 +16,7 @@ function compareIds (id1, id2) {
 | 
				
			|||||||
    return false
 | 
					    return false
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					Y.compareIds = compareIds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Struct = {
 | 
					var Struct = {
 | 
				
			||||||
  /* This Operations does _not_ have an id!
 | 
					  /* This Operations does _not_ have an id!
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
/* global createUsers, wait, Y, compareAllUsers, getRandomNumber, applyRandomTransactions */
 | 
					/* global createUsers, wait, Y, compareAllUsers, getRandomNumber, applyRandomTransactions, co, garbageCollectAllUsers */
 | 
				
			||||||
/* eslint-env browser,jasmine */
 | 
					/* eslint-env browser,jasmine */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var numberOfYArrayTests = 5
 | 
					var numberOfYArrayTests = 5
 | 
				
			||||||
@ -7,160 +7,160 @@ describe('Array Type', function () {
 | 
				
			|||||||
  var y1, y2, y3, yconfig1, yconfig2, yconfig3, flushAll
 | 
					  var y1, y2, y3, yconfig1, yconfig2, yconfig3, flushAll
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000
 | 
					  jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000
 | 
				
			||||||
  beforeEach(async function (done) {
 | 
					  beforeEach(co.wrap(function * (done) {
 | 
				
			||||||
    await createUsers(this, 3)
 | 
					    yield createUsers(this, 3)
 | 
				
			||||||
    y1 = (yconfig1 = this.users[0]).root
 | 
					    y1 = (yconfig1 = this.users[0]).root
 | 
				
			||||||
    y2 = (yconfig2 = this.users[1]).root
 | 
					    y2 = (yconfig2 = this.users[1]).root
 | 
				
			||||||
    y3 = (yconfig3 = this.users[2]).root
 | 
					    y3 = (yconfig3 = this.users[2]).root
 | 
				
			||||||
    flushAll = this.users[0].connector.flushAll
 | 
					    flushAll = this.users[0].connector.flushAll
 | 
				
			||||||
    done()
 | 
					    done()
 | 
				
			||||||
  })
 | 
					  }))
 | 
				
			||||||
  afterEach(async function(done) {
 | 
					  afterEach(co.wrap(function * (done) {
 | 
				
			||||||
    await compareAllUsers(this.users)
 | 
					    yield compareAllUsers(this.users)
 | 
				
			||||||
    done()
 | 
					    done()
 | 
				
			||||||
  })
 | 
					  }))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('Basic tests', function () {
 | 
					  describe('Basic tests', function () {
 | 
				
			||||||
    it('insert three elements, try re-get property', async function (done) {
 | 
					    it('insert three elements, try re-get property', co.wrap(function * (done) {
 | 
				
			||||||
      var array = await y1.set('Array', Y.Array)
 | 
					      var array = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      array.insert(0, [1, 2, 3])
 | 
					      array.insert(0, [1, 2, 3])
 | 
				
			||||||
      array = await y1.get('Array') // re-get property
 | 
					      array = yield y1.get('Array') // re-get property
 | 
				
			||||||
      expect(array.toArray()).toEqual([1, 2, 3])
 | 
					      expect(array.toArray()).toEqual([1, 2, 3])
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic insert in array (handle three conflicts)', async function (done) {
 | 
					    it('Basic insert in array (handle three conflicts)', co.wrap(function * (done) {
 | 
				
			||||||
      await y1.set('Array', Y.Array)
 | 
					      yield y1.set('Array', Y.Array)
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      var l1 = await y1.get('Array')
 | 
					      var l1 = yield y1.get('Array')
 | 
				
			||||||
      l1.insert(0, [0])
 | 
					      l1.insert(0, [0])
 | 
				
			||||||
      var l2 = await y2.get('Array')
 | 
					      var l2 = yield y2.get('Array')
 | 
				
			||||||
      l2.insert(0, [1])
 | 
					      l2.insert(0, [1])
 | 
				
			||||||
      var l3 = await y3.get('Array')
 | 
					      var l3 = yield y3.get('Array')
 | 
				
			||||||
      l3.insert(0, [2])
 | 
					      l3.insert(0, [2])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual(l3.toArray())
 | 
					      expect(l2.toArray()).toEqual(l3.toArray())
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic insert&delete in array (handle three conflicts)', async function (done) {
 | 
					    it('Basic insert&delete in array (handle three conflicts)', co.wrap(function * (done) {
 | 
				
			||||||
      var l1, l2, l3
 | 
					      var l1, l2, l3
 | 
				
			||||||
      l1 = await y1.set('Array', Y.Array)
 | 
					      l1 = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      l1.insert(0, ['x', 'y', 'z'])
 | 
					      l1.insert(0, ['x', 'y', 'z'])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      l1.insert(1, [0])
 | 
					      l1.insert(1, [0])
 | 
				
			||||||
      l2 = await y2.get('Array')
 | 
					      l2 = yield y2.get('Array')
 | 
				
			||||||
      l2.delete(0)
 | 
					      l2.delete(0)
 | 
				
			||||||
      l2.delete(1)
 | 
					      l2.delete(1)
 | 
				
			||||||
      l3 = await y3.get('Array')
 | 
					      l3 = yield y3.get('Array')
 | 
				
			||||||
      l3.insert(1, [2])
 | 
					      l3.insert(1, [2])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual(l3.toArray())
 | 
					      expect(l2.toArray()).toEqual(l3.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual([0, 2, 'y'])
 | 
					      expect(l2.toArray()).toEqual([0, 2, 'y'])
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Handles getOperations ascending ids bug in late sync', async function (done) {
 | 
					    it('Handles getOperations ascending ids bug in late sync', co.wrap(function * (done) {
 | 
				
			||||||
      var l1, l2
 | 
					      var l1, l2
 | 
				
			||||||
      l1 = await y1.set('Array', Y.Array)
 | 
					      l1 = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      l1.insert(0, ['x', 'y'])
 | 
					      l1.insert(0, ['x', 'y'])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      yconfig3.disconnect()
 | 
					      yconfig3.disconnect()
 | 
				
			||||||
      yconfig2.disconnect()
 | 
					      yconfig2.disconnect()
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      l2 = await y2.get('Array')
 | 
					      l2 = yield y2.get('Array')
 | 
				
			||||||
      l2.insert(1, [2])
 | 
					      l2.insert(1, [2])
 | 
				
			||||||
      l2.insert(1, [3])
 | 
					      l2.insert(1, [3])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      yconfig2.reconnect()
 | 
					      yconfig2.reconnect()
 | 
				
			||||||
      yconfig3.reconnect()
 | 
					      yconfig3.reconnect()
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Handles deletions in late sync', async function (done) {
 | 
					    it('Handles deletions in late sync', co.wrap(function * (done) {
 | 
				
			||||||
      var l1, l2
 | 
					      var l1, l2
 | 
				
			||||||
      l1 = await y1.set('Array', Y.Array)
 | 
					      l1 = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      l1.insert(0, ['x', 'y'])
 | 
					      l1.insert(0, ['x', 'y'])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      yconfig2.disconnect()
 | 
					      yconfig2.disconnect()
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      l2 = await y2.get('Array')
 | 
					      l2 = yield y2.get('Array')
 | 
				
			||||||
      l2.delete(1, 1)
 | 
					      l2.delete(1, 1)
 | 
				
			||||||
      l1.delete(0, 2)
 | 
					      l1.delete(0, 2)
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      yconfig2.reconnect()
 | 
					      yconfig2.reconnect()
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Handles deletions in late sync (2)', async function (done) {
 | 
					    it('Handles deletions in late sync (2)', co.wrap(function * (done) {
 | 
				
			||||||
      var l1, l2
 | 
					      var l1, l2
 | 
				
			||||||
      l1 = await y1.set('Array', Y.Array)
 | 
					      l1 = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      l2 = await y2.get('Array')
 | 
					      l2 = yield y2.get('Array')
 | 
				
			||||||
      l1.insert(0, ['x', 'y'])
 | 
					      l1.insert(0, ['x', 'y'])
 | 
				
			||||||
      l1.delete(0, 2)
 | 
					      l1.delete(0, 2)
 | 
				
			||||||
      await wait(500)
 | 
					      yield wait(500)
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      await wait(500)
 | 
					      yield wait(500)
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic insert. Then delete the whole array', async function (done) {
 | 
					    it('Basic insert. Then delete the whole array', co.wrap(function * (done) {
 | 
				
			||||||
      var l1, l2, l3
 | 
					      var l1, l2, l3
 | 
				
			||||||
      l1 = await y1.set('Array', Y.Array)
 | 
					      l1 = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      l1.insert(0, ['x', 'y', 'z'])
 | 
					      l1.insert(0, ['x', 'y', 'z'])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      l1.delete(0, 3)
 | 
					      l1.delete(0, 3)
 | 
				
			||||||
      l2 = await y2.get('Array')
 | 
					      l2 = yield y2.get('Array')
 | 
				
			||||||
      l3 = await y3.get('Array')
 | 
					      l3 = yield y3.get('Array')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual(l3.toArray())
 | 
					      expect(l2.toArray()).toEqual(l3.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual([])
 | 
					      expect(l2.toArray()).toEqual([])
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic insert. Then delete the whole array (merge listeners on late sync)', async function (done) {
 | 
					    it('Basic insert. Then delete the whole array (merge listeners on late sync)', co.wrap(function * (done) {
 | 
				
			||||||
      var l1, l2, l3
 | 
					      var l1, l2, l3
 | 
				
			||||||
      l1 = await y1.set('Array', Y.Array)
 | 
					      l1 = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      l1.insert(0, ['x', 'y', 'z'])
 | 
					      l1.insert(0, ['x', 'y', 'z'])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      yconfig2.disconnect()
 | 
					      yconfig2.disconnect()
 | 
				
			||||||
      l1.delete(0, 3)
 | 
					      l1.delete(0, 3)
 | 
				
			||||||
      l2 = await y2.get('Array')
 | 
					      l2 = yield y2.get('Array')
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      yconfig2.reconnect()
 | 
					      yconfig2.reconnect()
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      l3 = await y3.get('Array')
 | 
					      l3 = yield y3.get('Array')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual(l3.toArray())
 | 
					      expect(l2.toArray()).toEqual(l3.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual([])
 | 
					      expect(l2.toArray()).toEqual([])
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic insert. Then delete the whole array (merge deleter on late sync)', async function (done) {
 | 
					    it('Basic insert. Then delete the whole array (merge deleter on late sync)', co.wrap(function * (done) {
 | 
				
			||||||
      var l1, l2, l3
 | 
					      var l1, l2, l3
 | 
				
			||||||
      l1 = await y1.set('Array', Y.Array)
 | 
					      l1 = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      l1.insert(0, ['x', 'y', 'z'])
 | 
					      l1.insert(0, ['x', 'y', 'z'])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      yconfig1.disconnect()
 | 
					      yconfig1.disconnect()
 | 
				
			||||||
      l1.delete(0, 3)
 | 
					      l1.delete(0, 3)
 | 
				
			||||||
      l2 = await y2.get('Array')
 | 
					      l2 = yield y2.get('Array')
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      yconfig1.reconnect()
 | 
					      yconfig1.reconnect()
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      l3 = await y3.get('Array')
 | 
					      l3 = yield y3.get('Array')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual(l3.toArray())
 | 
					      expect(l2.toArray()).toEqual(l3.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual([])
 | 
					      expect(l2.toArray()).toEqual([])
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('throw insert & delete events', async function (done) {
 | 
					    it('throw insert & delete events', co.wrap(function * (done) {
 | 
				
			||||||
      var array = await this.users[0].root.set('array', Y.Array)
 | 
					      var array = yield this.users[0].root.set('array', Y.Array)
 | 
				
			||||||
      var event
 | 
					      var event
 | 
				
			||||||
      array.observe(function (e) {
 | 
					      array.observe(function (e) {
 | 
				
			||||||
        event = e
 | 
					        event = e
 | 
				
			||||||
@ -179,30 +179,30 @@ describe('Array Type', function () {
 | 
				
			|||||||
        index: 0,
 | 
					        index: 0,
 | 
				
			||||||
        length: 1
 | 
					        length: 1
 | 
				
			||||||
      }])
 | 
					      }])
 | 
				
			||||||
      await wait(50)
 | 
					      yield wait(50)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('garbage collects', async function (done) {
 | 
					    it('garbage collects', co.wrap(function * (done) {
 | 
				
			||||||
      var l1, l2, l3
 | 
					      var l1, l2, l3
 | 
				
			||||||
      l1 = await y1.set('Array', Y.Array)
 | 
					      l1 = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      l1.insert(0, ['x', 'y', 'z'])
 | 
					      l1.insert(0, ['x', 'y', 'z'])
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      yconfig1.disconnect()
 | 
					      yconfig1.disconnect()
 | 
				
			||||||
      l1.delete(0, 3)
 | 
					      l1.delete(0, 3)
 | 
				
			||||||
      l2 = await y2.get('Array')
 | 
					      l2 = yield y2.get('Array')
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      yconfig1.reconnect()
 | 
					      yconfig1.reconnect()
 | 
				
			||||||
      await wait()
 | 
					      yield wait()
 | 
				
			||||||
      l3 = await y3.get('Array')
 | 
					      l3 = yield y3.get('Array')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      await garbageCollectAllUsers(this.users)
 | 
					      yield garbageCollectAllUsers(this.users)
 | 
				
			||||||
      yconfig1.db.logTable()
 | 
					      yconfig1.db.logTable()
 | 
				
			||||||
      expect(l1.toArray()).toEqual(l2.toArray())
 | 
					      expect(l1.toArray()).toEqual(l2.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual(l3.toArray())
 | 
					      expect(l2.toArray()).toEqual(l3.toArray())
 | 
				
			||||||
      expect(l2.toArray()).toEqual([])
 | 
					      expect(l2.toArray()).toEqual([])
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  describe(`Random tests`, function () {
 | 
					  describe(`Random tests`, function () {
 | 
				
			||||||
    var randomArrayTransactions = [
 | 
					    var randomArrayTransactions = [
 | 
				
			||||||
@ -227,29 +227,29 @@ describe('Array Type', function () {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    beforeEach(async function (done) {
 | 
					    beforeEach(co.wrap(function * (done) {
 | 
				
			||||||
      await this.users[0].root.set('Array', Y.Array)
 | 
					      yield this.users[0].root.set('Array', Y.Array)
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var promises = []
 | 
					      var promises = []
 | 
				
			||||||
      for (var u = 0; u < this.users.length; u++) {
 | 
					      for (var u = 0; u < this.users.length; u++) {
 | 
				
			||||||
        promises.push(this.users[u].root.get('Array'))
 | 
					        promises.push(this.users[u].root.get('Array'))
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.arrays = await Promise.all(promises)
 | 
					      this.arrays = yield Promise.all(promises)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('arrays.length equals users.length', async function (done) { // eslint-disable-line
 | 
					    it('arrays.length equals users.length', co.wrap(function * (done) { // eslint-disable-line
 | 
				
			||||||
      expect(this.arrays.length).toEqual(this.users.length)
 | 
					      expect(this.arrays.length).toEqual(this.users.length)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it(`succeed after ${numberOfYArrayTests} actions`, async function (done) {
 | 
					    it(`succeed after ${numberOfYArrayTests} actions`, co.wrap(function * (done) {
 | 
				
			||||||
      for (var u of this.users) {
 | 
					      for (var u of this.users) {
 | 
				
			||||||
        u.connector.debug = true
 | 
					        u.connector.debug = true
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      await applyRandomTransactions(this.users, this.arrays, randomArrayTransactions, numberOfYArrayTests)
 | 
					      yield applyRandomTransactions(this.users, this.arrays, randomArrayTransactions, numberOfYArrayTests)
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      await compareArrayValues(this.arrays)
 | 
					      yield compareArrayValues(this.arrays)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
/* global createUsers, Y, compareAllUsers, getRandomNumber, applyRandomTransactions */
 | 
					/* global createUsers, Y, compareAllUsers, getRandomNumber, applyRandomTransactions, co */
 | 
				
			||||||
/* eslint-env browser,jasmine */
 | 
					/* eslint-env browser,jasmine */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var numberOfYMapTests = 100
 | 
					var numberOfYMapTests = 100
 | 
				
			||||||
@ -7,127 +7,127 @@ describe('Map Type', function () {
 | 
				
			|||||||
  var y1, y2, y3, y4, flushAll
 | 
					  var y1, y2, y3, y4, flushAll
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000
 | 
					  jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000
 | 
				
			||||||
  beforeEach(async function (done) {
 | 
					  beforeEach(co.wrap(function * (done) {
 | 
				
			||||||
    await createUsers(this, 5)
 | 
					    yield createUsers(this, 5)
 | 
				
			||||||
    y1 = this.users[0].root
 | 
					    y1 = this.users[0].root
 | 
				
			||||||
    y2 = this.users[1].root
 | 
					    y2 = this.users[1].root
 | 
				
			||||||
    y3 = this.users[2].root
 | 
					    y3 = this.users[2].root
 | 
				
			||||||
    y4 = this.users[3].root
 | 
					    y4 = this.users[3].root
 | 
				
			||||||
    flushAll = this.users[0].connector.flushAll
 | 
					    flushAll = this.users[0].connector.flushAll
 | 
				
			||||||
    done()
 | 
					    done()
 | 
				
			||||||
  })
 | 
					  }))
 | 
				
			||||||
  afterEach(async function(done) {
 | 
					  afterEach(co.wrap(function * (done) {
 | 
				
			||||||
    await compareAllUsers(this.users)
 | 
					    yield compareAllUsers(this.users)
 | 
				
			||||||
    done()
 | 
					    done()
 | 
				
			||||||
  }, 5000)
 | 
					  }), 5000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('Basic tests', function () {
 | 
					  describe('Basic tests', function () {
 | 
				
			||||||
    it('Basic get&set of Map property (converge via sync)', async function (done) {
 | 
					    it('Basic get&set of Map property (converge via sync)', co.wrap(function * (done) {
 | 
				
			||||||
      y1.set('stuff', 'stuffy')
 | 
					      y1.set('stuff', 'stuffy')
 | 
				
			||||||
      expect(y1.get('stuff')).toEqual('stuffy')
 | 
					      expect(y1.get('stuff')).toEqual('stuffy')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      for (var key in this.users) {
 | 
					      for (var key in this.users) {
 | 
				
			||||||
        var u = this.users[key].root
 | 
					        var u = this.users[key].root
 | 
				
			||||||
        expect(u.get('stuff')).toEqual('stuffy')
 | 
					        expect(u.get('stuff')).toEqual('stuffy')
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Map can set custom types (Map)', async function (done) {
 | 
					    it('Map can set custom types (Map)', co.wrap(function * (done) {
 | 
				
			||||||
      var map = await y1.set('Map', Y.Map)
 | 
					      var map = yield y1.set('Map', Y.Map)
 | 
				
			||||||
      map.set('one', 1)
 | 
					      map.set('one', 1)
 | 
				
			||||||
      map = await y1.get('Map')
 | 
					      map = yield y1.get('Map')
 | 
				
			||||||
      expect(map.get('one')).toEqual(1)
 | 
					      expect(map.get('one')).toEqual(1)
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Map can set custom types (Array)', async function (done) {
 | 
					    it('Map can set custom types (Array)', co.wrap(function * (done) {
 | 
				
			||||||
      var array = await y1.set('Array', Y.Array)
 | 
					      var array = yield y1.set('Array', Y.Array)
 | 
				
			||||||
      array.insert(0, [1, 2, 3])
 | 
					      array.insert(0, [1, 2, 3])
 | 
				
			||||||
      array = await y1.get('Array')
 | 
					      array = yield y1.get('Array')
 | 
				
			||||||
      expect(array.toArray()).toEqual([1, 2, 3])
 | 
					      expect(array.toArray()).toEqual([1, 2, 3])
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic get&set of Map property (converge via update)', async function (done) {
 | 
					    it('Basic get&set of Map property (converge via update)', co.wrap(function * (done) {
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      y1.set('stuff', 'stuffy')
 | 
					      y1.set('stuff', 'stuffy')
 | 
				
			||||||
      expect(y1.get('stuff')).toEqual('stuffy')
 | 
					      expect(y1.get('stuff')).toEqual('stuffy')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      for (var key in this.users) {
 | 
					      for (var key in this.users) {
 | 
				
			||||||
        var r = this.users[key].root
 | 
					        var r = this.users[key].root
 | 
				
			||||||
        expect(r.get('stuff')).toEqual('stuffy')
 | 
					        expect(r.get('stuff')).toEqual('stuffy')
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic get&set of Map property (handle conflict)', async function (done) {
 | 
					    it('Basic get&set of Map property (handle conflict)', co.wrap(function * (done) {
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      y1.set('stuff', 'c0')
 | 
					      y1.set('stuff', 'c0')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      y2.set('stuff', 'c1')
 | 
					      y2.set('stuff', 'c1')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      for (var key in this.users) {
 | 
					      for (var key in this.users) {
 | 
				
			||||||
        var u = this.users[key]
 | 
					        var u = this.users[key]
 | 
				
			||||||
        expect(u.root.get('stuff')).toEqual('c0')
 | 
					        expect(u.root.get('stuff')).toEqual('c0')
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic get&set&delete of Map property (handle conflict)', async function (done) {
 | 
					    it('Basic get&set&delete of Map property (handle conflict)', co.wrap(function * (done) {
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      y1.set('stuff', 'c0')
 | 
					      y1.set('stuff', 'c0')
 | 
				
			||||||
      y1.delete('stuff')
 | 
					      y1.delete('stuff')
 | 
				
			||||||
      y2.set('stuff', 'c1')
 | 
					      y2.set('stuff', 'c1')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for (var key in this.users) {
 | 
					      for (var key in this.users) {
 | 
				
			||||||
        var u = this.users[key]
 | 
					        var u = this.users[key]
 | 
				
			||||||
        expect(u.root.get('stuff')).toBeUndefined()
 | 
					        expect(u.root.get('stuff')).toBeUndefined()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic get&set of Map property (handle three conflicts)', async function (done) {
 | 
					    it('Basic get&set of Map property (handle three conflicts)', co.wrap(function * (done) {
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      y1.set('stuff', 'c0')
 | 
					      y1.set('stuff', 'c0')
 | 
				
			||||||
      y2.set('stuff', 'c1')
 | 
					      y2.set('stuff', 'c1')
 | 
				
			||||||
      y2.set('stuff', 'c2')
 | 
					      y2.set('stuff', 'c2')
 | 
				
			||||||
      y3.set('stuff', 'c3')
 | 
					      y3.set('stuff', 'c3')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for (var key in this.users) {
 | 
					      for (var key in this.users) {
 | 
				
			||||||
        var u = this.users[key]
 | 
					        var u = this.users[key]
 | 
				
			||||||
        expect(u.root.get('stuff')).toEqual('c0')
 | 
					        expect(u.root.get('stuff')).toEqual('c0')
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('Basic get&set&delete of Map property (handle three conflicts)', async function (done) {
 | 
					    it('Basic get&set&delete of Map property (handle three conflicts)', co.wrap(function * (done) {
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      y1.set('stuff', 'c0')
 | 
					      y1.set('stuff', 'c0')
 | 
				
			||||||
      y2.set('stuff', 'c1')
 | 
					      y2.set('stuff', 'c1')
 | 
				
			||||||
      y2.set('stuff', 'c2')
 | 
					      y2.set('stuff', 'c2')
 | 
				
			||||||
      y3.set('stuff', 'c3')
 | 
					      y3.set('stuff', 'c3')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      y1.set('stuff', 'deleteme')
 | 
					      y1.set('stuff', 'deleteme')
 | 
				
			||||||
      y1.delete('stuff')
 | 
					      y1.delete('stuff')
 | 
				
			||||||
      y2.set('stuff', 'c1')
 | 
					      y2.set('stuff', 'c1')
 | 
				
			||||||
      y3.set('stuff', 'c2')
 | 
					      y3.set('stuff', 'c2')
 | 
				
			||||||
      y4.set('stuff', 'c3')
 | 
					      y4.set('stuff', 'c3')
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for (var key in this.users) {
 | 
					      for (var key in this.users) {
 | 
				
			||||||
        var u = this.users[key]
 | 
					        var u = this.users[key]
 | 
				
			||||||
        expect(u.root.get('stuff')).toBeUndefined()
 | 
					        expect(u.root.get('stuff')).toBeUndefined()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      await compareAllUsers(this.users)
 | 
					      yield compareAllUsers(this.users)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it('throws add & update & delete events (with type and primitive content)', async function (done) {
 | 
					    it('throws add & update & delete events (with type and primitive content)', co.wrap(function * (done) {
 | 
				
			||||||
      var event
 | 
					      var event
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      y1.observe(function (e) {
 | 
					      y1.observe(function (e) {
 | 
				
			||||||
        event = e // just put it on event, should be thrown synchronously anyway
 | 
					        event = e // just put it on event, should be thrown synchronously anyway
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
@ -138,7 +138,7 @@ describe('Map Type', function () {
 | 
				
			|||||||
        name: 'stuff'
 | 
					        name: 'stuff'
 | 
				
			||||||
      }])
 | 
					      }])
 | 
				
			||||||
      // update, oldValue is in contents
 | 
					      // update, oldValue is in contents
 | 
				
			||||||
      await y1.set('stuff', Y.Array)
 | 
					      yield y1.set('stuff', Y.Array)
 | 
				
			||||||
      expect(event).toEqual([{
 | 
					      expect(event).toEqual([{
 | 
				
			||||||
        type: 'update',
 | 
					        type: 'update',
 | 
				
			||||||
        object: y1,
 | 
					        object: y1,
 | 
				
			||||||
@ -164,7 +164,7 @@ describe('Map Type', function () {
 | 
				
			|||||||
          done()
 | 
					          done()
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  describe(`${numberOfYMapTests} Random tests`, function () {
 | 
					  describe(`${numberOfYMapTests} Random tests`, function () {
 | 
				
			||||||
    var randomMapTransactions = [
 | 
					    var randomMapTransactions = [
 | 
				
			||||||
@ -186,22 +186,22 @@ describe('Map Type', function () {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    beforeEach(async function (done) {
 | 
					    beforeEach(co.wrap(function * (done) {
 | 
				
			||||||
      await y1.set('Map', Y.Map)
 | 
					      yield y1.set('Map', Y.Map)
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var promises = []
 | 
					      var promises = []
 | 
				
			||||||
      for (var u = 0; u < this.users.length; u++) {
 | 
					      for (var u = 0; u < this.users.length; u++) {
 | 
				
			||||||
        promises.push(this.users[u].root.get('Map'))
 | 
					        promises.push(this.users[u].root.get('Map'))
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.maps = await Promise.all(promises)
 | 
					      this.maps = yield Promise.all(promises)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
    it(`succeed after ${numberOfYMapTests} actions`, async function (done) {
 | 
					    it(`succeed after ${numberOfYMapTests} actions`, co.wrap(function * (done) {
 | 
				
			||||||
      await applyRandomTransactions(this.users, this.maps, randomMapTransactions, numberOfYMapTests)
 | 
					      yield applyRandomTransactions(this.users, this.maps, randomMapTransactions, numberOfYMapTests)
 | 
				
			||||||
      await flushAll()
 | 
					      yield flushAll()
 | 
				
			||||||
      await compareMapValues(this.maps)
 | 
					      yield compareMapValues(this.maps)
 | 
				
			||||||
      done()
 | 
					      done()
 | 
				
			||||||
    })
 | 
					    }))
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,6 @@
 | 
				
			|||||||
/* global Y, CustomType */
 | 
					/* global Y */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var CustomType = Y.CustomType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;(function () {
 | 
					;(function () {
 | 
				
			||||||
  class YTextBind extends Y . Array . class {
 | 
					  class YTextBind extends Y . Array . class {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,8 @@
 | 
				
			|||||||
/* global copyObject, compareIds */
 | 
					/* global Y */
 | 
				
			||||||
 | 
					'use strict'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var compareIds = Y.compareIds
 | 
				
			||||||
 | 
					var copyObject = Y.copyObject
 | 
				
			||||||
var GeneratorFunction = (function *() {}).constructor;// eslint-disable-line
 | 
					var GeneratorFunction = (function *() {}).constructor;// eslint-disable-line
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EventHandler { // eslint-disable-line
 | 
					class EventHandler { // eslint-disable-line
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								src/y.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/y.js
									
									
									
									
									
								
							@ -1,4 +1,5 @@
 | 
				
			|||||||
/* @flow */
 | 
					/* @flow */
 | 
				
			||||||
 | 
					'use strict'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Y (opts) {
 | 
					function Y (opts) {
 | 
				
			||||||
  var def = Promise.defer()
 | 
					  var def = Promise.defer()
 | 
				
			||||||
@ -35,10 +36,13 @@ class YConfig { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
  disconnect () {
 | 
					  disconnect () {
 | 
				
			||||||
    this.connector.disconnect()
 | 
					    this.connector.disconnect()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  async reconnect () {
 | 
					  reconnect () {
 | 
				
			||||||
    await this.db.garbageCollect()
 | 
					    Promise.all([
 | 
				
			||||||
    await this.db.garbageCollect()
 | 
					      this.db.garbageCollect(),
 | 
				
			||||||
 | 
					      this.db.garbageCollect()
 | 
				
			||||||
 | 
					    ]).then(function () {
 | 
				
			||||||
      this.connector.reconnect()
 | 
					      this.connector.reconnect()
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  destroy () {
 | 
					  destroy () {
 | 
				
			||||||
    this.connector.disconnect()
 | 
					    this.connector.disconnect()
 | 
				
			||||||
@ -50,3 +54,5 @@ class YConfig { // eslint-disable-line no-unused-vars
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (g) g.Y = Y //eslint-disable-line
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user