diff --git a/public/index.html b/public/index.html index 76c50bebd..d30f47e99 100644 --- a/public/index.html +++ b/public/index.html @@ -39,7 +39,7 @@ function displayLog(doc, codemirror) { logHolder.innerText = doc.toJSON(); - textLogHolder.innerText = doc.getRoot().content.getStructureAsString(); + textLogHolder.innerText = doc.getRoot().content.toTestString(); } function displayPeers(peers, myClientID) { diff --git a/public/prosemirror.html b/public/prosemirror.html index ff22cfe59..f1db6e9ca 100644 --- a/public/prosemirror.html +++ b/public/prosemirror.html @@ -107,7 +107,7 @@

Yorkie.RGASplit

*/ function updateSelectionLayer(view, tree, actor) { const { layer, fromPos, toPos } = selectionMap.get(actor); - const [fromIndex, toIndex] = tree.rangeToIndex([fromPos, toPos]); + const [fromIndex, toIndex] = tree.toIndexRange([fromPos, toPos]); const coords = view.coordsAtPos(Math.min(fromIndex, toIndex)); layer.style.left = `${coords.left - 10}px`; @@ -277,19 +277,6 @@

Yorkie.RGASplit

return true; } - function encodeRange(tree, from, to) { - const range = tree.createRange(from, to); - const fromBytes = yorkie.converter.treePosToBytes(range[0]); - const toBytes = yorkie.converter.treePosToBytes(range[1]); - return [fromBytes, toBytes]; - } - - function decodeRange(fromBytes, toBytes) { - const from = yorkie.converter.bytesToTreePos(fromBytes); - const to = yorkie.converter.bytesToTreePos(toBytes); - return [from, to]; - } - /** * main is the entry point of the example. */ @@ -337,11 +324,10 @@

Yorkie.RGASplit

}); doc.update((root) => { - root.selection = encodeRange( - root.tree, + root.selection = root.tree.toPosRange([ transaction.curSelection.from, transaction.curSelection.to, - ); + ]); }); printLog(); return; @@ -395,11 +381,10 @@

Yorkie.RGASplit

} } - root.selection = encodeRange( - root.tree, + root.selection = root.tree.toPosRange([ transaction.curSelection.from, transaction.curSelection.to, - ); + ]); }); printLog(); }, @@ -423,12 +408,11 @@

Yorkie.RGASplit

op.key === 'selection' ) { const selection = doc.getRoot().selection; - const range = decodeRange(selection[0], selection[1]); displayRemoteSelection( view, root.tree, - range[0], - range[1], + selection[0], + selection[1], actor, ); } @@ -541,9 +525,7 @@

Yorkie.RGASplit

