Skip to content

Commit fc47b38

Browse files
committed
Add fields markOpsBefore and markOpsAfter to TextNode in protobuf
1 parent 7ab0076 commit fc47b38

File tree

7 files changed

+741
-45
lines changed

7 files changed

+741
-45
lines changed

src/api/converter.ts

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import {
5252
RGATreeSplitNode,
5353
RGATreeSplitNodeID,
5454
RGATreeSplitPos,
55+
StyleOperation as MarkOperation,
5556
} from '@yorkie-js-sdk/src/document/crdt/rga_tree_split';
5657
import { CRDTText, CRDTTextValue } from '@yorkie-js-sdk/src/document/crdt/text';
5758
import {
@@ -83,6 +84,8 @@ import {
8384
TreePos as PbTreePos,
8485
TreeNodeID as PbTreeNodeID,
8586
ValueType as PbValueType,
87+
MarkOps as PbMarkOps,
88+
MarkOp as PbMarkOp,
8689
} from '@yorkie-js-sdk/src/api/yorkie/v1/resources_pb';
8790
import { IncreaseOperation } from '@yorkie-js-sdk/src/document/operation/increase_operation';
8891
import {
@@ -128,6 +131,33 @@ function toPresenceChange(
128131
return pbPresenceChange;
129132
}
130133

134+
/**
135+
* `toMarkOps` converts the given model to Protobuf format.
136+
*/
137+
function toMarkOps(markOps: Set<MarkOperation>): PbMarkOps {
138+
const pbMarkOps = new PbMarkOps();
139+
const pbMarkOpsList: Array<PbMarkOp> = [];
140+
for (const markOp of markOps) {
141+
pbMarkOpsList.push(toMarkOp(markOp));
142+
}
143+
pbMarkOps.setOperationsList(pbMarkOpsList);
144+
return pbMarkOps;
145+
}
146+
147+
/**
148+
* `toMarkOp` converts the given model to Protobuf format.
149+
*/
150+
function toMarkOp(markOp: MarkOperation): PbMarkOp {
151+
const pbMarkOp = new PbMarkOp();
152+
pbMarkOp.setFromboundary(toTextNodeBoundary(markOp.fromBoundary));
153+
pbMarkOp.setToboundary(toTextNodeBoundary(markOp.toBoundary));
154+
const pbAttributes = pbMarkOp.getAttributesMap();
155+
for (const [key, value] of Object.entries(markOp.attributes)) {
156+
pbAttributes.set(key, value);
157+
}
158+
return pbMarkOp;
159+
}
160+
131161
/**
132162
* `toCheckpoint` converts the given model to Protobuf format.
133163
*/
@@ -539,7 +569,6 @@ function toTextNodes(
539569
rgaTreeSplit: RGATreeSplit<CRDTTextValue>,
540570
): Array<PbTextNode> {
541571
const pbTextNodes = [];
542-
let currentAttr = new Map<string, string>();
543572

544573
for (const textNode of rgaTreeSplit) {
545574
const pbTextNode = new PbTextNode();
@@ -548,23 +577,6 @@ function toTextNodes(
548577
pbTextNode.setRemovedAt(toTimeTicket(textNode.getRemovedAt()));
549578

550579
const pbNodeAttrsMap = pbTextNode.getAttributesMap();
551-
552-
const beforeAnchor = textNode.getStyleOpsBefore();
553-
const afterAnchor = textNode.getStyleOpsAfter();
554-
if (beforeAnchor) {
555-
currentAttr = rgaTreeSplit.getAttrsFromAnchor(beforeAnchor);
556-
}
557-
if (!textNode.isRemoved()) {
558-
for (const [key, value] of currentAttr.entries()) {
559-
const pbNodeAttr = new PbNodeAttr();
560-
pbNodeAttr.setValue(value);
561-
pbNodeAttrsMap.set(key, pbNodeAttr);
562-
}
563-
}
564-
if (afterAnchor) {
565-
currentAttr = rgaTreeSplit.getAttrsFromAnchor(afterAnchor);
566-
}
567-
568580
const attrs = textNode.getValue().getAttrs();
569581
for (const attr of attrs) {
570582
const pbNodeAttr = new PbNodeAttr();
@@ -573,6 +585,14 @@ function toTextNodes(
573585
pbNodeAttrsMap.set(attr.getKey(), pbNodeAttr);
574586
}
575587

588+
const styleOpsBefore = textNode.getStyleOpsBefore();
589+
if (styleOpsBefore) {
590+
pbTextNode.setMarkopsbefore(toMarkOps(styleOpsBefore));
591+
}
592+
const styleOpsAfter = textNode.getStyleOpsAfter();
593+
if (styleOpsAfter) {
594+
pbTextNode.setMarkopsafter(toMarkOps(styleOpsAfter));
595+
}
576596
pbTextNodes.push(pbTextNode);
577597
}
578598

@@ -985,6 +1005,22 @@ function fromTextNodeID(pbTextNodeID: PbTextNodeID): RGATreeSplitNodeID {
9851005
);
9861006
}
9871007

1008+
/**
1009+
* `fromMarkOp` converts the given Protobuf format to model format.
1010+
*/
1011+
function fromMarkOp(pbMarkOp: PbMarkOp): MarkOperation {
1012+
const attributes: Record<string, string> = {};
1013+
pbMarkOp.getAttributesMap().forEach((value, key) => {
1014+
attributes[key as string] = value;
1015+
});
1016+
1017+
return {
1018+
fromBoundary: fromTextNodeBoundary(pbMarkOp.getFromboundary()!),
1019+
toBoundary: fromTextNodeBoundary(pbMarkOp.getToboundary()!),
1020+
attributes,
1021+
};
1022+
}
1023+
9881024
/**
9891025
* `fromTextNode` converts the given Protobuf format to model format.
9901026
*/
@@ -998,10 +1034,30 @@ function fromTextNode(pbTextNode: PbTextNode): RGATreeSplitNode<CRDTTextValue> {
9981034
);
9991035
});
10001036

1001-
const textNode = RGATreeSplitNode.create(
1002-
fromTextNodeID(pbTextNode.getId()!),
1003-
textValue,
1004-
);
1037+
let styleOpsBefore: Set<MarkOperation> | undefined;
1038+
const markOpsBefore = pbTextNode.getMarkopsbefore()?.getOperationsList();
1039+
if (markOpsBefore) {
1040+
styleOpsBefore = new Set();
1041+
for (const op of markOpsBefore) {
1042+
styleOpsBefore.add(fromMarkOp(op));
1043+
}
1044+
}
1045+
1046+
let styleOpsAfter: Set<MarkOperation> | undefined;
1047+
const markOpsAfter = pbTextNode.getMarkopsafter()?.getOperationsList();
1048+
if (markOpsAfter) {
1049+
styleOpsAfter = new Set();
1050+
for (const op of markOpsAfter) {
1051+
styleOpsAfter.add(fromMarkOp(op));
1052+
}
1053+
}
1054+
1055+
const textNode = RGATreeSplitNode.create({
1056+
id: fromTextNodeID(pbTextNode.getId()!),
1057+
value: textValue,
1058+
styleOpsBefore,
1059+
styleOpsAfter,
1060+
});
10051061
textNode.remove(fromTimeTicket(pbTextNode.getRemovedAt()));
10061062
return textNode;
10071063
}

src/api/yorkie/v1/resources.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,25 @@ message TextNode {
231231
TimeTicket removed_at = 3;
232232
TextNodeID ins_prev_id = 4;
233233
map<string, NodeAttr> attributes = 5;
234+
MarkOps markOpsBefore = 6;
235+
MarkOps markOpsAfter = 7;
234236
}
235237

236238
message TextNodeID {
237239
TimeTicket created_at = 1;
238240
int32 offset = 2;
239241
}
240242

243+
message MarkOps {
244+
repeated MarkOp operations = 1;
245+
}
246+
247+
message MarkOp {
248+
TextNodeBoundary fromBoundary = 1;
249+
TextNodeBoundary toBoundary = 2;
250+
map<string, string> attributes = 3;
251+
}
252+
241253
message TreeNode {
242254
TreeNodeID id = 1;
243255
string type = 2;

src/api/yorkie/v1/resources_pb.d.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,16 @@ export class TextNode extends jspb.Message {
10841084
getAttributesMap(): jspb.Map<string, NodeAttr>;
10851085
clearAttributesMap(): TextNode;
10861086

1087+
getMarkopsbefore(): MarkOps | undefined;
1088+
setMarkopsbefore(value?: MarkOps): TextNode;
1089+
hasMarkopsbefore(): boolean;
1090+
clearMarkopsbefore(): TextNode;
1091+
1092+
getMarkopsafter(): MarkOps | undefined;
1093+
setMarkopsafter(value?: MarkOps): TextNode;
1094+
hasMarkopsafter(): boolean;
1095+
clearMarkopsafter(): TextNode;
1096+
10871097
serializeBinary(): Uint8Array;
10881098
toObject(includeInstance?: boolean): TextNode.AsObject;
10891099
static toObject(includeInstance: boolean, msg: TextNode): TextNode.AsObject;
@@ -1099,6 +1109,8 @@ export namespace TextNode {
10991109
removedAt?: TimeTicket.AsObject,
11001110
insPrevId?: TextNodeID.AsObject,
11011111
attributesMap: Array<[string, NodeAttr.AsObject]>,
1112+
markopsbefore?: MarkOps.AsObject,
1113+
markopsafter?: MarkOps.AsObject,
11021114
}
11031115
}
11041116

@@ -1126,6 +1138,56 @@ export namespace TextNodeID {
11261138
}
11271139
}
11281140

1141+
export class MarkOps extends jspb.Message {
1142+
getOperationsList(): Array<MarkOp>;
1143+
setOperationsList(value: Array<MarkOp>): MarkOps;
1144+
clearOperationsList(): MarkOps;
1145+
addOperations(value?: MarkOp, index?: number): MarkOp;
1146+
1147+
serializeBinary(): Uint8Array;
1148+
toObject(includeInstance?: boolean): MarkOps.AsObject;
1149+
static toObject(includeInstance: boolean, msg: MarkOps): MarkOps.AsObject;
1150+
static serializeBinaryToWriter(message: MarkOps, writer: jspb.BinaryWriter): void;
1151+
static deserializeBinary(bytes: Uint8Array): MarkOps;
1152+
static deserializeBinaryFromReader(message: MarkOps, reader: jspb.BinaryReader): MarkOps;
1153+
}
1154+
1155+
export namespace MarkOps {
1156+
export type AsObject = {
1157+
operationsList: Array<MarkOp.AsObject>,
1158+
}
1159+
}
1160+
1161+
export class MarkOp extends jspb.Message {
1162+
getFromboundary(): TextNodeBoundary | undefined;
1163+
setFromboundary(value?: TextNodeBoundary): MarkOp;
1164+
hasFromboundary(): boolean;
1165+
clearFromboundary(): MarkOp;
1166+
1167+
getToboundary(): TextNodeBoundary | undefined;
1168+
setToboundary(value?: TextNodeBoundary): MarkOp;
1169+
hasToboundary(): boolean;
1170+
clearToboundary(): MarkOp;
1171+
1172+
getAttributesMap(): jspb.Map<string, string>;
1173+
clearAttributesMap(): MarkOp;
1174+
1175+
serializeBinary(): Uint8Array;
1176+
toObject(includeInstance?: boolean): MarkOp.AsObject;
1177+
static toObject(includeInstance: boolean, msg: MarkOp): MarkOp.AsObject;
1178+
static serializeBinaryToWriter(message: MarkOp, writer: jspb.BinaryWriter): void;
1179+
static deserializeBinary(bytes: Uint8Array): MarkOp;
1180+
static deserializeBinaryFromReader(message: MarkOp, reader: jspb.BinaryReader): MarkOp;
1181+
}
1182+
1183+
export namespace MarkOp {
1184+
export type AsObject = {
1185+
fromboundary?: TextNodeBoundary.AsObject,
1186+
toboundary?: TextNodeBoundary.AsObject,
1187+
attributesMap: Array<[string, string]>,
1188+
}
1189+
}
1190+
11291191
export class TreeNode extends jspb.Message {
11301192
getId(): TreeNodeID | undefined;
11311193
setId(value?: TreeNodeID): TreeNode;

0 commit comments

Comments
 (0)