fix generating too many cleanup transactions. closes #506
This commit is contained in:
		
							parent
							
								
									7e40fc442d
								
							
						
					
					
						commit
						fe48efe64f
					
				@ -257,7 +257,8 @@ export class YXmlFragment extends AbstractType {
 | 
				
			|||||||
   * @return {string} The string representation of all children.
 | 
					   * @return {string} The string representation of all children.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  toString () {
 | 
					  toString () {
 | 
				
			||||||
    return typeListMap(this, xml => xml.toString()).join('')
 | 
					    // toString can result in many cleanup transactions. We wrap all cleanup transactions here to reduce the work
 | 
				
			||||||
 | 
					    return transact(/** @type {Doc} */ (this.doc), () => typeListMap(this, xml => xml.toString()).join(''))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
 | 
				
			|||||||
@ -376,15 +376,21 @@ const cleanupTransactions = (transactionCleanups, i) => {
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Implements the functionality of `y.transact(()=>{..})`
 | 
					 * Implements the functionality of `y.transact(()=>{..})`
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * @template T
 | 
				
			||||||
 * @param {Doc} doc
 | 
					 * @param {Doc} doc
 | 
				
			||||||
 * @param {function(Transaction):void} f
 | 
					 * @param {function(Transaction):T} f
 | 
				
			||||||
 * @param {any} [origin=true]
 | 
					 * @param {any} [origin=true]
 | 
				
			||||||
 | 
					 * @return {T}
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @function
 | 
					 * @function
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export const transact = (doc, f, origin = null, local = true) => {
 | 
					export const transact = (doc, f, origin = null, local = true) => {
 | 
				
			||||||
  const transactionCleanups = doc._transactionCleanups
 | 
					  const transactionCleanups = doc._transactionCleanups
 | 
				
			||||||
  let initialCall = false
 | 
					  let initialCall = false
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * @type {any}
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  let result = null
 | 
				
			||||||
  if (doc._transaction === null) {
 | 
					  if (doc._transaction === null) {
 | 
				
			||||||
    initialCall = true
 | 
					    initialCall = true
 | 
				
			||||||
    doc._transaction = new Transaction(doc, origin, local)
 | 
					    doc._transaction = new Transaction(doc, origin, local)
 | 
				
			||||||
@ -395,7 +401,7 @@ export const transact = (doc, f, origin = null, local = true) => {
 | 
				
			|||||||
    doc.emit('beforeTransaction', [doc._transaction, doc])
 | 
					    doc.emit('beforeTransaction', [doc._transaction, doc])
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    f(doc._transaction)
 | 
					    result = f(doc._transaction)
 | 
				
			||||||
  } finally {
 | 
					  } finally {
 | 
				
			||||||
    if (initialCall) {
 | 
					    if (initialCall) {
 | 
				
			||||||
      const finishCleanup = doc._transaction === transactionCleanups[0]
 | 
					      const finishCleanup = doc._transaction === transactionCleanups[0]
 | 
				
			||||||
@ -413,4 +419,5 @@ export const transact = (doc, f, origin = null, local = true) => {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,24 @@
 | 
				
			|||||||
import * as Y from '../src/index.js'
 | 
					import * as Y from '../src/index.js'
 | 
				
			||||||
import * as t from 'lib0/testing'
 | 
					import * as t from 'lib0/testing'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {t.TestCase} _tc
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const testAfterTransactionRecursion = _tc => {
 | 
				
			||||||
 | 
					  const ydoc = new Y.Doc()
 | 
				
			||||||
 | 
					  const yxml = ydoc.getXmlFragment('')
 | 
				
			||||||
 | 
					  ydoc.on('afterTransaction', tr => {
 | 
				
			||||||
 | 
					    if (tr.origin === 'test') {
 | 
				
			||||||
 | 
					      yxml.toJSON()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  ydoc.transact(_tr => {
 | 
				
			||||||
 | 
					    for (let i = 0; i < 15000; i++) {
 | 
				
			||||||
 | 
					      yxml.push([new Y.XmlText('a')])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }, 'test')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {t.TestCase} _tc
 | 
					 * @param {t.TestCase} _tc
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user