handle local/remote autoload edge cases
This commit is contained in:
		
							parent
							
								
									9df5016667
								
							
						
					
					
						commit
						4154b12f14
					
				@ -132,4 +132,8 @@ export class ContentDoc {
 | 
			
		||||
 * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
 | 
			
		||||
 * @return {ContentDoc}
 | 
			
		||||
 */
 | 
			
		||||
export const readContentDoc = decoder => new ContentDoc(new Doc({ guid: decoder.readString(), ...decoder.readAny() }))
 | 
			
		||||
export const readContentDoc = decoder => {
 | 
			
		||||
  const guid = decoder.readString()
 | 
			
		||||
  const opts = decoder.readAny()
 | 
			
		||||
  return new ContentDoc(new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false }))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,7 @@ export const generateNewClientId = random.uint32
 | 
			
		||||
 * @property {string | null} [DocOpts.collectionid] Associate this document with a collection. This only plays a role if your provider has a concept of collection.
 | 
			
		||||
 * @property {any} [DocOpts.meta] Any kind of meta information you want to associate with this document. If this is a subdocument, remote peers will store the meta information as well.
 | 
			
		||||
 * @property {boolean} [DocOpts.autoLoad] If a subdocument, automatically load document. If this is a subdocument, remote peers will load the document as well automatically.
 | 
			
		||||
 * @property {boolean} [DocOpts.shouldLoad] Whether the document should be synced by the provider now. This is toggled to true when you call ydoc.load()
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -38,7 +39,7 @@ export class Doc extends Observable {
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {DocOpts} [opts] configuration
 | 
			
		||||
   */
 | 
			
		||||
  constructor ({ guid = random.uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false } = {}) {
 | 
			
		||||
  constructor ({ guid = random.uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true } = {}) {
 | 
			
		||||
    super()
 | 
			
		||||
    this.gc = gc
 | 
			
		||||
    this.gcFilter = gcFilter
 | 
			
		||||
@ -67,7 +68,7 @@ export class Doc extends Observable {
 | 
			
		||||
     * @type {Item?}
 | 
			
		||||
     */
 | 
			
		||||
    this._item = null
 | 
			
		||||
    this.shouldLoad = autoLoad
 | 
			
		||||
    this.shouldLoad = shouldLoad
 | 
			
		||||
    this.autoLoad = autoLoad
 | 
			
		||||
    this.meta = meta
 | 
			
		||||
  }
 | 
			
		||||
@ -252,12 +253,13 @@ export class Doc extends Observable {
 | 
			
		||||
        // @ts-ignore
 | 
			
		||||
        content.doc = null
 | 
			
		||||
      } else {
 | 
			
		||||
        content.doc = new Doc({ guid: this.guid, ...content.opts })
 | 
			
		||||
        content.doc = new Doc({ guid: this.guid, ...content.opts, shouldLoad: false })
 | 
			
		||||
        content.doc._item = item
 | 
			
		||||
      }
 | 
			
		||||
      transact(/** @type {any} */ (item).parent.doc, transaction => {
 | 
			
		||||
        const doc = content.doc
 | 
			
		||||
        if (!item.deleted) {
 | 
			
		||||
          transaction.subdocsAdded.add(content.doc)
 | 
			
		||||
          transaction.subdocsAdded.add(doc)
 | 
			
		||||
        }
 | 
			
		||||
        transaction.subdocsRemoved.add(this)
 | 
			
		||||
      }, null, true)
 | 
			
		||||
 | 
			
		||||
@ -88,7 +88,7 @@ export const testSubdoc = tc => {
 | 
			
		||||
    subdocs.get('a').load()
 | 
			
		||||
    t.compare(event, [[], [], ['a']])
 | 
			
		||||
 | 
			
		||||
    subdocs.set('b', new Y.Doc({ guid: 'a' }))
 | 
			
		||||
    subdocs.set('b', new Y.Doc({ guid: 'a', shouldLoad: false }))
 | 
			
		||||
    t.compare(event, [['a'], [], []])
 | 
			
		||||
    subdocs.get('b').load()
 | 
			
		||||
    t.compare(event, [[], [], ['a']])
 | 
			
		||||
@ -124,3 +124,92 @@ export const testSubdoc = tc => {
 | 
			
		||||
    t.compare(Array.from(doc2.getSubdocGuids()), ['a', 'c'])
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {t.TestCase} tc
 | 
			
		||||
 */
 | 
			
		||||
export const testSubdocLoadEdgeCases = tc => {
 | 
			
		||||
  const ydoc = new Y.Doc()
 | 
			
		||||
  const yarray = ydoc.getArray()
 | 
			
		||||
  const subdoc1 = new Y.Doc()
 | 
			
		||||
  /**
 | 
			
		||||
   * @type {any}
 | 
			
		||||
   */
 | 
			
		||||
  let lastEvent = null
 | 
			
		||||
  ydoc.on('subdocs', event => {
 | 
			
		||||
    lastEvent = event
 | 
			
		||||
  })
 | 
			
		||||
  yarray.insert(0, [subdoc1])
 | 
			
		||||
  t.assert(subdoc1.shouldLoad)
 | 
			
		||||
  t.assert(subdoc1.autoLoad === false)
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.loaded.has(subdoc1))
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.added.has(subdoc1))
 | 
			
		||||
  // destroy and check whether lastEvent adds it again to added (it shouldn't)
 | 
			
		||||
  subdoc1.destroy()
 | 
			
		||||
  const subdoc2 = yarray.get(0)
 | 
			
		||||
  t.assert(subdoc1 !== subdoc2)
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.added.has(subdoc2))
 | 
			
		||||
  t.assert(lastEvent !== null && !lastEvent.loaded.has(subdoc2))
 | 
			
		||||
  // load
 | 
			
		||||
  subdoc2.load()
 | 
			
		||||
  t.assert(lastEvent !== null && !lastEvent.added.has(subdoc2))
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.loaded.has(subdoc2))
 | 
			
		||||
  // apply from remote
 | 
			
		||||
  const ydoc2 = new Y.Doc()
 | 
			
		||||
  ydoc2.on('subdocs', event => {
 | 
			
		||||
    lastEvent = event
 | 
			
		||||
  })
 | 
			
		||||
  Y.applyUpdate(ydoc2, Y.encodeStateAsUpdate(ydoc))
 | 
			
		||||
  const subdoc3 = ydoc2.getArray().get(0)
 | 
			
		||||
  t.assert(subdoc3.shouldLoad === false)
 | 
			
		||||
  t.assert(subdoc3.autoLoad === false)
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.added.has(subdoc3))
 | 
			
		||||
  t.assert(lastEvent !== null && !lastEvent.loaded.has(subdoc3))
 | 
			
		||||
  // load
 | 
			
		||||
  subdoc3.load()
 | 
			
		||||
  t.assert(subdoc3.shouldLoad)
 | 
			
		||||
  t.assert(lastEvent !== null && !lastEvent.added.has(subdoc3))
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.loaded.has(subdoc3))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {t.TestCase} tc
 | 
			
		||||
 */
 | 
			
		||||
