From 3741f43a116a81a288e4ad9f1231d4e129812076 Mon Sep 17 00:00:00 2001 From: Noel Levy Date: Mon, 12 Jun 2023 16:56:19 -0700 Subject: [PATCH] group cleanups for YText changes into a single transaction Fixes #522 but is still massively slow --- src/types/YText.js | 11 ++++++++++- src/utils/Transaction.js | 13 ++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/types/YText.js b/src/types/YText.js index 8f4f0b60..dad41bdc 100644 --- a/src/types/YText.js +++ b/src/types/YText.js @@ -859,12 +859,21 @@ export class YText extends AbstractType { _callObserver (transaction, parentSubs) { super._callObserver(transaction, parentSubs) const event = new YTextEvent(this, transaction, parentSubs) - const doc = transaction.doc callTypeObservers(this, transaction, event) // If a remote change happened, we try to cleanup potential formatting duplicates. + if (!transaction.local) { + transaction._yTexts.push(this) + } + } + + /** + * @param {Transaction} transaction + */ + _cleanup (transaction) { if (!transaction.local) { // check if another formatting item was inserted let foundFormattingItem = false + const doc = transaction.doc for (const [client, afterClock] of transaction.afterState.entries()) { const clock = transaction.beforeState.get(client) || 0 if (afterClock === clock) { diff --git a/src/utils/Transaction.js b/src/utils/Transaction.js index 1e553a90..ea04d1d1 100644 --- a/src/utils/Transaction.js +++ b/src/utils/Transaction.js @@ -11,7 +11,7 @@ import { Item, generateNewClientId, createID, - UpdateEncoderV1, UpdateEncoderV2, GC, StructStore, AbstractType, AbstractStruct, YEvent, Doc // eslint-disable-line + UpdateEncoderV1, UpdateEncoderV2, GC, StructStore, AbstractType, AbstractStruct, YEvent, Doc, YText // eslint-disable-line } from '../internals.js' import * as map from 'lib0/map' @@ -114,6 +114,10 @@ export class Transaction { * @type {Set} */ this.subdocsLoaded = new Set() + /** + * @type {Array} + */ + this._yTexts = [] } } @@ -295,6 +299,13 @@ const cleanupTransactions = (transactionCleanups, i) => { fs.push(() => doc.emit('afterTransaction', [transaction, doc])) }) callAll(fs, []) + if (transaction._yTexts.length > 0) { + transact(doc, () => { + transaction._yTexts.forEach(yText => { + yText._cleanup(transaction) + }) + }) + } } finally { // Replace deleted items with ItemDeleted / GC. // This is where content is actually remove from the Yjs Doc.