From 9329a6ff87a1f94d956c4054613cc1956f52f008 Mon Sep 17 00:00:00 2001 From: Youngteac Hong Date: Wed, 19 Jul 2023 18:57:50 +0900 Subject: [PATCH] Apply new naming convention --- public/prosemirror.html | 71 +++++++++-------- src/api/converter.ts | 10 +-- src/document/crdt/rga_tree_split.ts | 90 ++++++++++------------ src/document/crdt/text.ts | 27 ++++--- src/document/crdt/tree.ts | 33 ++++---- src/document/document.ts | 4 +- src/document/json/text.ts | 26 +++---- src/document/json/tree.ts | 29 +++---- src/document/operation/edit_operation.ts | 18 ++--- src/document/operation/select_operation.ts | 18 ++--- src/document/operation/style_operation.ts | 18 ++--- src/util/object.ts | 3 + src/yorkie.ts | 2 +- test/integration/document_test.ts | 13 ---- test/integration/presence_test.ts | 2 +- test/integration/text_test.ts | 23 ------ test/unit/document/crdt/tree_test.ts | 8 +- test/unit/document/document_test.ts | 19 ----- 18 files changed, 185 insertions(+), 229 deletions(-) diff --git a/public/prosemirror.html b/public/prosemirror.html index f1db6e9ca..9c6804f09 100644 --- a/public/prosemirror.html +++ b/public/prosemirror.html @@ -323,11 +323,13 @@

Yorkie.RGASplit

selection: transaction.curSelection, }); - doc.update((root) => { - root.selection = root.tree.toPosRange([ - transaction.curSelection.from, - transaction.curSelection.to, - ]); + doc.update((root, presence) => { + presence.set({ + selection: root.tree.toPosRange([ + transaction.curSelection.from, + transaction.curSelection.to, + ]), + }); }); printLog(); return; @@ -338,7 +340,7 @@

Yorkie.RGASplit

transaction: transaction, }); - doc.update((root) => { + doc.update((root, presence) => { for (const step of transaction.steps) { const { jsonID: stepType, @@ -354,7 +356,7 @@

Yorkie.RGASplit

// TODO(hackerwins): replaceAround replaces the given range with given gap. if (stepType === 'replaceAround') { root.tree.move(from, to, gapFrom, gapTo); - return; + continue; } // 02-2. Enter Key: Insert Paragraph @@ -366,13 +368,13 @@

Yorkie.RGASplit

) { // TODO(hackerwins): Figure out how many depth to split. root.tree.split(from, 2); - return; + continue; } // 02-1. Delete the given range. if (!content.content.length) { root.tree.edit(from, to); - return; + continue; } // 03-4. Edit: Insert the given content. @@ -381,15 +383,30 @@

Yorkie.RGASplit

} } - root.selection = root.tree.toPosRange([ - transaction.curSelection.from, - transaction.curSelection.to, - ]); + presence.set({ + selection: root.tree.toPosRange([ + transaction.curSelection.from, + transaction.curSelection.to, + ]), + }); }); printLog(); }, }); + doc.subscribe('others', (event) => { + if (event.type === 'presence-changed') { + const { clientID, presence } = event.value; + displayRemoteSelection( + view, + doc.getRoot().tree, + presence.selection[0], + presence.selection[1], + clientID, + ); + } + }); + // 03. Downstream: yorkie.Tree to ProseMirror. doc.subscribe((event) => { if (event.type !== 'remote-change') { @@ -402,32 +419,20 @@

Yorkie.RGASplit

