Text vs. Array merge outcomes

Hello. I was testing some of the more obscure merge cases and was intrigued by the fact that arrays and text seem to behave differently for seems like identical scenarios.
Here’s the test I am running (the test passes):

export const testInsertAfterReplaceBeforeIndexAndIndexAndBeyond = tc => {
  const { testConnector, users, text0: txt0, text1: txt1, array0: arr0, array1: arr1 } = init(tc, { users: 2 })
  txt0.insert(0, 'abc')
  arr0.insert(0, ['a', 'b', 'c'])
  testConnector.flushAllMessages()
  txt0.delete(0, 3)
  arr0.delete(0, 3)
  txt0.insert(0, '1')
  arr0.insert(0, ['1'])
  txt1.insert(1, '2')
  arr1.insert(1, ['2'])
  testConnector.flushAllMessages()
  t.assert(txt0.toString() === '21', 'last-to-first')
  t.compare(arr0.toJSON(), ['1', '2'], 'first-to-last')
}

As you can see the last two lines indicate different resolutions.

My question are:

  1. Are the results meant to be non-deterministic? If that’s the case then my test probably is failing to trigger alternative resolutions and I’d like to know what it takes to make that happen.

  2. If the results are meant to be deterministic, was the choice of different resolution intentional? Is there something about text that makes this resolution better?

Thank you!

Hi @yann-achard,

The result of a conflict-resolution depends on the client-id of the document. The tests are always deterministic because we manually assign client-ids to the documents (e.g. text0 has client-id 0, text1 has client-id 1, and so forth).

In your example, there is no conflict resolution going on. Client 0 deleted the content and then inserted “1”. The text type has a search optimization that inserts after the deleted content and the array implementation inserts “1” before the deleted content. This is why the results are different.

In the real-world, the results of conflict resolution should be considered non-deterministic. However, it adheres to some rules. 1. Insertions do not interleave (e.g. insert(0, “xy”) || insert(0, “ab”) will never result in “xayb”). 2. Imagine the content to be a linked list of characters or JSON items. If you insert between item X and item Y, then the result after merging will ensure that your content is between item X and item Y. 3. All peers end up with the same content.