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
|
* @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
|
||||||
* @return {ContentDoc}
|
* @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 {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 {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.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
|
* @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()
|
super()
|
||||||
this.gc = gc
|
this.gc = gc
|
||||||
this.gcFilter = gcFilter
|
this.gcFilter = gcFilter
|
||||||
@ -67,7 +68,7 @@ export class Doc extends Observable {
|
|||||||
* @type {Item?}
|
* @type {Item?}
|
||||||
*/
|
*/
|
||||||
this._item = null
|
this._item = null
|
||||||
this.shouldLoad = autoLoad
|
this.shouldLoad = shouldLoad
|
||||||
this.autoLoad = autoLoad
|
this.autoLoad = autoLoad
|
||||||
this.meta = meta
|
this.meta = meta
|
||||||
}
|
}
|
||||||
@ -252,12 +253,13 @@ export class Doc extends Observable {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
content.doc = null
|
content.doc = null
|
||||||
} else {
|
} 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
|
content.doc._item = item
|
||||||
}
|
}
|
||||||
transact(/** @type {any} */ (item).parent.doc, transaction => {
|
transact(/** @type {any} */ (item).parent.doc, transaction => {
|
||||||
|
const doc = content.doc
|
||||||
if (!item.deleted) {
|
if (!item.deleted) {
|
||||||
transaction.subdocsAdded.add(content.doc)
|
transaction.subdocsAdded.add(doc)
|
||||||
}
|
}
|
||||||
transaction.subdocsRemoved.add(this)
|
transaction.subdocsRemoved.add(this)
|
||||||
}, null, true)
|
}, null, true)
|
||||||
|
@ -88,7 +88,7 @@ export const testSubdoc = tc => {
|
|||||||
subdocs.get('a').load()
|
subdocs.get('a').load()
|
||||||
t.compare(event, [[], [], ['a']])
|
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'], [], []])
|
t.compare(event, [['a'], [], []])
|
||||||
subdocs.get('b').load()
|
subdocs.get('b').load()
|
||||||
t.compare(event, [[], [], ['a']])
|
t.compare(event, [[], [], ['a']])
|
||||||
@ -124,3 +124,92 @@ export const testSubdoc = tc => {
|
|||||||
t.compare(Array.from(doc2.getSubdocGuids()), ['a', 'c'])
|
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