fix all tests
This commit is contained in:
		
							parent
							
								
									f94653424a
								
							
						
					
					
						commit
						52abcdd043
					
				@ -1,5 +1,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { createMutex } from '../../lib/mutex.js'
 | 
					import { createMutex } from '../lib/mutex.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Abstract class for bindings.
 | 
					 * Abstract class for bindings.
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/* global MutationObserver, getSelection */
 | 
					/* global MutationObserver, getSelection */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { fromRelativePosition } from '../../Util/relativePosition.js'
 | 
					import { fromRelativePosition } from '../../src/Util/relativePosition.js'
 | 
				
			||||||
import Binding from '../Binding.js'
 | 
					import Binding from '../Binding.js'
 | 
				
			||||||
import { createAssociation, removeAssociation } from './util.js'
 | 
					import { createAssociation, removeAssociation } from './util.js'
 | 
				
			||||||
import { beforeTransactionSelectionFixer, afterTransactionSelectionFixer, getCurrentRelativeSelection } from './selection.js'
 | 
					import { beforeTransactionSelectionFixer, afterTransactionSelectionFixer, getCurrentRelativeSelection } from './selection.js'
 | 
				
			||||||
@ -121,8 +121,15 @@ export default class DomBinding extends Binding {
 | 
				
			|||||||
    createAssociation(this, target, type)
 | 
					    createAssociation(this, target, type)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  flushDomChanges () {
 | 
				
			||||||
 | 
					    this._domObserver(this._mutationObserver.takeRecords())
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * NOTE: currently does not apply filter to existing elements!
 | 
					   * NOTE:
 | 
				
			||||||
 | 
					   * * does not apply filter to existing elements!
 | 
				
			||||||
 | 
					   * * only guarantees that changes are filtered locally. Remote sites may see different content.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
   * @param {DomFilter} filter The filter function to use from now on.
 | 
					   * @param {DomFilter} filter The filter function to use from now on.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  setFilter (filter) {
 | 
					  setFilter (filter) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import YXmlHook from '../../Types/YXml/YXmlHook.js'
 | 
					import YXmlHook from '../../src/Types/YXml/YXmlHook.js'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  iterateUntilUndeleted,
 | 
					  iterateUntilUndeleted,
 | 
				
			||||||
  removeAssociation,
 | 
					  removeAssociation,
 | 
				
			||||||
  insertNodeHelper } from './util.js'
 | 
					  insertNodeHelper } from './util.js'
 | 
				
			||||||
import diff from '../../../lib/simpleDiff.js'
 | 
					import diff from '../../lib/simpleDiff.js'
 | 
				
			||||||
import YXmlFragment from '../../Types/YXml/YXmlFragment.js'
 | 
					import YXmlFragment from '../../src/Types/YXml/YXmlFragment.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 1. Check if any of the nodes was deleted
 | 
					 * 1. Check if any of the nodes was deleted
 | 
				
			||||||
 | 
				
			|||||||
@ -47,12 +47,14 @@ export function splitHelper (y, a, b, diff) {
 | 
				
			|||||||
    o = o._right
 | 
					    o = o._right
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  y.os.put(b)
 | 
					  y.os.put(b)
 | 
				
			||||||
 | 
					  if (y._transaction !== null) {
 | 
				
			||||||
    if (y._transaction.newTypes.has(a)) {
 | 
					    if (y._transaction.newTypes.has(a)) {
 | 
				
			||||||
      y._transaction.newTypes.add(b)
 | 
					      y._transaction.newTypes.add(b)
 | 
				
			||||||
    } else if (y._transaction.deletedStructs.has(a)) {
 | 
					    } else if (y._transaction.deletedStructs.has(a)) {
 | 
				
			||||||
      y._transaction.deletedStructs.add(b)
 | 
					      y._transaction.deletedStructs.add(b)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Abstract class that represents any content.
 | 
					 * Abstract class that represents any content.
 | 
				
			||||||
@ -117,7 +119,7 @@ export default class Item {
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
  _copy () {
 | 
					  _copy () {
 | 
				
			||||||
    const C = this.constructor
 | 
					    const C = this.constructor
 | 
				
			||||||
    return C()
 | 
					    return new C()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
 | 
				
			|||||||
@ -54,7 +54,7 @@ export const stringifyDeleteSet = (decoder) => {
 | 
				
			|||||||
  const dsLength = decoding.readUint32(decoder)
 | 
					  const dsLength = decoding.readUint32(decoder)
 | 
				
			||||||
  for (let i = 0; i < dsLength; i++) {
 | 
					  for (let i = 0; i < dsLength; i++) {
 | 
				
			||||||
    str += ' -' + decoding.readVarUint(decoder) + ':\n' // decodes user
 | 
					    str += ' -' + decoding.readVarUint(decoder) + ':\n' // decodes user
 | 
				
			||||||
    const dvLength = decoding.readVarUint(decoder)
 | 
					    const dvLength = decoding.readUint32(decoder)
 | 
				
			||||||
    for (let j = 0; j < dvLength; j++) {
 | 
					    for (let j = 0; j < dvLength; j++) {
 | 
				
			||||||
      str += `clock: ${decoding.readVarUint(decoder)}, length: ${decoding.readVarUint(decoder)}, gc: ${decoding.readUint8(decoder) === 1}\n`
 | 
					      str += `clock: ${decoding.readVarUint(decoder)}, length: ${decoding.readVarUint(decoder)}, gc: ${decoding.readUint8(decoder) === 1}\n`
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -192,8 +192,8 @@ export const readDeleteSet = (decoder, y) => {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export const stringifyStateSet = decoder => {
 | 
					export const stringifyStateSet = decoder => {
 | 
				
			||||||
  let s = 'State Set: '
 | 
					  let s = 'State Set: '
 | 
				
			||||||
  readStateSet(decoder).forEach((user, userState) => {
 | 
					  readStateSet(decoder).forEach((clock, user) => {
 | 
				
			||||||
    s += `(${user}: ${userState}), `
 | 
					    s += `(${user}: ${clock}), `
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  return s
 | 
					  return s
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -209,7 +209,7 @@ export const writeStateSet = (encoder, y) => {
 | 
				
			|||||||
  // write as fixed-size number to stay consistent with the other encode functions.
 | 
					  // write as fixed-size number to stay consistent with the other encode functions.
 | 
				
			||||||
  // => anytime we write the number of objects that follow, encode as fixed-size number.
 | 
					  // => anytime we write the number of objects that follow, encode as fixed-size number.
 | 
				
			||||||
  encoding.writeUint32(encoder, state.size)
 | 
					  encoding.writeUint32(encoder, state.size)
 | 
				
			||||||
  state.forEach((user, clock) => {
 | 
					  state.forEach((clock, user) => {
 | 
				
			||||||
    encoding.writeVarUint(encoder, user)
 | 
					    encoding.writeVarUint(encoder, user)
 | 
				
			||||||
    encoding.writeVarUint(encoder, clock)
 | 
					    encoding.writeVarUint(encoder, clock)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
@ -317,7 +317,9 @@ export const writeStructs = (encoder, y, ss) => {
 | 
				
			|||||||
      const overlappingLeft = y.os.findPrev(minBound)
 | 
					      const overlappingLeft = y.os.findPrev(minBound)
 | 
				
			||||||
      const rightID = overlappingLeft === null ? null : overlappingLeft._id
 | 
					      const rightID = overlappingLeft === null ? null : overlappingLeft._id
 | 
				
			||||||
      if (rightID !== null && rightID.user === user && rightID.clock + overlappingLeft._length > clock) {
 | 
					      if (rightID !== null && rightID.user === user && rightID.clock + overlappingLeft._length > clock) {
 | 
				
			||||||
        const struct = overlappingLeft._clonePartial(clock - rightID.clock)
 | 
					        // TODO: only write partial content (only missing content)
 | 
				
			||||||
 | 
					        // const struct = overlappingLeft._clonePartial(clock - rightID.clock)
 | 
				
			||||||
 | 
					        const struct = overlappingLeft
 | 
				
			||||||
        struct._toBinary(encoder)
 | 
					        struct._toBinary(encoder)
 | 
				
			||||||
        len++
 | 
					        len++
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
				
			|||||||
@ -13,8 +13,8 @@ function testEncoding (t, write, read, val) {
 | 
				
			|||||||
  t.compare(val, result, 'Compare results')
 | 
					  t.compare(val, result, 'Compare results')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const writeVarUint = (encoder, val) => encoder.writeVarUint(val)
 | 
					const writeVarUint = (encoder, val) => encoding.writeVarUint(encoder, val)
 | 
				
			||||||
const readVarUint = decoder => decoder.readVarUint()
 | 
					const readVarUint = decoder => decoding.readVarUint(decoder)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('varUint 1 byte', async function varUint1 (t) {
 | 
					test('varUint 1 byte', async function varUint1 (t) {
 | 
				
			||||||
  testEncoding(t, writeVarUint, readVarUint, 42)
 | 
					  testEncoding(t, writeVarUint, readVarUint, 42)
 | 
				
			||||||
@ -46,8 +46,8 @@ test('varUint random user id', async function varUintRandomUserId (t) {
 | 
				
			|||||||
  testEncoding(t, writeVarUint, readVarUint, generateRandomUint32())
 | 
					  testEncoding(t, writeVarUint, readVarUint, generateRandomUint32())
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const writeVarString = (encoder, val) => encoder.writeVarString(val)
 | 
					const writeVarString = (encoder, val) => encoding.writeVarString(encoder, val)
 | 
				
			||||||
const readVarString = decoder => decoder.readVarString()
 | 
					const readVarString = decoder => decoding.readVarString(decoder)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('varString', async function varString (t) {
 | 
					test('varString', async function varString (t) {
 | 
				
			||||||
  testEncoding(t, writeVarString, readVarString, 'hello')
 | 
					  testEncoding(t, writeVarString, readVarString, 'hello')
 | 
				
			||||||
 | 
				
			|||||||
@ -65,6 +65,7 @@ test('insertions work in late sync', async function array4 (t) {
 | 
				
			|||||||
  array2.insert(1, ['user2'])
 | 
					  array2.insert(1, ['user2'])
 | 
				
			||||||
  await users[1].connect()
 | 
					  await users[1].connect()
 | 
				
			||||||
  await users[2].connect()
 | 
					  await users[2].connect()
 | 
				
			||||||
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -215,7 +216,7 @@ function getUniqueNumber () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var arrayTransactions = [
 | 
					var arrayTransactions = [
 | 
				
			||||||
  function insert (t, user, prng) {
 | 
					  function insert (t, user, prng) {
 | 
				
			||||||
    const yarray = user.get('array', Y.Array)
 | 
					    const yarray = user.define('array', Y.Array)
 | 
				
			||||||
    var uniqueNumber = getUniqueNumber()
 | 
					    var uniqueNumber = getUniqueNumber()
 | 
				
			||||||
    var content = []
 | 
					    var content = []
 | 
				
			||||||
    var len = random.int32(prng, 1, 4)
 | 
					    var len = random.int32(prng, 1, 4)
 | 
				
			||||||
@ -226,14 +227,14 @@ var arrayTransactions = [
 | 
				
			|||||||
    yarray.insert(pos, content)
 | 
					    yarray.insert(pos, content)
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function insertTypeArray (t, user, prng) {
 | 
					  function insertTypeArray (t, user, prng) {
 | 
				
			||||||
    const yarray = user.get('array', Y.Array)
 | 
					    const yarray = user.define('array', Y.Array)
 | 
				
			||||||
    var pos = random.int32(prng, 0, yarray.length)
 | 
					    var pos = random.int32(prng, 0, yarray.length)
 | 
				
			||||||
    yarray.insert(pos, [Y.Array])
 | 
					    yarray.insert(pos, [Y.Array])
 | 
				
			||||||
    var array2 = yarray.get(pos)
 | 
					    var array2 = yarray.get(pos)
 | 
				
			||||||
    array2.insert(0, [1, 2, 3, 4])
 | 
					    array2.insert(0, [1, 2, 3, 4])
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function insertTypeMap (t, user, prng) {
 | 
					  function insertTypeMap (t, user, prng) {
 | 
				
			||||||
    const yarray = user.get('array', Y.Array)
 | 
					    const yarray = user.define('array', Y.Array)
 | 
				
			||||||
    var pos = random.int32(prng, 0, yarray.length)
 | 
					    var pos = random.int32(prng, 0, yarray.length)
 | 
				
			||||||
    yarray.insert(pos, [Y.Map])
 | 
					    yarray.insert(pos, [Y.Map])
 | 
				
			||||||
    var map = yarray.get(pos)
 | 
					    var map = yarray.get(pos)
 | 
				
			||||||
@ -242,7 +243,7 @@ var arrayTransactions = [
 | 
				
			|||||||
    map.set('someprop', 44)
 | 
					    map.set('someprop', 44)
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function _delete (t, user, prng) {
 | 
					  function _delete (t, user, prng) {
 | 
				
			||||||
    const yarray = user.get('array', Y.Array)
 | 
					    const yarray = user.define('array', Y.Array)
 | 
				
			||||||
    var length = yarray.length
 | 
					    var length = yarray.length
 | 
				
			||||||
    if (length > 0) {
 | 
					    if (length > 0) {
 | 
				
			||||||
      var somePos = random.int32(prng, 0, length - 1)
 | 
					      var somePos = random.int32(prng, 0, length - 1)
 | 
				
			||||||
 | 
				
			|||||||
@ -50,7 +50,7 @@ test('Basic get&set of Map property (converge via sync)', async function map1 (t
 | 
				
			|||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (let user of users) {
 | 
					  for (let user of users) {
 | 
				
			||||||
    var u = user.get('map', Y.Map)
 | 
					    var u = user.define('map', Y.Map)
 | 
				
			||||||
    t.compare(u.get('stuff'), 'stuffy')
 | 
					    t.compare(u.get('stuff'), 'stuffy')
 | 
				
			||||||
    t.assert(u.get('undefined') === undefined, 'undefined')
 | 
					    t.assert(u.get('undefined') === undefined, 'undefined')
 | 
				
			||||||
    t.compare(u.get('null'), null, 'null')
 | 
					    t.compare(u.get('null'), null, 'null')
 | 
				
			||||||
@ -94,7 +94,7 @@ test('Basic get&set of Map property (converge via update)', async function map5
 | 
				
			|||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (let user of users) {
 | 
					  for (let user of users) {
 | 
				
			||||||
    var u = user.get('map', Y.Map)
 | 
					    var u = user.define('map', Y.Map)
 | 
				
			||||||
    t.compare(u.get('stuff'), 'stuffy')
 | 
					    t.compare(u.get('stuff'), 'stuffy')
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
@ -108,7 +108,7 @@ test('Basic get&set of Map property (handle conflict)', async function map6 (t)
 | 
				
			|||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (let user of users) {
 | 
					  for (let user of users) {
 | 
				
			||||||
    var u = user.get('map', Y.Map)
 | 
					    var u = user.define('map', Y.Map)
 | 
				
			||||||
    t.compare(u.get('stuff'), 'c0')
 | 
					    t.compare(u.get('stuff'), 'c0')
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
@ -121,7 +121,7 @@ test('Basic get&set&delete of Map property (handle conflict)', async function ma
 | 
				
			|||||||
  map1.set('stuff', 'c1')
 | 
					  map1.set('stuff', 'c1')
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  for (let user of users) {
 | 
					  for (let user of users) {
 | 
				
			||||||
    var u = user.get('map', Y.Map)
 | 
					    var u = user.define('map', Y.Map)
 | 
				
			||||||
    t.assert(u.get('stuff') === undefined)
 | 
					    t.assert(u.get('stuff') === undefined)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
@ -135,7 +135,7 @@ test('Basic get&set of Map property (handle three conflicts)', async function ma
 | 
				
			|||||||
  map2.set('stuff', 'c3')
 | 
					  map2.set('stuff', 'c3')
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  for (let user of users) {
 | 
					  for (let user of users) {
 | 
				
			||||||
    var u = user.get('map', Y.Map)
 | 
					    var u = user.define('map', Y.Map)
 | 
				
			||||||
    t.compare(u.get('stuff'), 'c0')
 | 
					    t.compare(u.get('stuff'), 'c0')
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
@ -155,7 +155,7 @@ test('Basic get&set&delete of Map property (handle three conflicts)', async func
 | 
				
			|||||||
  map3.set('stuff', 'c3')
 | 
					  map3.set('stuff', 'c3')
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  for (let user of users) {
 | 
					  for (let user of users) {
 | 
				
			||||||
    var u = user.get('map', Y.Map)
 | 
					    var u = user.define('map', Y.Map)
 | 
				
			||||||
    t.assert(u.get('stuff') === undefined)
 | 
					    t.assert(u.get('stuff') === undefined)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
@ -303,12 +303,12 @@ var mapTransactions = [
 | 
				
			|||||||
  function set (t, user, prng) {
 | 
					  function set (t, user, prng) {
 | 
				
			||||||
    let key = random.oneOf(prng, ['one', 'two'])
 | 
					    let key = random.oneOf(prng, ['one', 'two'])
 | 
				
			||||||
    var value = random.utf16String(prng)
 | 
					    var value = random.utf16String(prng)
 | 
				
			||||||
    user.get('map', Y.Map).set(key, value)
 | 
					    user.define('map', Y.Map).set(key, value)
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function setType (t, user, prng) {
 | 
					  function setType (t, user, prng) {
 | 
				
			||||||
    let key = random.oneOf(prng, ['one', 'two'])
 | 
					    let key = random.oneOf(prng, ['one', 'two'])
 | 
				
			||||||
    var type = random.oneOf(prng, [new Y.Array(), new Y.Map()])
 | 
					    var type = random.oneOf(prng, [new Y.Array(), new Y.Map()])
 | 
				
			||||||
    user.get('map', Y.Map).set(key, type)
 | 
					    user.define('map', Y.Map).set(key, type)
 | 
				
			||||||
    if (type instanceof Y.Array) {
 | 
					    if (type instanceof Y.Array) {
 | 
				
			||||||
      type.insert(0, [1, 2, 3, 4])
 | 
					      type.insert(0, [1, 2, 3, 4])
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -317,7 +317,7 @@ var mapTransactions = [
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  function _delete (t, user, prng) {
 | 
					  function _delete (t, user, prng) {
 | 
				
			||||||
    let key = random.oneOf(prng, ['one', 'two'])
 | 
					    let key = random.oneOf(prng, ['one', 'two'])
 | 
				
			||||||
    user.get('map', Y.Map).delete(key)
 | 
					    user.define('map', Y.Map).delete(key)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -61,20 +61,24 @@ test('attribute modifications (y -> dom)', async function xml2 (t) {
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('attribute modifications (dom -> y)', async function xml3 (t) {
 | 
					test('attribute modifications (dom -> y)', async function xml3 (t) {
 | 
				
			||||||
  var { users, xml0, dom0 } = await initArrays(t, { users: 3 })
 | 
					  var { users, xml0, dom0, domBinding0 } = await initArrays(t, { users: 3 })
 | 
				
			||||||
  dom0.setAttribute('height', '100px')
 | 
					  dom0.setAttribute('height', '100px')
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  t.assert(xml0.getAttribute('height') === '100px', 'setAttribute')
 | 
					  t.assert(xml0.getAttribute('height') === '100px', 'setAttribute')
 | 
				
			||||||
  dom0.removeAttribute('height')
 | 
					  dom0.removeAttribute('height')
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  t.assert(xml0.getAttribute('height') == null, 'removeAttribute')
 | 
					  t.assert(xml0.getAttribute('height') == null, 'removeAttribute')
 | 
				
			||||||
  dom0.setAttribute('class', 'stuffy stuff')
 | 
					  dom0.setAttribute('class', 'stuffy stuff')
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  t.assert(xml0.getAttribute('class') === 'stuffy stuff', 'set class attribute')
 | 
					  t.assert(xml0.getAttribute('class') === 'stuffy stuff', 'set class attribute')
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('element insert (dom -> y)', async function xml4 (t) {
 | 
					test('element insert (dom -> y)', async function xml4 (t) {
 | 
				
			||||||
  var { users, xml0, dom0 } = await initArrays(t, { users: 3 })
 | 
					  var { users, xml0, dom0, domBinding0 } = await initArrays(t, { users: 3 })
 | 
				
			||||||
  dom0.insertBefore(document.createTextNode('some text'), null)
 | 
					  dom0.insertBefore(document.createTextNode('some text'), null)
 | 
				
			||||||
  dom0.insertBefore(document.createElement('p'), null)
 | 
					  dom0.insertBefore(document.createElement('p'), null)
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  t.assert(xml0.get(0).toString() === 'some text', 'Retrieve Text Node')
 | 
					  t.assert(xml0.get(0).toString() === 'some text', 'Retrieve Text Node')
 | 
				
			||||||
  t.assert(xml0.get(1).nodeName === 'P', 'Retrieve Element node')
 | 
					  t.assert(xml0.get(1).nodeName === 'P', 'Retrieve Element node')
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
@ -90,10 +94,12 @@ test('element insert (y -> dom)', async function xml5 (t) {
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('y on insert, then delete (dom -> y)', async function xml6 (t) {
 | 
					test('y on insert, then delete (dom -> y)', async function xml6 (t) {
 | 
				
			||||||
  var { users, xml0, dom0 } = await initArrays(t, { users: 3 })
 | 
					  var { users, xml0, dom0, domBinding0 } = await initArrays(t, { users: 3 })
 | 
				
			||||||
  dom0.insertBefore(document.createElement('p'), null)
 | 
					  dom0.insertBefore(document.createElement('p'), null)
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  t.assert(xml0.length === 1, 'one node present')
 | 
					  t.assert(xml0.length === 1, 'one node present')
 | 
				
			||||||
  dom0.childNodes[0].remove()
 | 
					  dom0.childNodes[0].remove()
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  t.assert(xml0.length === 0, 'no node present after delete')
 | 
					  t.assert(xml0.length === 0, 'no node present after delete')
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
@ -164,11 +170,13 @@ test('Receive a bunch of elements (with disconnect)', async function xml12 (t) {
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('move element to a different position', async function xml13 (t) {
 | 
					test('move element to a different position', async function xml13 (t) {
 | 
				
			||||||
  var { testConnector, users, dom0, dom1 } = await initArrays(t, { users: 3 })
 | 
					  var { testConnector, users, dom0, dom1, domBinding0, domBinding1 } = await initArrays(t, { users: 3 })
 | 
				
			||||||
  dom0.append(document.createElement('div'))
 | 
					  dom0.append(document.createElement('div'))
 | 
				
			||||||
  dom0.append(document.createElement('h1'))
 | 
					  dom0.append(document.createElement('h1'))
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  dom1.insertBefore(dom1.childNodes[0], null)
 | 
					  dom1.insertBefore(dom1.childNodes[0], null)
 | 
				
			||||||
 | 
					  domBinding1.flushDomChanges()
 | 
				
			||||||
  t.assert(dom1.childNodes[0].nodeName === 'H1', 'div was deleted (user 0)')
 | 
					  t.assert(dom1.childNodes[0].nodeName === 'H1', 'div was deleted (user 0)')
 | 
				
			||||||
  t.assert(dom1.childNodes[1].nodeName === 'DIV', 'div was moved to the correct position (user 0)')
 | 
					  t.assert(dom1.childNodes[1].nodeName === 'DIV', 'div was moved to the correct position (user 0)')
 | 
				
			||||||
  t.assert(dom1.childNodes[0].nodeName === 'H1', 'div was deleted (user 1)')
 | 
					  t.assert(dom1.childNodes[0].nodeName === 'H1', 'div was deleted (user 1)')
 | 
				
			||||||
@ -189,6 +197,7 @@ test('filter node', async function xml14 (t) {
 | 
				
			|||||||
  domBinding1.setFilter(domFilter)
 | 
					  domBinding1.setFilter(domFilter)
 | 
				
			||||||
  dom0.append(document.createElement('div'))
 | 
					  dom0.append(document.createElement('div'))
 | 
				
			||||||
  dom0.append(document.createElement('h1'))
 | 
					  dom0.append(document.createElement('h1'))
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  t.assert(dom1.childNodes.length === 1, 'Only one node was not transmitted')
 | 
					  t.assert(dom1.childNodes.length === 1, 'Only one node was not transmitted')
 | 
				
			||||||
  t.assert(dom1.childNodes[0].nodeName === 'DIV', 'div node was transmitted')
 | 
					  t.assert(dom1.childNodes[0].nodeName === 'DIV', 'div node was transmitted')
 | 
				
			||||||
@ -206,6 +215,7 @@ test('filter attribute', async function xml15 (t) {
 | 
				
			|||||||
  dom0.setAttribute('hidden', 'true')
 | 
					  dom0.setAttribute('hidden', 'true')
 | 
				
			||||||
  dom0.setAttribute('style', 'height: 30px')
 | 
					  dom0.setAttribute('style', 'height: 30px')
 | 
				
			||||||
  dom0.setAttribute('data-me', '77')
 | 
					  dom0.setAttribute('data-me', '77')
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  t.assert(dom0.getAttribute('hidden') === 'true', 'User 0 still has the attribute')
 | 
					  t.assert(dom0.getAttribute('hidden') === 'true', 'User 0 still has the attribute')
 | 
				
			||||||
  t.assert(dom1.getAttribute('hidden') == null, 'User 1 did not receive update')
 | 
					  t.assert(dom1.getAttribute('hidden') == null, 'User 1 did not receive update')
 | 
				
			||||||
@ -215,7 +225,7 @@ test('filter attribute', async function xml15 (t) {
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('deep element insert', async function xml16 (t) {
 | 
					test('deep element insert', async function xml16 (t) {
 | 
				
			||||||
  var { testConnector, users, dom0, dom1 } = await initArrays(t, { users: 3 })
 | 
					  var { testConnector, users, dom0, dom1, domBinding0 } = await initArrays(t, { users: 3 })
 | 
				
			||||||
  let deepElement = document.createElement('p')
 | 
					  let deepElement = document.createElement('p')
 | 
				
			||||||
  let boldElement = document.createElement('b')
 | 
					  let boldElement = document.createElement('b')
 | 
				
			||||||
  let attrElement = document.createElement('img')
 | 
					  let attrElement = document.createElement('img')
 | 
				
			||||||
@ -225,6 +235,7 @@ test('deep element insert', async function xml16 (t) {
 | 
				
			|||||||
  deepElement.append(attrElement)
 | 
					  deepElement.append(attrElement)
 | 
				
			||||||
  dom0.append(deepElement)
 | 
					  dom0.append(deepElement)
 | 
				
			||||||
  let str0 = dom0.outerHTML
 | 
					  let str0 = dom0.outerHTML
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  let str1 = dom1.outerHTML
 | 
					  let str1 = dom1.outerHTML
 | 
				
			||||||
  t.compare(str0, str1, 'Dom string representation matches')
 | 
					  t.compare(str0, str1, 'Dom string representation matches')
 | 
				
			||||||
@ -253,8 +264,8 @@ test('treeWalker', async function xml17 (t) {
 | 
				
			|||||||
 * Incoming changes that contain malicious attributes should be deleted.
 | 
					 * Incoming changes that contain malicious attributes should be deleted.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
test('Filtering remote changes', async function xmlFilteringRemote (t) {
 | 
					test('Filtering remote changes', async function xmlFilteringRemote (t) {
 | 
				
			||||||
  var { testConnector, users, xml0, xml1, domBinding0 } = await initArrays(t, { users: 3 })
 | 
					  var { testConnector, users, xml0, xml1, domBinding0, domBinding1 } = await initArrays(t, { users: 3 })
 | 
				
			||||||
  domBinding0.setFilter(function (nodeName, attributes) {
 | 
					  const filter = (nodeName, attributes) => {
 | 
				
			||||||
    attributes.delete('malicious')
 | 
					    attributes.delete('malicious')
 | 
				
			||||||
    if (nodeName === 'HIDEME') {
 | 
					    if (nodeName === 'HIDEME') {
 | 
				
			||||||
      return null
 | 
					      return null
 | 
				
			||||||
@ -263,7 +274,9 @@ test('Filtering remote changes', async function xmlFilteringRemote (t) {
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return attributes
 | 
					      return attributes
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  })
 | 
					  }
 | 
				
			||||||
 | 
					  domBinding0.setFilter(filter)
 | 
				
			||||||
 | 
					  domBinding1.setFilter(filter)
 | 
				
			||||||
  let paragraph = new Y.XmlElement('p')
 | 
					  let paragraph = new Y.XmlElement('p')
 | 
				
			||||||
  let hideMe = new Y.XmlElement('hideMe')
 | 
					  let hideMe = new Y.XmlElement('hideMe')
 | 
				
			||||||
  let span = new Y.XmlElement('span')
 | 
					  let span = new Y.XmlElement('span')
 | 
				
			||||||
@ -275,13 +288,16 @@ test('Filtering remote changes', async function xmlFilteringRemote (t) {
 | 
				
			|||||||
  let tag2 = new Y.XmlElement('tag')
 | 
					  let tag2 = new Y.XmlElement('tag')
 | 
				
			||||||
  tag2.setAttribute('isHidden', 'true')
 | 
					  tag2.setAttribute('isHidden', 'true')
 | 
				
			||||||
  paragraph.insert(0, [tag2])
 | 
					  paragraph.insert(0, [tag2])
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
  // check dom
 | 
					  // check dom
 | 
				
			||||||
  domBinding0.typeToDom.get(paragraph).setAttribute('malicious', 'true')
 | 
					  domBinding0.typeToDom.get(paragraph).setAttribute('malicious', 'true')
 | 
				
			||||||
  domBinding0.typeToDom.get(span).setAttribute('malicious', 'true')
 | 
					  domBinding0.typeToDom.get(span).setAttribute('malicious', 'true')
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  // check incoming attributes
 | 
					  // check incoming attributes
 | 
				
			||||||
  xml1.get(0).get(0).setAttribute('malicious', 'true')
 | 
					  xml1.get(0).get(0).setAttribute('malicious', 'true')
 | 
				
			||||||
  xml1.insert(0, [new Y.XmlElement('hideMe')])
 | 
					  xml1.insert(0, [new Y.XmlElement('hideMe')])
 | 
				
			||||||
 | 
					  domBinding0.flushDomChanges()
 | 
				
			||||||
  testConnector.flushAllMessages()
 | 
					  testConnector.flushAllMessages()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
@ -292,30 +308,36 @@ var xmlTransactions = [
 | 
				
			|||||||
  function attributeChange (t, user, prng) {
 | 
					  function attributeChange (t, user, prng) {
 | 
				
			||||||
    // random.word generates non-empty words. prepend something
 | 
					    // random.word generates non-empty words. prepend something
 | 
				
			||||||
    user.dom.setAttribute('_' + random.word(prng), random.word(prng))
 | 
					    user.dom.setAttribute('_' + random.word(prng), random.word(prng))
 | 
				
			||||||
 | 
					    user.domBinding.flushDomChanges()
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function attributeChangeHidden (t, user, prng) {
 | 
					  function attributeChangeHidden (t, user, prng) {
 | 
				
			||||||
    user.dom.setAttribute('hidden', random.word(prng))
 | 
					    user.dom.setAttribute('hidden', random.word(prng))
 | 
				
			||||||
 | 
					    user.domBinding.flushDomChanges()
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function insertText (t, user, prng) {
 | 
					  function insertText (t, user, prng) {
 | 
				
			||||||
    let dom = user.dom
 | 
					    let dom = user.dom
 | 
				
			||||||
    var succ = dom.children.length > 0 ? random.oneOf(prng, dom.children) : null
 | 
					    var succ = dom.children.length > 0 ? random.oneOf(prng, dom.children) : null
 | 
				
			||||||
    dom.insertBefore(document.createTextNode(random.word(prng)), succ)
 | 
					    dom.insertBefore(document.createTextNode(random.word(prng)), succ)
 | 
				
			||||||
 | 
					    user.domBinding.flushDomChanges()
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function insertHiddenDom (t, user, prng) {
 | 
					  function insertHiddenDom (t, user, prng) {
 | 
				
			||||||
    let dom = user.dom
 | 
					    let dom = user.dom
 | 
				
			||||||
    var succ = dom.children.length > 0 ? random.oneOf(prng, dom.children) : null
 | 
					    var succ = dom.children.length > 0 ? random.oneOf(prng, dom.children) : null
 | 
				
			||||||
    dom.insertBefore(document.createElement('hidden'), succ)
 | 
					    dom.insertBefore(document.createElement('hidden'), succ)
 | 
				
			||||||
 | 
					    user.domBinding.flushDomChanges()
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function insertDom (t, user, prng) {
 | 
					  function insertDom (t, user, prng) {
 | 
				
			||||||
    let dom = user.dom
 | 
					    let dom = user.dom
 | 
				
			||||||
    var succ = dom.children.length > 0 ? random.oneOf(prng, dom.children) : null
 | 
					    var succ = dom.children.length > 0 ? random.oneOf(prng, dom.children) : null
 | 
				
			||||||
    dom.insertBefore(document.createElement('my-' + random.word(prng)), succ)
 | 
					    dom.insertBefore(document.createElement('my-' + random.word(prng)), succ)
 | 
				
			||||||
 | 
					    user.domBinding.flushDomChanges()
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function deleteChild (t, user, prng) {
 | 
					  function deleteChild (t, user, prng) {
 | 
				
			||||||
    let dom = user.dom
 | 
					    let dom = user.dom
 | 
				
			||||||
    if (dom.childNodes.length > 0) {
 | 
					    if (dom.childNodes.length > 0) {
 | 
				
			||||||
      var d = random.oneOf(prng, dom.childNodes)
 | 
					      var d = random.oneOf(prng, dom.childNodes)
 | 
				
			||||||
      d.remove()
 | 
					      d.remove()
 | 
				
			||||||
 | 
					      user.domBinding.flushDomChanges()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function insertTextSecondLayer (t, user, prng) {
 | 
					  function insertTextSecondLayer (t, user, prng) {
 | 
				
			||||||
@ -324,6 +346,7 @@ var xmlTransactions = [
 | 
				
			|||||||
      let dom2 = random.oneOf(prng, dom.children)
 | 
					      let dom2 = random.oneOf(prng, dom.children)
 | 
				
			||||||
      let succ = dom2.childNodes.length > 0 ? random.oneOf(prng, dom2.childNodes) : null
 | 
					      let succ = dom2.childNodes.length > 0 ? random.oneOf(prng, dom2.childNodes) : null
 | 
				
			||||||
      dom2.insertBefore(document.createTextNode(random.word(prng)), succ)
 | 
					      dom2.insertBefore(document.createTextNode(random.word(prng)), succ)
 | 
				
			||||||
 | 
					      user.domBinding.flushDomChanges()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function insertDomSecondLayer (t, user, prng) {
 | 
					  function insertDomSecondLayer (t, user, prng) {
 | 
				
			||||||
@ -332,6 +355,7 @@ var xmlTransactions = [
 | 
				
			|||||||
      let dom2 = random.oneOf(prng, dom.children)
 | 
					      let dom2 = random.oneOf(prng, dom.children)
 | 
				
			||||||
      let succ = dom2.childNodes.length > 0 ? random.oneOf(prng, dom2.childNodes) : null
 | 
					      let succ = dom2.childNodes.length > 0 ? random.oneOf(prng, dom2.childNodes) : null
 | 
				
			||||||
      dom2.insertBefore(document.createElement('my-' + random.word(prng)), succ)
 | 
					      dom2.insertBefore(document.createElement('my-' + random.word(prng)), succ)
 | 
				
			||||||
 | 
					      user.domBinding.flushDomChanges()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  function deleteChildSecondLayer (t, user, prng) {
 | 
					  function deleteChildSecondLayer (t, user, prng) {
 | 
				
			||||||
@ -342,6 +366,7 @@ var xmlTransactions = [
 | 
				
			|||||||
        let d = random.oneOf(prng, dom2.childNodes)
 | 
					        let d = random.oneOf(prng, dom2.childNodes)
 | 
				
			||||||
        d.remove()
 | 
					        d.remove()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      user.domBinding.flushDomChanges()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
				
			|||||||
@ -6,10 +6,12 @@ import { defragmentItemContent } from '../src/Util/defragmentItemContent.js'
 | 
				
			|||||||
import Quill from 'quill'
 | 
					import Quill from 'quill'
 | 
				
			||||||
import GC from '../src/Struct/GC.js'
 | 
					import GC from '../src/Struct/GC.js'
 | 
				
			||||||
import * as random from '../lib/random/random.js'
 | 
					import * as random from '../lib/random/random.js'
 | 
				
			||||||
import * as message from '../src/message.js'
 | 
					import * as syncProtocol from '../src/protocols/syncProtocol.js'
 | 
				
			||||||
import * as encoding from '../lib/encoding.js'
 | 
					import * as encoding from '../lib/encoding.js'
 | 
				
			||||||
import * as decoding from '../lib/decoding.js'
 | 
					import * as decoding from '../lib/decoding.js'
 | 
				
			||||||
import { createMutex } from '../lib/mutex.js'
 | 
					import { createMutex } from '../lib/mutex.js'
 | 
				
			||||||
 | 
					import QuillBinding from '../bindings/QuillBinding/QuillBinding.js'
 | 
				
			||||||
 | 
					import DomBinding from '../bindings/DomBinding/DomBinding.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export * from '../src/index.js'
 | 
					export * from '../src/index.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,7 +23,7 @@ const afterTransaction = (y, transaction) => {
 | 
				
			|||||||
  y.mMux(() => {
 | 
					  y.mMux(() => {
 | 
				
			||||||
    if (transaction.encodedStructsLen > 0) {
 | 
					    if (transaction.encodedStructsLen > 0) {
 | 
				
			||||||
      const encoder = encoding.createEncoder()
 | 
					      const encoder = encoding.createEncoder()
 | 
				
			||||||
      message.writeUpdate(encoder, transaction.encodedStructsLen, transaction.encodedStructs)
 | 
					      syncProtocol.writeUpdate(encoder, transaction.encodedStructsLen, transaction.encodedStructs)
 | 
				
			||||||
      broadcastMessage(y, encoding.toBuffer(encoder))
 | 
					      broadcastMessage(y, encoding.toBuffer(encoder))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
@ -31,8 +33,9 @@ export class TestYInstance extends Y.Y {
 | 
				
			|||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @param {TestConnector} testConnector
 | 
					   * @param {TestConnector} testConnector
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  constructor (testConnector) {
 | 
					  constructor (testConnector, clientID) {
 | 
				
			||||||
    super()
 | 
					    super()
 | 
				
			||||||
 | 
					    this.userID = clientID // overwriting clientID
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @type {TestConnector}
 | 
					     * @type {TestConnector}
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@ -64,17 +67,19 @@ export class TestYInstance extends Y.Y {
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
  connect () {
 | 
					  connect () {
 | 
				
			||||||
    if (!this.tc.onlineConns.has(this)) {
 | 
					    if (!this.tc.onlineConns.has(this)) {
 | 
				
			||||||
 | 
					      this.tc.onlineConns.add(this)
 | 
				
			||||||
      const encoder = encoding.createEncoder()
 | 
					      const encoder = encoding.createEncoder()
 | 
				
			||||||
      message.writeSyncStep1(encoder, this)
 | 
					      syncProtocol.writeSyncStep1(encoder, this)
 | 
				
			||||||
      // publish SyncStep1
 | 
					      // publish SyncStep1
 | 
				
			||||||
      broadcastMessage(this, encoding.toBuffer(encoder))
 | 
					      broadcastMessage(this, encoding.toBuffer(encoder))
 | 
				
			||||||
      this.tc.onlineConns.forEach(remoteYInstance => {
 | 
					      this.tc.onlineConns.forEach(remoteYInstance => {
 | 
				
			||||||
 | 
					        if (remoteYInstance !== this) {
 | 
				
			||||||
          // remote instance sends instance to this instance
 | 
					          // remote instance sends instance to this instance
 | 
				
			||||||
          const encoder = encoding.createEncoder()
 | 
					          const encoder = encoding.createEncoder()
 | 
				
			||||||
        message.writeSyncStep1(encoder, remoteYInstance)
 | 
					          syncProtocol.writeSyncStep1(encoder, remoteYInstance)
 | 
				
			||||||
          this._receive(encoding.toBuffer(encoder), remoteYInstance)
 | 
					          this._receive(encoding.toBuffer(encoder), remoteYInstance)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      this.tc.onlineConns.add(this)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@ -117,9 +122,10 @@ export class TestConnector {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Create a new Y instance and add it to the list of connections
 | 
					   * Create a new Y instance and add it to the list of connections
 | 
				
			||||||
 | 
					   * @param {number} clientID
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  createY () {
 | 
					  createY (clientID) {
 | 
				
			||||||
    return new TestYInstance(this)
 | 
					    return new TestYInstance(this, clientID)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Choose random connection and flush a random message from a random sender.
 | 
					   * Choose random connection and flush a random message from a random sender.
 | 
				
			||||||
@ -139,8 +145,9 @@ export class TestConnector {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      const encoder = encoding.createEncoder()
 | 
					      const encoder = encoding.createEncoder()
 | 
				
			||||||
      receiver.mMux(() => {
 | 
					      receiver.mMux(() => {
 | 
				
			||||||
 | 
					        console.log('receive (' + sender.userID + '->' + receiver.userID + '):\n', syncProtocol.stringifySyncMessage(decoding.createDecoder(m), receiver))
 | 
				
			||||||
        // do not publish data created when this function is executed (could be ss2 or update message)
 | 
					        // do not publish data created when this function is executed (could be ss2 or update message)
 | 
				
			||||||
        message.readMessage(decoding.createDecoder(m), encoder, receiver)
 | 
					        syncProtocol.readSyncMessage(decoding.createDecoder(m), encoder, receiver)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      if (encoding.length(encoder) > 0) {
 | 
					      if (encoding.length(encoder) > 0) {
 | 
				
			||||||
        // send reply message
 | 
					        // send reply message
 | 
				
			||||||
@ -202,12 +209,15 @@ export class TestConnector {
 | 
				
			|||||||
 * @param {TestYInstance} y // publish message created by `y` to all other online clients
 | 
					 * @param {TestYInstance} y // publish message created by `y` to all other online clients
 | 
				
			||||||
 * @param {ArrayBuffer} m
 | 
					 * @param {ArrayBuffer} m
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
const broadcastMessage = (y, m) =>
 | 
					const broadcastMessage = (y, m) => {
 | 
				
			||||||
 | 
					  if (y.tc.onlineConns.has(y)) {
 | 
				
			||||||
    y.tc.onlineConns.forEach(remoteYInstance => {
 | 
					    y.tc.onlineConns.forEach(remoteYInstance => {
 | 
				
			||||||
      if (remoteYInstance !== y) {
 | 
					      if (remoteYInstance !== y) {
 | 
				
			||||||
        remoteYInstance._receive(m, y)
 | 
					        remoteYInstance._receive(m, y)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Convert DS to a proper DeleteSet of Map.
 | 
					 * Convert DS to a proper DeleteSet of Map.
 | 
				
			||||||
@ -295,7 +305,7 @@ export function compareUsers (t, users) {
 | 
				
			|||||||
    data.os = ops
 | 
					    data.os = ops
 | 
				
			||||||
    data.ds = getDeleteSet(u)
 | 
					    data.ds = getDeleteSet(u)
 | 
				
			||||||
    const ss = {}
 | 
					    const ss = {}
 | 
				
			||||||
    u.ss.state.forEach((user, clock) => {
 | 
					    u.ss.state.forEach((clock, user) => {
 | 
				
			||||||
      ss[user] = clock
 | 
					      ss[user] = clock
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    data.ss = ss
 | 
					    data.ss = ss
 | 
				
			||||||
@ -347,20 +357,20 @@ export function initArrays (t, opts) {
 | 
				
			|||||||
  const testConnector = new TestConnector(prng)
 | 
					  const testConnector = new TestConnector(prng)
 | 
				
			||||||
  result.testConnector = testConnector
 | 
					  result.testConnector = testConnector
 | 
				
			||||||
  for (let i = 0; i < opts.users; i++) {
 | 
					  for (let i = 0; i < opts.users; i++) {
 | 
				
			||||||
    let y = testConnector.createY()
 | 
					    let y = testConnector.createY(i)
 | 
				
			||||||
    result.users.push(y)
 | 
					    result.users.push(y)
 | 
				
			||||||
    result['array' + i] = y.define('array', Y.Array)
 | 
					    result['array' + i] = y.define('array', Y.Array)
 | 
				
			||||||
    result['map' + i] = y.define('map', Y.Map)
 | 
					    result['map' + i] = y.define('map', Y.Map)
 | 
				
			||||||
    const yxml = y.define('xml', Y.XmlElement)
 | 
					    const yxml = y.define('xml', Y.XmlElement)
 | 
				
			||||||
    result['xml' + i] = yxml
 | 
					    result['xml' + i] = yxml
 | 
				
			||||||
    const dom = document.createElement('my-dom')
 | 
					    const dom = document.createElement('my-dom')
 | 
				
			||||||
    const domBinding = new Y.DomBinding(yxml, dom, { filter })
 | 
					    const domBinding = new DomBinding(yxml, dom, { filter })
 | 
				
			||||||
    result['domBinding' + i] = domBinding
 | 
					    result['domBinding' + i] = domBinding
 | 
				
			||||||
    result['dom' + i] = dom
 | 
					    result['dom' + i] = dom
 | 
				
			||||||
    const textType = y.define('text', Y.Text)
 | 
					    const textType = y.define('text', Y.Text)
 | 
				
			||||||
    result['text' + i] = textType
 | 
					    result['text' + i] = textType
 | 
				
			||||||
    const quill = new Quill(document.createElement('div'))
 | 
					    const quill = new Quill(document.createElement('div'))
 | 
				
			||||||
    result['quillBinding' + i] = new Y.QuillBinding(textType, quill)
 | 
					    result['quillBinding' + i] = new QuillBinding(textType, quill)
 | 
				
			||||||
    result['quill' + i] = quill
 | 
					    result['quill' + i] = quill
 | 
				
			||||||
    y.quill = quill // put quill on the y object (so we can use it later)
 | 
					    y.quill = quill // put quill on the y object (so we can use it later)
 | 
				
			||||||
    y.dom = dom
 | 
					    y.dom = dom
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user