Compare origin ids in item.integrate
This commit is contained in:
parent
1b17b5e400
commit
c635963747
@ -12,6 +12,8 @@ import {
|
||||
addToDeleteSet,
|
||||
ItemDeleted,
|
||||
findRootTypeKey,
|
||||
compareIDs,
|
||||
getItem,
|
||||
StructStore, ID, AbstractType, Y, Transaction // eslint-disable-line
|
||||
} from '../internals.js'
|
||||
|
||||
@ -133,6 +135,7 @@ export class AbstractItem extends AbstractStruct {
|
||||
* @param {Transaction} transaction
|
||||
*/
|
||||
integrate (transaction) {
|
||||
const store = transaction.y.store
|
||||
const id = this.id
|
||||
const parent = this.parent
|
||||
const parentSub = this.parentSub
|
||||
@ -165,7 +168,13 @@ export class AbstractItem extends AbstractStruct {
|
||||
} else {
|
||||
o = parent._start
|
||||
}
|
||||
/**
|
||||
* @type {Set<AbstractItem>}
|
||||
*/
|
||||
const conflictingItems = new Set()
|
||||
/**
|
||||
* @type {Set<AbstractItem>}
|
||||
*/
|
||||
const itemsBeforeOrigin = new Set()
|
||||
// Let c in conflictingItems, b in itemsBeforeOrigin
|
||||
// ***{origin}bbbb{this}{c,b}{c,b}{o}***
|
||||
@ -173,22 +182,22 @@ export class AbstractItem extends AbstractStruct {
|
||||
while (o !== null && o !== this.right) {
|
||||
itemsBeforeOrigin.add(o)
|
||||
conflictingItems.add(o)
|
||||
if (this.origin === o.origin) {
|
||||
if (compareIDs(this.origin, o.origin)) {
|
||||
// case 1
|
||||
if (o.id.client < id.client) {
|
||||
this.left = o
|
||||
conflictingItems.clear()
|
||||
}
|
||||
} else if (itemsBeforeOrigin.has(o.origin)) {
|
||||
} // TODO: verify break else?
|
||||
} else if (o.origin !== null && itemsBeforeOrigin.has(getItem(store, o.origin))) {
|
||||
// case 2
|
||||
if (!conflictingItems.has(o.origin)) {
|
||||
if (o.origin === null || !conflictingItems.has(getItem(store, o.origin))) {
|
||||
this.left = o
|
||||
conflictingItems.clear()
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
// TODO: try to use right_origin instead.
|
||||
// TODO: experiment with rightOrigin.
|
||||
// Then you could basically omit conflictingItems!
|
||||
// Note: you probably can't use right_origin in every case.. only when setting _left
|
||||
o = o.right
|
||||
@ -220,7 +229,7 @@ export class AbstractItem extends AbstractStruct {
|
||||
if (parentSub === null && this.countable) {
|
||||
parent._length += length
|
||||
}
|
||||
addStruct(transaction.y.store, this)
|
||||
addStruct(store, this)
|
||||
if (parent !== null) {
|
||||
maplib.setIfUndefined(transaction.changed, parent, set.create).add(parentSub)
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
GC,
|
||||
splitItem,
|
||||
compareIDs,
|
||||
addToDeleteSet,
|
||||
StructStore, Transaction, ID, AbstractType // eslint-disable-line
|
||||
} from '../internals.js'
|
||||
|
||||
@ -53,6 +54,13 @@ export class ItemDeleted extends AbstractItem {
|
||||
copy (id, left, origin, right, rightOrigin, parent, parentSub) {
|
||||
return new ItemDeleted(id, left, origin, right, rightOrigin, parent, parentSub, this.length)
|
||||
}
|
||||
/**
|
||||
* @param {Transaction} transaction
|
||||
*/
|
||||
integrate (transaction) {
|
||||
super.integrate(transaction)
|
||||
addToDeleteSet(transaction.deleteSet, this.id, this.length)
|
||||
}
|
||||
/**
|
||||
* @param {StructStore} store
|
||||
* @param {number} diff
|
||||
|
@ -125,6 +125,16 @@ export const find = (store, id) => {
|
||||
return structs[findIndexSS(structs, id.clock)]
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
|
||||
*
|
||||
* @param {StructStore} store
|
||||
* @param {ID} id
|
||||
* @return {AbstractItem}
|
||||
*/
|
||||
// @ts-ignore
|
||||
export const getItem = (store, id) => find(store, id)
|
||||
|
||||
/**
|
||||
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
|
||||
*
|
||||
|
@ -95,16 +95,16 @@ export class Y extends Observable {
|
||||
callEventHandlerListeners(type._dEH, [events, transaction])
|
||||
})
|
||||
// only call afterTransaction listeners if anything changed
|
||||
const transactionChangedContent = transaction.changedParentTypes.size !== 0
|
||||
const transactionChangedContent = transaction.changedParentTypes.size > 0 || transaction.deleteSet.clients.size > 0
|
||||
if (transactionChangedContent) {
|
||||
transaction.afterState = getStates(transaction.y.store)
|
||||
// when all changes & events are processed, emit afterTransaction event
|
||||
this.emit('afterTransaction', [this, transaction])
|
||||
// transaction cleanup
|
||||
const store = transaction.y.store
|
||||
const ds = transaction.deleteSet
|
||||
// replace deleted items with ItemDeleted / GC
|
||||
sortAndMergeDeleteSet(ds)
|
||||
this.emit('afterTransaction', [this, transaction])
|
||||
/**
|
||||
* @type {Set<ItemDeleted|GC>}
|
||||
*/
|
||||
|
@ -63,7 +63,7 @@ export class TestYInstance extends Y.Y {
|
||||
this.mMux = createMutex()
|
||||
testConnector.allConns.add(this)
|
||||
// set up observe on local model
|
||||
this.on('afterTransaction', afterTransaction)
|
||||
this.on('afterTransactionCleanup', afterTransaction)
|
||||
this.connect()
|
||||
}
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user