cleanup docs

This commit is contained in:
Kevin Jahns 2018-03-23 04:35:52 +01:00
parent 026675b438
commit 6dd43cde17
25 changed files with 218 additions and 82 deletions

View File

@ -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

View File

@ -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
*/

View File

@ -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(() => {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 => {

View File

@ -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) {

View File

@ -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

View File

@ -14,7 +14,6 @@ function getFreshCnf () {
} }
/** /**
* @private
* Abstract persistence class. * Abstract persistence class.
*/ */
export default class AbstractPersistence { export default class AbstractPersistence {

View File

@ -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

View File

@ -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 = []
} }

View File

@ -467,5 +467,4 @@ export default class Tree {
} }
} }
} }
flush () {}
} }

View File

@ -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 ||

View File

@ -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
} }

View File

@ -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)

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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)
} }

View File

@ -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])
}
}
}

View File

@ -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
} }

View File

@ -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)

View File

@ -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) {