let node = head; while (node) { const nodeType = node.type; - const pos = `${node.pos.createdAt.getStructureAsString()}-${ - node.pos.offset - }`; + const pos = `${node.pos.createdAt.toTestString()}-${node.pos.offset}`; if (nodeType === 'text') { arr.push({ type: nodeType, diff --git a/public/quill.html b/public/quill.html index fa7b9fc30..c825d7b63 100644 --- a/public/quill.html +++ b/public/quill.html @@ -34,7 +34,7 @@ function displayLog(elem, textElem, doc) { elem.innerText = doc.toJSON(); - textElem.innerText = doc.getRoot().content.getStructureAsString(); + textElem.innerText = doc.getRoot().content.toTestString(); } function toDeltaOperation(textValue) { diff --git a/src/api/converter.ts b/src/api/converter.ts index 644436578..d0feca306 100644 --- a/src/api/converter.ts +++ b/src/api/converter.ts @@ -256,8 +256,8 @@ function toTextNodePos(pos: RGATreeSplitNodePos): PbTextNodePos { */ function toTreePos(pos: CRDTTreePos): PbTreePos { const pbTreePos = new PbTreePos(); - pbTreePos.setCreatedAt(toTimeTicket(pos.createdAt)); - pbTreePos.setOffset(pos.offset); + pbTreePos.setCreatedAt(toTimeTicket(pos.getCreatedAt())); + pbTreePos.setOffset(pos.getOffset()); return pbTreePos; } @@ -831,10 +831,10 @@ function fromTextNode(pbTextNode: PbTextNode): RGATreeSplitNode { * `fromTreePos` converts the given Protobuf format to model format. */ function fromTreePos(pbTreePos: PbTreePos): CRDTTreePos { - return { - createdAt: fromTimeTicket(pbTreePos.getCreatedAt())!, - offset: pbTreePos.getOffset(), - }; + return CRDTTreePos.of( + fromTimeTicket(pbTreePos.getCreatedAt())!, + pbTreePos.getOffset(), + ); } /** @@ -1211,24 +1211,6 @@ function treeToBytes(tree: CRDTTree): Uint8Array { return toTree(tree).serializeBinary(); } -/** - * `treePosToBytes` converts the given CRDTTreePos to byte array. - */ -function treePosToBytes(pos: CRDTTreePos): Uint8Array { - return toTreePos(pos).serializeBinary(); -} - -/** - * `bytesToTreePos` creates an CRDTTreePos from the given bytes. - */ -function bytesToTreePos(bytes: Uint8Array): CRDTTreePos { - if (!bytes) { - throw new Error('bytes is empty'); - } - const pbTreePos = PbTreePos.deserializeBinary(bytes); - return fromTreePos(pbTreePos); -} - /** * `bytesToHex` creates an hex string from the given byte array. */ @@ -1279,6 +1261,4 @@ export const converter = { bytesToObject, toHexString, toUint8Array, - bytesToTreePos, - treePosToBytes, }; diff --git a/src/client/client.ts b/src/client/client.ts index 8e5b472dc..1397ec464 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -1171,7 +1171,7 @@ export class Client

implements Observable> { logger.info( `[PP] c:"${this.getKey()}" sync d:"${docKey}", push:${localSize} pull:${remoteSize} cp:${respPack .getCheckpoint() - .getStructureAsString()}`, + .toTestString()}`, ); }, ) diff --git a/src/document/change/change.ts b/src/document/change/change.ts index 663d4787a..24fc4eeb7 100644 --- a/src/document/change/change.ts +++ b/src/document/change/change.ts @@ -96,11 +96,11 @@ export class Change { } /** - * `getStructureAsString` returns a string containing the meta data of this change. + * `toTestString` returns a string containing the meta data of this change. */ - public getStructureAsString(): string { + public toTestString(): string { return `${this.operations - .map((operation) => operation.getStructureAsString()) + .map((operation) => operation.toTestString()) .join(',')}`; } } diff --git a/src/document/change/change_id.ts b/src/document/change/change_id.ts index c4fbd8d1f..cd6f78816 100644 --- a/src/document/change/change_id.ts +++ b/src/document/change/change_id.ts @@ -113,9 +113,9 @@ export class ChangeID { } /** - * `getStructureAsString` returns a string containing the meta data of this ID. + * `toTestString` returns a string containing the meta data of this ID. */ - public getStructureAsString(): string { + public toTestString(): string { if (!this.actor) { return `${this.lamport.toString()}:nil:${this.clientSeq}`; } diff --git a/src/document/change/checkpoint.ts b/src/document/change/checkpoint.ts index b26c143a4..131c3356a 100644 --- a/src/document/change/checkpoint.ts +++ b/src/document/change/checkpoint.ts @@ -99,10 +99,10 @@ export class Checkpoint { } /** - * `getStructureAsString` returns a string containing the meta data of this + * `toTestString` returns a string containing the meta data of this * checkpoint. */ - public getStructureAsString(): string { + public toTestString(): string { return `serverSeq=${this.serverSeq}, clientSeq=${this.clientSeq}`; } } diff --git a/src/document/crdt/array.ts b/src/document/crdt/array.ts index fc9c5de1b..8170ba18c 100644 --- a/src/document/crdt/array.ts +++ b/src/document/crdt/array.ts @@ -163,11 +163,11 @@ export class CRDTArray extends CRDTContainer { } /** - * `getStructureAsString` returns a String containing the meta data of this value + * `toTestString` returns a String containing the meta data of this value * for debugging purpose. */ - public getStructureAsString(): string { - return this.elements.getStructureAsString(); + public toTestString(): string { + return this.elements.toTestString(); } /** diff --git a/src/document/crdt/rga_tree_list.ts b/src/document/crdt/rga_tree_list.ts index decb1b5e3..3a1add11b 100644 --- a/src/document/crdt/rga_tree_list.ts +++ b/src/document/crdt/rga_tree_list.ts @@ -387,10 +387,10 @@ export class RGATreeList { } /** - * `getStructureAsString` returns a String containing the meta data of the node id + * `toTestString` returns a String containing the meta data of the node id * for debugging purpose. */ - public getStructureAsString(): string { + public toTestString(): string { const json = []; for (const node of this) { diff --git a/src/document/crdt/rga_tree_split.ts b/src/document/crdt/rga_tree_split.ts index 293f57616..100ed9e8e 100644 --- a/src/document/crdt/rga_tree_split.ts +++ b/src/document/crdt/rga_tree_split.ts @@ -23,6 +23,7 @@ import { InitialTimeTicket, MaxTimeTicket, TimeTicket, + TimeTicketStruct, } from '@yorkie-js-sdk/src/document/time/ticket'; export interface ValueChange { @@ -37,6 +38,15 @@ interface RGATreeSplitValue { substring(indexStart: number, indexEnd?: number): RGATreeSplitValue; } +/** + * `RGATreeSplitNodeIDStruct` is a structure represents the meta data of the node id. + * It is used to serialize and deserialize the node id. + */ +type RGATreeSplitNodeIDStruct = { + createdAt: TimeTicketStruct; + offset: number; +}; + /** * `RGATreeSplitNodeID` is an ID of RGATreeSplitNode. */ @@ -95,11 +105,28 @@ export class RGATreeSplitNodeID { } /** - * `getStructureAsString` returns a String containing + * `toStructure` returns the structure of this node id. + */ + public toStructure(): RGATreeSplitNodeIDStruct { + return { + createdAt: this.createdAt.toStructure(), + offset: this.offset, + }; + } + + /** + * `toTestString` returns a String containing * the meta data of the node id for debugging purpose. */ - public getStructureAsString(): string { - return `${this.createdAt.getStructureAsString()}:${this.offset}`; + public toTestString(): string { + return `${this.createdAt.toTestString()}:${this.offset}`; + } + + /** + * `toIDString` returns a string that can be used as an ID for this node id. + */ + public toIDString(): string { + return `${this.createdAt.toIDString()}:${this.offset}`; } } @@ -152,11 +179,11 @@ export class RGATreeSplitNodePos { } /** - *`getStructureAsString` returns a String containing + *`toTestString` returns a String containing * the meta data of the position for debugging purpose. */ - public getStructureAsString(): string { - return `${this.id.getStructureAsString()}:${this.relativeOffset}`; + public toTestString(): string { + return `${this.id.toTestString()}:${this.relativeOffset}`; } /** @@ -405,11 +432,11 @@ export class RGATreeSplitNode< } /** - * `getStructureAsString` returns a String containing + * `toTestString` returns a String containing * the meta data of the node for debugging purpose. */ - public getStructureAsString(): string { - return `${this.id.getStructureAsString()} ${this.value ? this.value : ''}`; + public toTestString(): string { + return `${this.id.toTestString()} ${this.value ? this.value : ''}`; } private splitValue(offset: number): T { @@ -547,7 +574,7 @@ export class RGATreeSplit { : this.findFloorNode(absoluteID); if (!node) { logger.fatal( - `the node of the given id should be found: ${absoluteID.getStructureAsString()}`, + `the node of the given id should be found: ${absoluteID.toTestString()}`, ); } const index = this.treeByIndex.indexOf(node!); @@ -635,18 +662,18 @@ export class RGATreeSplit { } /** - * `getStructureAsString` returns a String containing the meta data of the node + * `toTestString` returns a String containing the meta data of the node * for debugging purpose. */ - public getStructureAsString(): string { + public toTestString(): string { const result = []; let node: RGATreeSplitNode | undefined = this.head; while (node) { if (node.isRemoved()) { - result.push(`{${node.getStructureAsString()}}`); + result.push(`{${node.toTestString()}}`); } else { - result.push(`[${node.getStructureAsString()}]`); + result.push(`[${node.toTestString()}]`); } node = node.getNext(); @@ -700,7 +727,7 @@ export class RGATreeSplit { let node = this.findFloorNode(id); if (!node) { logger.fatal( - `the node of the given id should be found: ${id.getStructureAsString()}`, + `the node of the given id should be found: ${id.toTestString()}`, ); } @@ -810,7 +837,7 @@ export class RGATreeSplit { ) { createdAtMapByActor.set(actorID, node.getID().getCreatedAt()); } - removedNodeMap.set(node.getID().getStructureAsString(), node); + removedNodeMap.set(node.getID().toIDString(), node); node.remove(editedAt); } // Finally remove index nodes of tombstones. @@ -937,7 +964,7 @@ export class RGATreeSplit { this.treeByIndex.delete(node); this.purge(node); this.treeByID.remove(node.getID()); - this.removedNodeMap.delete(node.getID().getStructureAsString()); + this.removedNodeMap.delete(node.getID().toIDString()); count++; } } diff --git a/src/document/crdt/text.ts b/src/document/crdt/text.ts index 59591d35a..2d2555144 100644 --- a/src/document/crdt/text.ts +++ b/src/document/crdt/text.ts @@ -379,11 +379,11 @@ export class CRDTText extends CRDTGCElement { } /** - * `getStructureAsString` returns a String containing the meta data of this value + * `toTestString` returns a String containing the meta data of this value * for debugging purpose. */ - public getStructureAsString(): string { - return this.rgaTreeSplit.getStructureAsString(); + public toTestString(): string { + return this.rgaTreeSplit.toTestString(); } /** diff --git a/src/document/crdt/tree.ts b/src/document/crdt/tree.ts index a164c9f2e..d1d1a2044 100644 --- a/src/document/crdt/tree.ts +++ b/src/document/crdt/tree.ts @@ -14,9 +14,11 @@ * limitations under the License. */ +import Long from 'long'; import { TimeTicket, InitialTimeTicket, + TimeTicketStruct, } from '@yorkie-js-sdk/src/document/time/ticket'; import { CRDTGCElement } from '@yorkie-js-sdk/src/document/crdt/element'; import { @@ -79,53 +81,105 @@ export interface TreeChange { value?: TreeNode | { [key: string]: any }; } +/** + * `CRDTTreePos` represent a position in the tree. It indicates the virtual + * location in the tree, so whether the node is splitted or not, we can find + * the adjacent node to pos by calling `map.floorEntry()`. + */ +export class CRDTTreePos { + /** + * `createdAt` is the creation time of the node. + */ + private createdAt: TimeTicket; + + /** + * `offset` is the distance from the beginning of the node if the node is + * split. + */ + private offset: number; + + constructor(createdAt: TimeTicket, offset: number) { + this.createdAt = createdAt; + this.offset = offset; + } + + /** + * `of` creates a new instance of CRDTTreePos. + */ + public static of(createdAt: TimeTicket, offset: number): CRDTTreePos { + return new CRDTTreePos(createdAt, offset); + } + + /** + * `getCreatedAt` returns the creation time of the node. + */ + public getCreatedAt(): TimeTicket { + return this.createdAt; + } + + /** + * `getOffset` returns returns the offset of the node. + */ + public getOffset(): number { + return this.offset; + } + + /** + * `toStructure` returns the structure of this position. + */ + public toStructure(): CRDTTreePosStruct { + return { + createdAt: this.createdAt.toStructure(), + offset: this.offset, + }; + } + + /** + * `toIDString` returns a string that can be used as an ID for this position. + */ + public toIDString(): string { + return `${this.createdAt.toIDString()}:${this.offset}`; + } +} + +/** + * `CRDTTreePosStruct` represents the structure of CRDTTreePos. + * It is used to serialize and deserialize the CRDTTreePos. + */ +export type CRDTTreePosStruct = { createdAt: TimeTicketStruct; offset: number }; + /** * `InitialCRDTTreePos` is the initial position of the tree. */ -export const InitialCRDTTreePos = { - createdAt: InitialTimeTicket, - offset: 0, -}; +export const InitialCRDTTreePos = CRDTTreePos.of(InitialTimeTicket, 0); /** * `compareCRDTTreePos` compares the given two CRDTTreePos. */ function compareCRDTTreePos(posA: CRDTTreePos, posB: CRDTTreePos): number { - const compare = posA.createdAt.compare(posB.createdAt); + const compare = posA.getCreatedAt().compare(posB.getCreatedAt()); if (compare !== 0) { return compare; } - if (posA.offset > posB.offset) { + if (posA.getOffset() > posB.getOffset()) { return 1; - } else if (posA.offset < posB.offset) { + } else if (posA.getOffset() < posB.getOffset()) { return -1; } return 0; } /** - * `CRDTTreePos` represent a position in the tree. It indicates the virtual - * location in the tree, so whether the node is splitted or not, we can find - * the adjacent node to pos by calling `map.floorEntry()`. + * `TreeRange` represents a pair of CRDTTreePos. */ -export interface CRDTTreePos { - /** - * `createdAt` is the creation time of the node. - */ - createdAt: TimeTicket; - - /** - * `offset` is the distance from the beginning of the node if the node is - * split. - */ - offset: number; -} +export type TreeRange = [CRDTTreePos, CRDTTreePos]; /** - * `TreeRange` represents a pair of CRDTTreePos. + * `TreeRangeStruct` represents the structure of TreeRange. + * It is used to serialize and deserialize the TreeRange. */ -export type TreeRange = [CRDTTreePos, CRDTTreePos]; +export type TreeRangeStruct = [CRDTTreePosStruct, CRDTTreePosStruct]; /** * `CRDTTreeNode` is a node of CRDTTree. It is includes the logical clock and @@ -249,10 +303,7 @@ export class CRDTTreeNode extends IndexTreeNode { */ clone(offset: number): CRDTTreeNode { return new CRDTTreeNode( - { - createdAt: this.pos.createdAt, - offset, - }, + CRDTTreePos.of(this.pos.getCreatedAt(), offset), this.type, ); } @@ -261,7 +312,7 @@ export class CRDTTreeNode extends IndexTreeNode { * `getCreatedAt` returns the creation time of this element. */ public getCreatedAt(): TimeTicket { - return this.pos.createdAt; + return this.pos.getCreatedAt(); } } @@ -301,9 +352,9 @@ export function toXML(node: CRDTTreeNode): string { } /** - * `toStructure` converts the given CRDTNode JSON for debugging. + * `toTestTreeNode` converts the given CRDTNode JSON for debugging. */ -function toStructure(node: CRDTTreeNode): TreeNodeForTest { +function toTestTreeNode(node: CRDTTreeNode): TreeNodeForTest { if (node.isText) { const currentNode = node; return { @@ -316,7 +367,7 @@ function toStructure(node: CRDTTreeNode): TreeNodeForTest { return { type: node.type, - children: node.children.map(toStructure), + children: node.children.map(toTestTreeNode), size: node.size, isRemoved: node.isRemoved, }; @@ -407,7 +458,7 @@ export class CRDTTree extends CRDTGCElement { // handle the same position insertion of RGA. let current = treePos; while ( - current.node.next?.pos.createdAt.after(editedAt) && + current.node.next?.pos.getCreatedAt().after(editedAt) && current.node.parent === current.node.next.parent ) { current = { @@ -441,7 +492,7 @@ export class CRDTTree extends CRDTGCElement { // handle the same position insertion of RGA. let current = treePos; while ( - current.node.next?.pos.createdAt.after(editedAt) && + current.node.next?.pos.getCreatedAt().after(editedAt) && current.node.parent === current.node.next.parent ) { current = { @@ -557,10 +608,7 @@ export class CRDTTree extends CRDTGCElement { node.remove(editedAt); if (node.isRemoved) { - this.removedNodeMap.set( - `${node.getCreatedAt().getStructureAsString()}:${node.pos.offset}`, - node, - ); + this.removedNodeMap.set(node.pos.toIDString(), node); } } @@ -680,9 +728,7 @@ export class CRDTTree extends CRDTGCElement { [...nodesToRemoved].forEach((node) => { this.nodeMapByPos.remove(node.pos); this.purge(node); - this.removedNodeMap.delete( - `${node.getCreatedAt().getStructureAsString()}:${node.pos.offset}`, - ); + this.removedNodeMap.delete(node.pos.toIDString()); }); return count; @@ -713,10 +759,10 @@ export class CRDTTree extends CRDTGCElement { public findPos(index: number, preferText = true): CRDTTreePos { const treePos = this.indexTree.findTreePos(index, preferText); - return { - createdAt: treePos.node.pos.createdAt, - offset: treePos.node.pos.offset + treePos.offset, - }; + return CRDTTreePos.of( + treePos.node.pos.getCreatedAt(), + treePos.node.pos.getOffset() + treePos.offset, + ); } /** @@ -774,10 +820,10 @@ export class CRDTTree extends CRDTGCElement { public pathToPos(path: Array): CRDTTreePos { const treePos = this.indexTree.pathToTreePos(path); - return { - createdAt: treePos.node.pos.createdAt, - offset: treePos.node.pos.offset + treePos.offset, - }; + return CRDTTreePos.of( + treePos.node.pos.getCreatedAt(), + treePos.node.pos.getOffset() + treePos.offset, + ); } /** @@ -816,10 +862,10 @@ export class CRDTTree extends CRDTGCElement { } /** - * `toStructure` returns the JSON of this tree for debugging. + * `toTestTreeNode` returns the JSON of this tree for debugging. */ - public toStructure(): TreeNodeForTest { - return toStructure(this.indexTree.getRoot()); + public toTestTreeNode(): TreeNodeForTest { + return toTestTreeNode(this.indexTree.getRoot()); } /** @@ -869,19 +915,23 @@ export class CRDTTree extends CRDTGCElement { */ private toTreePos(pos: CRDTTreePos): TreePos | undefined { const entry = this.nodeMapByPos.floorEntry(pos); - if (!entry || !entry.key.createdAt.equals(pos.createdAt)) { + if (!entry || !entry.key.getCreatedAt().equals(pos.getCreatedAt())) { return; } // Choose the left node if the position is on the boundary of the split nodes. let node = entry.value; - if (pos.offset > 0 && pos.offset === node.pos.offset && node.insPrev) { + if ( + pos.getOffset() > 0 && + pos.getOffset() === node.pos.getOffset() && + node.insPrev + ) { node = node.insPrev; } return { node, - offset: pos.offset - node.pos.offset, + offset: pos.getOffset() - node.pos.getOffset(), }; } @@ -912,10 +962,40 @@ export class CRDTTree extends CRDTGCElement { } /** - * `rangeToIndex` returns pair of integer offsets of the given Tree. + * `toPosRange` converts the integer index range into the Tree position range structure. */ - public rangeToIndex(range: TreeRange): [number, number] { - return [this.toIndex(range[0]), this.toIndex(range[1])]; + public toPosRange(range: [number, number]): TreeRangeStruct { + const [fromIdx, toIdx] = range; + const fromPos = this.findPos(fromIdx).toStructure(); + if (fromIdx === toIdx) { + return [fromPos, fromPos]; + } + + return [fromPos, this.findPos(toIdx).toStructure()]; + } + + /** + * `toIndexRange` converts the Tree position range into the integer index range. + */ + public toIndexRange(range: TreeRangeStruct): [number, number] { + const [fromPosStruct, toPosStruct] = range; + const fromPos = CRDTTreePos.of( + TimeTicket.of( + Long.fromString(fromPosStruct.createdAt.lamport, true), + fromPosStruct.createdAt.delimiter, + fromPosStruct.createdAt.actorID, + ), + fromPosStruct.offset, + ); + const toPos = CRDTTreePos.of( + TimeTicket.of( + Long.fromString(toPosStruct.createdAt.lamport, true), + toPosStruct.createdAt.delimiter, + toPosStruct.createdAt.actorID, + ), + toPosStruct.offset, + ); + return [this.toIndex(fromPos), this.toIndex(toPos)]; } /** diff --git a/src/document/document.ts b/src/document/document.ts index cef2e1395..b7fad0684 100644 --- a/src/document/document.ts +++ b/src/document/document.ts @@ -739,9 +739,7 @@ export class Document { changes .map( (change) => - `${change - .getID() - .getStructureAsString()}\t${change.getStructureAsString()}`, + `${change.getID().toTestString()}\t${change.toTestString()}`, ) .join('\n'), ); diff --git a/src/document/json/array.ts b/src/document/json/array.ts index 68e5cef46..b449f4f65 100644 --- a/src/document/json/array.ts +++ b/src/document/json/array.ts @@ -96,10 +96,10 @@ export type JSONArray = { moveLast?(id: TimeTicket): void; /** - * `getStructureAsString` returns a String containing the meta data of the node + * `toTestString` returns a String containing the meta data of the node * for debugging purpose. */ - getStructureAsString?(): string; + toTestString?(): string; } & Array; /** @@ -288,8 +288,8 @@ export class ArrayProxy { fromIndex, ); }; - } else if (method === 'getStructureAsString') { - return (): string => ArrayProxy.getStructureAsString(target); + } else if (method === 'toTestString') { + return (): string => ArrayProxy.toTestString(target); } else if ( typeof method === 'string' && isReadOnlyArrayMethod(method) @@ -705,11 +705,11 @@ export class ArrayProxy { return -1; } /** - * `getStructureAsString` returns a String containing the meta data of the node + * `toTestString` returns a String containing the meta data of the node * for debugging purpose. */ - public static getStructureAsString(target: CRDTArray): string { - return target.getStructureAsString(); + public static toTestString(target: CRDTArray): string { + return target.toTestString(); } /** diff --git a/src/document/json/text.ts b/src/document/json/text.ts index ac4f73fce..0ab50965c 100644 --- a/src/document/json/text.ts +++ b/src/document/json/text.ts @@ -75,7 +75,7 @@ export class Text { const range = this.text.createRange(fromIdx, toIdx); if (logger.isEnabled(LogLevel.Debug)) { logger.debug( - `EDIT: f:${fromIdx}->${range[0].getStructureAsString()}, t:${toIdx}->${range[1].getStructureAsString()} c:${content}`, + `EDIT: f:${fromIdx}->${range[0].toTestString()}, t:${toIdx}->${range[1].toTestString()} c:${content}`, ); } const attrs = attributes ? stringifyObjectValues(attributes) : undefined; @@ -137,7 +137,7 @@ export class Text { const range = this.text.createRange(fromIdx, toIdx); if (logger.isEnabled(LogLevel.Debug)) { logger.debug( - `STYL: f:${fromIdx}->${range[0].getStructureAsString()}, t:${toIdx}->${range[1].getStructureAsString()} a:${JSON.stringify( + `STYL: f:${fromIdx}->${range[0].toTestString()}, t:${toIdx}->${range[1].toTestString()} a:${JSON.stringify( attributes, )}`, ); @@ -172,7 +172,7 @@ export class Text { const range = this.text.createRange(fromIdx, toIdx); if (logger.isEnabled(LogLevel.Debug)) { logger.debug( - `SELT: f:${fromIdx}->${range[0].getStructureAsString()}, t:${toIdx}->${range[1].getStructureAsString()}`, + `SELT: f:${fromIdx}->${range[0].toTestString()}, t:${toIdx}->${range[1].toTestString()}`, ); } const ticket = this.context.issueTimeTicket(); @@ -186,17 +186,17 @@ export class Text { } /** - * `getStructureAsString` returns a String containing the meta data of the node + * `toTestString` returns a String containing the meta data of the node * for debugging purpose. */ - getStructureAsString(): string { + toTestString(): string { if (!this.context || !this.text) { logger.fatal('it is not initialized yet'); // @ts-ignore return; } - return this.text.getStructureAsString(); + return this.text.toTestString(); } /** diff --git a/src/document/json/tree.ts b/src/document/json/tree.ts index 3acfe35e1..e7fd9d510 100644 --- a/src/document/json/tree.ts +++ b/src/document/json/tree.ts @@ -3,8 +3,10 @@ import { TimeTicket } from '@yorkie-js-sdk/src/document/time/ticket'; import { ChangeContext } from '@yorkie-js-sdk/src/document/change/context'; import { CRDTTree, + CRDTTreePos, CRDTTreeNode, TreeRange, + TreeRangeStruct, TreeChange, } from '@yorkie-js-sdk/src/document/crdt/tree'; @@ -57,7 +59,7 @@ function buildDescendants( if (type === 'text') { const { value } = treeNode as TextNode; const textNode = CRDTTreeNode.create( - { createdAt: ticket, offset: 0 }, + CRDTTreePos.of(ticket, 0), type, value, ); @@ -77,7 +79,7 @@ function buildDescendants( } } const elementNode = CRDTTreeNode.create( - { createdAt: ticket, offset: 0 }, + CRDTTreePos.of(ticket, 0), type, undefined, attrs, @@ -101,7 +103,7 @@ function createCRDTTreeNode(context: ChangeContext, content: TreeNode) { let root; if (content.type === 'text') { const { value } = content as TextNode; - root = CRDTTreeNode.create({ createdAt: ticket, offset: 0 }, type, value); + root = CRDTTreeNode.create(CRDTTreePos.of(ticket, 0), type, value); } else if (content) { const { children = [] } = content as ElementNode; let { attributes } = content as ElementNode; @@ -117,7 +119,7 @@ function createCRDTTreeNode(context: ChangeContext, content: TreeNode) { } root = CRDTTreeNode.create( - { createdAt: context.issueTimeTicket(), offset: 0 }, + CRDTTreePos.of(context.issueTimeTicket(), 0), type, undefined, attrs, @@ -166,14 +168,14 @@ export class Tree { public buildRoot(context: ChangeContext): CRDTTreeNode { if (!this.initialRoot) { return CRDTTreeNode.create( - { createdAt: context.issueTimeTicket(), offset: 0 }, + CRDTTreePos.of(context.issueTimeTicket(), 0), DefaultRootType, ); } // TODO(hackerwins): Need to use the ticket of operation of creating tree. const root = CRDTTreeNode.create( - { createdAt: context.issueTimeTicket(), offset: 0 }, + CRDTTreePos.of(context.issueTimeTicket(), 0), this.initialRoot.type, ); @@ -304,8 +306,8 @@ export class Tree { ); if ( - !fromPos.createdAt.equals(toPos.createdAt) || - fromPos.offset !== toPos.offset + !fromPos.getCreatedAt().equals(toPos.getCreatedAt()) || + fromPos.getOffset() !== toPos.getOffset() ) { this.context.registerElementHasRemovedNodes(this.tree!); } @@ -341,8 +343,8 @@ export class Tree { ); if ( - !fromPos.createdAt.equals(toPos.createdAt) || - fromPos.offset !== toPos.offset + !fromPos.getCreatedAt().equals(toPos.getCreatedAt()) || + fromPos.getOffset() !== toPos.getOffset() ) { this.context.registerElementHasRemovedNodes(this.tree!); } @@ -451,16 +453,29 @@ export class Tree { } /** - * `rangeToIndex` returns the integer offsets of the given range. + * `toPosRange` converts the integer index range into the Tree position range structure. */ - rangeToIndex(range: TreeRange): [number, number] { + toPosRange(range: [number, number]): TreeRangeStruct { if (!this.context || !this.tree) { logger.fatal('it is not initialized yet'); // @ts-ignore return; } - return this.tree.rangeToIndex(range); + return this.tree.toPosRange(range); + } + + /** + * `toIndexRange` converts the Tree position range into the integer index range. + */ + toIndexRange(range: TreeRangeStruct): [number, number] { + if (!this.context || !this.tree) { + logger.fatal('it is not initialized yet'); + // @ts-ignore + return; + } + + return this.tree.toIndexRange(range); } /** diff --git a/src/document/operation/add_operation.ts b/src/document/operation/add_operation.ts index 9a79b56a1..669001ffd 100644 --- a/src/document/operation/add_operation.ts +++ b/src/document/operation/add_operation.ts @@ -86,10 +86,10 @@ export class AddOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - return `${this.getParentCreatedAt().getStructureAsString()}.ADD`; + public toTestString(): string { + return `${this.getParentCreatedAt().toTestString()}.ADD`; } /** diff --git a/src/document/operation/edit_operation.ts b/src/document/operation/edit_operation.ts index bbbc9df34..473fe8bc1 100644 --- a/src/document/operation/edit_operation.ts +++ b/src/document/operation/edit_operation.ts @@ -124,12 +124,12 @@ export class EditOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - const parent = this.getParentCreatedAt().getStructureAsString(); - const fromPos = this.fromPos.getStructureAsString(); - const toPos = this.toPos.getStructureAsString(); + public toTestString(): string { + const parent = this.getParentCreatedAt().toTestString(); + const fromPos = this.fromPos.toTestString(); + const toPos = this.toPos.toTestString(); const content = this.content; return `${parent}.EDIT(${fromPos},${toPos},${content})`; } diff --git a/src/document/operation/increase_operation.ts b/src/document/operation/increase_operation.ts index f38a1b49b..37731a51e 100644 --- a/src/document/operation/increase_operation.ts +++ b/src/document/operation/increase_operation.ts @@ -83,10 +83,10 @@ export class IncreaseOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - return `${this.getParentCreatedAt().getStructureAsString()}.INCREASE`; + public toTestString(): string { + return `${this.getParentCreatedAt().toTestString()}.INCREASE`; } /** diff --git a/src/document/operation/move_operation.ts b/src/document/operation/move_operation.ts index c5b1b57d7..225ccc10a 100644 --- a/src/document/operation/move_operation.ts +++ b/src/document/operation/move_operation.ts @@ -91,10 +91,10 @@ export class MoveOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - return `${this.getParentCreatedAt().getStructureAsString()}.MOVE`; + public toTestString(): string { + return `${this.getParentCreatedAt().toTestString()}.MOVE`; } /** diff --git a/src/document/operation/operation.ts b/src/document/operation/operation.ts index 6be41f487..23630aed9 100644 --- a/src/document/operation/operation.ts +++ b/src/document/operation/operation.ts @@ -165,9 +165,9 @@ export abstract class Operation { public abstract getEffectedCreatedAt(): TimeTicket; /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data for debugging purpose. */ - public abstract getStructureAsString(): string; + public abstract toTestString(): string; /** * `execute` executes this operation on the given `CRDTRoot`. diff --git a/src/document/operation/remove_operation.ts b/src/document/operation/remove_operation.ts index 3f53757c4..897e90b52 100644 --- a/src/document/operation/remove_operation.ts +++ b/src/document/operation/remove_operation.ts @@ -91,10 +91,10 @@ export class RemoveOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - return `${this.getParentCreatedAt().getStructureAsString()}.REMOVE`; + public toTestString(): string { + return `${this.getParentCreatedAt().toTestString()}.REMOVE`; } /** diff --git a/src/document/operation/select_operation.ts b/src/document/operation/select_operation.ts index 36574fa73..e1eed495c 100644 --- a/src/document/operation/select_operation.ts +++ b/src/document/operation/select_operation.ts @@ -92,12 +92,12 @@ export class SelectOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - const parent = this.getParentCreatedAt().getStructureAsString(); - const fromPos = this.fromPos.getStructureAsString(); - const toPos = this.toPos.getStructureAsString(); + public toTestString(): string { + const parent = this.getParentCreatedAt().toTestString(); + const fromPos = this.fromPos.toTestString(); + const toPos = this.toPos.toTestString(); return `${parent}.SELT(${fromPos},${toPos})`; } diff --git a/src/document/operation/set_operation.ts b/src/document/operation/set_operation.ts index 3120f6f49..039d99c5d 100644 --- a/src/document/operation/set_operation.ts +++ b/src/document/operation/set_operation.ts @@ -87,10 +87,10 @@ export class SetOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - return `${this.getParentCreatedAt().getStructureAsString()}.SET`; + public toTestString(): string { + return `${this.getParentCreatedAt().toTestString()}.SET`; } /** diff --git a/src/document/operation/style_operation.ts b/src/document/operation/style_operation.ts index d2c2dcb0e..1ae30c4e6 100644 --- a/src/document/operation/style_operation.ts +++ b/src/document/operation/style_operation.ts @@ -101,12 +101,12 @@ export class StyleOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - const parent = this.getParentCreatedAt().getStructureAsString(); - const fromPos = this.fromPos.getStructureAsString(); - const toPos = this.toPos.getStructureAsString(); + public toTestString(): string { + const parent = this.getParentCreatedAt().toTestString(); + const fromPos = this.fromPos.toTestString(); + const toPos = this.toPos.toTestString(); const attributes = this.attributes; return `${parent}.STYL(${fromPos},${toPos},${JSON.stringify(attributes)})`; } diff --git a/src/document/operation/tree_edit_operation.ts b/src/document/operation/tree_edit_operation.ts index ab34e8856..91994f81b 100644 --- a/src/document/operation/tree_edit_operation.ts +++ b/src/document/operation/tree_edit_operation.ts @@ -86,8 +86,8 @@ export class TreeEditOperation extends Operation { ); if ( - !this.fromPos.createdAt.equals(this.toPos.createdAt) || - this.fromPos.offset !== this.toPos.offset + !this.fromPos.getCreatedAt().equals(this.toPos.getCreatedAt()) || + this.fromPos.getOffset() !== this.toPos.getOffset() ) { root.registerElementHasRemovedNodes(tree); } @@ -112,16 +112,16 @@ export class TreeEditOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - const parent = this.getParentCreatedAt().getStructureAsString(); - const fromPos = `${this.fromPos.createdAt.getStructureAsString()}:${ - this.fromPos.offset - }`; - const toPos = `${this.toPos.createdAt.getStructureAsString()}:${ - this.toPos.offset - }`; + public toTestString(): string { + const parent = this.getParentCreatedAt().toTestString(); + const fromPos = `${this.fromPos + .getCreatedAt() + .toTestString()}:${this.fromPos.getOffset()}`; + const toPos = `${this.toPos + .getCreatedAt() + .toTestString()}:${this.toPos.getOffset()}`; const content = this.content; return `${parent}.EDIT(${fromPos},${toPos},${content})`; } diff --git a/src/document/operation/tree_style_operation.ts b/src/document/operation/tree_style_operation.ts index c5f431e1c..5b326548c 100644 --- a/src/document/operation/tree_style_operation.ts +++ b/src/document/operation/tree_style_operation.ts @@ -106,16 +106,16 @@ export class TreeStyleOperation extends Operation { } /** - * `getStructureAsString` returns a string containing the meta data. + * `toTestString` returns a string containing the meta data. */ - public getStructureAsString(): string { - const parent = this.getParentCreatedAt().getStructureAsString(); - const fromPos = `${this.fromPos.createdAt.getStructureAsString()}:${ - this.fromPos.offset - }`; - const toPos = `${this.toPos.createdAt.getStructureAsString()}:${ - this.toPos.offset - }`; + public toTestString(): string { + const parent = this.getParentCreatedAt().toTestString(); + const fromPos = `${this.fromPos + .getCreatedAt() + .toTestString()}:${this.fromPos.getOffset()}`; + const toPos = `${this.toPos + .getCreatedAt() + .toTestString()}:${this.toPos.getOffset()}`; return `${parent}.STYLE(${fromPos},${toPos},${Object.entries( this.attributes || {}, diff --git a/src/document/time/ticket.ts b/src/document/time/ticket.ts index a85ce77aa..8ee777878 100644 --- a/src/document/time/ticket.ts +++ b/src/document/time/ticket.ts @@ -29,6 +29,16 @@ export const TicketComparator: Comparator = ( return p1.compare(p2); }; +/** + * `TimeTicketStruct` is a structure represents the meta data of the ticket. + * It is used to serialize and deserialize the ticket. + */ +export type TimeTicketStruct = { + lamport: string; + delimiter: number; + actorID: ActorID | undefined; +}; + /** * `TimeTicket` is a timestamp of the logical clock. Ticket is immutable. * It is created by `ChangeID`. @@ -69,10 +79,21 @@ export class TimeTicket { } /** - * `getStructureAsString` returns a string containing the meta data of the ticket + * `toStructure` returns the structure of this Ticket. + */ + public toStructure(): TimeTicketStruct { + return { + lamport: this.getLamportAsString(), + delimiter: this.getDelimiter(), + actorID: this.getActorID(), + }; + } + + /** + * `toTestString` returns a string containing the meta data of the ticket * for debugging purpose. */ - public getStructureAsString(): string { + public toTestString(): string { if (!this.actorID) { return `${this.lamport.toString()}:nil:${this.delimiter}`; } diff --git a/src/util/splay_tree.ts b/src/util/splay_tree.ts index 5143e4911..9dc0ce4b4 100644 --- a/src/util/splay_tree.ts +++ b/src/util/splay_tree.ts @@ -415,10 +415,10 @@ export class SplayTree { } /** - * `getStructureAsString` returns a string containing the meta data of the Node + * `toTestString` returns a string containing the meta data of the Node * for debugging purpose. */ - public getStructureAsString(): string { + public toTestString(): string { const metaString: Array> = []; this.traverseInorder(this.root!, metaString); return metaString diff --git a/src/yorkie.ts b/src/yorkie.ts index 04afe4f1d..10dbc344f 100644 --- a/src/yorkie.ts +++ b/src/yorkie.ts @@ -20,7 +20,6 @@ import { Text } from '@yorkie-js-sdk/src/document/json/text'; import { Tree } from '@yorkie-js-sdk/src/document/json/tree'; import { Counter } from '@yorkie-js-sdk/src/document/json/counter'; import { CounterType } from '@yorkie-js-sdk/src/document/crdt/counter'; -import { converter } from '@yorkie-js-sdk/src/api/converter'; export { Client, @@ -56,7 +55,7 @@ export { CompleteFn, Unsubscribe, } from '@yorkie-js-sdk/src/util/observable'; -export { TimeTicket } from '@yorkie-js-sdk/src/document/time/ticket'; +export { TimeTicket, TimeTicketStruct } from '@yorkie-js-sdk/src/document/time/ticket'; export { ActorID } from '@yorkie-js-sdk/src/document/time/actor_id'; export type { OperationInfo, @@ -73,6 +72,8 @@ export type { export { TreeChange, TreeChangeType, + CRDTTreePosStruct, + TreeRangeStruct, } from '@yorkie-js-sdk/src/document/crdt/tree'; export { @@ -96,7 +97,7 @@ export { TextNode, } from '@yorkie-js-sdk/src/document/json/tree'; export { Change } from '@yorkie-js-sdk/src/document/change/change'; -export { converter }; +export { converter } from '@yorkie-js-sdk/src/api/converter'; /** * The top-level yorkie namespace with additional properties. @@ -117,7 +118,6 @@ const yorkie = { Tree, IntType: CounterType.IntegerCnt, LongType: CounterType.LongCnt, - converter, }; export default yorkie; diff --git a/test/bench/document_test.ts b/test/bench/document_test.ts index e26764f8d..4e8c6901f 100644 --- a/test/bench/document_test.ts +++ b/test/bench/document_test.ts @@ -246,7 +246,7 @@ const tests = [ assert.equal(root.k1.length, 3); assert.equal( '[1:000000000000000000000000:2:1][1:000000000000000000000000:3:2][1:000000000000000000000000:4:3]', - root.k1.getStructureAsString!(), + root.k1.toTestString!(), ); root.k1.splice(1, 1); @@ -254,7 +254,7 @@ const tests = [ assert.equal(root.k1.length, 2); assert.equal( '[1:000000000000000000000000:2:1]{1:000000000000000000000000:3:2}[1:000000000000000000000000:4:3]', - root.k1.getStructureAsString!(), + root.k1.toTestString!(), ); const first = root.k1.getElementByIndex!(0); @@ -263,7 +263,7 @@ const tests = [ assert.equal(root.k1.length, 3); assert.equal( '[1:000000000000000000000000:2:1][1:000000000000000000000000:6:2]{1:000000000000000000000000:3:2}[1:000000000000000000000000:4:3]', - root.k1.getStructureAsString!(), + root.k1.toTestString!(), ); const third = root.k1.getElementByIndex!(2); @@ -272,7 +272,7 @@ const tests = [ assert.equal(root.k1.length, 4); assert.equal( '[1:000000000000000000000000:2:1][1:000000000000000000000000:6:2]{1:000000000000000000000000:3:2}[1:000000000000000000000000:4:3][1:000000000000000000000000:7:4]', - root.k1.getStructureAsString!(), + root.k1.toTestString!(), ); for (let i = 0; i < root.k1.length; i++) { @@ -296,19 +296,19 @@ const tests = [ ); assert.equal( `[0:00:0:0 ][1:00:2:0 A][1:00:3:0 12]{1:00:2:1 BC}[1:00:2:3 D]`, - doc.getRoot().k1.getStructureAsString(), + doc.getRoot().k1.toTestString(), ); doc.update((root) => { const [pos1] = root.k1.createRange(0, 0); - assert.equal('0:00:0:0:0', pos1.getStructureAsString()); + assert.equal('0:00:0:0:0', pos1.toTestString()); const [pos2] = root.k1.createRange(1, 1); - assert.equal('1:00:2:0:1', pos2.getStructureAsString()); + assert.equal('1:00:2:0:1', pos2.toTestString()); const [pos3] = root.k1.createRange(2, 2); - assert.equal('1:00:3:0:1', pos3.getStructureAsString()); + assert.equal('1:00:3:0:1', pos3.toTestString()); const [pos4] = root.k1.createRange(3, 3); - assert.equal('1:00:3:0:2', pos4.getStructureAsString()); + assert.equal('1:00:3:0:2', pos4.toTestString()); const [pos5] = root.k1.createRange(4, 4); - assert.equal('1:00:2:3:1', pos5.getStructureAsString()); + assert.equal('1:00:2:3:1', pos5.toTestString()); }); }, }, @@ -337,7 +337,7 @@ const tests = [ root.k1.edit(0, 0, 'Hello world'); assert.equal( '[0:00:0:0 ][1:00:2:0 Hello world]', - root.k1.getStructureAsString(), + root.k1.toTestString(), ); }); assert.equal('{"k1":[{"val":"Hello world"}]}', doc.toJSON()); @@ -345,7 +345,7 @@ const tests = [ root.k1.setStyle(0, 5, { b: '1' }); assert.equal( '[0:00:0:0 ][1:00:2:0 Hello][1:00:2:5 world]', - root.k1.getStructureAsString(), + root.k1.toTestString(), ); }); assert.equal( @@ -356,12 +356,12 @@ const tests = [ root.k1.setStyle(0, 5, { b: '1' }); assert.equal( '[0:00:0:0 ][1:00:2:0 Hello][1:00:2:5 world]', - root.k1.getStructureAsString(), + root.k1.toTestString(), ); root.k1.setStyle(3, 5, { i: '1' }); assert.equal( '[0:00:0:0 ][1:00:2:0 Hel][1:00:2:3 lo][1:00:2:5 world]', - root.k1.getStructureAsString(), + root.k1.toTestString(), ); }); assert.equal( @@ -372,7 +372,7 @@ const tests = [ root.k1.edit(5, 11, ' yorkie'); assert.equal( '[0:00:0:0 ][1:00:2:0 Hel][1:00:2:3 lo][4:00:1:0 yorkie]{1:00:2:5 world}', - root.k1.getStructureAsString(), + root.k1.toTestString(), ); }); assert.equal( @@ -384,7 +384,7 @@ const tests = [ assert( '[0:00:0:0 ][1:00:2:0 Hel][1:00:2:3 lo][5:00:1:0 ]' + '[4:00:1:0 yorkie]{1:00:2:5 world}', - root.k1.getStructureAsString(), + root.k1.toTestString(), ); }); assert.equal( diff --git a/test/integration/gc_test.ts b/test/integration/gc_test.ts index c2ea2770b..c587bc281 100644 --- a/test/integration/gc_test.ts +++ b/test/integration/gc_test.ts @@ -84,10 +84,10 @@ describe('Garbage Collection', function () { const root = (doc.getRootObject().get('list') as CRDTArray) .getElements() - .getStructureAsString(); + .toTestString(); const clone = (doc.getClone()!.get('list') as CRDTArray) .getElements() - .getStructureAsString(); + .toTestString(); assert.equal(root, clone); }); @@ -100,7 +100,7 @@ describe('Garbage Collection', function () { assert.equal( '[0:00:0:0 ][3:00:1:0 12]{2:00:1:0 AB}[2:00:1:2 CD]', - doc.getRoot().text.getStructureAsString(), + doc.getRoot().text.toTestString(), ); assert.equal(1, doc.getGarbageLen()); @@ -109,14 +109,14 @@ describe('Garbage Collection', function () { assert.equal( '[0:00:0:0 ][3:00:1:0 12][2:00:1:2 CD]', - doc.getRoot().text.getStructureAsString(), + doc.getRoot().text.toTestString(), ); doc.update((root) => root.text.edit(2, 4, '')); assert.equal( '[0:00:0:0 ][3:00:1:0 12]{2:00:1:2 CD}', - doc.getRoot().text.getStructureAsString(), + doc.getRoot().text.toTestString(), ); }); diff --git a/test/integration/text_test.ts b/test/integration/text_test.ts index f315fa0f5..c92ad102e 100644 --- a/test/integration/text_test.ts +++ b/test/integration/text_test.ts @@ -20,23 +20,23 @@ describe('Text', function () { doc.update((root) => { assert.equal( '[0:00:0:0 ][1:00:2:0 A][1:00:3:0 12]{1:00:2:1 BC}[1:00:2:3 D]', - root['k1'].getStructureAsString(), + root['k1'].toTestString(), ); let range = root['k1'].createRange(0, 0); - assert.equal('0:00:0:0:0', range[0].getStructureAsString()); + assert.equal('0:00:0:0:0', range[0].toTestString()); range = root['k1'].createRange(1, 1); - assert.equal('1:00:2:0:1', range[0].getStructureAsString()); + assert.equal('1:00:2:0:1', range[0].toTestString()); range = root['k1'].createRange(2, 2); - assert.equal('1:00:3:0:1', range[0].getStructureAsString()); + assert.equal('1:00:3:0:1', range[0].toTestString()); range = root['k1'].createRange(3, 3); - assert.equal('1:00:3:0:2', range[0].getStructureAsString()); + assert.equal('1:00:3:0:2', range[0].toTestString()); range = root['k1'].createRange(4, 4); - assert.equal('1:00:2:3:1', range[0].getStructureAsString()); + assert.equal('1:00:2:3:1', range[0].toTestString()); }); assert.equal( @@ -61,7 +61,7 @@ describe('Text', function () { doc.update((root) => { assert.equal( '[0:00:0:0 ][1:00:2:0 ABC][1:00:3:0 \n][1:00:2:3 D]', - root['k1'].getStructureAsString(), + root['k1'].toTestString(), ); }); @@ -234,7 +234,7 @@ describe('Text', function () { doc.update((root) => { assert.equal( '[0:00:0:0 ][1:00:2:0 ABC][1:00:3:0 \n][1:00:2:3 D]', - root['k1'].getStructureAsString(), + root['k1'].toTestString(), ); }); diff --git a/test/unit/document/crdt/root_test.ts b/test/unit/document/crdt/root_test.ts index 599186acf..bc432b287 100644 --- a/test/unit/document/crdt/root_test.ts +++ b/test/unit/document/crdt/root_test.ts @@ -119,10 +119,7 @@ describe('ROOT', function () { const text = new Text(change, crdtText); text.edit(0, 0, 'Hello World'); - assert.equal( - '[0:00:0:0 ][0:00:2:0 Hello World]', - text.getStructureAsString(), - ); + assert.equal('[0:00:0:0 ][0:00:2:0 Hello World]', text.toTestString()); assert.equal(0, root.getGarbageLen()); text.edit(6, 11, 'Yorkie'); @@ -132,7 +129,7 @@ describe('ROOT', function () { assert.equal(2, root.getGarbageLen()); assert.equal(2, root.garbageCollect(MaxTimeTicket)); - assert.equal('[0:00:0:0 ][0:00:3:0 Yorkie]', text.getStructureAsString()); + assert.equal('[0:00:0:0 ][0:00:3:0 Yorkie]', text.toTestString()); assert.equal(0, root.getGarbageLen()); }); }); diff --git a/test/unit/document/crdt/tree_test.ts b/test/unit/document/crdt/tree_test.ts index 9e74225a8..b6f89bffd 100644 --- a/test/unit/document/crdt/tree_test.ts +++ b/test/unit/document/crdt/tree_test.ts @@ -89,10 +89,7 @@ const dummyContext = ChangeContext.create( * `issuePos` is a helper function that issues a new CRDTTreePos. */ function issuePos(offset = 0): CRDTTreePos { - return { - createdAt: dummyContext.issueTimeTicket(), - offset, - }; + return CRDTTreePos.of(dummyContext.issueTimeTicket(), offset); } /** @@ -127,8 +124,8 @@ describe('CRDTTreeNode', function () { assert.equal(left.value, 'hello'); assert.equal(right!.value, 'yorkie'); - assert.deepEqual(left.pos, { createdAt: ITT, offset: 0 }); - assert.deepEqual(right!.pos, { createdAt: ITT, offset: 5 }); + assert.deepEqual(left.pos, CRDTTreePos.of(ITT, 0)); + assert.deepEqual(right!.pos, CRDTTreePos.of(ITT, 5)); }); }); @@ -180,7 +177,7 @@ describe('CRDTTree', function () { listEqual(tree, ['text.hello', 'text.!', 'p', 'text.world', 'p', 'r']); assert.deepEqual( - JSON.stringify(tree.toStructure()), + JSON.stringify(tree.toTestTreeNode()), JSON.stringify({ type: 'r', children: [ @@ -249,10 +246,10 @@ describe('CRDTTree', function () { assert.deepEqual(tree.toXML(), /*html*/ `

ab

cd

`); listEqual(tree, ['text.ab', 'p', 'text.cd', 'p', 'root']); - let structure = tree.toStructure(); - assert.equal(structure.size, 8); - assert.equal(structure.children![0].size, 2); - assert.equal(structure.children![0].children![0].size, 2); + let treeNode = tree.toTestTreeNode(); + assert.equal(treeNode.size, 8); + assert.equal(treeNode.children![0].size, 2); + assert.equal(treeNode.children![0].children![0].size, 2); // 02. delete b from first paragraph // 0 1 2 3 4 5 6 7 @@ -261,10 +258,10 @@ describe('CRDTTree', function () { assert.deepEqual(tree.toXML(), /*html*/ `

a

cd

`); listEqual(tree, ['text.a', 'p', 'text.cd', 'p', 'root']); - structure = tree.toStructure(); - assert.equal(structure.size, 7); - assert.equal(structure.children![0].size, 1); - assert.equal(structure.children![0].children![0].size, 1); + treeNode = tree.toTestTreeNode(); + assert.equal(treeNode.size, 7); + assert.equal(treeNode.children![0].size, 1); + assert.equal(treeNode.children![0].children![0].size, 1); }); it('Can delete nodes between element nodes with edit', function () { @@ -298,11 +295,11 @@ describe('CRDTTree', function () { // TODO(hackerwins): Uncomment the below line. // listEqual(tree, ['text.a', 'text.d', 'p', 'root']); - const structure = tree.toStructure(); - assert.equal(structure.size, 4); // root - assert.equal(structure.children![0].size, 2); // p - assert.equal(structure.children![0].children![0].size, 1); // a - assert.equal(structure.children![0].children![1].size, 1); // d + const treeNode = tree.toTestTreeNode(); + assert.equal(treeNode.size, 4); // root + assert.equal(treeNode.children![0].size, 2); // p + assert.equal(treeNode.children![0].children![0].size, 1); // a + assert.equal(treeNode.children![0].children![1].size, 1); // d // 03. insert a new text node at the start of the first paragraph. tree.editByIndex( @@ -626,11 +623,11 @@ describe('CRDTTree', function () { assert.deepEqual([fromIdx, toIdx], [5, 6]); assert.equal(tree.getSize(), 8); - let range = tree.createRange(0, 5); - assert.deepEqual(tree.rangeToIndex(range), [0, 5]); + let range = tree.toPosRange([0, 5]); + assert.deepEqual(tree.toIndexRange(range), [0, 5]); - range = tree.createRange(5, 7); - assert.deepEqual(tree.rangeToIndex(range), [5, 7]); + range = tree.toPosRange([5, 7]); + assert.deepEqual(tree.toIndexRange(range), [5, 7]); }); }); diff --git a/test/unit/util/splay_tree_test.ts b/test/unit/util/splay_tree_test.ts index fed1e19dd..f13fda77d 100644 --- a/test/unit/util/splay_tree_test.ts +++ b/test/unit/util/splay_tree_test.ts @@ -76,22 +76,16 @@ describe('SplayTree', function () { const tree = new SplayTree(); const nodeA = tree.insert(StringNode.create('A2')); - assert.equal('[2,2]A2', tree.getStructureAsString()); + assert.equal('[2,2]A2', tree.toTestString()); const nodeB = tree.insert(StringNode.create('B23')); - assert.equal('[2,2]A2[5,3]B23', tree.getStructureAsString()); + assert.equal('[2,2]A2[5,3]B23', tree.toTestString()); const nodeC = tree.insert(StringNode.create('C234')); - assert.equal('[2,2]A2[5,3]B23[9,4]C234', tree.getStructureAsString()); + assert.equal('[2,2]A2[5,3]B23[9,4]C234', tree.toTestString()); const nodeD = tree.insert(StringNode.create('D2345')); - assert.equal( - '[2,2]A2[5,3]B23[9,4]C234[14,5]D2345', - tree.getStructureAsString(), - ); + assert.equal('[2,2]A2[5,3]B23[9,4]C234[14,5]D2345', tree.toTestString()); tree.splayNode(nodeB); - assert.equal( - '[2,2]A2[14,3]B23[9,4]C234[5,5]D2345', - tree.getStructureAsString(), - ); + assert.equal('[2,2]A2[14,3]B23[9,4]C234[5,5]D2345', tree.toTestString()); assert.equal(tree.indexOf(nodeA), 0); assert.equal(tree.indexOf(nodeB), 2); @@ -105,16 +99,16 @@ describe('SplayTree', function () { const tree = new SplayTree(); const nodeH = tree.insert(StringNode.create('H')); - assert.equal('[1,1]H', tree.getStructureAsString()); + assert.equal('[1,1]H', tree.toTestString()); const nodeE = tree.insert(StringNode.create('E')); - assert.equal('[1,1]H[2,1]E', tree.getStructureAsString()); + assert.equal('[1,1]H[2,1]E', tree.toTestString()); const nodeL = tree.insert(StringNode.create('LL')); - assert.equal('[1,1]H[2,1]E[4,2]LL', tree.getStructureAsString()); + assert.equal('[1,1]H[2,1]E[4,2]LL', tree.toTestString()); const nodeO = tree.insert(StringNode.create('O')); - assert.equal('[1,1]H[2,1]E[4,2]LL[5,1]O', tree.getStructureAsString()); + assert.equal('[1,1]H[2,1]E[4,2]LL[5,1]O', tree.toTestString()); tree.delete(nodeE); - assert.equal('[4,1]H[3,2]LL[1,1]O', tree.getStructureAsString()); + assert.equal('[4,1]H[3,2]LL[1,1]O', tree.toTestString()); assert.equal(tree.indexOf(nodeH), 0); assert.equal(tree.indexOf(nodeE), -1);