migrate to ObservableV2

This commit is contained in:
Kevin Jahns 2024-02-29 17:08:57 +01:00
parent 53173a9ea7
commit 541306b254
5 changed files with 53 additions and 41 deletions

View File

@ -1,4 +1,4 @@
import { Observable } from 'lib0/observable'
import { ObservableV2 } from 'lib0/observable'
import {
Doc // eslint-disable-line
@ -10,9 +10,9 @@ import {
* @note This interface is experimental and it is not advised to actually inherit this class.
* It just serves as typing information.
*
* @extends {Observable<any>}
* @extends {ObservableV2<any>}
*/
export class AbstractConnector extends Observable {
export class AbstractConnector extends ObservableV2 {
/**
* @param {Doc} ydoc
* @param {any} awareness

View File

@ -14,7 +14,7 @@ import {
ContentDoc, Item, Transaction, YEvent // eslint-disable-line
} from '../internals.js'
import { Observable } from 'lib0/observable'
import { ObservableV2 } from 'lib0/observable'
import * as random from 'lib0/random'
import * as map from 'lib0/map'
import * as array from 'lib0/array'
@ -34,10 +34,26 @@ export const generateNewClientId = random.uint32
*/
/**
* A Yjs instance handles the state of shared data.
* @extends Observable<string>
* @typedef {Object} DocEvents
* @property {function(Doc):void} DocEvents.destroy
* @property {function(Doc):void} DocEvents.load
* @property {function(boolean, Doc):void} DocEvents.sync
* @property {function(Uint8Array, any, Doc, Transaction):void} DocEvents.update
* @property {function(Uint8Array, any, Doc, Transaction):void} DocEvents.updateV2
* @property {function(Doc):void} DocEvents.beforeAllTransactions
* @property {function(Transaction, Doc):void} DocEvents.beforeTransaction
* @property {function(Transaction, Doc):void} DocEvents.beforeObserverCalls
* @property {function(Transaction, Doc):void} DocEvents.afterTransaction
* @property {function(Transaction, Doc):void} DocEvents.afterTransactionCleanup
* @property {function(Doc, Array<Transaction>):void} DocEvents.afterAllTransactions
* @property {function({ loaded: Set<Doc>, added: Set<Doc>, removed: Set<Doc> }, Doc, Transaction):void} DocEvents.subdocs
*/
export class Doc extends Observable {
/**
* A Yjs instance handles the state of shared data.
* @extends ObservableV2<DocEvents>
*/
export class Doc extends ObservableV2 {
/**
* @param {DocOpts} opts configuration
*/
@ -115,7 +131,7 @@ export class Doc extends Observable {
}
this.isSynced = isSynced === undefined || isSynced === true
if (this.isSynced && !this.isLoaded) {
this.emit('load', [])
this.emit('load', [this])
}
})
/**
@ -321,24 +337,9 @@ export class Doc extends Observable {
transaction.subdocsRemoved.add(this)
}, null, true)
}
this.emit('destroyed', [true])
// @ts-ignore
this.emit('destroyed', [true]) // DEPRECATED!
this.emit('destroy', [this])
super.destroy()
}
/**
* @param {string} eventName
* @param {function(...any):any} f
*/
on (eventName, f) {
super.on(eventName, f)
}
/**
* @param {string} eventName
* @param {function} f
*/
off (eventName, f) {
super.off(eventName, f)
}
}

View File

@ -10,13 +10,13 @@ import {
getItemCleanStart,
isDeleted,
addToDeleteSet,
Transaction, Doc, Item, GC, DeleteSet, AbstractType // eslint-disable-line
YEvent, Transaction, Doc, Item, GC, DeleteSet, AbstractType // eslint-disable-line
} from '../internals.js'
import * as time from 'lib0/time'
import * as array from 'lib0/array'
import * as logging from 'lib0/logging'
import { Observable } from 'lib0/observable'
import { ObservableV2 } from 'lib0/observable'
export class StackItem {
/**
@ -48,7 +48,7 @@ const clearUndoManagerStackItem = (tr, um, stackItem) => {
/**
* @param {UndoManager} undoManager
* @param {Array<StackItem>} stack
* @param {string} eventType
* @param {'undo'|'redo'} eventType
* @return {StackItem?}
*/
const popStackItem = (undoManager, stack, eventType) => {
@ -120,7 +120,7 @@ const popStackItem = (undoManager, stack, eventType) => {
}, undoManager)
if (undoManager.currStackItem != null) {
const changedParentTypes = _tr.changedParentTypes
undoManager.emit('stack-item-popped', [{ stackItem: undoManager.currStackItem, type: eventType, changedParentTypes }, undoManager])
undoManager.emit('stack-item-popped', [{ stackItem: undoManager.currStackItem, type: eventType, changedParentTypes, origin: undoManager }, undoManager])
undoManager.currStackItem = null
}
return undoManager.currStackItem
@ -139,6 +139,14 @@ const popStackItem = (undoManager, stack, eventType) => {
* @property {Doc} [doc] The document that this UndoManager operates on. Only needed if typeScope is empty.
*/
/**
* @typedef {Object} StackItemEvent
* @property {StackItem} StackItemEvent.stackItem
* @property {any} StackItemEvent.origin
* @property {'undo'|'redo'} StackItemEvent.type
* @property {Map<AbstractType<YEvent<any>>,Array<YEvent<any>>>} StackItemEvent.changedParentTypes
*/
/**
* Fires 'stack-item-added' event when a stack item was added to either the undo- or
* the redo-stack. You may store additional stack information via the
@ -146,9 +154,9 @@ const popStackItem = (undoManager, stack, eventType) => {
* Fires 'stack-item-popped' event when a stack item was popped from either the
* undo- or the redo-stack. You may restore the saved stack information from `event.stackItem.meta`.
*
* @extends {Observable<'stack-item-added'|'stack-item-popped'|'stack-cleared'|'stack-item-updated'>}
* @extends {ObservableV2<{'stack-item-added':function(StackItemEvent, UndoManager):void, 'stack-item-popped': function(StackItemEvent, UndoManager):void, 'stack-cleared': function({ undoStackCleared: boolean, redoStackCleared: boolean }):void, 'stack-item-updated': function(StackItemEvent, UndoManager):void }>}
*/
export class UndoManager extends Observable {
export class UndoManager extends ObservableV2 {
/**
* @param {AbstractType<any>|Array<AbstractType<any>>} typeScope Accepts either a single type, or an array of types
* @param {UndoManagerOptions} options
@ -246,6 +254,9 @@ export class UndoManager extends Observable {
keepItem(item, true)
}
})
/**
* @type {[StackItemEvent, UndoManager]}
*/
const changeEvent = [{ stackItem: stack[stack.length - 1], origin: transaction.origin, type: undoing ? 'redo' : 'undo', changedParentTypes: transaction.changedParentTypes }, this]
if (didAdd) {
this.emit('stack-item-added', changeEvent)

View File

@ -34,7 +34,7 @@ export const encV1 = {
mergeUpdates: Y.mergeUpdates,
applyUpdate: Y.applyUpdate,
logUpdate: Y.logUpdate,
updateEventName: 'update',
updateEventName: /** @type {'update'} */ ('update'),
diffUpdate: Y.diffUpdate
}
@ -43,7 +43,7 @@ export const encV2 = {
mergeUpdates: Y.mergeUpdatesV2,
applyUpdate: Y.applyUpdateV2,
logUpdate: Y.logUpdateV2,
updateEventName: 'updateV2',
updateEventName: /** @type {'updateV2'} */ ('updateV2'),
diffUpdate: Y.diffUpdateV2
}

View File

@ -15,7 +15,7 @@ import * as object from 'lib0/object'
* @property {function(Uint8Array):{from:Map<number,number>,to:Map<number,number>}} Enc.parseUpdateMeta
* @property {function(Y.Doc):Uint8Array} Enc.encodeStateVector
* @property {function(Uint8Array):Uint8Array} Enc.encodeStateVectorFromUpdate
* @property {string} Enc.updateEventName
* @property {'update'|'updateV2'} Enc.updateEventName
* @property {string} Enc.description
* @property {function(Uint8Array, Uint8Array):Uint8Array} Enc.diffUpdate
*/
@ -169,7 +169,7 @@ const checkUpdateCases = (ydoc, updates, enc, hasDeletes) => {
// t.info('Target State: ')
// enc.logUpdate(targetState)
cases.forEach((mergedUpdates, i) => {
cases.forEach((mergedUpdates) => {
// t.info('State Case $' + i + ':')
// enc.logUpdate(updates)
const merged = new Y.Doc({ gc: false })
@ -218,10 +218,10 @@ const checkUpdateCases = (ydoc, updates, enc, hasDeletes) => {
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testMergeUpdates1 = tc => {
encoders.forEach((enc, i) => {
export const testMergeUpdates1 = _tc => {
encoders.forEach((enc) => {
t.info(`Using encoder: ${enc.description}`)
const ydoc = new Y.Doc({ gc: false })
const updates = /** @type {Array<Uint8Array>} */ ([])
@ -299,16 +299,16 @@ export const testMergePendingUpdates = tc => {
Y.applyUpdate(yDoc5, update4)
Y.applyUpdate(yDoc5, serverUpdates[4])
// @ts-ignore
const update5 = Y.encodeStateAsUpdate(yDoc5) // eslint-disable-line
const _update5 = Y.encodeStateAsUpdate(yDoc5) // eslint-disable-line
const yText5 = yDoc5.getText('textBlock')
t.compareStrings(yText5.toString(), 'nenor')
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testObfuscateUpdates = tc => {
export const testObfuscateUpdates = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText('text')
const ymap = ydoc.getMap('map')