fix compiling issues
This commit is contained in:
		
							parent
							
								
									82015d5a37
								
							
						
					
					
						commit
						0e426f8928
					
				@ -5,6 +5,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[include]
 | 
					[include]
 | 
				
			||||||
./src/
 | 
					./src/
 | 
				
			||||||
 | 
					./tests-lib/
 | 
				
			||||||
 | 
					./test/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[libs]
 | 
					[libs]
 | 
				
			||||||
./declarations/
 | 
					./declarations/
 | 
				
			||||||
 | 
				
			|||||||
@ -64,7 +64,6 @@
 | 
				
			|||||||
    "tag-dist-files": "^0.1.6"
 | 
					    "tag-dist-files": "^0.1.6"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "debug": "^2.6.8",
 | 
					    "debug": "^2.6.8"
 | 
				
			||||||
    "utf-8": "^1.0.0"
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ import commonjs from 'rollup-plugin-commonjs'
 | 
				
			|||||||
var pkg = require('./package.json')
 | 
					var pkg = require('./package.json')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  entry: 'src/y.js',
 | 
					  entry: 'src/Y.js',
 | 
				
			||||||
  moduleName: 'Y',
 | 
					  moduleName: 'Y',
 | 
				
			||||||
  format: 'umd',
 | 
					  format: 'umd',
 | 
				
			||||||
  plugins: [
 | 
					  plugins: [
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ import commonjs from 'rollup-plugin-commonjs'
 | 
				
			|||||||
var pkg = require('./package.json')
 | 
					var pkg = require('./package.json')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  entry: 'src/y.js',
 | 
					  entry: 'src/Y.js',
 | 
				
			||||||
  moduleName: 'Y',
 | 
					  moduleName: 'Y',
 | 
				
			||||||
  format: 'umd',
 | 
					  format: 'umd',
 | 
				
			||||||
  plugins: [
 | 
					  plugins: [
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import utf8 from 'utf-8'
 | 
					import '../../node_modules/utf8/utf8.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class BinaryDecoder {
 | 
					export default class BinaryDecoder {
 | 
				
			||||||
  constructor (buffer) {
 | 
					  constructor (buffer) {
 | 
				
			||||||
@ -11,25 +11,36 @@ export default class BinaryDecoder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    this.pos = 0
 | 
					    this.pos = 0
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Clone this decoder instance
 | 
				
			||||||
 | 
					   * Optionally set a new position parameter
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  clone (newPos = this.pos) {
 | 
					  clone (newPos = this.pos) {
 | 
				
			||||||
    let decoder = new BinaryDecoder(this.uint8arr)
 | 
					    let decoder = new BinaryDecoder(this.uint8arr)
 | 
				
			||||||
    decoder.pos = newPos
 | 
					    decoder.pos = newPos
 | 
				
			||||||
    return decoder
 | 
					    return decoder
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Number of bytes
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  get length () {
 | 
					  get length () {
 | 
				
			||||||
    return this.uint8arr.length
 | 
					    return this.uint8arr.length
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Skip one byte, jump to the next position
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  skip8 () {
 | 
					  skip8 () {
 | 
				
			||||||
    this.pos++
 | 
					    this.pos++
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Read one byte as unsigned integer
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  readUint8 () {
 | 
					  readUint8 () {
 | 
				
			||||||
    return this.uint8arr[this.pos++]
 | 
					    return this.uint8arr[this.pos++]
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Read 4 bytes as unsigned integer
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  readUint32 () {
 | 
					  readUint32 () {
 | 
				
			||||||
    let uint =
 | 
					    let uint =
 | 
				
			||||||
      this.uint8arr[this.pos] +
 | 
					      this.uint8arr[this.pos] +
 | 
				
			||||||
@ -39,11 +50,20 @@ export default class BinaryDecoder {
 | 
				
			|||||||
    this.pos += 4
 | 
					    this.pos += 4
 | 
				
			||||||
    return uint
 | 
					    return uint
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Look ahead without incrementing position
 | 
				
			||||||
 | 
					   * to the next byte and read it as unsigned integer
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  peekUint8 () {
 | 
					  peekUint8 () {
 | 
				
			||||||
    return this.uint8arr[this.pos]
 | 
					    return this.uint8arr[this.pos]
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Read unsigned integer (32bit) with variable length
 | 
				
			||||||
 | 
					   * 1/8th of the storage is used as encoding overhead
 | 
				
			||||||
 | 
					   *  - numbers < 2^7 is stored in one byte
 | 
				
			||||||
 | 
					   *  - numbers < 2^14 is stored in two bytes
 | 
				
			||||||
 | 
					   *  ..
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  readVarUint () {
 | 
					  readVarUint () {
 | 
				
			||||||
    let num = 0
 | 
					    let num = 0
 | 
				
			||||||
    let len = 0
 | 
					    let len = 0
 | 
				
			||||||
@ -59,7 +79,10 @@ export default class BinaryDecoder {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Read string of variable length
 | 
				
			||||||
 | 
					   * - varUint is used to store the length of the string
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  readVarString () {
 | 
					  readVarString () {
 | 
				
			||||||
    let len = this.readVarUint()
 | 
					    let len = this.readVarUint()
 | 
				
			||||||
    let bytes = new Array(len)
 | 
					    let bytes = new Array(len)
 | 
				
			||||||
@ -68,20 +91,26 @@ export default class BinaryDecoder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return utf8.getStringFromBytes(bytes)
 | 
					    return utf8.getStringFromBytes(bytes)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   *  Look ahead and read varString without incrementing position
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  peekVarString () {
 | 
					  peekVarString () {
 | 
				
			||||||
    let pos = this.pos
 | 
					    let pos = this.pos
 | 
				
			||||||
    let s = this.readVarString()
 | 
					    let s = this.readVarString()
 | 
				
			||||||
    this.pos = pos
 | 
					    this.pos = pos
 | 
				
			||||||
    return s
 | 
					    return s
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
  readOpID () {
 | 
					   * Read ID
 | 
				
			||||||
 | 
					   * - If first varUint read is 0xFFFFFF a RootID is returned
 | 
				
			||||||
 | 
					   * - Otherwise an ID is returned
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  readID () {
 | 
				
			||||||
    let user = this.readVarUint()
 | 
					    let user = this.readVarUint()
 | 
				
			||||||
    if (user !== 0xFFFFFF) {
 | 
					    if (user === 0xFFFFFF) {
 | 
				
			||||||
      return [user, this.readVarUint()]
 | 
					      // read property name and type id
 | 
				
			||||||
    } else {
 | 
					      return new RootID(this.readVarString(), this.readVarUint())
 | 
				
			||||||
      return [user, this.readVarString()]
 | 
					    }
 | 
				
			||||||
    }
 | 
					    return new ID(user, this.readVarUint())
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import utf8 from 'utf-8'
 | 
					import '../../node_modules/utf8/utf8.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const bits7 = 0b1111111
 | 
					const bits7 = 0b1111111
 | 
				
			||||||
const bits8 = 0b11111111
 | 
					const bits8 = 0b11111111
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,11 @@
 | 
				
			|||||||
import { BinaryEncoder, BinaryDecoder } from './Encoding.js'
 | 
					import BinaryEncoder from './Binary/Encoder.js'
 | 
				
			||||||
 | 
					import BinaryDecoder from './Binary/Decoder.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { sendSyncStep1, readSyncStep1 } from './MessageHandler/syncStep1'
 | 
					import { sendSyncStep1, readSyncStep1 } from './MessageHandler/syncStep1.js'
 | 
				
			||||||
import { readSyncStep2 } from './MessageHandler/syncStep2'
 | 
					import { readSyncStep2 } from './MessageHandler/syncStep2.js'
 | 
				
			||||||
import { readUpdate } from './MessageHandler/update.js'
 | 
					import { readUpdate } from './MessageHandler/update.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import debug from 'debug'
 | 
					import { debug } from './Y.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class AbstractConnector {
 | 
					export default class AbstractConnector {
 | 
				
			||||||
  constructor (y, opts) {
 | 
					  constructor (y, opts) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { getStruct } from '../Util/StructReferences'
 | 
					import { getStruct } from '../Util/StructReferences.js'
 | 
				
			||||||
import BinaryDecoder from '../Util/Binary/Decoder'
 | 
					import BinaryDecoder from '../Binary/Decoder.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MissingEntry {
 | 
					class MissingEntry {
 | 
				
			||||||
  constructor (decoder, missing, struct) {
 | 
					  constructor (decoder, missing, struct) {
 | 
				
			||||||
@ -39,7 +39,7 @@ function _integrateRemoteStructHelper (y, struct) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function integrateRemoteStructs (decoder, encoder, y) {
 | 
					export function integrateRemoteStructs (decoder, encoder, y) {
 | 
				
			||||||
  while (decoder.length !== decoder.pos) {
 | 
					  while (decoder.length !== decoder.pos) {
 | 
				
			||||||
    let decoderPos = decoder.pos
 | 
					    let decoderPos = decoder.pos
 | 
				
			||||||
    let reference = decoder.readVarUint()
 | 
					    let reference = decoder.readVarUint()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import BinaryDecoder from '../Utily/Binary/Decoder'
 | 
					import BinaryDecoder from '../Binary/Decoder.js'
 | 
				
			||||||
import { stringifyUpdate } from './update'
 | 
					import { stringifyUpdate } from './update.js'
 | 
				
			||||||
import { stringifySyncStep1 } from './syncStep1'
 | 
					import { stringifySyncStep1 } from './syncStep1.js'
 | 
				
			||||||
import { stringifySyncStep2 } from './syncStep2'
 | 
					import { stringifySyncStep2 } from './syncStep2.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function messageToString (buffer) {
 | 
					export function messageToString (buffer) {
 | 
				
			||||||
  let decoder = new BinaryDecoder(buffer)
 | 
					  let decoder = new BinaryDecoder(buffer)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import BinaryEncoder from './Util/Binary/Encoder.js'
 | 
					import BinaryEncoder from '../Binary/Encoder.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function stringifySyncStep1 (decoder, strBuilder) {
 | 
					export function stringifySyncStep1 (decoder, strBuilder) {
 | 
				
			||||||
  let auth = decoder.readVarString()
 | 
					  let auth = decoder.readVarString()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import integrateRemoteStructs from './integrateRemoteStructs'
 | 
					import { integrateRemoteStructs } from './integrateRemoteStructs.js'
 | 
				
			||||||
import { stringifyUpdate } from './update.js'
 | 
					import { stringifyUpdate } from './update.js'
 | 
				
			||||||
import ID from '../Util/ID'
 | 
					import ID from '../Util/ID.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function stringifySyncStep2 (decoder, strBuilder) {
 | 
					export function stringifySyncStep2 (decoder, strBuilder) {
 | 
				
			||||||
  strBuilder.push('     - auth: ' + decoder.readVarString() + '\n')
 | 
					  strBuilder.push('     - auth: ' + decoder.readVarString() + '\n')
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { getStruct } from '../Util/StructReferences'
 | 
					import { getStruct } from '../Util/StructReferences.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function stringifyUpdate (decoder, strBuilder) {
 | 
					export function stringifyUpdate (decoder, strBuilder) {
 | 
				
			||||||
  while (decoder.length !== decoder.pos) {
 | 
					  while (decoder.length !== decoder.pos) {
 | 
				
			||||||
@ -16,4 +16,4 @@ export function stringifyUpdate (decoder, strBuilder) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { integrateRemoteStructs as readUpdate } from './integrateRemoteStructs'
 | 
					export { integrateRemoteStructs as readUpdate } from './integrateRemoteStructs.js'
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { BinaryEncoder } from './Encoding.js'
 | 
					import BinaryEncoder from './Binary/Encoder.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function extendPersistence (Y) {
 | 
					export default function extendPersistence (Y) {
 | 
				
			||||||
  class AbstractPersistence {
 | 
					  class AbstractPersistence {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import Tree from '../Util/Tree'
 | 
					import Tree from '../Util/Tree.js'
 | 
				
			||||||
import ID from '../Util/ID'
 | 
					import ID from '../Util/ID.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DSNode {
 | 
					class DSNode {
 | 
				
			||||||
  constructor (id, len, gc) {
 | 
					  constructor (id, len, gc) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,8 @@
 | 
				
			|||||||
import Tree from '../Util/Tree'
 | 
					import Tree from '../Util/Tree.js'
 | 
				
			||||||
import RootID from '../Util/ID'
 | 
					import RootID from '../Util/ID.js'
 | 
				
			||||||
import { getStruct } from '../Util/structReferences'
 | 
					import { getStruct } from '../Util/structReferences.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class OperationStore extends Tree {
 | 
					export default class OperationStore extends Tree {
 | 
				
			||||||
  constructor () {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  get (id) {
 | 
					  get (id) {
 | 
				
			||||||
    let struct = this.find(id)
 | 
					    let struct = this.find(id)
 | 
				
			||||||
    if (struct === null && id instanceof RootID) {
 | 
					    if (struct === null && id instanceof RootID) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import ID from '../Util/ID'
 | 
					import ID from '../Util/ID.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class StateStore {
 | 
					export default class StateStore {
 | 
				
			||||||
  constructor (y) {
 | 
					  constructor (y) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import StructManager from '../Util/StructManager'
 | 
					import StructManager from '../Util/StructManager.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Delete {
 | 
					export default class Delete {
 | 
				
			||||||
  constructor () {
 | 
					  constructor () {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
import StructManager from '../Util/StructManager'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Item {
 | 
					export default class Item {
 | 
				
			||||||
  constructor () {
 | 
					  constructor () {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import Item from './Item'
 | 
					import Item from './Item.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class ItemJSON extends Item {
 | 
					export default class ItemJSON extends Item {
 | 
				
			||||||
  constructor () {
 | 
					  constructor () {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import Item from './Item'
 | 
					import Item from './Item.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class ItemString extends Item {
 | 
					export default class ItemString extends Item {
 | 
				
			||||||
  constructor () {
 | 
					  constructor () {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import Item from './Item'
 | 
					import Item from './Item.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Type extends Item {
 | 
					export default class Type extends Item {
 | 
				
			||||||
  constructor () {
 | 
					  constructor () {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import Type from '../Struct/Type'
 | 
					import Type from '../Struct/Type.js'
 | 
				
			||||||
import ItemJSON from '../Struct/ItemJSON'
 | 
					import ItemJSON from '../Struct/ItemJSON.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class YArray extends Type {
 | 
					export default class YArray extends Type {
 | 
				
			||||||
  forEach (f) {
 | 
					  forEach (f) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import Type from '../Struct/Type'
 | 
					import Type from '../Struct/Type.js'
 | 
				
			||||||
import Item from '../Struct/Item'
 | 
					import Item from '../Struct/Item.js'
 | 
				
			||||||
import ItemJSON from '../Struct/ItemJSON'
 | 
					import ItemJSON from '../Struct/ItemJSON.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class YMap extends Type {
 | 
					export default class YMap extends Type {
 | 
				
			||||||
  set (key, value) {
 | 
					  set (key, value) {
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					import YArray from './YArray.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class YText extends YArray {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					import YArray from './YArray.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class YXml extends YArray {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import StructManager from './StructManager'
 | 
					import { getReference } from './structReferences.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class ID {
 | 
					export default class ID {
 | 
				
			||||||
  constructor (user, clock) {
 | 
					  constructor (user, clock) {
 | 
				
			||||||
    this.user = user
 | 
					    this.user = user
 | 
				
			||||||
    this.clock = clock
 | 
					    this.clock = clock
 | 
				
			||||||
@ -16,17 +16,3 @@ export class ID {
 | 
				
			|||||||
    return this.user < id.user || (this.user === id.user && this.clock < id.clock)
 | 
					    return this.user < id.user || (this.user === id.user && this.clock < id.clock)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
export class RootID {
 | 
					 | 
				
			||||||
  constructor (name, typeConstructor) {
 | 
					 | 
				
			||||||
    this.user = -1
 | 
					 | 
				
			||||||
    this.name = name
 | 
					 | 
				
			||||||
    this.type = StructManager.getReference(typeConstructor)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  equals (id) {
 | 
					 | 
				
			||||||
    return id !== null && id.user === this.user && id.name === this.name && id.type === this.type
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  lessThan (id) {
 | 
					 | 
				
			||||||
    return this.user < id.user || (this.user === id.user && (this.name < id.name || (this.name === id.name && this.type < id.type)))
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								src/Util/RootID.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/Util/RootID.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					export default class RootID {
 | 
				
			||||||
 | 
					  constructor (name, typeConstructor) {
 | 
				
			||||||
 | 
					    this.user = -1
 | 
				
			||||||
 | 
					    this.name = name
 | 
				
			||||||
 | 
					    this.type = StructManager.getReference(typeConstructor)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  equals (id) {
 | 
				
			||||||
 | 
					    return id !== null && id.user === this.user && id.name === this.name && id.type === this.type
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  lessThan (id) {
 | 
				
			||||||
 | 
					    return this.user < id.user || (this.user === id.user && (this.name < id.name || (this.name === id.name && this.type < id.type)))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import Delete from '../Struct/Delete'
 | 
					import Delete from '../Struct/Delete'
 | 
				
			||||||
import ID from './ID'
 | 
					import ID from './ID'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function deleteItemRange (y, user, clock, length) {
 | 
					export function deleteItemRange (y, user, clock, length) {
 | 
				
			||||||
  let del = new Delete()
 | 
					  let del = new Delete()
 | 
				
			||||||
  del._target = new ID(user, clock)
 | 
					  del._target = new ID(user, clock)
 | 
				
			||||||
  del._length = length
 | 
					  del._length = length
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/* global crypto */
 | 
					/* global crypto */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function generateUserID () {
 | 
					export function generateUserID () {
 | 
				
			||||||
  if (typeof crypto !== 'undefined' && crypto.getRandomValue != null) {
 | 
					  if (typeof crypto !== 'undefined' && crypto.getRandomValue != null) {
 | 
				
			||||||
    // browser
 | 
					    // browser
 | 
				
			||||||
    let arr = new Uint32Array(1)
 | 
					    let arr = new Uint32Array(1)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
import YArray from '../Type/YArray'
 | 
					import YArray from '../Type/YArray.js'
 | 
				
			||||||
import YMap from '../Type/YMap'
 | 
					import YMap from '../Type/YMap.js'
 | 
				
			||||||
import YText from '../Type/YText'
 | 
					import YText from '../Type/YText.js'
 | 
				
			||||||
import YXml from '../Type/YXml'
 | 
					import YXml from '../Type/YXml.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ItemJSON from '../Struct/ItemJSON'
 | 
					import ItemJSON from '../Struct/ItemJSON.js'
 | 
				
			||||||
import ItemString from '../Struct/ItemString'
 | 
					import ItemString from '../Struct/ItemString.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const structs = new Map()
 | 
					const structs = new Map()
 | 
				
			||||||
const references = new Map()
 | 
					const references = new Map()
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										35
									
								
								src/Y.js
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/Y.js
									
									
									
									
									
								
							@ -1,20 +1,25 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import debug from 'debug'
 | 
					// import debug from 'debug'
 | 
				
			||||||
 | 
					export function debug (namespace) {
 | 
				
			||||||
 | 
					  return function log (message) {
 | 
				
			||||||
 | 
					    console.log(namespace, message)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import DeleteStore from './Store/DeleteStore'
 | 
					import DeleteStore from './Store/DeleteStore.js'
 | 
				
			||||||
import OperationStore from './Store/OperationStore'
 | 
					import OperationStore from './Store/OperationStore.js'
 | 
				
			||||||
import StateStore from './Store/StateStore'
 | 
					import StateStore from './Store/StateStore.js'
 | 
				
			||||||
import generateUserID from './Function/generateUserID'
 | 
					import { generateUserID } from './Util/generateUserID.js'
 | 
				
			||||||
import { RootID } from './Util/ID.js'
 | 
					import RootID from './Util/RootID.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { formatYjsMessage, formatYjsMessageType } from './MessageHandler'
 | 
					import { messageToString, messageToRoomname } from './MessageHandler/messageToString.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Connector from './Connector'
 | 
					import Connector from './Connector.js'
 | 
				
			||||||
import Persistence from './Persistence'
 | 
					import Persistence from './Persistence.js'
 | 
				
			||||||
import YArray from './Type/YArray'
 | 
					import YArray from './Type/YArray.js'
 | 
				
			||||||
import YMap from './Type/YMap'
 | 
					import YMap from './Type/YMap.js'
 | 
				
			||||||
import YText from './Type/YText'
 | 
					import YText from './Type/YText.js'
 | 
				
			||||||
import YXml from './Type/YXml'
 | 
					import YXml from './Type/YXml.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Y {
 | 
					export default class Y {
 | 
				
			||||||
  constructor (opts) {
 | 
					  constructor (opts) {
 | 
				
			||||||
@ -97,5 +102,5 @@ Y.Text = YText
 | 
				
			|||||||
Y.Xml = YXml
 | 
					Y.Xml = YXml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Y.debug = debug
 | 
					Y.debug = debug
 | 
				
			||||||
debug.formatters.Y = formatYjsMessage
 | 
					debug.formatters.Y = messageToString
 | 
				
			||||||
debug.formatters.y = formatYjsMessageType
 | 
					debug.formatters.y = messageToRoomname
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,9 @@
 | 
				
			|||||||
import { test } from 'cutest'
 | 
					import { test } from '../node_modules/cutest/cutest.js'
 | 
				
			||||||
import Chance from 'chance'
 | 
					import '../node_modules/chance/chance.js'
 | 
				
			||||||
import Y from '../src/y.js'
 | 
					import Y from '../src/y.js'
 | 
				
			||||||
import { BinaryEncoder, BinaryDecoder } from '../src/Encoding.js'
 | 
					import BinaryEncoder from '../src/Binary/Encoder.js'
 | 
				
			||||||
 | 
					import BinaryDecoder from '../src/Binary/Decoder.js'
 | 
				
			||||||
 | 
					import { generateUserID } from '../src/Util/generateUserID.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function testEncoding (t, write, read, val) {
 | 
					function testEncoding (t, write, read, val) {
 | 
				
			||||||
  let encoder = new BinaryEncoder()
 | 
					  let encoder = new BinaryEncoder()
 | 
				
			||||||
@ -42,7 +44,7 @@ test('varUint random', async function varUintRandom (t) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
test('varUint random user id', async function varUintRandomUserId (t) {
 | 
					test('varUint random user id', async function varUintRandomUserId (t) {
 | 
				
			||||||
  t.getSeed() // enforces that this test is repeated
 | 
					  t.getSeed() // enforces that this test is repeated
 | 
				
			||||||
  testEncoding(t, writeVarUint, readVarUint, Y.utils.generateUserId())
 | 
					  testEncoding(t, writeVarUint, readVarUint, generateUserID())
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const writeVarString = (encoder, val) => encoder.writeVarString(val)
 | 
					const writeVarString = (encoder, val) => encoder.writeVarString(val)
 | 
				
			||||||
@ -59,122 +61,3 @@ test('varString random', async function varStringRandom (t) {
 | 
				
			|||||||
  const chance = new Chance(t.getSeed() * 1000000000)
 | 
					  const chance = new Chance(t.getSeed() * 1000000000)
 | 
				
			||||||
  testEncoding(t, writeVarString, readVarString, chance.string())
 | 
					  testEncoding(t, writeVarString, readVarString, chance.string())
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					 | 
				
			||||||
const writeDelete = Y.Struct.Delete.binaryEncode
 | 
					 | 
				
			||||||
const readDelete = Y.Struct.Delete.binaryDecode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test('encode/decode Delete operation', async function binDelete (t) {
 | 
					 | 
				
			||||||
  let op = {
 | 
					 | 
				
			||||||
    target: [10, 3000],
 | 
					 | 
				
			||||||
    length: 40000,
 | 
					 | 
				
			||||||
    struct: 'Delete'
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  testEncoding(t, writeDelete, readDelete, op)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const writeInsert = Y.Struct.Insert.binaryEncode
 | 
					 | 
				
			||||||
const readInsert = Y.Struct.Insert.binaryDecode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test('encode/decode Insert operations', async function binInsert (t) {
 | 
					 | 
				
			||||||
  testEncoding(t, writeInsert, readInsert, {
 | 
					 | 
				
			||||||
    id: [1, 2],
 | 
					 | 
				
			||||||
    right: [5, 6],
 | 
					 | 
				
			||||||
    left: [3, 4],
 | 
					 | 
				
			||||||
    origin: [7, 8],
 | 
					 | 
				
			||||||
    parent: [9, 10],
 | 
					 | 
				
			||||||
    struct: 'Insert',
 | 
					 | 
				
			||||||
    content: ['a']
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  t.log('left === origin')
 | 
					 | 
				
			||||||
  testEncoding(t, writeInsert, readInsert, {
 | 
					 | 
				
			||||||
    id: [1, 2],
 | 
					 | 
				
			||||||
    right: [5, 6],
 | 
					 | 
				
			||||||
    left: [3, 4],
 | 
					 | 
				
			||||||
    origin: [3, 4],
 | 
					 | 
				
			||||||
    parent: [9, 10],
 | 
					 | 
				
			||||||
    struct: 'Insert',
 | 
					 | 
				
			||||||
    content: ['a']
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  t.log('parentsub')
 | 
					 | 
				
			||||||
  testEncoding(t, writeInsert, readInsert, {
 | 
					 | 
				
			||||||
    id: [1, 2],
 | 
					 | 
				
			||||||
    right: [5, 6],
 | 
					 | 
				
			||||||
    left: [3, 4],
 | 
					 | 
				
			||||||
    origin: [3, 4],
 | 
					 | 
				
			||||||
    parent: [9, 10],
 | 
					 | 
				
			||||||
    parentSub: 'sub',
 | 
					 | 
				
			||||||
    struct: 'Insert',
 | 
					 | 
				
			||||||
    content: ['a']
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  t.log('opContent')
 | 
					 | 
				
			||||||
  testEncoding(t, writeInsert, readInsert, {
 | 
					 | 
				
			||||||
    id: [1, 2],
 | 
					 | 
				
			||||||
    right: [5, 6],
 | 
					 | 
				
			||||||
    left: [3, 4],
 | 
					 | 
				
			||||||
    origin: [3, 4],
 | 
					 | 
				
			||||||
    parent: [9, 10],
 | 
					 | 
				
			||||||
    struct: 'Insert',
 | 
					 | 
				
			||||||
    opContent: [1000, 10000]
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  t.log('mixed content')
 | 
					 | 
				
			||||||
  testEncoding(t, writeInsert, readInsert, {
 | 
					 | 
				
			||||||
    id: [1, 2],
 | 
					 | 
				
			||||||
    right: [5, 6],
 | 
					 | 
				
			||||||
    left: [3, 4],
 | 
					 | 
				
			||||||
    origin: [3, 4],
 | 
					 | 
				
			||||||
    parent: [9, 10],
 | 
					 | 
				
			||||||
    struct: 'Insert',
 | 
					 | 
				
			||||||
    content: ['a', 1]
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  t.log('origin is null')
 | 
					 | 
				
			||||||
  testEncoding(t, writeInsert, readInsert, {
 | 
					 | 
				
			||||||
    id: [1, 2],
 | 
					 | 
				
			||||||
    right: [5, 6],
 | 
					 | 
				
			||||||
    left: [3, 4],
 | 
					 | 
				
			||||||
    origin: null,
 | 
					 | 
				
			||||||
    parent: [9, 10],
 | 
					 | 
				
			||||||
    struct: 'Insert',
 | 
					 | 
				
			||||||
    content: ['a']
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  t.log('left = origin = right = null')
 | 
					 | 
				
			||||||
  testEncoding(t, writeInsert, readInsert, {
 | 
					 | 
				
			||||||
    id: [1, 2],
 | 
					 | 
				
			||||||
    right: null,
 | 
					 | 
				
			||||||
    left: null,
 | 
					 | 
				
			||||||
    origin: null,
 | 
					 | 
				
			||||||
    parent: [9, 10],
 | 
					 | 
				
			||||||
    struct: 'Insert',
 | 
					 | 
				
			||||||
    content: ['a']
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const writeList = Y.Struct.List.binaryEncode
 | 
					 | 
				
			||||||
const readList = Y.Struct.List.binaryDecode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test('encode/decode List operations', async function binList (t) {
 | 
					 | 
				
			||||||
  testEncoding(t, writeList, readList, {
 | 
					 | 
				
			||||||
    struct: 'List',
 | 
					 | 
				
			||||||
    id: [100, 33],
 | 
					 | 
				
			||||||
    type: 'Array',
 | 
					 | 
				
			||||||
    start: null,
 | 
					 | 
				
			||||||
    end: null
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const writeMap = Y.Struct.Map.binaryEncode
 | 
					 | 
				
			||||||
const readMap = Y.Struct.Map.binaryDecode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test('encode/decode Map operations', async function binMap (t) {
 | 
					 | 
				
			||||||
  testEncoding(t, writeMap, readMap, {
 | 
					 | 
				
			||||||
    struct: 'Map',
 | 
					 | 
				
			||||||
    id: [100, 33],
 | 
					 | 
				
			||||||
    type: 'Map',
 | 
					 | 
				
			||||||
    map: {}
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								test/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								test/index.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					  <head>
 | 
				
			||||||
 | 
					  </head>
 | 
				
			||||||
 | 
					  <body>
 | 
				
			||||||
 | 
					    <script type="module" src="./encode-decode.js"></script>
 | 
				
			||||||
 | 
					  </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { wait, initArrays, compareUsers, Y, flushAll, garbageCollectUsers, applyRandomTests } from '../tests-lib/helper.js'
 | 
					import { wait, initArrays, compareUsers, Y, flushAll, applyRandomTests } from '../tests-lib/helper.js'
 | 
				
			||||||
import { test, proxyConsole } from 'cutest'
 | 
					import { test, proxyConsole } from 'cutest'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
proxyConsole()
 | 
					proxyConsole()
 | 
				
			||||||
@ -38,7 +38,6 @@ test('concurrent insert (handle three conflicts)', async function array2 (t) {
 | 
				
			|||||||
  array0.insert(0, [0])
 | 
					  array0.insert(0, [0])
 | 
				
			||||||
  array1.insert(0, [1])
 | 
					  array1.insert(0, [1])
 | 
				
			||||||
  array2.insert(0, [2])
 | 
					  array2.insert(0, [2])
 | 
				
			||||||
 | 
					 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -213,7 +212,6 @@ test('garbage collector', async function gc1 (t) {
 | 
				
			|||||||
  await wait()
 | 
					  await wait()
 | 
				
			||||||
  await users[0].reconnect()
 | 
					  await users[0].reconnect()
 | 
				
			||||||
  await flushAll(t, users)
 | 
					  await flushAll(t, users)
 | 
				
			||||||
  await garbageCollectUsers(t, users)
 | 
					 | 
				
			||||||
  await compareUsers(t, users)
 | 
					  await compareUsers(t, users)
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,34 +1,25 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import _Y from '../../yjs/src/y.js'
 | 
					import _Y from '../../yjs/src/y.js'
 | 
				
			||||||
 | 
					 | 
				
			||||||
import yArray from '../../y-array/src/y-array.js'
 | 
					 | 
				
			||||||
import yText from '../../y-text/src/y-text.js'
 | 
					 | 
				
			||||||
import yMap from '../../y-map/src/y-map.js'
 | 
					 | 
				
			||||||
import yXml from '../../y-xml/src/y-xml.js'
 | 
					 | 
				
			||||||
import yTest from './test-connector.js'
 | 
					import yTest from './test-connector.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Chance from 'chance'
 | 
					import Chance from 'chance'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export let Y = _Y
 | 
					export let Y = _Y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Y.extend(yArray, yText, yMap, yTest, yXml)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export var database = { name: 'memory' }
 | 
					export var database = { name: 'memory' }
 | 
				
			||||||
export var connector = { name: 'test', url: 'http://localhost:1234' }
 | 
					export var connector = { name: 'test', url: 'http://localhost:1234' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getStateSet () {
 | 
					function getStateSet (y) {
 | 
				
			||||||
  var ss = {}
 | 
					  let ss = {}
 | 
				
			||||||
  this.ss.iterate(this, null, null, function (n) {
 | 
					  for (let [user, clock] of y.ss.state) {
 | 
				
			||||||
    var user = n.id[0]
 | 
					 | 
				
			||||||
    var clock = n.clock
 | 
					 | 
				
			||||||
    ss[user] = clock
 | 
					    ss[user] = clock
 | 
				
			||||||
  })
 | 
					  }
 | 
				
			||||||
  return ss
 | 
					  return ss
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getDeleteSet () {
 | 
					function getDeleteSet (y) {
 | 
				
			||||||
  var ds = {}
 | 
					  var ds = {}
 | 
				
			||||||
  this.ds.iterate(this, null, null, function (n) {
 | 
					  y.ds.iterate(this, null, null, function (n) {
 | 
				
			||||||
    var user = n.id[0]
 | 
					    var user = n.id[0]
 | 
				
			||||||
    var counter = n.id[1]
 | 
					    var counter = n.id[1]
 | 
				
			||||||
    var len = n.len
 | 
					    var len = n.len
 | 
				
			||||||
@ -43,11 +34,6 @@ function getDeleteSet () {
 | 
				
			|||||||
  return ds
 | 
					  return ds
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function garbageCollectUsers (t, users) {
 | 
					 | 
				
			||||||
  await flushAll(t, users)
 | 
					 | 
				
			||||||
  await Promise.all(users.map(u => u.db.emptyGarbageCollector()))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function attrsObject (dom) {
 | 
					export function attrsObject (dom) {
 | 
				
			||||||
  let keys = []
 | 
					  let keys = []
 | 
				
			||||||
  let yxml = dom.__yxml
 | 
					  let yxml = dom.__yxml
 | 
				
			||||||
@ -67,7 +53,7 @@ export function domToJson (dom) {
 | 
				
			|||||||
  if (dom.nodeType === document.TEXT_NODE) {
 | 
					  if (dom.nodeType === document.TEXT_NODE) {
 | 
				
			||||||
    return dom.textContent
 | 
					    return dom.textContent
 | 
				
			||||||
  } else if (dom.nodeType === document.ELEMENT_NODE) {
 | 
					  } else if (dom.nodeType === document.ELEMENT_NODE) {
 | 
				
			||||||
    let attributes = attrsObject(dom, dom.__yxml)
 | 
					    let attributes = attrsObject(dom)
 | 
				
			||||||
    let children = Array.from(dom.childNodes.values())
 | 
					    let children = Array.from(dom.childNodes.values())
 | 
				
			||||||
      .filter(d => d.__yxml !== false)
 | 
					      .filter(d => d.__yxml !== false)
 | 
				
			||||||
      .map(domToJson)
 | 
					      .map(domToJson)
 | 
				
			||||||
@ -97,20 +83,9 @@ export async function compareUsers (t, users) {
 | 
				
			|||||||
  await wait()
 | 
					  await wait()
 | 
				
			||||||
  await flushAll(t, users)
 | 
					  await flushAll(t, users)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var userArrayValues = users.map(u => u.share.array._content.map(c => c.val || JSON.stringify(c.type)))
 | 
					  var userArrayValues = users.map(u => u.get('array', Y.Array).toJSON())
 | 
				
			||||||
  function valueToComparable (v) {
 | 
					  var userMapValues = users.map(u => u.get('map', Y.Map).toJSON())
 | 
				
			||||||
    if (v != null && v._model != null) {
 | 
					  var userXmlValues = users.map(u => u.get('xml', Y.Xml).getDom().toString())
 | 
				
			||||||
      return v._model
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return v || null
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  var userMapOneValues = users.map(u => u.share.map.get('one')).map(valueToComparable)
 | 
					 | 
				
			||||||
  var userMapTwoValues = users.map(u => u.share.map.get('two')).map(valueToComparable)
 | 
					 | 
				
			||||||
  var userXmlValues = users.map(u => u.share.xml.getDom()).map(domToJson)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await users[0].db.garbageCollect()
 | 
					 | 
				
			||||||
  await users[0].db.garbageCollect()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // disconnect all except user 0
 | 
					  // disconnect all except user 0
 | 
				
			||||||
  await Promise.all(users.slice(1).map(async u =>
 | 
					  await Promise.all(users.slice(1).map(async u =>
 | 
				
			||||||
@ -130,13 +105,17 @@ export async function compareUsers (t, users) {
 | 
				
			|||||||
      u.connector.whenSynced(resolve)
 | 
					      u.connector.whenSynced(resolve)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  ))
 | 
					  ))
 | 
				
			||||||
  let filterDeletedOps = users.every(u => u.db.gc === false)
 | 
					  var data = users.forEach(u => {
 | 
				
			||||||
  var data = await Promise.all(users.map(async (u) => {
 | 
					 | 
				
			||||||
    var data = {}
 | 
					    var data = {}
 | 
				
			||||||
    u.db.requestTransaction(function () {
 | 
					 | 
				
			||||||
    let ops = []
 | 
					    let ops = []
 | 
				
			||||||
      this.os.iterate(this, null, null, function (op) {
 | 
					    y.os.iterate(null, null, function (op) {
 | 
				
			||||||
        ops.push(Y.Struct[op.struct].encode(op))
 | 
					      if (!op._deleted) {
 | 
				
			||||||
 | 
					        ops.push({
 | 
				
			||||||
 | 
					          left: op._left,
 | 
				
			||||||
 | 
					          right: op._right,
 | 
				
			||||||
 | 
					          deleted: op._deleted
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data.os = {}
 | 
					    data.os = {}
 | 
				
			||||||
@ -144,25 +123,12 @@ export async function compareUsers (t, users) {
 | 
				
			|||||||
      let op = ops[i]
 | 
					      let op = ops[i]
 | 
				
			||||||
      op = Y.Struct[op.struct].encode(op)
 | 
					      op = Y.Struct[op.struct].encode(op)
 | 
				
			||||||
      delete op.origin
 | 
					      delete op.origin
 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
          If gc = false, it is necessary to filter deleted ops
 | 
					 | 
				
			||||||
          as they might have been split up differently..
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if (filterDeletedOps) {
 | 
					 | 
				
			||||||
          let opIsDeleted = this.isDeleted(op.id)
 | 
					 | 
				
			||||||
          if (!opIsDeleted) {
 | 
					 | 
				
			||||||
      data.os[JSON.stringify(op.id)] = op
 | 
					      data.os[JSON.stringify(op.id)] = op
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          data.os[JSON.stringify(op.id)] = op
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    data.ds = getDeleteSet.apply(this)
 | 
					    data.ds = getDeleteSet.apply(this)
 | 
				
			||||||
    data.ss = getStateSet.apply(this)
 | 
					    data.ss = getStateSet.apply(this)
 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    await u.db.whenTransactionsFinished()
 | 
					 | 
				
			||||||
    return data
 | 
					    return data
 | 
				
			||||||
  }))
 | 
					  })
 | 
				
			||||||
  for (var i = 0; i < data.length - 1; i++) {
 | 
					  for (var i = 0; i < data.length - 1; i++) {
 | 
				
			||||||
    await t.asyncGroup(async () => {
 | 
					    await t.asyncGroup(async () => {
 | 
				
			||||||
      t.compare(userArrayValues[i], userArrayValues[i + 1], 'array types')
 | 
					      t.compare(userArrayValues[i], userArrayValues[i + 1], 'array types')
 | 
				
			||||||
@ -174,39 +140,27 @@ export async function compareUsers (t, users) {
 | 
				
			|||||||
      t.compare(data[i].ss, data[i + 1].ss, 'ss')
 | 
					      t.compare(data[i].ss, data[i + 1].ss, 'ss')
 | 
				
			||||||
    }, `Compare user${i} with user${i + 1}`)
 | 
					    }, `Compare user${i} with user${i + 1}`)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  await Promise.all(users.map(async (u) => {
 | 
					  users.map(u => u.close())
 | 
				
			||||||
    await u.close()
 | 
					 | 
				
			||||||
  }))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function initArrays (t, opts) {
 | 
					export async function initArrays (t, opts) {
 | 
				
			||||||
  var result = {
 | 
					  var result = {
 | 
				
			||||||
    users: []
 | 
					    users: []
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  var share = Object.assign({ flushHelper: 'Map', array: 'Array', map: 'Map', xml: 'XmlElement("div")' }, opts.share)
 | 
					 | 
				
			||||||
  var chance = opts.chance || new Chance(t.getSeed() * 1000000000)
 | 
					  var chance = opts.chance || new Chance(t.getSeed() * 1000000000)
 | 
				
			||||||
  var conn = Object.assign({ room: 'debugging_' + t.name, generateUserId: false, testContext: t, chance }, connector)
 | 
					  var conn = Object.assign({ room: 'debugging_' + t.name, generateUserId: false, testContext: t, chance }, connector)
 | 
				
			||||||
  for (let i = 0; i < opts.users; i++) {
 | 
					  for (let i = 0; i < opts.users; i++) {
 | 
				
			||||||
    let dbOpts
 | 
					 | 
				
			||||||
    let connOpts
 | 
					    let connOpts
 | 
				
			||||||
    if (i === 0) {
 | 
					    if (i === 0) {
 | 
				
			||||||
      // Only one instance can gc!
 | 
					 | 
				
			||||||
      dbOpts = Object.assign({ gc: false }, database)
 | 
					 | 
				
			||||||
      connOpts = Object.assign({ role: 'master' }, conn)
 | 
					      connOpts = Object.assign({ role: 'master' }, conn)
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      dbOpts = Object.assign({ gc: false }, database)
 | 
					 | 
				
			||||||
      connOpts = Object.assign({ role: 'slave' }, conn)
 | 
					      connOpts = Object.assign({ role: 'slave' }, conn)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let y = await Y({
 | 
					    let y = new Y({
 | 
				
			||||||
      connector: connOpts,
 | 
					      connector: connOpts
 | 
				
			||||||
      db: dbOpts,
 | 
					 | 
				
			||||||
      share: share
 | 
					 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    result.users.push(y)
 | 
					    result.users.push(y)
 | 
				
			||||||
    for (let name in share) {
 | 
					    y.get('xml', Y.Xml).setDomFilter(function (d, attrs) {
 | 
				
			||||||
      result[name + i] = y.share[name]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    y.share.xml.setDomFilter(function (d, attrs) {
 | 
					 | 
				
			||||||
      if (d.nodeName === 'HIDDEN') {
 | 
					      if (d.nodeName === 'HIDDEN') {
 | 
				
			||||||
        return null
 | 
					        return null
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
@ -241,7 +195,7 @@ export async function flushAll (t, users) {
 | 
				
			|||||||
    // flush for any connector
 | 
					    // flush for any connector
 | 
				
			||||||
    await Promise.all(users.map(u => { return u.db.whenTransactionsFinished() }))
 | 
					    await Promise.all(users.map(u => { return u.db.whenTransactionsFinished() }))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var flushCounter = users[0].share.flushHelper.get('0') || 0
 | 
					    var flushCounter = users[0].get('flushHelper', Y.Map).get('0') || 0
 | 
				
			||||||
    flushCounter++
 | 
					    flushCounter++
 | 
				
			||||||
    await Promise.all(users.map(async (u, i) => {
 | 
					    await Promise.all(users.map(async (u, i) => {
 | 
				
			||||||
      // wait for all users to set the flush counter to the same value
 | 
					      // wait for all users to set the flush counter to the same value
 | 
				
			||||||
@ -249,7 +203,7 @@ export async function flushAll (t, users) {
 | 
				
			|||||||
        function observer () {
 | 
					        function observer () {
 | 
				
			||||||
          var allUsersReceivedUpdate = true
 | 
					          var allUsersReceivedUpdate = true
 | 
				
			||||||
          for (var i = 0; i < users.length; i++) {
 | 
					          for (var i = 0; i < users.length; i++) {
 | 
				
			||||||
            if (u.share.flushHelper.get(i + '') !== flushCounter) {
 | 
					            if (u.get('flushHelper', Y.Map).get(i + '') !== flushCounter) {
 | 
				
			||||||
              allUsersReceivedUpdate = false
 | 
					              allUsersReceivedUpdate = false
 | 
				
			||||||
              break
 | 
					              break
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -258,8 +212,8 @@ export async function flushAll (t, users) {
 | 
				
			|||||||
            resolve()
 | 
					            resolve()
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        u.share.flushHelper.observe(observer)
 | 
					        u.get('flushHelper', Y.Map).observe(observer)
 | 
				
			||||||
        u.share.flushHelper.set(i + '', flushCounter)
 | 
					        u.get('flushHelper').set(i + '', flushCounter)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    }))
 | 
					    }))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/* global Y */
 | 
					/* global Y */
 | 
				
			||||||
import { wait } from './helper.js'
 | 
					import { wait } from './helper'
 | 
				
			||||||
import { formatYjsMessage } from '../src/MessageHandler.js'
 | 
					import { messageToString, messageToRoomname } from '../src/MessageHandler/messageToString'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var rooms = {}
 | 
					var rooms = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user