export const testSubdocLoadEdgeCasesAutoload = tc => {
 | 
			
		||||
  const ydoc = new Y.Doc()
 | 
			
		||||
  const yarray = ydoc.getArray()
 | 
			
		||||
  const subdoc1 = new Y.Doc({ autoLoad: true })
 | 
			
		||||
  /**
 | 
			
		||||
   * @type {any}
 | 
			
		||||
   */
 | 
			
		||||
  let lastEvent = null
 | 
			
		||||
  ydoc.on('subdocs', event => {
 | 
			
		||||
    lastEvent = event
 | 
			
		||||
  })
 | 
			
		||||
  yarray.insert(0, [subdoc1])
 | 
			
		||||
  t.assert(subdoc1.shouldLoad)
 | 
			
		||||
  t.assert(subdoc1.autoLoad)
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.loaded.has(subdoc1))
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.added.has(subdoc1))
 | 
			
		||||
  // destroy and check whether lastEvent adds it again to added (it shouldn't)
 | 
			
		||||
  subdoc1.destroy()
 | 
			
		||||
  const subdoc2 = yarray.get(0)
 | 
			
		||||
  t.assert(subdoc1 !== subdoc2)
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.added.has(subdoc2))
 | 
			
		||||
  t.assert(lastEvent !== null && !lastEvent.loaded.has(subdoc2))
 | 
			
		||||
  // load
 | 
			
		||||
  subdoc2.load()
 | 
			
		||||
  t.assert(lastEvent !== null && !lastEvent.added.has(subdoc2))
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.loaded.has(subdoc2))
 | 
			
		||||
  // apply from remote
 | 
			
		||||
  const ydoc2 = new Y.Doc()
 | 
			
		||||
  ydoc2.on('subdocs', event => {
 | 
			
		||||
    lastEvent = event
 | 
			
		||||
  })
 | 
			
		||||
  Y.applyUpdate(ydoc2, Y.encodeStateAsUpdate(ydoc))
 | 
			
		||||
  const subdoc3 = ydoc2.getArray().get(0)
 | 
			
		||||
  t.assert(subdoc1.shouldLoad)
 | 
			
		||||
  t.assert(subdoc1.autoLoad)
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.added.has(subdoc3))
 | 
			
		||||
  t.assert(lastEvent !== null && lastEvent.loaded.has(subdoc3))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user