Delta calculate error in transaction

Describe the bug
Trasaction calculate delta error, when i swap array order.

To Reproduce
a YArray: [1, 3, 2],
swap the order to: [1, 2, 3], use:

yarray.delete(2, 1)     // delete
yarray.insert(1, [2])   // insert

Put two operate in a transaction like this:

ydoc.transact(() => {
    yarray.delete(2, 1)     // delete
    yarray.insert(1, [2])   // insert
})

the delta is error:
image

If just use two operate, there have 2 correct delta in each event:

hi, @JackieTang

I didn’t reproduce the error you described via the demo below.

const Y = require('yjs')

const doc = new Y.Doc()

const arr = doc.getArray('arr')

arr.insert(0, [1, 3, 2])

console.log(arr.toJSON())
// [ 1, 3, 2 ]

doc.transact(() => {
  arr.delete(2, 1)
  arr.insert(1, [2])
})

console.log(arr.toJSON())
// [ 1, 2, 3 ]

The deltas are equivalent.

In two transactions, the deltas say:

  • Keep the 1 and 3, then delete the 2
  • Keep the 1, then insert the 2

In one transaction, the delta says:

  • Keep the 1
  • Delete the 3
  • Keep the 2
  • Insert the 3

The result is the same, but the steps are compressed in the transaction.

Thx for reply, the delta compressed not as you expected.
Reproduce below:

const Y = require('yjs')
const doc = new Y.Doc()
const arr = doc.getArray('arr')
arr.insert(0, ['a', 'c', 'b'])
console.log(arr.toJSON())
// [ 'a', 'c', 'b' ]

arr.observeDeep(function (events) {
  events.forEach((event) => {
    console.log(event.delta)
  })
  /**
   *  One transaction log:
   *  [ { retain: 1 }, { insert: [ 'b' ] }, { retain: 1 }, { delete: 1 } ]
   *  insert 'b' at position 1.  result: ['a', 'b', 'c', 'b']
   *  delete position 1.  result: ['a', 'c', 'b']
   *  Incorrect.
   */

  /**
   *  Two transaction have 2 logs:
   *  [ { retain: 2 }, { delete: 1 } ]          // delete 'b' at position 2
   *  [ { retain: 1 }, { insert: [ 'b' ] } ]    // insert 'b' at position 1
   *  Correctly.
   */
})

// One transaction
doc.transact(() => {
  arr.delete(2, 1) // delete 'b', arr = ['a', 'c']
  arr.insert(1, ['b']) // insert 'b' at position 1, arr = ['a', 'b', 'c']
})

// Two transactions
// arr.delete(2, 1)
// arr.insert(1, ['b'])

console.log(arr.toJSON())
// Both result is [ 'a', 'b', 'c' ]

Thx for reply, the result of two ways in the arr is same, but delta error.
You can see reply above.

It looks correct to me. Why do you expect them to be the same? There are an infinite number of deltas that can converge to the same value. Maybe I’m missing something.

Maybe i misunderstand the retain means?
[ { retain: 1 }, { insert: [ 'b' ] }, { retain: 1 }, { delete: 1 } ] this delta for ['a', 'c', 'b'] means:

  • { retain: 1 }: keep ‘a’ at position 1 (index 0)
  • { insert: [ 'b' ] }: insert ‘b’ after ‘a’
  • { retain: 1 }: keep ‘c’ at position 2 (index 1)
  • { delete: 1 } delete 1 item at positon 3 (index 2)
    i should add all of retain and insert length before delete ?

retain means keep, but not necessarily at its original index.

retain means keep after previous steps of the delta have been applied.

  • { retain: 1 }: keep ‘a’ at position 1 (index 0)
  • { insert: [ 'b' ] }: insert ‘b’ after ‘a’ (index 1)
  • { retain: 1 }: keep ‘c’ now at position 3 (index 2)
  • { delete: 1 } delete 1 item now at positon 4 (index 3)
1 Like