fire top-level events first

This commit is contained in:
Kevin Jahns 2020-10-29 12:40:39 +01:00
parent fd211731cc
commit 4fb9cc2a30
2 changed files with 31 additions and 0 deletions

View File

@ -284,6 +284,9 @@ const cleanupTransactions = (transactionCleanups, i) => {
.forEach(event => {
event.currentTarget = type
})
// sort events by path length so that top-level events are fired first.
events
.sort((event1, event2) => event1.path.length - event2.path.length)
// We don't need to check for events.length
// because we know it has at least one element
callEventHandlerListeners(type._dEH, events, transaction)

View File

@ -204,6 +204,34 @@ export const testInsertAndDeleteEventsForTypes = tc => {
compare(users)
}
/**
* This issue has been reported in https://discuss.yjs.dev/t/order-in-which-events-yielded-by-observedeep-should-be-applied/261/2
*
* Deep observers generate multiple events. When an array added at item at, say, position 0,
* and item 1 changed then the array-add event should fire first so that the change event
* path is correct. A array binding might lead to an inconsistent state otherwise.
*
* @param {t.TestCase} tc
*/
export const testObserveDeepEventOrder = tc => {
const { array0, users } = init(tc, { users: 2 })
/**
* @type {Array<any>}
*/
let events = []
array0.observeDeep(e => {
events = e
})
array0.insert(0, [new Y.Map()])
users[0].transact(() => {
array0.get(0).set('a', 'a')
array0.insert(0, [0])
})
for (let i = 1; i < events.length; i++) {
t.assert(events[i - 1].path.length <= events[i].path.length, 'path size increases, fire top-level events first')
}
}
/**
* @param {t.TestCase} tc
*/