From d25307c355de1bb0b975e114f5d3f116d6335072 Mon Sep 17 00:00:00 2001 From: Bartosz Sypytkowski Date: Thu, 17 Aug 2023 20:20:49 +0200 Subject: [PATCH] fixed linter errors --- src/structs/ContentType.js | 11 +- src/structs/Item.js | 8 +- src/types/AbstractType.js | 2 +- src/types/YArray.js | 3 +- src/types/YMap.js | 7 +- src/types/YText.js | 229 ++++++++++++++++++------------------ src/types/YWeakLink.js | 91 +++++++------- src/types/YXmlText.js | 6 +- src/utils/StructStore.js | 5 +- tests/y-weak-links.tests.js | 223 +++++++++++++++++++---------------- 10 files changed, 300 insertions(+), 285 deletions(-) diff --git a/src/structs/ContentType.js b/src/structs/ContentType.js index e3e9241b..7a8b6757 100644 --- a/src/structs/ContentType.js +++ b/src/structs/ContentType.js @@ -8,10 +8,9 @@ import { readYXmlFragment, readYXmlHook, readYXmlText, - UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, StructStore, Transaction, Item, YEvent, AbstractType, // eslint-disable-line + UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, StructStore, Transaction, Item, YEvent, AbstractType, ID, // eslint-disable-line readYWeakLink, - unlinkFrom, - ID + unlinkFrom } from '../internals.js' import * as error from 'lib0/error' @@ -111,9 +110,9 @@ export class ContentType { */ delete (transaction) { if (this.type.constructor === WeakLink) { - // when removing weak links, remove references to them + // when removing weak links, remove references to them // from type they're pointing to - const type = /** @type {WeakLink} */ (this.type); + const type = /** @type {WeakLink} */ (this.type) const end = /** @type {ID} */ (type._quoteEnd.item) for (let item = type._firstItem; item !== null; item = item.right) { if (item.linked) { @@ -121,7 +120,7 @@ export class ContentType { } const lastId = item.lastId if (lastId.client === end.client && lastId.clock === end.clock) { - break; + break } } type._firstItem = null diff --git a/src/structs/Item.js b/src/structs/Item.js index 8cad00cf..6388186e 100644 --- a/src/structs/Item.js +++ b/src/structs/Item.js @@ -326,13 +326,13 @@ export class Item extends AbstractStruct { * * @type {boolean} */ - set linked(isLinked) { + set linked (isLinked) { if (((this.info & binary.BIT9) > 0) !== isLinked) { this.info ^= binary.BIT9 } } - get linked() { + get linked () { return (this.info & binary.BIT9) > 0 } @@ -581,7 +581,7 @@ export class Item extends AbstractStruct { // notify links about changes const linkedBy = transaction.doc.store.linkedBy.get(this) if (linkedBy !== undefined) { - for (let link of linkedBy) { + for (const link of linkedBy) { addChangedTypeToTransaction(transaction, link, this.parentSub) } } @@ -695,7 +695,7 @@ export class Item extends AbstractStruct { const allLinks = transaction.doc.store.linkedBy const linkedBy = allLinks.get(this) if (linkedBy !== undefined) { - for (let link of linkedBy) { + for (const link of linkedBy) { addChangedTypeToTransaction(transaction, link, this.parentSub) } allLinks.delete(this) diff --git a/src/types/AbstractType.js b/src/types/AbstractType.js index d2fa5b67..645375e7 100644 --- a/src/types/AbstractType.js +++ b/src/types/AbstractType.js @@ -246,7 +246,7 @@ export const callTypeObservers = (type, transaction, event, visitedLinks = null) } else if (type._item.linked) { const linkedBy = transaction.doc.store.linkedBy.get(type._item) if (linkedBy !== undefined) { - for (let link of linkedBy) { + for (const link of linkedBy) { if (visitedLinks === null || !visitedLinks.has(link)) { visitedLinks = visitedLinks !== null ? visitedLinks : new Set() visitedLinks.add(link) diff --git a/src/types/YArray.js b/src/types/YArray.js index b765c5d2..8fbd7aee 100644 --- a/src/types/YArray.js +++ b/src/types/YArray.js @@ -16,8 +16,7 @@ import { YArrayRefID, callTypeObservers, transact, - ArraySearchMarker, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, Doc, Transaction, Item, // eslint-disable-line - YWeakLink, + ArraySearchMarker, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, Doc, Transaction, Item, YWeakLink, // eslint-disable-line arrayWeakLink } from '../internals.js' import { typeListSlice } from './AbstractType.js' diff --git a/src/types/YMap.js b/src/types/YMap.js index dc42b93b..2a634d80 100644 --- a/src/types/YMap.js +++ b/src/types/YMap.js @@ -14,8 +14,7 @@ import { YMapRefID, callTypeObservers, transact, - UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, Doc, Transaction, Item, // eslint-disable-line - YWeakLink, + UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, Doc, Transaction, Item, YWeakLink, // eslint-disable-line mapWeakLink } from '../internals.js' @@ -237,8 +236,8 @@ export class YMap extends AbstractType { /** * Returns a weak reference link to another element stored in the same document. - * - * @param {string} key + * + * @param {string} key * @return {YWeakLink|undefined} */ link (key) { diff --git a/src/types/YText.js b/src/types/YText.js index 00a43ffb..8723573d 100644 --- a/src/types/YText.js +++ b/src/types/YText.js @@ -27,14 +27,13 @@ import { typeMapGetAll, updateMarkerChanges, ContentType, - ArraySearchMarker, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, ID, Doc, Item, Snapshot, Transaction, // eslint-disable-line + ArraySearchMarker, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, ID, Doc, Item, Snapshot, Transaction, YWeakLink, // eslint-disable-line quoteText } from '../internals.js' import * as object from 'lib0/object' import * as map from 'lib0/map' import * as error from 'lib0/error' -import { WeakLink } from 'yjs' /** * @param {any} a @@ -1059,15 +1058,15 @@ export class YText extends AbstractType { /** * Returns a WeakLink representing a dynamic quotation of a range of elements. - * + * * In case when quotation happens in a middle of formatting range, formatting - * attributes will be split into before|within|after eg. quoting fragment of + * attributes will be split into before|within|after eg. quoting fragment of * `hello world` could result in `he"llo wo"rld` * where `"llo wo"` represents quoted range. * * @param {number} index The index where quoted range should start * @param {number} length Number of quoted elements - * @return {WeakLink} + * @return {YWeakLink} * * @public */ @@ -1079,7 +1078,7 @@ export class YText extends AbstractType { return quoteText(transaction, this, pos, length) }) } - throw new Error('Quoted text was not integrated into Doc') + throw new Error('Quoted text was not integrated into Doc') } /** @@ -1218,138 +1217,140 @@ export const readYText = _decoder => new YText() /** * Returns a delta representation that happens between `start` and `end` ranges (both sides inclusive). - * - * @param {AbstractType} parent + * + * @param {AbstractType} parent * @param {ID|null} start * @param {ID|null} end - * @param {Snapshot|undefined} snapshot - * @param {Snapshot|undefined} prevSnapshot - * @param {(function('removed' | 'added', ID):any)|undefined} computeYChange + * @param {Snapshot|undefined} snapshot + * @param {Snapshot|undefined} prevSnapshot + * @param {(function('removed' | 'added', ID):any)|undefined} computeYChange * @returns {any} The Delta representation of this type. */ export const rangeDelta = (parent, start, end, snapshot, prevSnapshot, computeYChange) => { - /** + /** * @type{Array} */ - const ops = [] - const currentAttributes = new Map() - const doc = /** @type {Doc} */ (parent.doc) - let str = '' - let n = parent._start - function packStr () { - if (str.length > 0) { - // pack str with attributes to ops - /** + const ops = [] + const currentAttributes = new Map() + const doc = /** @type {Doc} */ (parent.doc) + let str = '' + let n = parent._start + function packStr () { + if (str.length > 0) { + // pack str with attributes to ops + /** * @type {Object} */ - const attributes = {} - let addAttributes = false - currentAttributes.forEach((value, key) => { - addAttributes = true - attributes[key] = value - }) - /** + const attributes = {} + let addAttributes = false + currentAttributes.forEach((value, key) => { + addAttributes = true + attributes[key] = value + }) + /** * @type {Object} */ - const op = { insert: str } - if (addAttributes) { - op.attributes = attributes - } - ops.push(op) - str = '' + const op = { insert: str } + if (addAttributes) { + op.attributes = attributes } + ops.push(op) + str = '' } - const computeDelta = () => { - // startOffset represents offset at current block from which we're intersted in picking string - // if it's -1 it means, we're out of scope and we should break at this point - let startOffset = start === null ? 0 : -1 - loop: while (n !== null) { - if (startOffset < 0 && start !== null) { - if (start.client === n.id.client && start.clock >= n.id.clock && start.clock < n.id.clock + n.length) { - startOffset = start.clock - n.id.clock - } + } + const computeDelta = () => { + // startOffset represents offset at current block from which we're intersted in picking string + // if it's -1 it means, we're out of scope and we should break at this point + let startOffset = start === null ? 0 : -1 + // eslint-disable-next-line no-labels + loop: while (n !== null) { + if (startOffset < 0 && start !== null) { + if (start.client === n.id.client && start.clock >= n.id.clock && start.clock < n.id.clock + n.length) { + startOffset = start.clock - n.id.clock } - if (isVisible(n, snapshot) || (prevSnapshot !== undefined && isVisible(n, prevSnapshot))) { - switch (n.content.constructor) { - case ContentString: { - const cur = currentAttributes.get('ychange') - if (snapshot !== undefined && !isVisible(n, snapshot)) { - if (cur === undefined || cur.user !== n.id.client || cur.type !== 'removed') { - packStr() - currentAttributes.set('ychange', computeYChange ? computeYChange('removed', n.id) : { type: 'removed' }) - } - } else if (prevSnapshot !== undefined && !isVisible(n, prevSnapshot)) { - if (cur === undefined || cur.user !== n.id.client || cur.type !== 'added') { - packStr() - currentAttributes.set('ychange', computeYChange ? computeYChange('added', n.id) : { type: 'added' }) - } - } else if (cur !== undefined) { + } + if (isVisible(n, snapshot) || (prevSnapshot !== undefined && isVisible(n, prevSnapshot))) { + switch (n.content.constructor) { + case ContentString: { + const cur = currentAttributes.get('ychange') + if (snapshot !== undefined && !isVisible(n, snapshot)) { + if (cur === undefined || cur.user !== n.id.client || cur.type !== 'removed') { packStr() - currentAttributes.delete('ychange') + currentAttributes.set('ychange', computeYChange ? computeYChange('removed', n.id) : { type: 'removed' }) } - let s = /** @type {ContentString} */ (n.content).str - if (startOffset > 0) { - str += s.slice(startOffset) - startOffset = 0 - } else if (end !== null && end.client === n.id.client && end.clock >= n.id.clock && end.clock < n.id.clock + n.length) { - // we reached the end or range - const endOffset = n.id.clock + n.length - end.clock - 1 - str += s.slice(0, s.length + endOffset) // scope is negative + } else if (prevSnapshot !== undefined && !isVisible(n, prevSnapshot)) { + if (cur === undefined || cur.user !== n.id.client || cur.type !== 'added') { packStr() - break loop - } else if (startOffset == 0) { - str += s + currentAttributes.set('ychange', computeYChange ? computeYChange('added', n.id) : { type: 'added' }) } - break - } - case ContentType: - case ContentEmbed: { + } else if (cur !== undefined) { packStr() - /** + currentAttributes.delete('ychange') + } + const s = /** @type {ContentString} */ (n.content).str + if (startOffset > 0) { + str += s.slice(startOffset) + startOffset = 0 + } else if (end !== null && end.client === n.id.client && end.clock >= n.id.clock && end.clock < n.id.clock + n.length) { + // we reached the end or range + const endOffset = n.id.clock + n.length - end.clock - 1 + str += s.slice(0, s.length + endOffset) // scope is negative + packStr() + // eslint-disable-next-line no-labels + break loop + } else if (startOffset === 0) { + str += s + } + break + } + case ContentType: + case ContentEmbed: { + packStr() + /** * @type {Object} */ - const op = { - insert: n.content.getContent()[0] - } - if (currentAttributes.size > 0) { - const attrs = /** @type {Object} */ ({}) - op.attributes = attrs - currentAttributes.forEach((value, key) => { - attrs[key] = value - }) - } - ops.push(op) - break + const op = { + insert: n.content.getContent()[0] } - case ContentFormat: - if (isVisible(n, snapshot)) { - packStr() - updateCurrentAttributes(currentAttributes, /** @type {ContentFormat} */ (n.content)) - } - break + if (currentAttributes.size > 0) { + const attrs = /** @type {Object} */ ({}) + op.attributes = attrs + currentAttributes.forEach((value, key) => { + attrs[key] = value + }) + } + ops.push(op) + break } - } else if (end !== null && end.client === n.id.client && end.clock >= n.id.clock && end.clock < n.id.clock + n.length) { - // block may not passed visibility check, but we still need to verify boundaries - break; + case ContentFormat: + if (isVisible(n, snapshot)) { + packStr() + updateCurrentAttributes(currentAttributes, /** @type {ContentFormat} */ (n.content)) + } + break } - n = n.right + } else if (end !== null && end.client === n.id.client && end.clock >= n.id.clock && end.clock < n.id.clock + n.length) { + // block may not passed visibility check, but we still need to verify boundaries + break } - packStr() + n = n.right } - if (snapshot || prevSnapshot) { - // snapshots are merged again after the transaction, so we need to keep the - // transaction alive until we are done - transact(doc, transaction => { - if (snapshot) { - splitSnapshotAffectedStructs(transaction, snapshot) - } - if (prevSnapshot) { - splitSnapshotAffectedStructs(transaction, prevSnapshot) - } - computeDelta() - }, 'cleanup') - } else { + packStr() + } + if (snapshot || prevSnapshot) { + // snapshots are merged again after the transaction, so we need to keep the + // transaction alive until we are done + transact(doc, transaction => { + if (snapshot) { + splitSnapshotAffectedStructs(transaction, snapshot) + } + if (prevSnapshot) { + splitSnapshotAffectedStructs(transaction, prevSnapshot) + } computeDelta() - } - return ops -} \ No newline at end of file + }, 'cleanup') + } else { + computeDelta() + } + return ops +} diff --git a/src/types/YWeakLink.js b/src/types/YWeakLink.js index 176a471e..0b1b747a 100644 --- a/src/types/YWeakLink.js +++ b/src/types/YWeakLink.js @@ -1,8 +1,8 @@ -import { decoding, encoding, error } from "lib0" +import { decoding, encoding, error } from 'lib0' import * as map from 'lib0/map' import * as set from 'lib0/set' -import { - YEvent, Transaction, ID, GC, AbstractType, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, Doc, Item, +import { + YEvent, AbstractType, transact, getItemCleanEnd, createID, @@ -12,14 +12,13 @@ import { writeID, readID, RelativePosition, - ItemTextListPosition, ContentString, rangeDelta, formatXmlString, - Snapshot, YText, - YXmlText -} from "../internals.js" + YXmlText, + Transaction, Item, Doc, ID, Snapshot, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, ItemTextListPosition // eslint-disable-line +} from '../internals.js' /** * @template T extends AbstractType @@ -31,6 +30,7 @@ export class YWeakLinkEvent extends YEvent { * @param {YWeakLink} ylink The YWeakLink to which this event was propagated to. * @param {Transaction} transaction */ + // eslint-disable-next-line no-useless-constructor constructor (ylink, transaction) { super(ylink, transaction) } @@ -39,7 +39,7 @@ export class YWeakLinkEvent extends YEvent { /** * @template T * @extends AbstractType> - * + * * Weak link to another value stored somewhere in the document. */ export class YWeakLink extends AbstractType { @@ -48,7 +48,7 @@ export class YWeakLink extends AbstractType { * @param {RelativePosition} end * @param {Item|null} firstItem */ - constructor(start, end, firstItem) { + constructor (start, end, firstItem) { super() this._quoteStart = start this._quoteEnd = end @@ -57,16 +57,16 @@ export class YWeakLink extends AbstractType { /** * Check if current link contains only a single element. - * + * * @returns {boolean} */ isSingle () { return this._quoteStart.item === this._quoteEnd.item } - + /** * Returns a reference to an underlying value existing somewhere on in the document. - * + * * @return {T|undefined} */ deref () { @@ -84,26 +84,26 @@ export class YWeakLink extends AbstractType { } } - return undefined; + return undefined } - + /** * Returns an array of references to all elements quoted by current weak link. - * + * * @return {Array} */ unquote () { let result = /** @type {Array} */ ([]) let item = this._firstItem const end = /** @type {ID} */ (this._quoteEnd.item) - //TODO: moved elements + // TODO: moved elements while (item !== null) { if (!item.deleted) { result = result.concat(item.content.getContent()) } const lastId = item.lastId if (lastId.client === end.client && lastId.clock === end.clock) { - break; + break } item = item.right } @@ -136,15 +136,15 @@ export class YWeakLink extends AbstractType { } } this._firstItem = firstItem - + /** @type {Item|null} */ let item = firstItem - let end = /** @type {ID} */ (this._quoteEnd.item) + const end = /** @type {ID} */ (this._quoteEnd.item) for (;item !== null; item = item.right) { createLink(transaction, item, this) const lastId = item.lastId if (lastId.client === end.client && lastId.clock === end.clock) { - break; + break } } }) @@ -182,7 +182,7 @@ export class YWeakLink extends AbstractType { _write (encoder) { encoder.writeTypeRef(YWeakLinkRefID) const isSingle = this.isSingle() - const info = (isSingle ? 0 : 1) | (this._quoteStart.assoc >= 0 ? 2 : 0) | (this._quoteEnd.assoc >= 0 ? 4 :0) + const info = (isSingle ? 0 : 1) | (this._quoteStart.assoc >= 0 ? 2 : 0) | (this._quoteEnd.assoc >= 0 ? 4 : 0) encoding.writeUint8(encoder.restEncoder, info) writeID(encoder.restEncoder, /** @type {ID} */ (this._quoteStart.item)) if (!isSingle) { @@ -198,7 +198,7 @@ export class YWeakLink extends AbstractType { toString () { if (this._firstItem !== null) { switch (/** @type {AbstractType} */ (this._firstItem.parent).constructor) { - case YText: + case YText: { let str = '' /** * @type {Item|null} @@ -211,12 +211,12 @@ export class YWeakLink extends AbstractType { } const lastId = n.lastId if (lastId.client === end.client && lastId.clock === end.clock) { - break; + break } n = n.right } return str - + } case YXmlText: return this.toDelta().map(delta => formatXmlString(delta)).join('') } @@ -227,13 +227,13 @@ export class YWeakLink extends AbstractType { /** * Returns the Delta representation of quoted part of underlying text type. - * + * * @param {Snapshot|undefined} [snapshot] * @param {Snapshot|undefined} [prevSnapshot] * @param {function('removed' | 'added', ID):any} [computeYChange] * @returns {Array} */ - toDelta(snapshot, prevSnapshot, computeYChange) { + toDelta (snapshot, prevSnapshot, computeYChange) { if (this._firstItem !== null && this._quoteStart.item !== null && this._quoteEnd.item !== null) { const parent = /** @type {AbstractType} */ (this._firstItem.parent) return rangeDelta(parent, this._quoteStart.item, this._quoteEnd.item, snapshot, prevSnapshot, computeYChange) @@ -243,7 +243,6 @@ export class YWeakLink extends AbstractType { } } - /** * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder * @return {YWeakLink} @@ -263,7 +262,7 @@ const invalidQuotedRange = error.create('Invalid quoted range length.') /** * Returns a {WeakLink} to an YArray element at given index. - * + * * @param {Transaction} transaction * @param {AbstractType} parent * @param {number} index @@ -278,9 +277,9 @@ export const arrayWeakLink = (transaction, parent, index, length = 1) => { if (!startItem.deleted && startItem.countable) { if (index < startItem.length) { if (index > 0) { - startItem = getItemCleanStart(transaction, createID(startItem.id.client, startItem.id.clock + index)) + startItem = getItemCleanStart(transaction, createID(startItem.id.client, startItem.id.clock + index)) } - break; + break } index -= startItem.length } @@ -293,11 +292,11 @@ export const arrayWeakLink = (transaction, parent, index, length = 1) => { remaining -= endItem.length } else { endItem = getItemCleanEnd(transaction, transaction.doc.store, createID(endItem.id.client, endItem.id.clock + remaining - 1)) - break; + break } } } - if (startItem !== null && endItem !== null) { + if (startItem !== null && endItem !== null) { const start = new RelativePosition(null, null, startItem.id, 0) const end = new RelativePosition(null, null, endItem.lastId, -1) const link = new YWeakLink(start, end, startItem) @@ -308,7 +307,7 @@ export const arrayWeakLink = (transaction, parent, index, length = 1) => { createLink(transaction, item, link) const lastId = item.lastId if (lastId.client === end.client && lastId.clock === end.clock) { - break; + break } } }) @@ -320,7 +319,7 @@ export const arrayWeakLink = (transaction, parent, index, length = 1) => { /** * Returns a {WeakLink} to an YMap element at given key. - * + * * @param {Transaction} transaction * @param {AbstractType} parent * @param {ItemTextListPosition} pos @@ -350,7 +349,7 @@ export const quoteText = (transaction, parent, pos, length) => { createLink(transaction, item, link) const lastId = item.lastId if (lastId.client === end.client && lastId.clock === end.clock) { - break; + break } } }) @@ -358,13 +357,13 @@ export const quoteText = (transaction, parent, pos, length) => { return link } } - - throw invalidQuotedRange + + throw invalidQuotedRange } /** * Returns a {WeakLink} to an YMap element at given key. - * + * * @param {AbstractType} parent * @param {string} key * @return {YWeakLink|undefined} @@ -389,8 +388,8 @@ export const mapWeakLink = (parent, key) => { /** * Establishes a link between source and weak link reference. * It assumes that source has already been split if necessary. - * - * @param {Transaction} transaction + * + * @param {Transaction} transaction * @param {Item} source * @param {YWeakLink} linkRef */ @@ -402,8 +401,8 @@ export const createLink = (transaction, source, linkRef) => { /** * Deletes the link between source and a weak link reference. - * - * @param {Transaction} transaction + * + * @param {Transaction} transaction * @param {Item} source * @param {YWeakLink} linkRef */ @@ -427,7 +426,7 @@ export const unlinkFrom = (transaction, source, linkRef) => { /** * Rebinds linkedBy links pointed between neighbours of a current item. * This method expects that current item has both left and right neighbours. - * + * * @param {Transaction} transaction * @param {Item} item */ @@ -438,13 +437,13 @@ export const joinLinkedRange = (transaction, item) => { const rightLinks = allLinks.get(/** @type {Item} */ (item.right)) if (leftLinks && rightLinks) { const common = new Set() - for (let link of leftLinks) { + for (const link of leftLinks) { if (rightLinks.has(link)) { common.add(link) } } - if (common.size != 0) { + if (common.size !== 0) { allLinks.set(item, common) } } -} \ No newline at end of file +} diff --git a/src/types/YXmlText.js b/src/types/YXmlText.js index 763b5527..136271c1 100644 --- a/src/types/YXmlText.js +++ b/src/types/YXmlText.js @@ -84,9 +84,9 @@ export class YXmlText extends YText { /** * Formats individual delta segment provided by `Text.toDelta` into XML-formatted string. - * - * @param {any} delta - * @returns {string} + * + * @param {any} delta + * @returns {string} */ export const formatXmlString = (delta) => { const nestedNodes = [] diff --git a/src/utils/StructStore.js b/src/utils/StructStore.js index 4b6edc1a..75742b21 100644 --- a/src/utils/StructStore.js +++ b/src/utils/StructStore.js @@ -2,8 +2,7 @@ import { GC, splitItem, - Transaction, ID, Item, DSDecoderV2, // eslint-disable-line - YWeakLink + Transaction, ID, Item, DSDecoderV2, YWeakLink // eslint-disable-line } from '../internals.js' import * as math from 'lib0/math' @@ -18,7 +17,7 @@ export class StructStore { /** * If this item was referenced by other weak links, here we keep the references * to these weak refs. - * + * * @type {Map>>} */ this.linkedBy = new Map() diff --git a/tests/y-weak-links.tests.js b/tests/y-weak-links.tests.js index 2f0750c1..66a6e4ab 100644 --- a/tests/y-weak-links.tests.js +++ b/tests/y-weak-links.tests.js @@ -1,6 +1,6 @@ import * as Y from '../src/index.js' import * as t from 'lib0/testing' -import { init, compare } from './testHelper.js' +import { init } from './testHelper.js' /** * @param {t.TestCase} tc @@ -8,7 +8,7 @@ import { init, compare } from './testHelper.js' export const testBasicMap = tc => { const doc = new Y.Doc() const map = doc.getMap('map') - + const nested = new Y.Map() nested.set('a1', 'hello') map.set('a', nested) @@ -25,8 +25,8 @@ export const testBasicMap = tc => { * @param {t.TestCase} tc */ export const testBasicArray = tc => { - const { testConnector, array0, array1 } = init(tc, {users:2}) - array0.insert(0, [1,2,3]) + const { testConnector, array0, array1 } = init(tc, { users: 2 }) + array0.insert(0, [1, 2, 3]) array0.insert(3, [array0.quote(1)]) t.compare(array0.get(0), 1) @@ -46,7 +46,7 @@ export const testBasicArray = tc => { * @param {t.TestCase} tc */ export const testArrayQuoteMultipleElements = tc => { - const { testConnector, array0, array1 } = init(tc, {users:2}) + const { testConnector, array0, array1 } = init(tc, { users: 2 }) const nested = new Y.Map([['key', 'value']]) array0.insert(0, [1, 2, nested, 3]) array0.insert(0, [array0.quote(1, 3)]) @@ -63,11 +63,11 @@ export const testArrayQuoteMultipleElements = tc => { const link1 = array1.get(0) let unquoted = link1.unquote() t.compare(unquoted[0], 2) - t.compare(unquoted[1].toJSON(), {'key':'value'}) + t.compare(unquoted[1].toJSON(), { key: 'value' }) t.compare(unquoted[2], 3) t.compare(array1.get(1), 1) t.compare(array1.get(2), 2) - t.compare(array1.get(3).toJSON(), {'key':'value'}) + t.compare(array1.get(3).toJSON(), { key: 'value' }) t.compare(array1.get(4), 3) array1.insert(3, ['A', 'B']) @@ -75,11 +75,11 @@ export const testArrayQuoteMultipleElements = tc => { t.compare(unquoted[0], 2) t.compare(unquoted[1], 'A') t.compare(unquoted[2], 'B') - t.compare(unquoted[3].toJSON(), {'key':'value'}) + t.compare(unquoted[3].toJSON(), { key: 'value' }) t.compare(unquoted[4], 3) - + testConnector.flushAllMessages() - + t.compare(array0.get(0).unquote(), [2, 'A', 'B', nested, 3]) } @@ -87,7 +87,7 @@ export const testArrayQuoteMultipleElements = tc => { * @param {t.TestCase} tc */ export const testSelfQuotation = tc => { - const { testConnector, array0, array1 } = init(tc, {users:2}) + const { testConnector, array0, array1 } = init(tc, { users: 2 }) array0.insert(0, [1, 2, 3, 4]) const link0 = array0.quote(0, 3) array0.insert(1, [link0]) // link is inserted into its own range @@ -102,7 +102,7 @@ export const testSelfQuotation = tc => { testConnector.flushAllMessages() const link1 = array1.get(1) - let unquoted = link1.unquote() + const unquoted = link1.unquote() t.compare(unquoted, [1, link1, 2, 3]) t.compare(array1.get(0), 1) t.compare(array1.get(1), link1) @@ -115,7 +115,7 @@ export const testSelfQuotation = tc => { * @param {t.TestCase} tc */ export const testUpdate = tc => { - const { testConnector, users, map0, map1 } = init(tc, { users: 2 }) + const { testConnector, map0, map1 } = init(tc, { users: 2 }) map0.set('a', new Y.Map([['a1', 'hello']])) const link0 = /** @type {Y.WeakLink>} */ (map0.link('a')) map0.set('b', link0) @@ -139,13 +139,13 @@ export const testUpdate = tc => { * @param {t.TestCase} tc */ export const testDeleteWeakLink = tc => { - const { testConnector, users, map0, map1 } = init(tc, { users: 2 }) + const { testConnector, map0, map1 } = init(tc, { users: 2 }) map0.set('a', new Y.Map([['a1', 'hello']])) const link0 = /** @type {Y.WeakLink>} */ (map0.link('a')) map0.set('b', link0) testConnector.flushAllMessages() - + const link1 = /** @type {Y.WeakLink} */ map1.get('b') const l1 = /** @type {Y.Map} */ (link1.deref()) const l0 = /** @type {Y.Map} */ (link0.deref()) @@ -164,15 +164,15 @@ export const testDeleteWeakLink = tc => { * @param {t.TestCase} tc */ export const testDeleteSource = tc => { - const { testConnector, users, map0, map1 } = init(tc, { users: 2 }) + const { testConnector, map0, map1 } = init(tc, { users: 2 }) map0.set('a', new Y.Map([['a1', 'hello']])) const link0 = /** @type {Y.WeakLink>} */ (map0.link('a')) map0.set('b', link0) testConnector.flushAllMessages() const link1 = /** @type {Y.WeakLink>} */ (map1.get('b')) - let l1 = /** @type {Y.Map} */ (link1.deref()) - let l0 = /** @type {Y.Map} */ (link0.deref()) + const l1 = /** @type {Y.Map} */ (link1.deref()) + const l0 = /** @type {Y.Map} */ (link0.deref()) t.compare(l1.get('a1'), l0.get('a1')) map1.delete('a') // delete source of the link @@ -188,7 +188,7 @@ export const testDeleteSource = tc => { * @param {t.TestCase} tc */ export const testObserveMapUpdate = tc => { - const { testConnector, users, map0, map1 } = init(tc, { users: 2 }) + const { testConnector, map0, map1 } = init(tc, { users: 2 }) map0.set('a', 'value') const link0 = /** @type {Y.WeakLink} */ (map0.link('a')) map0.set('b', link0) @@ -196,17 +196,21 @@ export const testObserveMapUpdate = tc => { * @type {any} */ let target0 - link0.observe((e) => target0 = e.target) + link0.observe((e) => { + target0 = e.target + }) testConnector.flushAllMessages() - let link1 = /** @type {Y.WeakLink} */ (map1.get('b')) + const link1 = /** @type {Y.WeakLink} */ (map1.get('b')) t.compare(link1.deref(), 'value') /** * @type {any} */ let target1 - link1.observe((e) => target1 = e.target) + link1.observe((e) => { + target1 = e.target + }) map0.set('a', 'value2') t.compare(target0.deref(), 'value2') @@ -219,7 +223,7 @@ export const testObserveMapUpdate = tc => { * @param {t.TestCase} tc */ export const testObserveMapDelete = tc => { - const { testConnector, users, map0, map1 } = init(tc, { users: 2 }) + const { testConnector, map0, map1 } = init(tc, { users: 2 }) map0.set('a', 'value') const link0 = /** @type {Y.WeakLink} */ (map0.link('a')) map0.set('b', link0) @@ -227,17 +231,21 @@ export const testObserveMapDelete = tc => { * @type {any} */ let target0 - link0.observe((e) => target0 = e.target) + link0.observe((e) => { + target0 = e.target + }) testConnector.flushAllMessages() - let link1 = /** @type {Y.WeakLink} */ (map1.get('b')) + const link1 = /** @type {Y.WeakLink} */ (map1.get('b')) t.compare(link1.deref(), 'value') /** * @type {any} */ let target1 - link1.observe((e) => target1 = e.target) + link1.observe((e) => { + target1 = e.target + }) map0.delete('a') t.compare(target0.deref(), undefined) @@ -250,31 +258,35 @@ export const testObserveMapDelete = tc => { */ export const testObserveArray = tc => { const { testConnector, array0, array1 } = init(tc, { users: 2 }) - array0.insert(0, ['A','B','C']) + array0.insert(0, ['A', 'B', 'C']) const link0 = /** @type {Y.WeakLink} */ (array0.quote(1, 2)) array0.insert(0, [link0]) /** * @type {any} */ let target0 - link0.observe((e) => target0 = e.target) + link0.observe((e) => { + target0 = e.target + }) testConnector.flushAllMessages() - let link1 = /** @type {Y.WeakLink} */ (array1.get(0)) - t.compare(link1.unquote(), ['B','C']) + const link1 = /** @type {Y.WeakLink} */ (array1.get(0)) + t.compare(link1.unquote(), ['B', 'C']) /** * @type {any} */ let target1 - link1.observe((e) => target1 = e.target) + link1.observe((e) => { + target1 = e.target + }) array0.delete(2) t.compare(target0.unquote(), ['C']) testConnector.flushAllMessages() t.compare(target1.unquote(), ['C']) - + array1.delete(2) t.compare(target1.unquote(), []) @@ -308,14 +320,16 @@ export const testDeepObserveTransitive = tc => { map2.set('key', 'value1') const link1 = /** @type {Y.WeakLink} */ (map2.link('key')) map1.set('link-key', link1) - const link2 = /** @type {Y.WeakLink} */ (map1.link('link-key')) + const link2 = /** @type {Y.WeakLink} */ (map1.link('link-key')) map2.set('link-link', link2) /** * @type {Array} */ let events = [] - link2.observeDeep((e) => events = e) + link2.observeDeep((e) => { + events = e + }) map2.set('key', 'value2') const values = events.map((e) => e.target.deref()) t.compare(values, ['value2']) @@ -345,16 +359,18 @@ export const testDeepObserveTransitive2 = tc => { map2.set('key', 'value1') const link1 = /** @type {Y.WeakLink} */ (map2.link('key')) map1.set('link-key', link1) - const link2 = /** @type {Y.WeakLink} */ (map1.link('link-key')) + const link2 = /** @type {Y.WeakLink} */ (map1.link('link-key')) map2.set('link-link', link2) - const link3 = /** @type {Y.WeakLink} */ (map2.link('link-link')) + const link3 = /** @type {Y.WeakLink} */ (map2.link('link-link')) map3.set('link-link-link', link3) /** * @type {Array} */ let events = [] - link3.observeDeep((e) => events = e) + link3.observeDeep((e) => { + events = e + }) map2.set('key', 'value2') const values = events.map((e) => e.target.deref()) t.compare(values, ['value2']) @@ -381,7 +397,9 @@ export const testDeepObserveMap = tc => { * @type {Array} */ let events = [] - map.observeDeep((e) => events = e) + map.observeDeep((e) => { + events = e + }) const nested = new Y.Map() array.insert(0, [nested]) @@ -393,15 +411,15 @@ export const testDeepObserveMap = tc => { nested.set('key', 'value') t.compare(events.length, 1) t.compare(events[0].target, nested) - t.compare(events[0].keys, new Map([['key', {action:'add', oldValue: undefined}]])) + t.compare(events[0].keys, new Map([['key', { action: 'add', oldValue: undefined }]])) // delete entry in linked map events = [] nested.delete('key') t.compare(events.length, 1) t.compare(events[0].target, nested) - t.compare(events[0].keys, new Map([['key', {action:'delete', oldValue: undefined}]])) - + t.compare(events[0].keys, new Map([['key', { action: 'delete', oldValue: undefined }]])) + // delete linked map array.delete(0) t.compare(events.length, 1) @@ -411,7 +429,7 @@ export const testDeepObserveMap = tc => { /** * @param {t.TestCase} tc */ -export const testDeepObserveArray = tc => { //FIXME +export const testDeepObserveArray = tc => { // FIXME // test observers in a face of linked chains of values const doc = new Y.Doc() /* @@ -436,14 +454,14 @@ export const testDeepObserveArray = tc => { //FIXME let events = [] array.observeDeep((evts) => { events = [] - for (let e of evts) { + for (const e of evts) { switch (e.constructor) { case Y.YMapEvent: - events.push({target: e.target, keys: e.keys}) - break; + events.push({ target: e.target, keys: e.keys }) + break case Y.YWeakLinkEvent: - events.push({target: e.target}) - break; + events.push({ target: e.target }) + break default: throw new Error('unexpected event type ' + e.constructor) } } @@ -454,19 +472,19 @@ export const testDeepObserveArray = tc => { //FIXME nested.set('key', 'value') t.compare(events.length, 1) t.compare(events[0].target, nested) - t.compare(events[0].keys, new Map([['key', {action:'add', oldValue: undefined}]])) + t.compare(events[0].keys, new Map([['key', { action: 'add', oldValue: undefined }]])) nested.set('key', 'value2') t.compare(events.length, 1) t.compare(events[0].target, nested) - t.compare(events[0].keys, new Map([['key', {action:'update', oldValue: 'value'}]])) + t.compare(events[0].keys, new Map([['key', { action: 'update', oldValue: 'value' }]])) // delete entry in linked map nested.delete('key') t.compare(events.length, 1) t.compare(events[0].target, nested) - t.compare(events[0].keys, new Map([['key', {action:'delete', oldValue: 'value2'}]])) - + t.compare(events[0].keys, new Map([['key', { action: 'delete', oldValue: 'value2' }]])) + // delete linked map map.delete('nested') t.compare(events.length, 1) @@ -477,10 +495,10 @@ export const testDeepObserveArray = tc => { //FIXME * @param {t.TestCase} tc */ export const testDeepObserveNewElementWithinQuotedRange = tc => { - const { testConnector, users, array0, array1 } = init(tc, { users: 2 }) + const { testConnector, array0, array1 } = init(tc, { users: 2 }) const m1 = new Y.Map() const m3 = new Y.Map() - array0.insert(0, [1,m1,m3,2]) + array0.insert(0, [1, m1, m3, 2]) const link0 = array0.quote(1, 2) array0.insert(0, [link0]) @@ -492,14 +510,14 @@ export const testDeepObserveNewElementWithinQuotedRange = tc => { let e0 = [] link0.observeDeep((evts) => { e0 = [] - for (let e of evts) { + for (const e of evts) { switch (e.constructor) { case Y.YMapEvent: - e0.push({target: e.target, keys: e.keys}) - break; + e0.push({ target: e.target, keys: e.keys }) + break case Y.YWeakLinkEvent: - e0.push({target: e.target}) - break; + e0.push({ target: e.target }) + break default: throw new Error('unexpected event type ' + e.constructor) } } @@ -512,14 +530,14 @@ export const testDeepObserveNewElementWithinQuotedRange = tc => { let e1 = [] link1.observeDeep((evts) => { e1 = [] - for (let e of evts) { + for (const e of evts) { switch (e.constructor) { case Y.YMapEvent: - e1.push({target: e.target, keys: e.keys}) - break; + e1.push({ target: e.target, keys: e.keys }) + break case Y.YWeakLinkEvent: - e1.push({target: e.target}) - break; + e1.push({ target: e.target }) + break default: throw new Error('unexpected event type ' + e.constructor) } } @@ -531,20 +549,20 @@ export const testDeepObserveNewElementWithinQuotedRange = tc => { m20.set('key', 'value') t.compare(e0.length, 1) t.compare(e0[0].target, m20) - t.compare(e0[0].keys, new Map([['key', {action:'add', oldValue: undefined}]])) + t.compare(e0[0].keys, new Map([['key', { action: 'add', oldValue: undefined }]])) testConnector.flushAllMessages() const m21 = array1.get(3) t.compare(e1.length, 1) t.compare(e1[0].target, m21) - t.compare(e1[0].keys, new Map([['key', {action:'add', oldValue: undefined}]])) + t.compare(e1[0].keys, new Map([['key', { action: 'add', oldValue: undefined }]])) } /** * @param {t.TestCase} tc */ -export const testMapDeepObserve = tc => { //FIXME +export const testMapDeepObserve = tc => { // FIXME const doc = new Y.Doc() const outer = doc.getMap('outer') const inner = new Y.Map() @@ -556,36 +574,35 @@ export const testMapDeepObserve = tc => { //FIXME let events = [] outer.observeDeep((evts) => { events = [] - for (let e of evts) { + for (const e of evts) { switch (e.constructor) { case Y.YMapEvent: - events.push({target: e.target, keys: e.keys}) - break; + events.push({ target: e.target, keys: e.keys }) + break case Y.YWeakLinkEvent: - events.push({target: e.target}) - break; + events.push({ target: e.target }) + break default: throw new Error('unexpected event type ' + e.constructor) } } }) - inner.set('key', 'value1') t.compare(events.length, 1) t.compare(events[0].target, inner) - t.compare(events[0].keys, new Map([['key', {action:'add', oldValue: undefined}]])) - + t.compare(events[0].keys, new Map([['key', { action: 'add', oldValue: undefined }]])) + events = [] inner.set('key', 'value2') t.compare(events.length, 1) t.compare(events[0].target, inner) - t.compare(events[0].keys, new Map([['key', {action:'update', oldValue: 'value1'}]])) + t.compare(events[0].keys, new Map([['key', { action: 'update', oldValue: 'value1' }]])) events = [] inner.delete('key') t.compare(events.length, 1) t.compare(events[0].target, inner) - t.compare(events[0].keys, new Map([['key', {action:'delete', oldValue: 'value2'}]])) + t.compare(events[0].keys, new Map([['key', { action: 'delete', oldValue: 'value2' }]])) } /** @@ -629,23 +646,25 @@ export const testDeepObserveRecursive = tc => { * @type {Array} */ let events = [] - m0.observeDeep((e) => events = e) + m0.observeDeep((e) => { + events = e + }) m1.set('test-key1', 'value1') t.compare(events.length, 1) t.compare(events[0].target, m1) - t.compare(events[0].keys, new Map([['test-key1', {action:'add', oldValue: undefined}]])) - + t.compare(events[0].keys, new Map([['test-key1', { action: 'add', oldValue: undefined }]])) + events = [] m2.set('test-key2', 'value2') t.compare(events.length, 1) t.compare(events[0].target, m2) - t.compare(events[0].keys, new Map([['test-key2', {action:'add', oldValue: undefined}]])) + t.compare(events[0].keys, new Map([['test-key2', { action: 'add', oldValue: undefined }]])) m1.delete('test-key1') t.compare(events.length, 1) t.compare(events[0].target, m1) - t.compare(events[0].keys, new Map([['test-key1', {action:'delete', oldValue: undefined}]])) + t.compare(events[0].keys, new Map([['test-key1', { action: 'delete', oldValue: undefined }]])) } /** @@ -662,7 +681,7 @@ export const testRemoteMapUpdate = tc => { map0.set('key', 3) // apply updated content first, link second - Y.applyUpdate(users[2], Y.encodeStateAsUpdate(users[0])) + Y.applyUpdate(users[2], Y.encodeStateAsUpdate(users[0])) Y.applyUpdate(users[2], Y.encodeStateAsUpdate(users[1])) // make sure that link can find the most recent block @@ -685,15 +704,15 @@ export const testRemoteMapUpdate = tc => { export const testTextBasic = tc => { const { testConnector, text0, text1 } = init(tc, { users: 2 }) - text0.insert(0, 'abcd') // 'abcd' - const link0 = text0.quote(1, 2) // quote: [bc] + text0.insert(0, 'abcd') // 'abcd' + const link0 = text0.quote(1, 2) // quote: [bc] t.compare(link0.toString(), 'bc') - text0.insert(2, 'ef') // 'abefcd', quote: [befc] - t.compare(link0.toString(), 'befc') - text0.delete(3, 3) // 'abe', quote: [be] + text0.insert(2, 'ef') // 'abefcd', quote: [befc] + t.compare(link0.toString(), 'befc') + text0.delete(3, 3) // 'abe', quote: [be] t.compare(link0.toString(), 'be') - text0.insertEmbed(3, link0) // 'abe[be]' - + text0.insertEmbed(3, link0) // 'abe[be]' + testConnector.flushAllMessages() const delta = text1.toDelta() @@ -709,15 +728,15 @@ export const testXmlTextBasic = tc => { const text0 = new Y.XmlText() xml0.insert(0, [text0]) - text0.insert(0, 'abcd') // 'abcd' - const link0 = text0.quote(1, 2) // quote: [bc] + text0.insert(0, 'abcd') // 'abcd' + const link0 = text0.quote(1, 2) // quote: [bc] t.compare(link0.toString(), 'bc') - text0.insert(2, 'ef') // 'abefcd', quote: [befc] - t.compare(link0.toString(), 'befc') - text0.delete(3, 3) // 'abe', quote: [be] + text0.insert(2, 'ef') // 'abefcd', quote: [befc] + t.compare(link0.toString(), 'befc') + text0.delete(3, 3) // 'abe', quote: [be] t.compare(link0.toString(), 'be') - text0.insertEmbed(3, link0) // 'abe[be]' - + text0.insertEmbed(3, link0) // 'abe[be]' + testConnector.flushAllMessages() const text1 = /** @type {Y.XmlText} */ (xml1.get(0)) const delta = text1.toDelta() @@ -733,8 +752,8 @@ export const testQuoteFormattedText = tc => { const text2 = /** @type {Y.XmlText} */ (doc.get('text2', Y.XmlText)) text.insert(0, 'abcde') - text.format(0, 1, {b:true}) - text.format(1, 3, {i:true}) // 'abcde' + text.format(0, 1, { b: true }) + text.format(1, 3, { i: true }) // 'abcde' const l1 = text.quote(0, 2) t.compare(l1.toString(), 'ab') const l2 = text.quote(2, 1) // 'c' @@ -748,8 +767,8 @@ export const testQuoteFormattedText = tc => { const delta = text2.toDelta() t.compare(delta, [ - {insert: l1}, - {insert: l2}, - {insert: l3}, + { insert: l1 }, + { insert: l2 }, + { insert: l3 } ]) -} \ No newline at end of file +}