prelim refactor commit

This commit is contained in:
Kevin Jahns
2019-03-26 01:14:15 +01:00
parent 293527e62b
commit d9ab593b07
44 changed files with 2263 additions and 1914 deletions

237
src/types/AbstractType.js Normal file
View File

@@ -0,0 +1,237 @@
/**
* @module structs
*/
import { Y } from '../utils/Y.js' // eslint-disable-line
import { EventHandler } from '../utils/EventHandler.js'
import { YEvent } from '../utils/YEvent.js'
import { AbstractItem } from '../structs/AbstractItem.js' // eslint-disable-line
import { ItemType } from '../structs/ItemType.js' // eslint-disable-line
import { Encoder } from 'lib0/encoding.js' // eslint-disable-line
import { Transaction, nextID } from '../utils/Transaction.js' // eslint-disable-line
/**
* Restructure children as if they were inserted one after another
* @param {Transaction} transaction
* @param {AbstractItem} start
*/
const integrateChildren = (transaction, start) => {
let right
while (true) {
right = start.right
start.id = nextID(transaction)
start.right = null
start.rightOrigin = null
start.origin = start.left
start.integrate(transaction)
if (right !== null) {
start = right
} else {
break
}
}
}
/**
* Abstract Yjs Type class
*/
export class AbstractType {
constructor () {
/**
* @type {ItemType|null}
*/
this._item = null
/**
* @private
* @type {Map<string,AbstractItem>}
*/
this._map = new Map()
/**
* @private
* @type {AbstractItem|null}
*/
this._start = null
/**
* @private
* @type {Y|null}
*/
this._y = null
this._length = 0
this._eventHandler = new EventHandler()
this._deepEventHandler = new EventHandler()
}
/**
* Integrate this type into the Yjs instance.
*
* * Save this struct in the os
* * This type is sent to other client
* * Observer functions are fired
*
* @param {Transaction} transaction The Yjs instance
* @param {ItemType} item
* @private
*/
_integrate (transaction, item) {
this._y = transaction.y
this._item = item
// when integrating children we must make sure to
// integrate start
const start = this._start
if (start !== null) {
this._start = null
integrateChildren(transaction, start)
}
// integrate map children_integrate
const map = this._map
this._map = new Map()
map.forEach(t => {
t.right = null
t.rightOrigin = null
integrateChildren(transaction, t)
})
}
/**
* @return {AbstractType}
*/
_copy () {
throw new Error('unimplemented')
}
/**
* @param {Encoder} encoder
*/
_write (encoder) {
throw new Error('unimplemented')
}
/**
* The first non-deleted item
*/
get _first () {
let n = this._start
while (n !== null && n.deleted) {
n = n.right
}
return n
}
/**
* Creates YArray Event and calls observers.
* @private
*/
_callObserver (transaction, parentSubs, remote) {
this._callEventHandler(transaction, new YEvent(this))
}
/**
* Call event listeners with an event. This will also add an event to all
* parents (for `.observeDeep` handlers).
* @private
*/
_callEventHandler (transaction, event) {
const changedParentTypes = transaction.changedParentTypes
this._eventHandler.callEventListeners(transaction, event)
/**
* @type {any}
*/
let type = this
while (type !== this._y) {
let events = changedParentTypes.get(type)
if (events === undefined) {
events = []
changedParentTypes.set(type, events)
}
events.push(event)
type = type._parent
}
}
/**
* Helper method to transact if the y instance is available.
*
* TODO: Currently event handlers are not thrown when a type is not registered
* with a Yjs instance.
* @private
*/
_transact (f) {
const y = this._y
if (y !== null) {
y.transact(f)
} else {
f(y)
}
}
/**
* Observe all events that are created on this type.
*
* @param {Function} f Observer function
*/
observe (f) {
this._eventHandler.addEventListener(f)
}
/**
* Observe all events that are created by this type and its children.
*
* @param {Function} f Observer function
*/
observeDeep (f) {
this._deepEventHandler.addEventListener(f)
}
/**
* Unregister an observer function.
*
* @param {Function} f Observer function
*/
unobserve (f) {
this._eventHandler.removeEventListener(f)
}
/**
* Unregister an observer function.
*
* @param {Function} f Observer function
*/
unobserveDeep (f) {
this._deepEventHandler.removeEventListener(f)
}
/**
* @abstract
* @return {Object | Array | number | string}
*/
toJSON () {}
}
/**
* @param {AbstractType} type
* @return {Array<any>}
*/
export const typeToArray = type => {
}
/**
* Executes a provided function on once on overy element of this YArray.
*
* @param {AbstractType} type
* @param {function(any,number,AbstractType):void} f A function to execute on every element of this YArray.
* @param {HistorySnapshot} [snapshot]
*/
export const typeForEach = (type, f, snapshot) => {
let index = 0
let n = type._start
while (n !== null) {
if (isVisible(n, snapshot) && n._countable) {
const c = n.getContent()
for (let i = 0; i < c.length; i++) {
f(c[i], index++, type)
}
}
n = n._right
}
}

