/** * @module utils */ import { Tree } from '../lib/Tree.mjs' import * as ID from '../utils/ID.mjs' import { getStruct } from '../utils/structReferences.mjs' import { stringifyID, stringifyItemID } from '../protocols/syncProtocol.mjs' import { GC } from '../structs/GC.mjs' 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: stringifyItemID(item), content: item._length, deleted: 'GC' }) } else { items.push({ id: stringifyItemID(item), origin: item._origin === null ? '()' : stringifyID(item._origin._lastId), left: item._left === null ? '()' : stringifyID(item._left._lastId), right: stringifyItemID(item._right), right_origin: stringifyItemID(item._right_origin), parent: 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 } } }