99 lines
2.7 KiB
JavaScript
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
|
|
}
|
|
}
|
|
}
|