From 6886881b761b4057401f69827143d7f4ac5daae9 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Tue, 25 May 2021 21:17:01 +0200 Subject: [PATCH] fix #297 (length not updated) by updating search markers properly --- src/structs/Item.js | 13 +++++++++++++ tests/y-array.tests.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/structs/Item.js b/src/structs/Item.js index b88407af..b8d58f6a 100644 --- a/src/structs/Item.js +++ b/src/structs/Item.js @@ -566,6 +566,19 @@ export class Item extends AbstractStruct { this.content.constructor === right.content.constructor && this.content.mergeWith(right.content) ) { + const searchMarker = /** @type {AbstractType} */ (this.parent)._searchMarker + if (searchMarker) { + searchMarker.forEach(marker => { + if (marker.p === right) { + // right is going to be "forgotten" so we need to update the marker + marker.p = this + // adjust marker index + if (!this.deleted) { + marker.index -= this.length + } + } + }) + } if (right.keep) { this.keep = true } diff --git a/tests/y-array.tests.js b/tests/y-array.tests.js index f86d3947..23931f4d 100644 --- a/tests/y-array.tests.js +++ b/tests/y-array.tests.js @@ -32,6 +32,35 @@ export const testSlice = tc => { t.compareArrays(arr.slice(0, 2), [0, 1]) } +/** + * Debugging yjs#297 - a critical bug connected to the search-marker approach + * + * @param {t.TestCase} tc + */ +export const testLengthIssue = tc => { + const doc1 = new Y.Doc() + const arr = doc1.getArray('array') + arr.push([0, 1, 2, 3]) + arr.delete(0) + arr.insert(0, [0]) + t.assert(arr.length === arr.toArray().length) + doc1.transact(() => { + arr.delete(1) + t.assert(arr.length === arr.toArray().length) + arr.insert(1, [1]) + t.assert(arr.length === arr.toArray().length) + arr.delete(2) + t.assert(arr.length === arr.toArray().length) + arr.insert(2, [2]) + t.assert(arr.length === arr.toArray().length) + }) + t.assert(arr.length === arr.toArray().length) + arr.delete(1) + t.assert(arr.length === arr.toArray().length) + arr.insert(1, [1]) + t.assert(arr.length === arr.toArray().length) +} + /** * @param {t.TestCase} tc */