let toPos = -1; for (const op of operations) { if (op.type !== 'tree-edit') { - if ( - op.type === 'set' && - op.path === '$' && - op.key === 'selection' - ) { - const selection = doc.getRoot().selection; - displayRemoteSelection( - view, - root.tree, - selection[0], - selection[1], - actor, - ); - } continue; } - const { from, to, value: content } = op; + const { from, to, value: contents } = op; const transform = view.state.tr; - if (content) { + if (contents) { transform.replaceWith( from, to, - Node.fromJSON(mySchema, { - type: content.type, - text: content.value, - }), + ...contents.map((content) => + Node.fromJSON(mySchema, { + type: content.type, + text: content.value, + }), + ), ); } else { transform.replace(from, to); diff --git a/src/api/converter.ts b/src/api/converter.ts index e3cc203d3..8d8ff58ca 100644 --- a/src/api/converter.ts +++ b/src/api/converter.ts @@ -49,7 +49,7 @@ import { RGATreeSplit, RGATreeSplitNode, RGATreeSplitNodeID, - RGATreeSplitNodePos, + RGATreeSplitPos, } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; import { CRDTText, CRDTTextValue } from '@yorkie-js-sdk/src/document/crdt/text'; import { @@ -248,7 +248,7 @@ function toTextNodeID(id: RGATreeSplitNodeID): PbTextNodeID { /** * `toTextNodePos` converts the given model to Protobuf format. */ -function toTextNodePos(pos: RGATreeSplitNodePos): PbTextNodePos { +function toTextNodePos(pos: RGATreeSplitPos): PbTextNodePos { const pbTextNodePos = new PbTextNodePos(); pbTextNodePos.setCreatedAt(toTimeTicket(pos.getID().getCreatedAt())); pbTextNodePos.setOffset(pos.getID().getOffset()); @@ -521,7 +521,7 @@ function toTextNodes( function toTreeNodesWhenEdit(nodes: Array): Array { const pbTreeNodesList: Array = []; - if (!nodes.length) { + if (!nodes || !nodes.length) { return pbTreeNodesList; } @@ -863,8 +863,8 @@ function fromElementSimple(pbElementSimple: PbJSONElementSimple): CRDTElement { /** * `fromTextNodePos` converts the given Protobuf format to model format. */ -function fromTextNodePos(pbTextNodePos: PbTextNodePos): RGATreeSplitNodePos { - return RGATreeSplitNodePos.of( +function fromTextNodePos(pbTextNodePos: PbTextNodePos): RGATreeSplitPos { + return RGATreeSplitPos.of( RGATreeSplitNodeID.of( fromTimeTicket(pbTextNodePos.getCreatedAt())!, pbTextNodePos.getOffset(), diff --git a/src/document/crdt/rga_tree_split.ts b/src/document/crdt/rga_tree_split.ts index 2766a4e73..008e3680a 100644 --- a/src/document/crdt/rga_tree_split.ts +++ b/src/document/crdt/rga_tree_split.ts @@ -39,10 +39,10 @@ interface RGATreeSplitValue { } /** - * `RGATreeSplitNodePosStruct` is a structure represents the meta data of the node pos. + * `RGATreeSplitPosStruct` is a structure represents the meta data of the node pos. * It is used to serialize and deserialize the node pos. */ -export type RGATreeSplitNodePosStruct = { +export type RGATreeSplitPosStruct = { id: RGATreeSplitNodeIDStruct; relativeOffset: number; }; @@ -154,9 +154,9 @@ export class RGATreeSplitNodeID { const InitialRGATreeSplitNodeID = RGATreeSplitNodeID.of(InitialTimeTicket, 0); /** - * `RGATreeSplitNodePos` is the position of the text inside the node. + * `RGATreeSplitPos` is the position of the text inside the node. */ -export class RGATreeSplitNodePos { +export class RGATreeSplitPos { private id: RGATreeSplitNodeID; private relativeOffset: number; @@ -166,41 +166,39 @@ export class RGATreeSplitNodePos { } /** - * `of` creates a instance of RGATreeSplitNodePos. + * `of` creates a instance of RGATreeSplitPos. */ public static of( id: RGATreeSplitNodeID, relativeOffset: number, - ): RGATreeSplitNodePos { - return new RGATreeSplitNodePos(id, relativeOffset); + ): RGATreeSplitPos { + return new RGATreeSplitPos(id, relativeOffset); } /** - * `fromStruct` creates a instance of RGATreeSplitNodePos from the struct. + * `fromStruct` creates a instance of RGATreeSplitPos from the struct. */ - public static fromStruct( - struct: RGATreeSplitNodePosStruct, - ): RGATreeSplitNodePos { + public static fromStruct(struct: RGATreeSplitPosStruct): RGATreeSplitPos { const id = RGATreeSplitNodeID.fromStruct(struct.id); - return RGATreeSplitNodePos.of(id, struct.relativeOffset); + return RGATreeSplitPos.of(id, struct.relativeOffset); } /** - * `getID` returns the ID of this RGATreeSplitNodePos. + * `getID` returns the ID of this RGATreeSplitPos. */ public getID(): RGATreeSplitNodeID { return this.id; } /** - * `getRelativeOffset` returns the relative offset of this RGATreeSplitNodePos. + * `getRelativeOffset` returns the relative offset of this RGATreeSplitPos. */ public getRelativeOffset(): number { return this.relativeOffset; } /** - * `getAbsoluteID` returns the absolute id of this RGATreeSplitNodePos. + * `getAbsoluteID` returns the absolute id of this RGATreeSplitPos. */ public getAbsoluteID(): RGATreeSplitNodeID { return RGATreeSplitNodeID.of( @@ -220,7 +218,7 @@ export class RGATreeSplitNodePos { /** * `toStruct` returns the structure of this node pos. */ - public toStruct(): RGATreeSplitNodePosStruct { + public toStruct(): RGATreeSplitPosStruct { return { id: this.id.toStruct(), relativeOffset: this.relativeOffset, @@ -230,7 +228,7 @@ export class RGATreeSplitNodePos { /** * `equals` returns whether given pos equal to this pos or not. */ - public equals(other: RGATreeSplitNodePos): boolean { + public equals(other: RGATreeSplitPos): boolean { if (!this.id.equals(other.id)) { return false; } @@ -242,7 +240,7 @@ export class RGATreeSplitNodePos { /** * @internal */ -export type RGATreeSplitNodeRange = [RGATreeSplitNodePos, RGATreeSplitNodePos]; +export type RGATreeSplitPosRange = [RGATreeSplitPos, RGATreeSplitPos]; /** * `RGATreeSplitNode` is a node of RGATreeSplit. @@ -456,12 +454,12 @@ export class RGATreeSplitNode< } /** - * `createRange` creates ranges of RGATreeSplitNodePos. + * `createRange` creates ranges of RGATreeSplitPos. */ - public createRange(): RGATreeSplitNodeRange { + public createPosRange(): RGATreeSplitPosRange { return [ - RGATreeSplitNodePos.of(this.id, 0), - RGATreeSplitNodePos.of(this.id, this.getLength()), + RGATreeSplitPos.of(this.id, 0), + RGATreeSplitPos.of(this.id, this.getLength()), ]; } @@ -528,14 +526,14 @@ export class RGATreeSplit { * @param editedAt - edited time * @param value - value * @param latestCreatedAtMapByActor - latestCreatedAtMapByActor - * @returns `[RGATreeSplitNodePos, Map, Array]` + * @returns `[RGATreeSplitPos, Map, Array]` */ public edit( - range: RGATreeSplitNodeRange, + range: RGATreeSplitPosRange, editedAt: TimeTicket, value?: T, latestCreatedAtMapByActor?: Map, - ): [RGATreeSplitNodePos, Map, Array>] { + ): [RGATreeSplitPos, Map, Array>] { // 01. split nodes with from and to const [toLeft, toRight] = this.findNodeWithSplit(range[1], editedAt); const [fromLeft, fromRight] = this.findNodeWithSplit(range[0], editedAt); @@ -546,11 +544,11 @@ export class RGATreeSplit { this.deleteNodes(nodesToDelete, editedAt, latestCreatedAtMapByActor); const caretID = toRight ? toRight.getID() : toLeft.getID(); - let caretPos = RGATreeSplitNodePos.of(caretID, 0); + let caretPos = RGATreeSplitPos.of(caretID, 0); // 03. insert a new node if (value) { - const idx = this.findIdxFromNodePos(fromLeft.createRange()[1], true); + const idx = this.posToIndex(fromLeft.createPosRange()[1], true); const inserted = this.insertAfter( fromLeft, @@ -568,7 +566,7 @@ export class RGATreeSplit { }); } - caretPos = RGATreeSplitNodePos.of( + caretPos = RGATreeSplitPos.of( inserted.getID(), inserted.getContentLength(), ); @@ -583,32 +581,26 @@ export class RGATreeSplit { } /** - * `findNodePos` finds RGATreeSplitNodePos of given offset. + * `indexToPos` finds RGATreeSplitPos of given offset. */ - public findNodePos(idx: number): RGATreeSplitNodePos { + public indexToPos(idx: number): RGATreeSplitPos { const [node, offset] = this.treeByIndex.find(idx); const splitNode = node as RGATreeSplitNode; - return RGATreeSplitNodePos.of(splitNode.getID(), offset); + return RGATreeSplitPos.of(splitNode.getID(), offset); } /** * `findIndexesFromRange` finds indexes based on range. */ - public findIndexesFromRange(range: RGATreeSplitNodeRange): [number, number] { + public findIndexesFromRange(range: RGATreeSplitPosRange): [number, number] { const [fromPos, toPos] = range; - return [ - this.findIdxFromNodePos(fromPos, false), - this.findIdxFromNodePos(toPos, true), - ]; + return [this.posToIndex(fromPos, false), this.posToIndex(toPos, true)]; } /** - * `findIdxFromNodePos` finds index based on node position. + * `posToIndex` converts the given position to index. */ - public findIdxFromNodePos( - pos: RGATreeSplitNodePos, - preferToLeft: boolean, - ): number { + public posToIndex(pos: RGATreeSplitPos, preferToLeft: boolean): number { const absoluteID = pos.getAbsoluteID(); const node = preferToLeft ? this.findFloorNodePreferToLeft(absoluteID) @@ -746,7 +738,7 @@ export class RGATreeSplit { * `findNodeWithSplit` splits and return nodes of the given position. */ public findNodeWithSplit( - pos: RGATreeSplitNodePos, + pos: RGATreeSplitPos, editedAt: TimeTicket, ): [RGATreeSplitNode, RGATreeSplitNode] { const absoluteID = pos.getAbsoluteID(); @@ -949,11 +941,11 @@ export class RGATreeSplit { } [fromIdx] = this.findIndexesFromRange( - leftBoundary!.getNext()!.createRange(), + leftBoundary!.getNext()!.createPosRange(), ); if (rightBoundary) { [, toIdx] = this.findIndexesFromRange( - rightBoundary.getPrev()!.createRange(), + rightBoundary.getPrev()!.createPosRange(), ); } else { toIdx = this.treeByIndex.length; @@ -1049,13 +1041,13 @@ export class RGATreeSplit { * `Selection` represents the selection of text range in the editor. */ export class Selection { - private from: RGATreeSplitNodePos; - private to: RGATreeSplitNodePos; + private from: RGATreeSplitPos; + private to: RGATreeSplitPos; private updatedAt: TimeTicket; constructor( - from: RGATreeSplitNodePos, - to: RGATreeSplitNodePos, + from: RGATreeSplitPos, + to: RGATreeSplitPos, updatedAt: TimeTicket, ) { this.from = from; @@ -1067,7 +1059,7 @@ export class Selection { * `of` creates a new instance of Selection. */ public static of( - range: RGATreeSplitNodeRange, + range: RGATreeSplitPosRange, updatedAt: TimeTicket, ): Selection { return new Selection(range[0], range[1], updatedAt); diff --git a/src/document/crdt/text.ts b/src/document/crdt/text.ts index c65216cbb..f3eca0ae1 100644 --- a/src/document/crdt/text.ts +++ b/src/document/crdt/text.ts @@ -20,7 +20,7 @@ import { RHT } from '@yorkie-js-sdk/src/document/crdt/rht'; import { CRDTGCElement } from '@yorkie-js-sdk/src/document/crdt/element'; import { RGATreeSplit, - RGATreeSplitNodeRange, + RGATreeSplitPosRange, Selection, ValueChange, } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; @@ -189,12 +189,12 @@ export class CRDTText extends CRDTGCElement { * @internal */ public edit( - range: RGATreeSplitNodeRange, + range: RGATreeSplitPosRange, content: string, editedAt: TimeTicket, attributes?: Record, latestCreatedAtMapByActor?: Map, - ): [Map, Array>, RGATreeSplitNodeRange] { + ): [Map, Array>, RGATreeSplitPosRange] { const crdtTextValue = content ? CRDTTextValue.create(content) : undefined; if (crdtTextValue && attributes) { for (const [k, v] of Object.entries(attributes)) { @@ -237,7 +237,7 @@ export class CRDTText extends CRDTGCElement { * @internal */ public setStyle( - range: RGATreeSplitNodeRange, + range: RGATreeSplitPosRange, attributes: Record, editedAt: TimeTicket, ): Array> { @@ -257,7 +257,7 @@ export class CRDTText extends CRDTGCElement { } const [fromIdx, toIdx] = this.rgaTreeSplit.findIndexesFromRange( - node.createRange(), + node.createPosRange(), ); changes.push({ type: TextChangeType.Style, @@ -283,22 +283,25 @@ export class CRDTText extends CRDTGCElement { * @internal */ public select( - range: RGATreeSplitNodeRange, + range: RGATreeSplitPosRange, updatedAt: TimeTicket, ): TextChange | undefined { return this.selectPriv(range, updatedAt); } /** - * `createRange` returns pair of RGATreeSplitNodePos of the given integer offsets. + * `indexRangeToPosRange` returns the position range of the given index range. */ - public createRange(fromIdx: number, toIdx: number): RGATreeSplitNodeRange { - const fromPos = this.rgaTreeSplit.findNodePos(fromIdx); + public indexRangeToPosRange( + fromIdx: number, + toIdx: number, + ): RGATreeSplitPosRange { + const fromPos = this.rgaTreeSplit.indexToPos(fromIdx); if (fromIdx === toIdx) { return [fromPos, fromPos]; } - return [fromPos, this.rgaTreeSplit.findNodePos(toIdx)]; + return [fromPos, this.rgaTreeSplit.indexToPos(toIdx)]; } /** @@ -412,12 +415,12 @@ export class CRDTText extends CRDTGCElement { /** * `findIndexesFromRange` returns pair of integer offsets of the given range. */ - public findIndexesFromRange(range: RGATreeSplitNodeRange): [number, number] { + public findIndexesFromRange(range: RGATreeSplitPosRange): [number, number] { return this.rgaTreeSplit.findIndexesFromRange(range); } private selectPriv( - range: RGATreeSplitNodeRange, + range: RGATreeSplitPosRange, updatedAt: TimeTicket, ): TextChange | undefined { const prevSelection = this.selectionMap.get(updatedAt.getActorID()!); diff --git a/src/document/crdt/tree.ts b/src/document/crdt/tree.ts index 897493c8f..3e3cb25c8 100644 --- a/src/document/crdt/tree.ts +++ b/src/document/crdt/tree.ts @@ -171,15 +171,15 @@ function compareCRDTTreePos(posA: CRDTTreePos, posB: CRDTTreePos): number { } /** - * `TreeRange` represents a pair of CRDTTreePos. + * `TreePosRange` represents a pair of CRDTTreePos. */ -export type TreeRange = [CRDTTreePos, CRDTTreePos]; +export type TreePosRange = [CRDTTreePos, CRDTTreePos]; /** - * `TreeRangeStruct` represents the structure of TreeRange. + * `TreePosStructRange` represents the structure of TreeRange. * It is used to serialize and deserialize the TreeRange. */ -export type TreeRangeStruct = [CRDTTreePosStruct, CRDTTreePosStruct]; +export type TreePosStructRange = [CRDTTreePosStruct, CRDTTreePosStruct]; /** * `CRDTTreeNode` is a node of CRDTTree. It is includes the logical clock and @@ -938,28 +938,29 @@ export class CRDTTree extends CRDTGCElement { } /** - * `indexToPath` converts the given path to index. + * `pathToIndex` converts the given path to index. */ public pathToIndex(path: Array): number { return this.indexTree.pathToIndex(path); } /** - * `createRange` returns pair of RGATreeSplitNodePos of the given integer offsets. + * `indexRangeToPosRange` returns the position range from the given index range. */ - public createRange(fromIdx: number, toIdx: number): TreeRange { + public indexRangeToPosRange(fromIdx: number, toIdx: number): TreePosRange { const fromPos = this.findPos(fromIdx); if (fromIdx === toIdx) { return [fromPos, fromPos]; } - return [fromPos, this.findPos(toIdx)]; } /** - * `toPosRange` converts the integer index range into the Tree position range structure. + * `indexRangeToPosStructRange` converts the integer index range into the Tree position range structure. */ - public toPosRange(range: [number, number]): TreeRangeStruct { + public indexRangeToPosStructRange( + range: [number, number], + ): TreePosStructRange { const [fromIdx, toIdx] = range; const fromPos = this.findPos(fromIdx).toStruct(); if (fromIdx === toIdx) { @@ -970,9 +971,11 @@ export class CRDTTree extends CRDTGCElement { } /** - * `toIndexRange` converts the Tree position range into the integer index range. + * `posStructRangeToIndexRange` converts the given position range to the index range. */ - public toIndexRange(range: TreeRangeStruct): [number, number] { + public posStructRangeToIndexRange( + range: TreePosStructRange, + ): [number, number] { const [fromPosStruct, toPosStruct] = range; const fromPos = CRDTTreePos.of( TimeTicket.of( @@ -994,9 +997,11 @@ export class CRDTTree extends CRDTGCElement { } /** - * `rangeToPath` returns pair of integer offsets of the given Tree. + * `posRangeToPathRange` converts the given position range to the path range. */ - public rangeToPath(range: TreeRange): [Array, Array] { + public posRangeToPathRange( + range: TreePosRange, + ): [Array, Array] { const fromPath = this.indexTree.indexToPath(this.toIndex(range[0])); const toPath = this.indexTree.indexToPath(this.toIndex(range[1])); diff --git a/src/document/document.ts b/src/document/document.ts index 82f0b7786..8439b46e4 100644 --- a/src/document/document.ts +++ b/src/document/document.ts @@ -972,8 +972,8 @@ export class Document { for (const change of changes) { change.execute(this.clone!.root, this.clone!.presences); - let changeInfo: ChangeInfo | null = null; - let docEvent: DocEvent

| null = null; + let changeInfo: ChangeInfo | undefined; + let docEvent: DocEvent

| undefined; const actorID = change.getID().getActorID()!; if (change.hasPresenceChange()) { const presenceChange = change.getPresenceChange()!; diff --git a/src/document/json/text.ts b/src/document/json/text.ts index ba94bacac..cc2c26643 100644 --- a/src/document/json/text.ts +++ b/src/document/json/text.ts @@ -22,8 +22,8 @@ import { } from '@yorkie-js-sdk/src/document/time/ticket'; import { ChangeContext } from '@yorkie-js-sdk/src/document/change/context'; import { - RGATreeSplitNodeRange, - RGATreeSplitNodePos, + RGATreeSplitPosRange, + RGATreeSplitPos, } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; import { CRDTText, TextValueType } from '@yorkie-js-sdk/src/document/crdt/text'; import { EditOperation } from '@yorkie-js-sdk/src/document/operation/edit_operation'; @@ -93,7 +93,7 @@ export class Text { return; } - const range = this.text.createRange(fromIdx, toIdx); + const range = this.text.indexRangeToPosRange(fromIdx, toIdx); if (logger.isEnabled(LogLevel.Debug)) { logger.debug( `EDIT: f:${fromIdx}->${range[0].toTestString()}, t:${toIdx}->${range[1].toTestString()} c:${content}`, @@ -101,7 +101,7 @@ export class Text { } const attrs = attributes ? stringifyObjectValues(attributes) : undefined; const ticket = this.context.issueTimeTicket(); - const [maxCreatedAtMapByActor, _, rangeAfterEdit] = this.text.edit( + const [maxCreatedAtMapByActor, , rangeAfterEdit] = this.text.edit( range, content, ticket, @@ -155,7 +155,7 @@ export class Text { return false; } - const range = this.text.createRange(fromIdx, toIdx); + const range = this.text.indexRangeToPosRange(fromIdx, toIdx); if (logger.isEnabled(LogLevel.Debug)) { logger.debug( `STYL: f:${fromIdx}->${range[0].toTestString()}, t:${toIdx}->${range[1].toTestString()} a:${JSON.stringify( @@ -190,7 +190,7 @@ export class Text { return false; } - const range = this.text.createRange(fromIdx, toIdx); + const range = this.text.indexRangeToPosRange(fromIdx, toIdx); if (logger.isEnabled(LogLevel.Debug)) { logger.debug( `SELT: f:${fromIdx}->${range[0].toTestString()}, t:${toIdx}->${range[1].toTestString()}`, @@ -207,16 +207,16 @@ export class Text { } /** - * `createRange` returns TextRangeStruct of the given indexes. + * `indexRangeToPosRange` returns TextRangeStruct of the given index range. */ - createRange(range: [number, number]): TextRangeStruct { + indexRangeToPosRange(range: [number, number]): TextRangeStruct { if (!this.context || !this.text) { logger.fatal('it is not initialized yet'); // @ts-ignore return; } - const textRange = this.text.createRange(range[0], range[1]); + const textRange = this.text.indexRangeToPosRange(range[0], range[1]); return [textRange[0].toStruct(), textRange[1].toStruct()]; } @@ -231,8 +231,8 @@ export class Text { } const textRange = this.text.findIndexesFromRange([ - RGATreeSplitNodePos.fromStruct(range[0]), - RGATreeSplitNodePos.fromStruct(range[1]), + RGATreeSplitPos.fromStruct(range[0]), + RGATreeSplitPos.fromStruct(range[1]), ]); return [textRange[0], textRange[1]]; } @@ -295,13 +295,13 @@ export class Text { * `createRangeForTest` returns pair of RGATreeSplitNodePos of the given indexes * for testing purpose. */ - createRangeForTest(fromIdx: number, toIdx: number): RGATreeSplitNodeRange { + createRangeForTest(fromIdx: number, toIdx: number): RGATreeSplitPosRange { if (!this.context || !this.text) { logger.fatal('it is not initialized yet'); // @ts-ignore return; } - return this.text.createRange(fromIdx, toIdx); + return this.text.indexRangeToPosRange(fromIdx, toIdx); } } diff --git a/src/document/json/tree.ts b/src/document/json/tree.ts index 0c66e8376..836beda3e 100644 --- a/src/document/json/tree.ts +++ b/src/document/json/tree.ts @@ -5,8 +5,8 @@ import { CRDTTree, CRDTTreePos, CRDTTreeNode, - TreeRange, - TreeRangeStruct, + TreePosRange, + TreePosStructRange, TreeChange, } from '@yorkie-js-sdk/src/document/crdt/tree'; @@ -510,20 +510,23 @@ export class Tree { /** * `createRange` returns pair of CRDTTreePos of the given integer offsets. */ - createRange(fromIdx: number, toIdx: number): TreeRange { + createRange(fromIdx: number, toIdx: number): TreePosRange { if (!this.context || !this.tree) { logger.fatal('it is not initialized yet'); // @ts-ignore return; } - return this.tree.createRange(fromIdx, toIdx); + return this.tree.indexRangeToPosRange(fromIdx, toIdx); } /** * `createRangeByPath` returns pair of CRDTTreePos of the given path. */ - createRangeByPath(fromPath: Array, toPath: Array): TreeRange { + createRangeByPath( + fromPath: Array, + toPath: Array, + ): TreePosRange { if (!this.context || !this.tree) { logger.fatal('it is not initialized yet'); // @ts-ignore @@ -532,45 +535,45 @@ export class Tree { const fromIdx = this.tree.pathToIndex(fromPath); const toIdx = this.tree.pathToIndex(toPath); - return this.tree.createRange(fromIdx, toIdx); + return this.tree.indexRangeToPosRange(fromIdx, toIdx); } /** - * `toPosRange` converts the integer index range into the Tree position range structure. + * `indexRangeToPosRange` converts the index range into the position range. */ - toPosRange(range: [number, number]): TreeRangeStruct { + indexRangeToPosRange(range: [number, number]): TreePosStructRange { if (!this.context || !this.tree) { logger.fatal('it is not initialized yet'); // @ts-ignore return; } - return this.tree.toPosRange(range); + return this.tree.indexRangeToPosStructRange(range); } /** * `toIndexRange` converts the Tree position range into the integer index range. */ - toIndexRange(range: TreeRangeStruct): [number, number] { + toIndexRange(range: TreePosStructRange): [number, number] { if (!this.context || !this.tree) { logger.fatal('it is not initialized yet'); // @ts-ignore return; } - return this.tree.toIndexRange(range); + return this.tree.posStructRangeToIndexRange(range); } /** * `rangeToPath` returns the path of the given range. */ - rangeToPath(range: TreeRange): [Array, Array] { + rangeToPath(range: TreePosRange): [Array, Array] { if (!this.context || !this.tree) { logger.fatal('it is not initialized yet'); // @ts-ignore return; } - return this.tree.rangeToPath(range); + return this.tree.posRangeToPathRange(range); } } diff --git a/src/document/operation/edit_operation.ts b/src/document/operation/edit_operation.ts index 3145f1912..edd4644a3 100644 --- a/src/document/operation/edit_operation.ts +++ b/src/document/operation/edit_operation.ts @@ -17,7 +17,7 @@ import { logger } from '@yorkie-js-sdk/src/util/logger'; import { TimeTicket } from '@yorkie-js-sdk/src/document/time/ticket'; import { CRDTRoot } from '@yorkie-js-sdk/src/document/crdt/root'; -import { RGATreeSplitNodePos } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; +import { RGATreeSplitPos } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; import { CRDTText } from '@yorkie-js-sdk/src/document/crdt/text'; import { Operation, @@ -30,16 +30,16 @@ import { Indexable } from '../document'; * Edit, but with additional style properties, attributes. */ export class EditOperation extends Operation { - private fromPos: RGATreeSplitNodePos; - private toPos: RGATreeSplitNodePos; + private fromPos: RGATreeSplitPos; + private toPos: RGATreeSplitPos; private maxCreatedAtMapByActor: Map; private content: string; private attributes: Map; constructor( parentCreatedAt: TimeTicket, - fromPos: RGATreeSplitNodePos, - toPos: RGATreeSplitNodePos, + fromPos: RGATreeSplitPos, + toPos: RGATreeSplitPos, maxCreatedAtMapByActor: Map, content: string, attributes: Map, @@ -58,8 +58,8 @@ export class EditOperation extends Operation { */ public static create( parentCreatedAt: TimeTicket, - fromPos: RGATreeSplitNodePos, - toPos: RGATreeSplitNodePos, + fromPos: RGATreeSplitPos, + toPos: RGATreeSplitPos, maxCreatedAtMapByActor: Map, content: string, attributes: Map, @@ -139,14 +139,14 @@ export class EditOperation extends Operation { /** * `getFromPos` returns the start point of the editing range. */ - public getFromPos(): RGATreeSplitNodePos { + public getFromPos(): RGATreeSplitPos { return this.fromPos; } /** * `getToPos` returns the end point of the editing range. */ - public getToPos(): RGATreeSplitNodePos { + public getToPos(): RGATreeSplitPos { return this.toPos; } diff --git a/src/document/operation/select_operation.ts b/src/document/operation/select_operation.ts index da10aff99..8aa6cab42 100644 --- a/src/document/operation/select_operation.ts +++ b/src/document/operation/select_operation.ts @@ -17,7 +17,7 @@ import { logger } from '@yorkie-js-sdk/src/util/logger'; import { TimeTicket } from '@yorkie-js-sdk/src/document/time/ticket'; import { CRDTRoot } from '@yorkie-js-sdk/src/document/crdt/root'; -import { RGATreeSplitNodePos } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; +import { RGATreeSplitPos } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; import { CRDTText } from '@yorkie-js-sdk/src/document/crdt/text'; import { Operation, @@ -29,13 +29,13 @@ import { Indexable } from '../document'; * `SelectOperation` represents an operation that selects an area in the text. */ export class SelectOperation extends Operation { - private fromPos: RGATreeSplitNodePos; - private toPos: RGATreeSplitNodePos; + private fromPos: RGATreeSplitPos; + private toPos: RGATreeSplitPos; constructor( parentCreatedAt: TimeTicket, - fromPos: RGATreeSplitNodePos, - toPos: RGATreeSplitNodePos, + fromPos: RGATreeSplitPos, + toPos: RGATreeSplitPos, executedAt: TimeTicket, ) { super(parentCreatedAt, executedAt); @@ -48,8 +48,8 @@ export class SelectOperation extends Operation { */ public static create( parentCreatedAt: TimeTicket, - fromPos: RGATreeSplitNodePos, - toPos: RGATreeSplitNodePos, + fromPos: RGATreeSplitPos, + toPos: RGATreeSplitPos, executedAt: TimeTicket, ): SelectOperation { return new SelectOperation(parentCreatedAt, fromPos, toPos, executedAt); @@ -104,14 +104,14 @@ export class SelectOperation extends Operation { /** * `getFromPos` returns the start point of the editing range. */ - public getFromPos(): RGATreeSplitNodePos { + public getFromPos(): RGATreeSplitPos { return this.fromPos; } /** * `getToPos` returns the end point of the editing range. */ - public getToPos(): RGATreeSplitNodePos { + public getToPos(): RGATreeSplitPos { return this.toPos; } } diff --git a/src/document/operation/style_operation.ts b/src/document/operation/style_operation.ts index a0e1478e7..c46140f1f 100644 --- a/src/document/operation/style_operation.ts +++ b/src/document/operation/style_operation.ts @@ -17,7 +17,7 @@ import { logger } from '@yorkie-js-sdk/src/util/logger'; import { TimeTicket } from '@yorkie-js-sdk/src/document/time/ticket'; import { CRDTRoot } from '@yorkie-js-sdk/src/document/crdt/root'; -import { RGATreeSplitNodePos } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; +import { RGATreeSplitPos } from '@yorkie-js-sdk/src/document/crdt/rga_tree_split'; import { CRDTText } from '@yorkie-js-sdk/src/document/crdt/text'; import { Operation, @@ -29,14 +29,14 @@ import { Indexable } from '../document'; * `StyleOperation` is an operation applies the style of the given range to Text. */ export class StyleOperation extends Operation { - private fromPos: RGATreeSplitNodePos; - private toPos: RGATreeSplitNodePos; + private fromPos: RGATreeSplitPos; + private toPos: RGATreeSplitPos; private attributes: Map; constructor( parentCreatedAt: TimeTicket, - fromPos: RGATreeSplitNodePos, - toPos: RGATreeSplitNodePos, + fromPos: RGATreeSplitPos, + toPos: RGATreeSplitPos, attributes: Map, executedAt: TimeTicket, ) { @@ -51,8 +51,8 @@ export class StyleOperation extends Operation { */ public static create( parentCreatedAt: TimeTicket, - fromPos: RGATreeSplitNodePos, - toPos: RGATreeSplitNodePos, + fromPos: RGATreeSplitPos, + toPos: RGATreeSplitPos, attributes: Map, executedAt: TimeTicket, ): StyleOperation { @@ -114,14 +114,14 @@ export class StyleOperation extends Operation { /** * `getFromPos` returns the start point of the editing range. */ - public getFromPos(): RGATreeSplitNodePos { + public getFromPos(): RGATreeSplitPos { return this.fromPos; } /** * `getToPos` returns the end point of the editing range. */ - public getToPos(): RGATreeSplitNodePos { + public getToPos(): RGATreeSplitPos { return this.toPos; } diff --git a/src/util/object.ts b/src/util/object.ts index 877f170e1..f26381683 100644 --- a/src/util/object.ts +++ b/src/util/object.ts @@ -14,6 +14,9 @@ * limitations under the License. */ +/** + * `deepcopy` returns a deep copy of the given object. + */ export function deepcopy(object: T): T { if (object instanceof Map) { const pairs = Array.from(object); diff --git a/src/yorkie.ts b/src/yorkie.ts index 3816736ae..7daa7b26f 100644 --- a/src/yorkie.ts +++ b/src/yorkie.ts @@ -74,7 +74,7 @@ export { TreeChange, TreeChangeType, CRDTTreePosStruct, - TreeRangeStruct, + TreePosStructRange as TreeRangeStruct, } from '@yorkie-js-sdk/src/document/crdt/tree'; export { diff --git a/test/integration/document_test.ts b/test/integration/document_test.ts index 2a2f1a60d..d88ce18db 100644 --- a/test/integration/document_test.ts +++ b/test/integration/document_test.ts @@ -167,12 +167,6 @@ describe('Document', function () { }, path: '$.content', }, - { - type: 'select', - from: 11, - to: 11, - path: '$.content', - }, { type: 'set', path: '$', key: 'obj' }, { type: 'set', path: '$.obj', key: 'name' }, { type: 'set', path: '$.obj', key: 'age' }, @@ -197,7 +191,6 @@ describe('Document', function () { const prevItem = root.todos.getElementByIndex!(1); const currItem = root.todos.getElementByIndex!(0); root.todos.moveAfter!(prevItem.getID!(), currItem.getID!()); - root.content.select(0, 5); root.content.setStyle(0, 5, { bold: true }); expectedEvents1 = [ { type: 'increase', path: '$.counter', value: 1 }, @@ -208,12 +201,6 @@ describe('Document', function () { index: 1, previousIndex: 0, }, - { - type: 'select', - from: 0, - to: 5, - path: '$.content', - }, { type: 'style', from: 0, diff --git a/test/integration/presence_test.ts b/test/integration/presence_test.ts index a0c819705..e5ac8c152 100644 --- a/test/integration/presence_test.ts +++ b/test/integration/presence_test.ts @@ -102,7 +102,7 @@ describe('Presence', function () { assert.deepEqual(doc1.getPresence(c2.getID()!), emptyObject); }); - it(`Should be synced eventually`, async function () { + it('Should be synced eventually', async function () { const c1 = new yorkie.Client(testRPCAddr); const c2 = new yorkie.Client(testRPCAddr); await c1.activate(); diff --git a/test/integration/text_test.ts b/test/integration/text_test.ts index ab8cb11fe..7dd07aef3 100644 --- a/test/integration/text_test.ts +++ b/test/integration/text_test.ts @@ -175,29 +175,6 @@ describe('Text', function () { } }); - it('should handle select operations', async function () { - const doc = new Document<{ - text: Text; - }>('test-doc'); - - doc.update((root) => { - root.text = new Text(); - root.text.edit(0, 0, 'ABCD'); - }); - - doc.subscribe('$.text', (event) => { - if (event.type === 'local-change') { - const { operations } = event.value; - - if (operations[0].type === 'select') { - assert.equal(operations[0].from, 2); - assert.equal(operations[0].to, 4); - } - } - }); - doc.update((root) => root.text.select(2, 4)); - }); - it('should handle edit operations', async function () { await withTwoClientsAndDocuments<{ k1: Text }>(async (c1, d1, c2, d2) => { d1.update((root) => { diff --git a/test/unit/document/crdt/tree_test.ts b/test/unit/document/crdt/tree_test.ts index 52ded0eb0..7c8aece68 100644 --- a/test/unit/document/crdt/tree_test.ts +++ b/test/unit/document/crdt/tree_test.ts @@ -489,11 +489,11 @@ describe('CRDTTree', function () { assert.deepEqual([fromIdx, toIdx], [5, 6]); assert.equal(tree.getSize(), 8); - let range = tree.toPosRange([0, 5]); - assert.deepEqual(tree.toIndexRange(range), [0, 5]); + let range = tree.indexRangeToPosStructRange([0, 5]); + assert.deepEqual(tree.posStructRangeToIndexRange(range), [0, 5]); - range = tree.toPosRange([5, 7]); - assert.deepEqual(tree.toIndexRange(range), [5, 7]); + range = tree.indexRangeToPosStructRange([5, 7]); + assert.deepEqual(tree.posStructRangeToIndexRange(range), [5, 7]); }); }); diff --git a/test/unit/document/document_test.ts b/test/unit/document/document_test.ts index 4d9408fc4..17ff27435 100644 --- a/test/unit/document/document_test.ts +++ b/test/unit/document/document_test.ts @@ -1095,19 +1095,6 @@ describe('Document', function () { to: 0, value: { attributes: {}, content: 'hello world' }, }); - expectedOps.push({ - type: 'select', - from: 11, - to: 11, - path: '$.text', - }); - root.text.select(0, 2); - expectedOps.push({ - type: 'select', - path: '$.text', - from: 0, - to: 2, - }); }); await waitStubCallCount(stub1, 1); assert.deepEqual( @@ -1145,12 +1132,6 @@ describe('Document', function () { to: 0, value: { attributes: {}, content: 'hello world' }, }); - expectedOps.push({ - type: 'select', - from: 11, - to: 11, - path: '$.textWithAttr', - }); root.textWithAttr.setStyle(0, 1, { bold: 'true' }); expectedOps.push({ type: 'style',