cleanup docs
This commit is contained in:
		
							parent
							
								
									026675b438
								
							
						
					
					
						commit
						6dd43cde17
					
				@ -2,7 +2,7 @@
 | 
				
			|||||||
import { createMutualExclude } from '../Util/mutualExclude.js'
 | 
					import { createMutualExclude } from '../Util/mutualExclude.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Abstract class for bindings
 | 
					 * Abstract class for bindings.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * A binding handles data binding from a Yjs type to a data object. For example,
 | 
					 * A binding handles data binding from a Yjs type to a data object. For example,
 | 
				
			||||||
 * you can bind a Quill editor instance to a YText instance with the `QuillBinding` class.
 | 
					 * you can bind a Quill editor instance to a YText instance with the `QuillBinding` class.
 | 
				
			||||||
@ -18,16 +18,27 @@ import { createMutualExclude } from '../Util/mutualExclude.js'
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export default class Binding {
 | 
					export default class Binding {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @param {YType} type Yjs type
 | 
					   * @param {YType} type Yjs type.
 | 
				
			||||||
   * @param {any} target Binding Target
 | 
					   * @param {any} target Binding Target.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  constructor (type, target) {
 | 
					  constructor (type, target) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The Yjs type that is bound to `target`
 | 
				
			||||||
 | 
					     * @type {YType}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.type = type
 | 
					    this.type = type
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The target that `type` is bound to.
 | 
				
			||||||
 | 
					     * @type {*}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.target = target
 | 
					    this.target = target
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @private
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this._mutualExclude = createMutualExclude()
 | 
					    this._mutualExclude = createMutualExclude()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Remove all data observers (both from the type and th target).
 | 
					   * Remove all data observers (both from the type and the target).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  destroy () {
 | 
					  destroy () {
 | 
				
			||||||
    this.type = null
 | 
					    this.type = null
 | 
				
			||||||
 | 
				
			|||||||
@ -17,9 +17,9 @@ import { removeAssociation } from './util.js'
 | 
				
			|||||||
 * This binding is automatically destroyed when its parent is deleted.
 | 
					 * This binding is automatically destroyed when its parent is deleted.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @example
 | 
					 * @example
 | 
				
			||||||
 *   const div = document.createElement('div')
 | 
					 * const div = document.createElement('div')
 | 
				
			||||||
 *   const type = y.define('xml', Y.XmlFragment)
 | 
					 * const type = y.define('xml', Y.XmlFragment)
 | 
				
			||||||
 *   const binding = new Y.QuillBinding(type, div)
 | 
					 * const binding = new Y.QuillBinding(type, div)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export default class DomBinding extends Binding {
 | 
					export default class DomBinding extends Binding {
 | 
				
			||||||
@ -27,12 +27,28 @@ export default class DomBinding extends Binding {
 | 
				
			|||||||
   * @param {YXmlFragment} type The bind source. This is the ultimate source of
 | 
					   * @param {YXmlFragment} type The bind source. This is the ultimate source of
 | 
				
			||||||
   *                            truth.
 | 
					   *                            truth.
 | 
				
			||||||
   * @param {Element} target The bind target. Mirrors the target.
 | 
					   * @param {Element} target The bind target. Mirrors the target.
 | 
				
			||||||
 | 
					   * @param {Object} [opts] Optional configurations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   * @param {FilterFunction} [opts.filter=defaultFilter] The filter function to use.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  constructor (type, target, opts = {}) {
 | 
					  constructor (type, target, opts = {}) {
 | 
				
			||||||
    // Binding handles textType as this.type and domTextarea as this.target
 | 
					    // Binding handles textType as this.type and domTextarea as this.target
 | 
				
			||||||
    super(type, target)
 | 
					    super(type, target)
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Maps each DOM element to the type that it is associated with.
 | 
				
			||||||
 | 
					     * @type {Map}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.domToType = new Map()
 | 
					    this.domToType = new Map()
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Maps each YXml type to the DOM element that it is associated with.
 | 
				
			||||||
 | 
					     * @type {Map}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.typeToDom = new Map()
 | 
					    this.typeToDom = new Map()
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Defines which DOM attributes and elements to filter out.
 | 
				
			||||||
 | 
					     * Also filters remote changes.
 | 
				
			||||||
 | 
					     * @type {FilterFunction}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.filter = opts.filter || defaultFilter
 | 
					    this.filter = opts.filter || defaultFilter
 | 
				
			||||||
    // set initial value
 | 
					    // set initial value
 | 
				
			||||||
    target.innerHTML = ''
 | 
					    target.innerHTML = ''
 | 
				
			||||||
@ -103,6 +119,7 @@ export default class DomBinding extends Binding {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * NOTE: currently does not apply filter to existing elements!
 | 
					   * NOTE: currently does not apply filter to existing elements!
 | 
				
			||||||
 | 
					   * @param {FilterFunction} filter The filter function to use from now on.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  setFilter (filter) {
 | 
					  setFilter (filter) {
 | 
				
			||||||
    this.filter = filter
 | 
					    this.filter = filter
 | 
				
			||||||
@ -110,7 +127,7 @@ export default class DomBinding extends Binding {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Remove all properties that are handled by this class
 | 
					   * Remove all properties that are handled by this class.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  destroy () {
 | 
					  destroy () {
 | 
				
			||||||
    this.domToType = null
 | 
					    this.domToType = null
 | 
				
			||||||
@ -125,3 +142,11 @@ export default class DomBinding extends Binding {
 | 
				
			|||||||
    super.destroy()
 | 
					    super.destroy()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * A filter defines which elements and attributes to share.
 | 
				
			||||||
 | 
					   * Return null if the node should be filtered. Otherwise return the Map of
 | 
				
			||||||
 | 
					   * accepted attributes.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @typedef {function(nodeName: String, attrs: Map): Map|null} FilterFunction
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ import {
 | 
				
			|||||||
import diff from '../../Util/simpleDiff.js'
 | 
					import diff from '../../Util/simpleDiff.js'
 | 
				
			||||||
import YXmlFragment from '../../Types/YXml/YXmlFragment.js'
 | 
					import YXmlFragment from '../../Types/YXml/YXmlFragment.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/**
 | 
				
			||||||
 * 1. Check if any of the nodes was deleted
 | 
					 * 1. Check if any of the nodes was deleted
 | 
				
			||||||
 * 2. Iterate over the children.
 | 
					 * 2. Iterate over the children.
 | 
				
			||||||
 *    2.1 If a node exists that is not yet bound to a type, insert a new node
 | 
					 *    2.1 If a node exists that is not yet bound to a type, insert a new node
 | 
				
			||||||
@ -17,6 +17,7 @@ import YXmlFragment from '../../Types/YXml/YXmlFragment.js'
 | 
				
			|||||||
 *       recreate a new yxml element that is bound to that node.
 | 
					 *       recreate a new yxml element that is bound to that node.
 | 
				
			||||||
 *       You can detect that a node was moved because expectedId
 | 
					 *       You can detect that a node was moved because expectedId
 | 
				
			||||||
 *       !== actualId in the list
 | 
					 *       !== actualId in the list
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function applyChangesFromDom (binding, dom, yxml, _document) {
 | 
					function applyChangesFromDom (binding, dom, yxml, _document) {
 | 
				
			||||||
  if (yxml == null || yxml === false || yxml.constructor === YXmlHook) {
 | 
					  if (yxml == null || yxml === false || yxml.constructor === YXmlHook) {
 | 
				
			||||||
@ -79,6 +80,9 @@ function applyChangesFromDom (binding, dom, yxml, _document) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export default function domObserver (mutations, _document) {
 | 
					export default function domObserver (mutations, _document) {
 | 
				
			||||||
  this._mutualExclude(() => {
 | 
					  this._mutualExclude(() => {
 | 
				
			||||||
    this.type._y.transact(() => {
 | 
					    this.type._y.transact(() => {
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,11 @@ import { createAssociation } from './util.js'
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Creates a Yjs type (YXml) based on the contents of a DOM Element.
 | 
					 * Creates a Yjs type (YXml) based on the contents of a DOM Element.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param {Element|TextNode}
 | 
					 * @param {Element|TextNode} element The DOM Element
 | 
				
			||||||
 | 
					 * @param {?Document} _document Optional. Provide the global document object.
 | 
				
			||||||
 | 
					 * @param {?DomBinding} binding This property should only be set if the type
 | 
				
			||||||
 | 
					 *                              is going to be bound with the dom-binding.
 | 
				
			||||||
 | 
					 * @return {YXmlElement | YXmlText}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export default function domToType (element, _document = document, binding) {
 | 
					export default function domToType (element, _document = document, binding) {
 | 
				
			||||||
  let type
 | 
					  let type
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,27 @@
 | 
				
			|||||||
import isParentOf from '../../Util/isParentOf.js'
 | 
					import isParentOf from '../../Util/isParentOf.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Default filter method (does nothing).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param {String} nodeName The nodeName of the element
 | 
				
			||||||
 | 
					 * @param {Map} attrs Map of key-value pairs that are attributes of the node.
 | 
				
			||||||
 | 
					 * @return {Map | null} The allowed attributes or null, if the element should be
 | 
				
			||||||
 | 
					 *                      filtered.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function defaultFilter (nodeName, attrs) {
 | 
					export function defaultFilter (nodeName, attrs) {
 | 
				
			||||||
 | 
					  // TODO: implement basic filter that filters out dangerous properties!
 | 
				
			||||||
  return attrs
 | 
					  return attrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Applies a filter on a type.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param {Y} y The Yjs instance.
 | 
				
			||||||
 | 
					 * @param {DomBinding} binding The DOM binding instance that has the dom filter.
 | 
				
			||||||
 | 
					 * @param {YXmlElement | YXmlFragment } type The type to apply the filter to.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function applyFilterOnType (y, binding, type) {
 | 
					export function applyFilterOnType (y, binding, type) {
 | 
				
			||||||
  if (isParentOf(binding.type, type)) {
 | 
					  if (isParentOf(binding.type, type)) {
 | 
				
			||||||
    const nodeName = type.nodeName
 | 
					    const nodeName = type.nodeName
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,9 @@ import { getRelativePosition, fromRelativePosition } from '../../Util/relativePo
 | 
				
			|||||||
let browserSelection = null
 | 
					let browserSelection = null
 | 
				
			||||||
let relativeSelection = null
 | 
					let relativeSelection = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export let beforeTransactionSelectionFixer
 | 
					export let beforeTransactionSelectionFixer
 | 
				
			||||||
if (typeof getSelection !== 'undefined') {
 | 
					if (typeof getSelection !== 'undefined') {
 | 
				
			||||||
  beforeTransactionSelectionFixer = function _beforeTransactionSelectionFixer (y, domBinding, transaction, remote) {
 | 
					  beforeTransactionSelectionFixer = function _beforeTransactionSelectionFixer (y, domBinding, transaction, remote) {
 | 
				
			||||||
@ -30,6 +33,9 @@ if (typeof getSelection !== 'undefined') {
 | 
				
			|||||||
  beforeTransactionSelectionFixer = function _fakeBeforeTransactionSelectionFixer () {}
 | 
					  beforeTransactionSelectionFixer = function _fakeBeforeTransactionSelectionFixer () {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function afterTransactionSelectionFixer (y, domBinding, transaction, remote) {
 | 
					export function afterTransactionSelectionFixer (y, domBinding, transaction, remote) {
 | 
				
			||||||
  if (relativeSelection === null || !remote) {
 | 
					  if (relativeSelection === null || !remote) {
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,9 @@ import YXmlText from '../../Types/YXml/YXmlText.js'
 | 
				
			|||||||
import YXmlHook from '../../Types/YXml/YXmlHook.js'
 | 
					import YXmlHook from '../../Types/YXml/YXmlHook.js'
 | 
				
			||||||
import { removeDomChildrenUntilElementFound } from './util.js'
 | 
					import { removeDomChildrenUntilElementFound } from './util.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export default function typeObserver (events, _document) {
 | 
					export default function typeObserver (events, _document) {
 | 
				
			||||||
  this._mutualExclude(() => {
 | 
					  this._mutualExclude(() => {
 | 
				
			||||||
    events.forEach(event => {
 | 
					    events.forEach(event => {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import domToType from './domToType.js'
 | 
					import domToType from './domToType.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Iterates items until an undeleted item is found.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function iterateUntilUndeleted (item) {
 | 
					export function iterateUntilUndeleted (item) {
 | 
				
			||||||
  while (item !== null && item._deleted) {
 | 
					  while (item !== null && item._deleted) {
 | 
				
			||||||
    item = item._right
 | 
					    item = item._right
 | 
				
			||||||
@ -8,11 +13,23 @@ export function iterateUntilUndeleted (item) {
 | 
				
			|||||||
  return item
 | 
					  return item
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Removes an association (the information that a DOM element belongs to a
 | 
				
			||||||
 | 
					 * type).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function removeAssociation (domBinding, dom, type) {
 | 
					export function removeAssociation (domBinding, dom, type) {
 | 
				
			||||||
  domBinding.domToType.delete(dom)
 | 
					  domBinding.domToType.delete(dom)
 | 
				
			||||||
  domBinding.typeToDom.delete(type)
 | 
					  domBinding.typeToDom.delete(type)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Creates an association (the information that a DOM element belongs to a
 | 
				
			||||||
 | 
					 * type).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function createAssociation (domBinding, dom, type) {
 | 
					export function createAssociation (domBinding, dom, type) {
 | 
				
			||||||
  if (domBinding !== undefined) {
 | 
					  if (domBinding !== undefined) {
 | 
				
			||||||
    domBinding.domToType.set(dom, type)
 | 
					    domBinding.domToType.set(dom, type)
 | 
				
			||||||
@ -31,12 +48,18 @@ export function createAssociation (domBinding, dom, type) {
 | 
				
			|||||||
 *                           the beginning.
 | 
					 *                           the beginning.
 | 
				
			||||||
 * @param {Array<Element>} doms The Dom elements to insert.
 | 
					 * @param {Array<Element>} doms The Dom elements to insert.
 | 
				
			||||||
 * @param {?Document} _document Optional. Provide the global document object.
 | 
					 * @param {?Document} _document Optional. Provide the global document object.
 | 
				
			||||||
 | 
					 * @param {DomBinding} binding The dom binding
 | 
				
			||||||
 * @return {Array<YXmlElement>} The YxmlElements that are inserted.
 | 
					 * @return {Array<YXmlElement>} The YxmlElements that are inserted.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function insertDomElementsAfter (type, prev, doms, _document, binding) {
 | 
					export function insertDomElementsAfter (type, prev, doms, _document, binding) {
 | 
				
			||||||
  return type.insertAfter(prev, doms.map(dom => domToType(dom, _document, binding)))
 | 
					  return type.insertAfter(prev, doms.map(dom => domToType(dom, _document, binding)))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function insertNodeHelper (yxml, prevExpectedNode, child, _document, binding) {
 | 
					export function insertNodeHelper (yxml, prevExpectedNode, child, _document, binding) {
 | 
				
			||||||
  let insertedNodes = insertDomElementsAfter(yxml, prevExpectedNode, [child], _document, binding)
 | 
					  let insertedNodes = insertDomElementsAfter(yxml, prevExpectedNode, [child], _document, binding)
 | 
				
			||||||
  if (insertedNodes.length > 0) {
 | 
					  if (insertedNodes.length > 0) {
 | 
				
			||||||
@ -54,6 +77,8 @@ export function insertNodeHelper (yxml, prevExpectedNode, child, _document, bind
 | 
				
			|||||||
 * @param {Element} currentChild Start removing elements with `currentChild`. If
 | 
					 * @param {Element} currentChild Start removing elements with `currentChild`. If
 | 
				
			||||||
 *                               `currentChild` is `elem` it won't be removed.
 | 
					 *                               `currentChild` is `elem` it won't be removed.
 | 
				
			||||||
 * @param {Element|null} elem The elemnt to look for.
 | 
					 * @param {Element|null} elem The elemnt to look for.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function removeDomChildrenUntilElementFound (parent, currentChild, elem) {
 | 
					export function removeDomChildrenUntilElementFound (parent, currentChild, elem) {
 | 
				
			||||||
  while (currentChild !== elem) {
 | 
					  while (currentChild !== elem) {
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,8 @@ import { integrateRemoteStructs } from './MessageHandler/integrateRemoteStructs.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import debug from 'debug'
 | 
					import debug from 'debug'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: rename Connector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class AbstractConnector {
 | 
					export default class AbstractConnector {
 | 
				
			||||||
  constructor (y, opts) {
 | 
					  constructor (y, opts) {
 | 
				
			||||||
    this.y = y
 | 
					    this.y = y
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,6 @@ function getFreshCnf () {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @private
 | 
					 | 
				
			||||||
 * Abstract persistence class.
 | 
					 * Abstract persistence class.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export default class AbstractPersistence {
 | 
					export default class AbstractPersistence {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,26 +1,69 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Changes that are created within a transaction are bundled and sent as one
 | 
					 * A transaction is created for every change on the Yjs model. It is possible
 | 
				
			||||||
 * message to the remote peers. This implies that the changes are applied
 | 
					 * to bundle changes on the Yjs model in a single transaction to
 | 
				
			||||||
 * in one flush and at most one {@link YEvent} per type is created.
 | 
					 * minimize the number on messages sent and the number of observer calls.
 | 
				
			||||||
 | 
					 * If possible the user of this library should bundle as many changes as
 | 
				
			||||||
 | 
					 * possible. Here is an example to illustrate the advantages of bundling:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @example
 | 
				
			||||||
 | 
					 * const map = y.define('map', YMap)
 | 
				
			||||||
 | 
					 * // Log content when change is triggered
 | 
				
			||||||
 | 
					 * map.observe(function () {
 | 
				
			||||||
 | 
					 *   console.log('change triggered')
 | 
				
			||||||
 | 
					 * })
 | 
				
			||||||
 | 
					 * // Each change on the map type triggers a log message:
 | 
				
			||||||
 | 
					 * map.set('a', 0) // => "change triggered"
 | 
				
			||||||
 | 
					 * map.set('b', 0) // => "change triggered"
 | 
				
			||||||
 | 
					 * // When put in a transaction, it will trigger the log after the transaction:
 | 
				
			||||||
 | 
					 * y.transact(function () {
 | 
				
			||||||
 | 
					 *   map.set('a', 1)
 | 
				
			||||||
 | 
					 *   map.set('b', 1)
 | 
				
			||||||
 | 
					 * }) // => "change triggered"
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * It is best to bundle as many changes in a single Transaction as possible.
 | 
					 | 
				
			||||||
 * This way only few changes need to be computed
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export default class Transaction {
 | 
					export default class Transaction {
 | 
				
			||||||
  constructor (y) {
 | 
					  constructor (y) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @type {Y} The Yjs instance.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.y = y
 | 
					    this.y = y
 | 
				
			||||||
    // types added during transaction
 | 
					    /**
 | 
				
			||||||
 | 
					     * All new types that are added during a transaction.
 | 
				
			||||||
 | 
					     * @type {Set<Item>}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.newTypes = new Set()
 | 
					    this.newTypes = new Set()
 | 
				
			||||||
    // changed types (does not include new types)
 | 
					    /**
 | 
				
			||||||
    // maps from type to parentSubs (item._parentSub = null for array elements)
 | 
					     * All types that were directly modified (property added or child
 | 
				
			||||||
 | 
					     * inserted/deleted). New types are not included in this Set.
 | 
				
			||||||
 | 
					     * Maps from type to parentSubs (`item._parentSub = null` for YArray)
 | 
				
			||||||
 | 
					     * @type {Set<YType,String>}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.changedTypes = new Map()
 | 
					    this.changedTypes = new Map()
 | 
				
			||||||
 | 
					    // TODO: rename deletedTypes
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Set of all deleted Types and Structs.
 | 
				
			||||||
 | 
					     * @type {Set<Item>}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.deletedStructs = new Set()
 | 
					    this.deletedStructs = new Set()
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Saves the old state set of the Yjs instance. If a state was modified,
 | 
				
			||||||
 | 
					     * the original value is saved here.
 | 
				
			||||||
 | 
					     * @type {Map<Number,Number>}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.beforeState = new Map()
 | 
					    this.beforeState = new Map()
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Stores the events for the types that observe also child elements.
 | 
				
			||||||
 | 
					     * It is mainly used by `observeDeep`.
 | 
				
			||||||
 | 
					     * @type {Map<YType,Array<YEvent>>}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.changedParentTypes = new Map()
 | 
					    this.changedParentTypes = new Map()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function transactionTypeChanged (y, type, sub) {
 | 
					export function transactionTypeChanged (y, type, sub) {
 | 
				
			||||||
  if (type !== y && !type._deleted && !y._transaction.newTypes.has(type)) {
 | 
					  if (type !== y && !type._deleted && !y._transaction.newTypes.has(type)) {
 | 
				
			||||||
    const changedTypes = y._transaction.changedTypes
 | 
					    const changedTypes = y._transaction.changedTypes
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ const bits8 = 0b11111111
 | 
				
			|||||||
export default class BinaryEncoder {
 | 
					export default class BinaryEncoder {
 | 
				
			||||||
  constructor () {
 | 
					  constructor () {
 | 
				
			||||||
    // TODO: implement chained Uint8Array buffers instead of Array buffer
 | 
					    // TODO: implement chained Uint8Array buffers instead of Array buffer
 | 
				
			||||||
 | 
					    // TODO: Rewrite all methods as functions!
 | 
				
			||||||
    this.data = []
 | 
					    this.data = []
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -467,5 +467,4 @@ export default class Tree {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  flush () {}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
import ID from './ID/ID.js'
 | 
					import ID from './ID/ID.js'
 | 
				
			||||||
 | 
					import isParentOf from './isParentOf.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ReverseOperation {
 | 
					class ReverseOperation {
 | 
				
			||||||
  constructor (y, transaction) {
 | 
					  constructor (y, transaction) {
 | 
				
			||||||
@ -15,16 +16,6 @@ class ReverseOperation {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function isStructInScope (y, struct, scope) {
 | 
					 | 
				
			||||||
  while (struct !== y) {
 | 
					 | 
				
			||||||
    if (struct === scope) {
 | 
					 | 
				
			||||||
      return true
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    struct = struct._parent
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function applyReverseOperation (y, scope, reverseBuffer) {
 | 
					function applyReverseOperation (y, scope, reverseBuffer) {
 | 
				
			||||||
  let performedUndo = false
 | 
					  let performedUndo = false
 | 
				
			||||||
  y.transact(() => {
 | 
					  y.transact(() => {
 | 
				
			||||||
@ -38,7 +29,7 @@ function applyReverseOperation (y, scope, reverseBuffer) {
 | 
				
			|||||||
          while (op._deleted && op._redone !== null) {
 | 
					          while (op._deleted && op._redone !== null) {
 | 
				
			||||||
            op = op._redone
 | 
					            op = op._redone
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          if (op._deleted === false && isStructInScope(y, op, scope)) {
 | 
					          if (op._deleted === false && isParentOf(scope, op)) {
 | 
				
			||||||
            performedUndo = true
 | 
					            performedUndo = true
 | 
				
			||||||
            op._delete(y)
 | 
					            op._delete(y)
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@ -46,7 +37,7 @@ function applyReverseOperation (y, scope, reverseBuffer) {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      for (let op of undoOp.deletedStructs) {
 | 
					      for (let op of undoOp.deletedStructs) {
 | 
				
			||||||
        if (
 | 
					        if (
 | 
				
			||||||
          isStructInScope(y, op, scope) &&
 | 
					          isParentOf(scope, op) &&
 | 
				
			||||||
          op._parent !== y &&
 | 
					          op._parent !== y &&
 | 
				
			||||||
          (
 | 
					          (
 | 
				
			||||||
            op._id.user !== y.userID ||
 | 
					            op._id.user !== y.userID ||
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,15 @@ export default class YEvent {
 | 
				
			|||||||
   * @param {YType} target The changed type.
 | 
					   * @param {YType} target The changed type.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  constructor (target) {
 | 
					  constructor (target) {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The type on which this event was created on.
 | 
				
			||||||
 | 
					     * @type {YType}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.target = target
 | 
					    this.target = target
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The current target on which the observe callback is called.
 | 
				
			||||||
 | 
					     * @type {YType}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.currentTarget = target
 | 
					    this.currentTarget = target
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/* global crypto */
 | 
					/* global crypto */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function generateUserID () {
 | 
					export function generateRandomUint32 () {
 | 
				
			||||||
  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)
 | 
				
			||||||
@ -5,6 +5,8 @@
 | 
				
			|||||||
 * @param {Type} parent
 | 
					 * @param {Type} parent
 | 
				
			||||||
 * @param {Type} child
 | 
					 * @param {Type} child
 | 
				
			||||||
 * @return {Boolean} Whether `parent` is a parent of `child`.
 | 
					 * @return {Boolean} Whether `parent` is a parent of `child`.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @public
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export default function isParentOf (parent, child) {
 | 
					export default function isParentOf (parent, child) {
 | 
				
			||||||
  child = child._parent
 | 
					  child = child._parent
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: rename mutex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Creates a mutual exclude function with the following property:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @example
 | 
				
			||||||
 | 
					 * const mutualExclude = createMutualExclude()
 | 
				
			||||||
 | 
					 * mutualExclude(function () {
 | 
				
			||||||
 | 
					 *   // This function is immediately executed
 | 
				
			||||||
 | 
					 *   mutualExclude(function () {
 | 
				
			||||||
 | 
					 *     // This function is never executed, as it is called with the same
 | 
				
			||||||
 | 
					 *     // mutualExclude
 | 
				
			||||||
 | 
					 *   })
 | 
				
			||||||
 | 
					 * })
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return {Function} A mutual exclude function
 | 
				
			||||||
 | 
					 * @public
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function createMutualExclude () {
 | 
					export function createMutualExclude () {
 | 
				
			||||||
  var token = true
 | 
					  var token = true
 | 
				
			||||||
  return function mutualExclude (f) {
 | 
					  return function mutualExclude (f) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,8 @@
 | 
				
			|||||||
import ID from './ID/ID.js'
 | 
					import ID from './ID/ID.js'
 | 
				
			||||||
import RootID from './ID/RootID.js'
 | 
					import RootID from './ID/RootID.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: Implement function to describe ranges
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A relative position that is based on the Yjs model. In contrast to an
 | 
					 * A relative position that is based on the Yjs model. In contrast to an
 | 
				
			||||||
 * absolute position (position by index), the relative position can be
 | 
					 * absolute position (position by index), the relative position can be
 | 
				
			||||||
 | 
				
			|||||||
@ -11,16 +11,16 @@
 | 
				
			|||||||
 * a === b // values match
 | 
					 * a === b // values match
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @typedef {Object} SimpleDiff
 | 
					 * @typedef {Object} SimpleDiff
 | 
				
			||||||
 * @property {NaturalNumber} pos The index where changes were applied
 | 
					 * @property {Number} pos The index where changes were applied
 | 
				
			||||||
 * @property {NaturalNumber} delete The number of characters to delete starting
 | 
					 * @property {Number} delete The number of characters to delete starting
 | 
				
			||||||
 *                                  at `index`.
 | 
					 *                                  at `index`.
 | 
				
			||||||
 * @property {String} insert The new text to insert at `index` after applying
 | 
					 * @property {String} insert The new text to insert at `index` after applying
 | 
				
			||||||
 *                           `delete`
 | 
					 *                           `delete`
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Create a diff between two strings. This diff implementation is intentionally
 | 
					 * Create a diff between two strings. This diff implementation is highly
 | 
				
			||||||
 * not very smart.
 | 
					 * efficient, but not very sophisticated.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @public
 | 
					 * @public
 | 
				
			||||||
 * @param {String} a The old version of the string
 | 
					 * @param {String} a The old version of the string
 | 
				
			||||||
 | 
				
			|||||||
@ -12,15 +12,30 @@ import ItemEmbed from '../Struct/ItemEmbed.js'
 | 
				
			|||||||
const structs = new Map()
 | 
					const structs = new Map()
 | 
				
			||||||
const references = new Map()
 | 
					const references = new Map()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Register a new Yjs types. The same type must be defined with the same
 | 
				
			||||||
 | 
					 * reference on all clients!
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param {Number} reference
 | 
				
			||||||
 | 
					 * @param {class} structConstructor
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @public
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function registerStruct (reference, structConstructor) {
 | 
					export function registerStruct (reference, structConstructor) {
 | 
				
			||||||
  structs.set(reference, structConstructor)
 | 
					  structs.set(reference, structConstructor)
 | 
				
			||||||
  references.set(structConstructor, reference)
 | 
					  references.set(structConstructor, reference)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function getStruct (reference) {
 | 
					export function getStruct (reference) {
 | 
				
			||||||
  return structs.get(reference)
 | 
					  return structs.get(reference)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @private
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
export function getStructReference (typeConstructor) {
 | 
					export function getStructReference (typeConstructor) {
 | 
				
			||||||
  return references.get(typeConstructor)
 | 
					  return references.get(typeConstructor)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,33 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
import YMap from '../Types/YMap'
 | 
					 | 
				
			||||||
import YArray from '../Types/YArray'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function writeObjectToYMap (object, type) {
 | 
					 | 
				
			||||||
  for (var key in object) {
 | 
					 | 
				
			||||||
    var val = object[key]
 | 
					 | 
				
			||||||
    if (Array.isArray(val)) {
 | 
					 | 
				
			||||||
      type.set(key, YArray)
 | 
					 | 
				
			||||||
      writeArrayToYArray(val, type.get(key))
 | 
					 | 
				
			||||||
    } else if (typeof val === 'object') {
 | 
					 | 
				
			||||||
      type.set(key, YMap)
 | 
					 | 
				
			||||||
      writeObjectToYMap(val, type.get(key))
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      type.set(key, val)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function writeArrayToYArray (array, type) {
 | 
					 | 
				
			||||||
  for (var i = array.length - 1; i >= 0; i--) {
 | 
					 | 
				
			||||||
    var val = array[i]
 | 
					 | 
				
			||||||
    if (Array.isArray(val)) {
 | 
					 | 
				
			||||||
      type.insert(0, [YArray])
 | 
					 | 
				
			||||||
      writeArrayToYArray(val, type.get(0))
 | 
					 | 
				
			||||||
    } else if (typeof val === 'object') {
 | 
					 | 
				
			||||||
      type.insert(0, [YMap])
 | 
					 | 
				
			||||||
      writeObjectToYMap(val, type.get(0))
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      type.insert(0, [val])
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										10
									
								
								src/Y.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/Y.js
									
									
									
									
									
								
							@ -1,19 +1,13 @@
 | 
				
			|||||||
import DeleteStore from './Store/DeleteStore.js'
 | 
					import DeleteStore from './Store/DeleteStore.js'
 | 
				
			||||||
import OperationStore from './Store/OperationStore.js'
 | 
					import OperationStore from './Store/OperationStore.js'
 | 
				
			||||||
import StateStore from './Store/StateStore.js'
 | 
					import StateStore from './Store/StateStore.js'
 | 
				
			||||||
import { generateUserID } from './Util/generateUserID.js'
 | 
					import { generateRandomUint32 } from './Util/generateRandomUint32.js'
 | 
				
			||||||
import RootID from './Util/ID/RootID.js'
 | 
					import RootID from './Util/ID/RootID.js'
 | 
				
			||||||
import NamedEventHandler from './Util/NamedEventHandler.js'
 | 
					import NamedEventHandler from './Util/NamedEventHandler.js'
 | 
				
			||||||
import Transaction from './Transaction.js'
 | 
					import Transaction from './Transaction.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { default as DomBinding } from './Bindings/DomBinding/DomBinding.js'
 | 
					export { default as DomBinding } from './Bindings/DomBinding/DomBinding.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * A positive natural number including zero: 0, 1, 2, ..
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @typedef {number} NaturalNumber
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Anything that can be encoded with `JSON.stringify` and can be decoded with
 | 
					 * Anything that can be encoded with `JSON.stringify` and can be decoded with
 | 
				
			||||||
 * `JSON.parse`.
 | 
					 * `JSON.parse`.
 | 
				
			||||||
@ -47,7 +41,7 @@ export default class Y extends NamedEventHandler {
 | 
				
			|||||||
    this._contentReady = false
 | 
					    this._contentReady = false
 | 
				
			||||||
    this._opts = opts
 | 
					    this._opts = opts
 | 
				
			||||||
    if (typeof opts.userID !== 'number') {
 | 
					    if (typeof opts.userID !== 'number') {
 | 
				
			||||||
      this.userID = generateUserID()
 | 
					      this.userID = generateRandomUint32()
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this.userID = opts.userID
 | 
					      this.userID = opts.userID
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import { test } from '../node_modules/cutest/cutest.mjs'
 | 
					import { test } from '../node_modules/cutest/cutest.mjs'
 | 
				
			||||||
import BinaryEncoder from '../src/Util/Binary/Encoder.js'
 | 
					import BinaryEncoder from '../src/Util/Binary/Encoder.js'
 | 
				
			||||||
import BinaryDecoder from '../src/Util/Binary/Decoder.js'
 | 
					import BinaryDecoder from '../src/Util/Binary/Decoder.js'
 | 
				
			||||||
import { generateUserID } from '../src/Util/generateUserID.js'
 | 
					import { generateRandomUint32 } from '../src/Util/generateRandomUint32.js'
 | 
				
			||||||
import Chance from 'chance'
 | 
					import Chance from 'chance'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function testEncoding (t, write, read, val) {
 | 
					function testEncoding (t, write, read, val) {
 | 
				
			||||||
@ -43,7 +43,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, generateUserID())
 | 
					  testEncoding(t, writeVarUint, readVarUint, generateRandomUint32())
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const writeVarString = (encoder, val) => encoder.writeVarString(val)
 | 
					const writeVarString = (encoder, val) => encoder.writeVarString(val)
 | 
				
			||||||
 | 
				
			|||||||
@ -156,7 +156,7 @@ export async function initArrays (t, opts) {
 | 
				
			|||||||
    users: []
 | 
					    users: []
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  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, testContext: t, chance }, connector)
 | 
				
			||||||
  for (let i = 0; i < opts.users; i++) {
 | 
					  for (let i = 0; i < opts.users; i++) {
 | 
				
			||||||
    let connOpts
 | 
					    let connOpts
 | 
				
			||||||
    if (i === 0) {
 | 
					    if (i === 0) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user