yjs/y-indexeddb

Syncing has unexpected type

Closed this issue · 4 comments

Describe the bug

Unexpected Type

A clear and concise description of what the bug is.

To Reproduce

While pushing an object into a Y.Array, there is a Unexpected case error in the console

This is the stack

create3 @ error.js:12
unexpectedCase @ error.js:29
findRootTypeKey @ ID.js:89
write @ Item.js:675
writeStructs @ encoding.js:67
(anonymous) @ encoding.js:100
writeClientsStructs @ encoding.js:99
writeStateAsUpdate @ encoding.js:505
encodeStateAsUpdateV2 @ encoding.js:524
encodeStateAsUpdate @ encoding.js:555
(anonymous) @ y-indexeddb.js:40
Promise.then
storeState @ y-indexeddb.js:38
(anonymous) @ y-indexeddb.js:117
setTimeout
IndexeddbPersistence._storeUpdate @ y-indexeddb.js:116
(anonymous) @ observable.js:82
emit @ observable.js:82
cleanupTransactions @ Transaction.js:364
transact @ Transaction.js:440
push @ YArray.js:157

Followed by an abortion of the syncing
Expected behavior

No error and proper syncing

Environment Information

  • Chrome, Firefox
  • yjs "13.6.18"
  • y-indexeddb "9.0.12",

[x] This issue is a blocker for my project.

Removing this line, removes the error, but also the persistency

const ydocIndexeddbProvider = new IndexeddbPersistence(docName, ydoc);

Unable to reproduce

It is this function that throws

export const findRootTypeKey = type => {
  // @ts-ignore _y must be defined, otherwise unexpected case
  for (const [key, value] of type.doc.share.entries()) {
    if (value === type) {
      return key
    }
  }
  throw error.unexpectedCase()
}

Can you explain how the === may not be met? - in particular in light of using a Y.Array on JS (proxy [vue]) objects

The test contains some kind of recursion: value is a value of the map type.doc.share.entries(), which howeve is compared against type - but the mentioned map comes from a nested field of type

More info: It happens when the syncing from IndexedDB is still in progress and we already access somewhere else yDoc.getArray("events")

EDIT: If i wait with calling yDoc.getArray("events") until ydocIndexeddbProvider.on('synced') has been called, the error disappears! For example by using a promise and resolving it in the on-synced callback - and (only) then (i.e. upon then) calling the getArray