diff --git a/src/Persistence.js b/src/Persistence.js index d1fa95d4..3a4e0b11 100644 --- a/src/Persistence.js +++ b/src/Persistence.js @@ -47,12 +47,33 @@ export default class AbstractPersistence { } deinit (y) { this.ys.delete(y) + y.persistence = null } destroy () { this.ys = null } + /** + * Remove all persisted data that belongs to a room. + * Automatically destroys all Yjs all Yjs instances that persist to + * the room. If `destroyYjsInstances = false` the persistence functionality + * will be removed from the Yjs instances. + * + * ** Must be overwritten! ** + */ + removePersistedData (room, destroyYjsInstances = true) { + this.ys.forEach((cnf, y) => { + if (y.room === room) { + if (destroyYjsInstances) { + y.destroy() + } else { + this.deinit(y) + } + } + }) + } + /* overwrite */ saveUpdate (buffer) { } @@ -77,17 +98,17 @@ export default class AbstractPersistence { y.transact(function () { if (model != null) { fromBinary(y, new BinaryDecoder(new Uint8Array(model))) - y._setContentReady() } if (updates != null) { for (let i = 0; i < updates.length; i++) { integrateRemoteStructs(y, new BinaryDecoder(new Uint8Array(updates[i]))) - y._setContentReady() } } }) + y.emit('persistenceReady') }) } + /* overwrite */ persist (y) { return toBinary(y).createBuffer() diff --git a/src/Util/NamedEventHandler.js b/src/Util/NamedEventHandler.js index 83f2458d..632d8321 100644 --- a/src/Util/NamedEventHandler.js +++ b/src/Util/NamedEventHandler.js @@ -1,6 +1,7 @@ export default class NamedEventHandler { constructor () { this._eventListener = new Map() + this._stateListener = new Map() } _getListener (name) { let listeners = this._eventListener.get(name) @@ -21,6 +22,20 @@ export default class NamedEventHandler { let listeners = this._getListener(name) listeners.on.add(f) } + _initStateListener (name) { + let state = this._stateListener.get(name) + if (state === undefined) { + state = {} + state.promise = new Promise(function (resolve) { + state.resolve = resolve + }) + this._stateListener.set(name, state) + } + return state + } + when (name) { + return this._initStateListener(name).promise + } off (name, f) { if (name == null || f == null) { throw new Error('You must specify event name and function!') @@ -32,6 +47,7 @@ export default class NamedEventHandler { } } emit (name, ...args) { + this._initStateListener(name).resolve() const listener = this._eventListener.get(name) if (listener !== undefined) { listener.on.forEach(f => f.apply(null, args)) diff --git a/src/Y.js b/src/Y.js index 41c43746..03829b8a 100644 --- a/src/Y.js +++ b/src/Y.js @@ -62,6 +62,15 @@ export default class Y extends NamedEventHandler { this.emit('content') } } + whenContentReady () { + if (this._contentReady) { + return Promise.resolve() + } else { + return new Promise(resolve => { + this.once('content', resolve) + }) + } + } _beforeChange () {} transact (f, remote = false) { let initialCall = this._transaction === null