diff --git a/src/types/AbstractType.js b/src/types/AbstractType.js index 43c6127d..8a291af1 100644 --- a/src/types/AbstractType.js +++ b/src/types/AbstractType.js @@ -735,6 +735,29 @@ export const typeListInsertGenerics = (transaction, parent, index, content) => { return typeListInsertGenericsAfter(transaction, parent, n, content) } +/** + * Pushing content is special as we generally want to push after the last item. So we don't have to update + * the serach marker. + * + * @param {Transaction} transaction + * @param {AbstractType} parent + * @param {Array|Array|number|null|string|Uint8Array>} content + * + * @private + * @function + */ +export const typeListPushGenerics = (transaction, parent, content) => { + // Use the marker with the highest index and iterate to the right. + const marker = (parent._searchMarker || []).reduce((maxMarker, currMarker) => currMarker.index > maxMarker.index ? currMarker : maxMarker, { index: 0, p: parent._start }) + let n = marker.p + if (n) { + while (n.right) { + n = n.right + } + } + return typeListInsertGenericsAfter(transaction, parent, n, content) +} + /** * @param {Transaction} transaction * @param {AbstractType} parent diff --git a/src/types/YArray.js b/src/types/YArray.js index 7c210fa6..63c07a6b 100644 --- a/src/types/YArray.js +++ b/src/types/YArray.js @@ -10,6 +10,7 @@ import { typeListForEach, typeListCreateIterator, typeListInsertGenerics, + typeListPushGenerics, typeListDelete, typeListMap, YArrayRefID, @@ -142,9 +143,17 @@ export class YArray extends AbstractType { * Appends content to this YArray. * * @param {Array} content Array of content to append. + * + * @todo Use the following implementation in all types. */ push (content) { - this.insert(this.length, content) + if (this.doc !== null) { + transact(this.doc, transaction => { + typeListPushGenerics(transaction, this, content) + }) + } else { + /** @type {Array} */ (this._prelimContent).push(...content) + } } /**