Indicate to Yjs that content has been modified?

I have a Y.Map that contains a plain javascript array, and an UndoManager tracking its parent’s changes, e.g.

const doc = new Y.Doc()
const yarray = doc.getArray('entities')
const ymap = new Y.Map()
yarray.push([ymap])
ymap.set('position', [0, 0, 0])

const undoManager = new Y.UndoManager([yarray])

Later, I retrieve the array, modify-in-place, and set it back:

const pos = ymap.get('position')
pos[1] = 1.5
ymap.set('position', pos)

When I undo this change, events are fired, but the content is the new value (i.e. [0, 1.5, 0] on undo). Is there a way to indicate to Yjs that this modification-in-place should be treated as a real change?

I’m trying to avoid javascript garbage collection by avoiding allocating new arrays.

Hi @canadaduane,

I need to be more explicit about this. You shouldn’t modify objects that you maintain in Yjs. In order to avoid garbage collection, I reuse the values that you put into Yjs. So when you set ymap.set('position', [0, 0 0]), I’m not going to copy [0,0,0] to a new array and maintain that. Because then, I’d also need to create a new instance of [0, 0, 0] every time you retrieve the value.

Since you modified pos[1], the local Yjs instance thinks that the old value is [0, 1.5, 0].

Instead, you should simply copy/slice the position before you modify it. ymap.get('position').slice() // ready to be modified .

Ok, that’s what I suspected. There is no “dirty” flag to set, it’s just a matter of referential equality under the hood, and I’ll need to make copies. Thanks!