[Bug?] unloading subdocs leads to endless loop

Unloading all subdocs (e.g., in order to reclaim their resources) seems to be a dangerous operation.

Try the following code

  const sharedDoc = new Y.Doc()
    sharedDoc.on('subdocs', (Event) => {
      const { added, removed, loaded } = Event
      console.log('  # added',added.size, '# removed',removed.size, '# loaded',loaded.size)
      console.log('  # SubDocs:',sharedDoc.getSubdocs().size)
    })

/**** create new subdoc (will also automatically be loaded) ****/

  const sharedMap = sharedDoc.getMap('sharedMap')
    console.log('adding subdoc to outer map')
    sharedMap.set('doc', new Y.Doc())

/**** unload subdoc... ****/

  console.log('unloading subdoc')
  sharedDoc.getSubdocs().forEach((SubDoc) => {
    SubDoc.destroy()
  })

and watch your browser’s console growing as the following lines are added over and over again:

  # added 1 # removed 1 # loaded 0
  # SubDocs: 1

(mind also the “added: 1”!)

Definitely a bug: it seems as if doc.getSubdocs() returns a reference(!) to an internal data structure - which is always a very bad idea.

Just change the above unloading loop to

  Array.from(sharedDoc.getSubdocs().values()).forEach((SubDoc) => {
    SubDoc.destroy()
  })

and try again: you will see that the subdoc is now unloaded as intended - but, still, mind the output from the subdocs event:

  # added 1 # removed 1 # loaded 0
  # SubDocs: 1

which is very misleading

Thanks for the research! That’s good to know.

You also may want to post bug reports on the issue page: GitHub - yjs/yjs: Shared data types for building collaborative software

Though, personal word of warning, the founder seems to have other priorities now, so it’s not unlikely to have your issue ignored. Still, could be good for ‘documentation’.