yjs/utils/OperationStore.js

99 lines
2.7 KiB
JavaScript

/**
* @module utils
*/
import { Tree } from '../lib/Tree.js'
import * as ID from '../utils/ID.js'
import { getStruct } from '../utils/structReferences.js'
import { GC } from '../structs/GC.js'
import * as stringify from '../utils/structStringify.js'
export class OperationStore extends Tree {
constructor (y) {
super()
this.y = y
}
logTable () {
const items = []
this.iterate(null, null, item => {
if (item.constructor === GC) {
items.push({
id: stringify.stringifyItemID(item),
content: item._length,
deleted: 'GC'
})
} else {
items.push({
id: stringify.stringifyItemID(item),
origin: item._origin === null ? '()' : stringify.stringifyID(item._origin._lastId),
left: item._left === null ? '()' : stringify.stringifyID(item._left._lastId),
right: stringify.stringifyItemID(item._right),
right_origin: stringify.stringifyItemID(item._right_origin),
parent: stringify.stringifyItemID(item._parent),
parentSub: item._parentSub,
deleted: item._deleted,
content: JSON.stringify(item._content)
})
}
})
console.table(items)
}
get (id) {
let struct = this.find(id)
if (struct === null && id instanceof ID.RootID) {
const Constr = getStruct(id.type)
const y = this.y
struct = new Constr()
struct._id = id
struct._parent = y
y.transact(() => {
struct._integrate(y)
})
this.put(struct)
}
return struct
}
// Use getItem for structs with _length > 1
getItem (id) {
var item = this.findWithUpperBound(id)
if (item === null) {
return null
}
const itemID = item._id
if (id.user === itemID.user && id.clock < itemID.clock + item._length) {
return item
} else {
return null
}
}
// Return an insertion such that id is the first element of content
// This function manipulates an item, if necessary
getItemCleanStart (id) {
var ins = this.getItem(id)
if (ins === null || ins._length === 1) {
return ins
}
const insID = ins._id
if (insID.clock === id.clock) {
return ins
} else {
return ins._splitAt(this.y, id.clock - insID.clock)
}
}
// Return an insertion such that id is the last element of content
// This function manipulates an operation, if necessary
getItemCleanEnd (id) {
var ins = this.getItem(id)
if (ins === null || ins._length === 1) {
return ins
}
const insID = ins._id
if (insID.clock + ins._length - 1 === id.clock) {
return ins
} else {
ins._splitAt(this.y, id.clock - insID.clock + 1)
return ins
}
}
}