fix nicks test

This commit is contained in:
Kevin Jahns
2025-05-01 14:44:24 +02:00
parent 316dfd28f6
commit a5e390160c
4 changed files with 20 additions and 15 deletions

View File

@@ -153,29 +153,28 @@ export class DiffAttributionManager {
* @param {Doc} nextDoc
*/
constructor (prevDoc, nextDoc) {
const nextDocInserts = createInsertionSetFromStructStore(nextDoc.store)
const prevDocInserts = createInsertionSetFromStructStore(prevDoc.store)
const nextDocDeletes = createDeleteSetFromStructStore(nextDoc.store)
const prevDocDeletes = createDeleteSetFromStructStore(prevDoc.store)
this.inserts = createIdMapFromIdSet(diffIdSet(nextDocInserts, prevDocInserts), [])
const _nextDocInserts = createInsertionSetFromStructStore(nextDoc.store, false) // unmaintained
const _prevDocInserts = createInsertionSetFromStructStore(prevDoc.store, false) // unmaintained
const nextDocDeletes = createDeleteSetFromStructStore(nextDoc.store) // maintained
const prevDocDeletes = createDeleteSetFromStructStore(prevDoc.store) // maintained
this.inserts = createIdMapFromIdSet(diffIdSet(_nextDocInserts, _prevDocInserts), [])
this.deletes = createIdMapFromIdSet(diffIdSet(nextDocDeletes, prevDocDeletes), [])
this._prevDoc = prevDoc
this._prevDocStore = prevDoc.store
this._nextDoc = nextDoc
// update before observer calls fired
this._nextBOH = nextDoc.on('beforeObserverCalls', tr => {
// update inserts
insertIntoIdSet(nextDocInserts, tr.insertSet)
const diffInserts = diffIdSet(tr.insertSet, prevDocInserts)
const diffInserts = diffIdSet(tr.insertSet, _prevDocInserts)
insertIntoIdMap(this.inserts, createIdMapFromIdSet(diffInserts, []))
// update deletes
insertIntoIdSet(nextDocDeletes, tr.deleteSet)
const diffDeletes = diffIdSet(tr.deleteSet, prevDocDeletes)
insertIntoIdMap(this.deletes, createIdMapFromIdSet(diffDeletes, []))
// @todo fire update ranges on `diffInserts` and `diffDeletes`
})
this._prevBOH = prevDoc.on('beforeObserverCalls', tr => {
insertIntoIdSet(_prevDocInserts, tr.insertSet)
insertIntoIdSet(prevDocDeletes, tr.deleteSet)
this.inserts = diffIdMap(this.inserts, tr.insertSet)
this.deletes = diffIdMap(this.deletes, tr.deleteSet)
// @todo fire update ranges on `tr.insertSet` and `tr.deleteSet`
@@ -199,7 +198,7 @@ export class DiffAttributionManager {
const deleted = item.deleted || /** @type {any} */ (item.parent).doc !== this._nextDoc
const slice = (deleted ? this.deletes : this.inserts).slice(item.id, item.length)
let content = slice.length === 1 ? item.content : item.content.copy()
if (content instanceof ContentDeleted && slice[0].attrs != null) {
if (content instanceof ContentDeleted && slice[0].attrs != null && !this.inserts.hasId(item.id)) {
// Retrieved item is never more fragmented than the newer item.
const prevItem = getItem(this._prevDocStore, item.id)
content = prevItem.length > 1 ? prevItem.content.copy() : prevItem.content

View File

@@ -452,8 +452,9 @@ export const createDeleteSetFromStructStore = ss => {
/**
* @param {import('../internals.js').StructStore} ss
* @param {boolean} filterDeleted
*/
export const createInsertionSetFromStructStore = ss => {
export const createInsertionSetFromStructStore = (ss, filterDeleted) => {
const idset = createIdSet()
ss.clients.forEach((structs, client) => {
/**
@@ -462,11 +463,12 @@ export const createInsertionSetFromStructStore = ss => {
const iditems = []
for (let i = 0; i < structs.length; i++) {
const struct = structs[i]
if (!struct.deleted) {
if (!(filterDeleted && struct.deleted)) {
const clock = struct.id.clock
let len = struct.length
if (i + 1 < structs.length) {
for (let next = structs[i + 1]; i + 1 < structs.length && !next.deleted; next = structs[++i + 1]) {
// eslint-disable-next-line
for (let next = structs[i + 1]; i + 1 < structs.length && !(filterDeleted && next.deleted); next = structs[++i + 1]) {
len += next.length
}
}

View File

@@ -2343,10 +2343,10 @@ export const testAttributedDiffing = _tc => {
const ytext = ydoc.getText()
ytext.applyDelta([{ retain: 4, attributes: { italic: true } }, { retain: 2 }, { delete: 5 }, { insert: 'attributions' }])
// this represents to all insertions of ydoc
const insertionSet = Y.createInsertionSetFromStructStore(ydoc.store)
const insertionSet = Y.createInsertionSetFromStructStore(ydoc.store, false)
const deleteSet = Y.createDeleteSetFromStructStore(ydoc.store)
// exclude the changes from `ydocVersion0`
const insertionSetDiff = Y.diffIdSet(insertionSet, Y.createInsertionSetFromStructStore(ydocVersion0.store))
const insertionSetDiff = Y.diffIdSet(insertionSet, Y.createInsertionSetFromStructStore(ydocVersion0.store, false))
const deleteSetDiff = Y.diffIdSet(deleteSet, Y.createDeleteSetFromStructStore(ydocVersion0.store))
// assign attributes to the diff
const attributedInsertions = createIdMapFromIdSet(insertionSetDiff, [new Y.Attribution('insert', 'Bob')])

View File

@@ -380,9 +380,11 @@ export const testElementAttributedContentViaDiffer = _tc => {
*/
export const testAttributionManagerSimpleExample = _tc => {
const ydoc = new Y.Doc()
ydoc.clientID = 0
// create some initial content
ydoc.getXmlFragment().insert(0, [new Y.XmlText('hello world')])
const ydocFork = new Y.Doc()
ydocFork.clientID = 1
Y.applyUpdate(ydocFork, Y.encodeStateAsUpdate(ydoc))
// modify the fork
// append a span element
@@ -390,6 +392,8 @@ export const testAttributionManagerSimpleExample = _tc => {
const ytext = /** @type {Y.XmlText} */ (ydocFork.getXmlFragment().get(0))
// make "hello" italic
ytext.format(0, 5, { italic: true })
ytext.insert(11, 'deleteme')
ytext.delete(11, 8)
ytext.insert(11, '!')
// highlight the changes
console.log(JSON.stringify(ydocFork.getXmlFragment().getContentDeep(Y.createAttributionManagerFromDiff(ydoc, ydocFork)), null, 2))