toDelta doesnt create transaction - fixes #506

This commit is contained in:
Kevin Jahns 2023-03-11 09:13:27 +01:00
parent da8bacfc78
commit 227018f5c7
4 changed files with 23 additions and 15 deletions

View File

@ -1018,15 +1018,7 @@ export class YText extends AbstractType {
str = '' str = ''
} }
} }
// snapshots are merged again after the transaction, so we need to keep the const computeDelta = () => {
// transalive until we are done
transact(doc, transaction => {
if (snapshot) {
splitSnapshotAffectedStructs(transaction, snapshot)
}
if (prevSnapshot) {
splitSnapshotAffectedStructs(transaction, prevSnapshot)
}
while (n !== null) { while (n !== null) {
if (isVisible(n, snapshot) || (prevSnapshot !== undefined && isVisible(n, prevSnapshot))) { if (isVisible(n, snapshot) || (prevSnapshot !== undefined && isVisible(n, prevSnapshot))) {
switch (n.content.constructor) { switch (n.content.constructor) {
@ -1079,7 +1071,22 @@ export class YText extends AbstractType {
n = n.right n = n.right
} }
packStr() packStr()
}, 'cleanup') }
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 {
computeDelta()
}
return ops return ops
} }

View File

@ -257,8 +257,7 @@ export class YXmlFragment extends AbstractType {
* @return {string} The string representation of all children. * @return {string} The string representation of all children.
*/ */
toString () { toString () {
// toString can result in many cleanup transactions. We wrap all cleanup transactions here to reduce the work return typeListMap(this, xml => xml.toString()).join('')
return transact(/** @type {Doc} */ (this.doc), () => typeListMap(this, xml => xml.toString()).join(''))
} }
/** /**

View File

@ -156,13 +156,15 @@ export class Doc extends Observable {
* that happened inside of the transaction are sent as one message to the * that happened inside of the transaction are sent as one message to the
* other peers. * other peers.
* *
* @param {function(Transaction):void} f The function that should be executed as a transaction * @template T
* @param {function(Transaction):T} f The function that should be executed as a transaction
* @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin
* @return T
* *
* @public * @public
*/ */
transact (f, origin = null) { transact (f, origin = null) {
transact(this, f, origin) return transact(this, f, origin)
} }
/** /**

View File

@ -33,7 +33,7 @@ export const testOriginInTransaction = _tc => {
doc.on('afterTransaction', (tr) => { doc.on('afterTransaction', (tr) => {
origins.push(tr.origin) origins.push(tr.origin)
if (origins.length <= 1) { if (origins.length <= 1) {
ytext.toDelta() ytext.toDelta(Y.snapshot(doc)) // adding a snapshot forces toDelta to create a cleanup transaction
doc.transact(() => { doc.transact(() => {
ytext.insert(0, 'a') ytext.insert(0, 'a')
}, 'nested') }, 'nested')