add whenSynced and isSynced property with refined logic
This commit is contained in:
		
							parent
							
								
									7f6c12a541
								
							
						
					
					
						commit
						7445a9ce5f
					
				@ -72,13 +72,57 @@ export class Doc extends Observable {
 | 
				
			|||||||
    this.shouldLoad = shouldLoad
 | 
					    this.shouldLoad = shouldLoad
 | 
				
			||||||
    this.autoLoad = autoLoad
 | 
					    this.autoLoad = autoLoad
 | 
				
			||||||
    this.meta = meta
 | 
					    this.meta = meta
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This is set to true when the persistence provider loaded the document from the database or when the `sync` event fires.
 | 
				
			||||||
 | 
					     * Note that not all providers implement this feature. Provider authors are encouraged to fire the `load` event when the doc content is loaded from the database.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @type {boolean}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.isLoaded = false
 | 
					    this.isLoaded = false
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This is set to true when the connection provider has successfully synced with a backend.
 | 
				
			||||||
 | 
					     * Note that when using peer-to-peer providers this event may not provide very useful.
 | 
				
			||||||
 | 
					     * Also note that not all providers implement this feature. Provider authors are encouraged to fire
 | 
				
			||||||
 | 
					     * the `sync` event when the doc has been synced (with `true` as a parameter) or if connection is
 | 
				
			||||||
 | 
					     * lost (with false as a parameter).
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    this.isSynced = false
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Promise that resolves once the document has been loaded from a presistence provider.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    this.whenLoaded = promise.create(resolve => {
 | 
					    this.whenLoaded = promise.create(resolve => {
 | 
				
			||||||
      this.on('load', () => {
 | 
					      this.on('load', () => {
 | 
				
			||||||
        this.isLoaded = true
 | 
					        this.isLoaded = true
 | 
				
			||||||
        resolve(this)
 | 
					        resolve(this)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					    const provideSyncedPromise = () => promise.create(resolve => {
 | 
				
			||||||
 | 
					      /**
 | 
				
			||||||
 | 
					       * @param {boolean} isSynced
 | 
				
			||||||
 | 
					       */
 | 
				
			||||||
 | 
					      const eventHandler = (isSynced) => {
 | 
				
			||||||
 | 
					        if (isSynced === undefined || isSynced === true) {
 | 
				
			||||||
 | 
					          this.off('sync', eventHandler)
 | 
				
			||||||
 | 
					          resolve()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this.on('sync', eventHandler)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    this.on('sync', isSynced => {
 | 
				
			||||||
 | 
					      if (isSynced === false && this.isSynced) {
 | 
				
			||||||
 | 
					        this.whenSynced = provideSyncedPromise()
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this.isSynced = isSynced === undefined || isSynced === true
 | 
				
			||||||
 | 
					      if (!this.isLoaded) {
 | 
				
			||||||
 | 
					        this.emit('load', [])
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Promise that resolves once the document has been synced with a backend.
 | 
				
			||||||
 | 
					     * This promise is recreated when the connection is lost.
 | 
				
			||||||
 | 
					     * Note the documentation about the `isSynced` property.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    this.whenSynced = provideSyncedPromise()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
 | 
				
			|||||||
@ -257,7 +257,7 @@ export const testSubdocsUndo = _tc => {
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {t.TestCase} _tc
 | 
					 * @param {t.TestCase} _tc
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export const testLoadDocs = async _tc => {
 | 
					export const testLoadDocsEvent = async _tc => {
 | 
				
			||||||
  const ydoc = new Y.Doc()
 | 
					  const ydoc = new Y.Doc()
 | 
				
			||||||
  t.assert(ydoc.isLoaded === false)
 | 
					  t.assert(ydoc.isLoaded === false)
 | 
				
			||||||
  let loadedEvent = false
 | 
					  let loadedEvent = false
 | 
				
			||||||
@ -269,3 +269,44 @@ export const testLoadDocs = async _tc => {
 | 
				
			|||||||
  t.assert(loadedEvent)
 | 
					  t.assert(loadedEvent)
 | 
				
			||||||
  t.assert(ydoc.isLoaded)
 | 
					  t.assert(ydoc.isLoaded)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {t.TestCase} _tc
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const testSyncDocsEvent = async _tc => {
 | 
				
			||||||
 | 
					  const ydoc = new Y.Doc()
 | 
				
			||||||
 | 
					  t.assert(ydoc.isLoaded === false)
 | 
				
			||||||
 | 
					  t.assert(ydoc.isSynced === false)
 | 
				
			||||||
 | 
					  let loadedEvent = false
 | 
				
			||||||
 | 
					  ydoc.once('load', () => {
 | 
				
			||||||
 | 
					    loadedEvent = true
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  let syncedEvent = false
 | 
				
			||||||
 | 
					  ydoc.once('sync', /** @param {any} isSynced */ (isSynced) => {
 | 
				
			||||||
 | 
					    syncedEvent = true
 | 
				
			||||||
 | 
					    t.assert(isSynced)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  ydoc.emit('sync', [true, ydoc])
 | 
				
			||||||
 | 
					  await ydoc.whenLoaded
 | 
				
			||||||
 | 
					  const oldWhenSynced = ydoc.whenSynced
 | 
				
			||||||
 | 
					  await ydoc.whenSynced
 | 
				
			||||||
 | 
					  t.assert(loadedEvent)
 | 
				
			||||||
 | 
					  t.assert(syncedEvent)
 | 
				
			||||||
 | 
					  t.assert(ydoc.isLoaded)
 | 
				
			||||||
 | 
					  t.assert(ydoc.isSynced)
 | 
				
			||||||
 | 
					  let loadedEvent2 = false
 | 
				
			||||||
 | 
					  ydoc.on('load', () => {
 | 
				
			||||||
 | 
					    loadedEvent2 = true
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  let syncedEvent2 = false
 | 
				
			||||||
 | 
					  ydoc.on('sync', (isSynced) => {
 | 
				
			||||||
 | 
					    syncedEvent2 = true
 | 
				
			||||||
 | 
					    t.assert(isSynced === false)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  ydoc.emit('sync', [false, ydoc])
 | 
				
			||||||
 | 
					  t.assert(!loadedEvent2)
 | 
				
			||||||
 | 
					  t.assert(syncedEvent2)
 | 
				
			||||||
 | 
					  t.assert(ydoc.isLoaded)
 | 
				
			||||||
 | 
					  t.assert(!ydoc.isSynced)
 | 
				
			||||||
 | 
					  t.assert(ydoc.whenSynced !== oldWhenSynced)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user