View File

@@ -2,14 +2,14 @@
* @module types
*/
import { Type } from '../structs/Type.js'
import { AbstractType } from './AbstractType.js'
import { ItemJSON } from '../structs/ItemJSON.js'
import { ItemString } from '../structs/ItemString.js'
import { ItemBinary } from '../structs/ItemBinary.js'
import { stringifyItemID, logItemHelper } from '../structs/AbstractItem.js' // eslint-disable-line
import { YEvent } from '../utils/YEvent.js'
import { Transaction } from '../utils/Transaction.js' // eslint-disable-line
import { Item, stringifyItemID, logItemHelper } from '../structs/Item.js' // eslint-disable-line
import { ItemBinary } from '../structs/ItemBinary.js'
import { isVisible } from '../utils/snapshot.js'
import { isVisible, HistorySnapshot } from '../utils/snapshot.js' // eslint-disable-line
/**
* Event that describes the changes on a YArray
@@ -38,8 +38,8 @@ export class YArrayEvent extends YEvent {
const target = this.target
const transaction = this._transaction
const addedElements = new Set()
transaction.newTypes.forEach(type => {
if (type._parent === target && !transaction.deletedStructs.has(type)) {
transaction.added.forEach(type => {
if (type._parent === target && !transaction.deleted.has(type)) {
addedElements.add(type)
}
})
@@ -58,8 +58,8 @@ export class YArrayEvent extends YEvent {
const target = this.target
const transaction = this._transaction
const removedElements = new Set()
transaction.deletedStructs.forEach(struct => {
if (struct._parent === target && !transaction.newTypes.has(struct)) {
transaction.deleted.forEach(struct => {
if (struct._parent === target && !transaction.added.has(struct)) {
removedElements.add(struct)
}
})
@@ -72,7 +72,7 @@ export class YArrayEvent extends YEvent {
/**
* A shared Array implementation.
*/
export class YArray extends Type {
export class YArray extends AbstractType {
constructor () {
super()
this.length = 0
@@ -128,7 +128,7 @@ export class YArray extends Type {
*/
toJSON () {
return this.map(c => {
if (c instanceof Type) {
if (c instanceof AbstractType) {
return c.toJSON()
}
return c
@@ -140,7 +140,7 @@ export class YArray extends Type {
* element of this YArray.
*
* @param {Function} f Function that produces an element of the new Array
* @param {import('../protocols/history.js').HistorySnapshot} [snapshot]
* @param {HistorySnapshot} [snapshot]
* @return {Array} A new array with each element being the result of the
* callback function
*/
@@ -156,7 +156,7 @@ export class YArray extends Type {
* Executes a provided function on once on overy element of this YArray.
*
* @param {Function} f A function to execute on every element of this YArray.
* @param {import('../protocols/history.js').HistorySnapshot} [snapshot]
* @param {HistorySnapshot} [snapshot]
*/
forEach (f, snapshot) {
let index = 0
@@ -404,3 +404,5 @@ export class YArray extends Type {
return logItemHelper('YArray', this, `start:${stringifyItemID(this._start)}"`)
}
}
export const readYArray = decoder => new YArray()

View File

@@ -2,12 +2,11 @@
* @module types
*/
import { Item, logItemHelper } from '../structs/Item.js'
import { Type } from '../structs/Type.js'
import { AbstractType } from './AbstractType.js'
import { ItemJSON } from '../structs/ItemJSON.js'
import { YEvent } from '../utils/YEvent.js'
import { ItemBinary } from '../structs/ItemBinary.js'
import { isVisible } from '../utils/snapshot.js'
import { HistorySnapshot, isVisible } from '../utils/snapshot.js' // eslint-disable-line
/**
* Event that describes the changes on a YMap.
@@ -28,7 +27,7 @@ export class YMapEvent extends YEvent {
/**
* A shared Map implementation.
*/
export class YMap extends Type {
export class YMap extends AbstractType {
/**
* Creates YMap Event and calls observers.
*
@@ -68,7 +67,7 @@ export class YMap extends Type {
/**
* Returns the keys for each element in the YMap Type.
*
* @param {import('../protocols/history.js').HistorySnapshot} [snapshot]
* @param {HistorySnapshot} [snapshot]
* @return {Array}
*/
keys (snapshot) {
@@ -156,7 +155,7 @@ export class YMap extends Type {
* Returns a specified element from this YMap.
*
* @param {string} key The key of the element to return.
* @param {import('../protocols/history.js').HistorySnapshot} [snapshot]
* @param {HistorySnapshot} [snapshot]
*/
get (key, snapshot) {
let v = this._map.get(key)
@@ -184,7 +183,7 @@ export class YMap extends Type {
* Returns a boolean indicating whether the specified key exists or not.
*
* @param {string} key The key to test.
* @param {import('../protocols/history.js').HistorySnapshot} [snapshot]
* @param {HistorySnapshot} [snapshot]
*/
has (key, snapshot) {
let v = this._map.get(key)
@@ -210,3 +209,5 @@ export class YMap extends Type {
return logItemHelper('YMap', this, `mapSize:${this._map.size}`)
}
}
export const readYMap = decoder => new YMap()

View File

@@ -2,7 +2,7 @@
* @module types
*/
import { logItemHelper } from '../structs/Item.js'
import { logItemHelper } from '../structs/AbstractItem.js/index.js'
import { ItemEmbed } from '../structs/ItemEmbed.js'
import { ItemString } from '../structs/ItemString.js'
import { ItemFormat } from '../structs/ItemFormat.js'
@@ -723,3 +723,5 @@ export class YText extends YArray {
return logItemHelper('YText', this)
}
}
export const readYText = decoder => new YText()

View File

@@ -2,7 +2,7 @@
* @module types
*/
import { logItemHelper } from '../structs/Item.js'
import { logItemHelper } from '../structs/AbstractItem.js/index.js'
import { YMap } from './YMap.js'
import * as encoding from 'lib0/encoding.js'
import * as decoding from 'lib0/decoding.js'
@@ -433,3 +433,6 @@ export class YXmlElement extends YXmlFragment {
return dom
}
}
export const readYXmlElement = decoder => new YXmlElement(decoding.readVarString(decoder))
export const readYXmlFragment = decoder => new YXmlFragment()

View File

@@ -4,7 +4,7 @@
import { YEvent } from '../utils/YEvent.js'
import { Type } from '../structs/Type.js' // eslint-disable-line
import { Type } from './AbstractType.js/index.js.js.js.js' // eslint-disable-line
import { Transaction } from '../utils/Transaction.js' // eslint-disable-line
/**

View File

@@ -114,3 +114,5 @@ export class YXmlHook extends YMap {
super._integrate(y)
}
}
export const readYXmlHook = decoder => new YXmlHook()

View File

@@ -48,3 +48,5 @@ export class YXmlText extends YText {
super._delete(y, createDelete, gcChildren)
}
}
export const readYXmlText = decoder => new YXmlText()