@yorkie-js/react 0.6.49 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -12497,7 +12497,7 @@ class CRDTTree extends CRDTElement {
|
|
|
12497
12497
|
}
|
|
12498
12498
|
}
|
|
12499
12499
|
}
|
|
12500
|
-
return [changes, pairs, diff];
|
|
12500
|
+
return [changes, pairs, diff, nodesToBeRemoved, fromIdx];
|
|
12501
12501
|
}
|
|
12502
12502
|
/**
|
|
12503
12503
|
* `editT` edits the given range with the given value.
|
|
@@ -12935,29 +12935,46 @@ class CRDTTree extends CRDTElement {
|
|
|
12935
12935
|
return [prev, prev.isText ? TokenType.Text : TokenType.End];
|
|
12936
12936
|
}
|
|
12937
12937
|
}
|
|
12938
|
+
function clearRemovedAt(node) {
|
|
12939
|
+
traverseAll(node, (n) => {
|
|
12940
|
+
n.removedAt = void 0;
|
|
12941
|
+
n.visibleSize = n.totalSize;
|
|
12942
|
+
});
|
|
12943
|
+
}
|
|
12938
12944
|
class TreeEditOperation extends Operation {
|
|
12939
12945
|
fromPos;
|
|
12940
12946
|
toPos;
|
|
12941
12947
|
contents;
|
|
12942
12948
|
splitLevel;
|
|
12943
|
-
|
|
12949
|
+
isUndoOp;
|
|
12950
|
+
fromIdx;
|
|
12951
|
+
toIdx;
|
|
12952
|
+
lastFromIdx;
|
|
12953
|
+
lastToIdx;
|
|
12954
|
+
constructor(parentCreatedAt, fromPos, toPos, contents, splitLevel, executedAt, isUndoOp, fromIdx, toIdx) {
|
|
12944
12955
|
super(parentCreatedAt, executedAt);
|
|
12945
12956
|
this.fromPos = fromPos;
|
|
12946
12957
|
this.toPos = toPos;
|
|
12947
12958
|
this.contents = contents;
|
|
12948
12959
|
this.splitLevel = splitLevel;
|
|
12960
|
+
this.isUndoOp = isUndoOp;
|
|
12961
|
+
this.fromIdx = fromIdx;
|
|
12962
|
+
this.toIdx = toIdx;
|
|
12949
12963
|
}
|
|
12950
12964
|
/**
|
|
12951
12965
|
* `create` creates a new instance of EditOperation.
|
|
12952
12966
|
*/
|
|
12953
|
-
static create(parentCreatedAt, fromPos, toPos, contents, splitLevel, executedAt) {
|
|
12967
|
+
static create(parentCreatedAt, fromPos, toPos, contents, splitLevel, executedAt, isUndoOp, fromIdx, toIdx) {
|
|
12954
12968
|
return new TreeEditOperation(
|
|
12955
12969
|
parentCreatedAt,
|
|
12956
12970
|
fromPos,
|
|
12957
12971
|
toPos,
|
|
12958
12972
|
contents,
|
|
12959
12973
|
splitLevel,
|
|
12960
|
-
executedAt
|
|
12974
|
+
executedAt,
|
|
12975
|
+
isUndoOp,
|
|
12976
|
+
fromIdx,
|
|
12977
|
+
toIdx
|
|
12961
12978
|
);
|
|
12962
12979
|
}
|
|
12963
12980
|
/**
|
|
@@ -12979,7 +12996,15 @@ class TreeEditOperation extends Operation {
|
|
|
12979
12996
|
}
|
|
12980
12997
|
const editedAt = this.getExecutedAt();
|
|
12981
12998
|
const tree = parentObject;
|
|
12982
|
-
|
|
12999
|
+
if (this.isUndoOp && this.fromIdx !== void 0 && this.toIdx !== void 0) {
|
|
13000
|
+
this.fromPos = tree.findPos(this.fromIdx);
|
|
13001
|
+
if (this.fromIdx === this.toIdx) {
|
|
13002
|
+
this.toPos = this.fromPos;
|
|
13003
|
+
} else {
|
|
13004
|
+
this.toPos = tree.findPos(this.toIdx);
|
|
13005
|
+
}
|
|
13006
|
+
}
|
|
13007
|
+
const [changes, pairs, diff, removedNodes, preEditFromIdx] = tree.edit(
|
|
12983
13008
|
[this.fromPos, this.toPos],
|
|
12984
13009
|
this.contents?.map((content) => content.deepcopy()),
|
|
12985
13010
|
this.splitLevel,
|
|
@@ -13005,6 +13030,13 @@ class TreeEditOperation extends Operation {
|
|
|
13005
13030
|
})(),
|
|
13006
13031
|
versionVector
|
|
13007
13032
|
);
|
|
13033
|
+
this.lastFromIdx = preEditFromIdx;
|
|
13034
|
+
const removedSize = removedNodes.reduce(
|
|
13035
|
+
(sum, node) => sum + node.paddedSize(),
|
|
13036
|
+
0
|
|
13037
|
+
);
|
|
13038
|
+
this.lastToIdx = preEditFromIdx + removedSize;
|
|
13039
|
+
const reverseOp = this.splitLevel === 0 ? this.toReverseOperation(tree, removedNodes, preEditFromIdx) : void 0;
|
|
13008
13040
|
root.acc(diff);
|
|
13009
13041
|
for (const pair of pairs) {
|
|
13010
13042
|
root.registerGCPair(pair);
|
|
@@ -13023,9 +13055,131 @@ class TreeEditOperation extends Operation {
|
|
|
13023
13055
|
toPath
|
|
13024
13056
|
};
|
|
13025
13057
|
}
|
|
13026
|
-
)
|
|
13058
|
+
),
|
|
13059
|
+
reverseOp
|
|
13027
13060
|
};
|
|
13028
13061
|
}
|
|
13062
|
+
/**
|
|
13063
|
+
* `toReverseOperation` creates the reverse operation for undo.
|
|
13064
|
+
*
|
|
13065
|
+
* The reverse op stores both CRDTTreePos (for initial use) and integer
|
|
13066
|
+
* indices (for reconciliation adjustment when remote edits arrive).
|
|
13067
|
+
* At undo execution time, the integer indices take precedence and are
|
|
13068
|
+
* converted to CRDTTreePos via tree.findPos().
|
|
13069
|
+
*
|
|
13070
|
+
* @param tree - The CRDTTree after the edit has been applied
|
|
13071
|
+
* @param removedNodes - Nodes that were removed by this edit
|
|
13072
|
+
* @param preEditFromIdx - The from index captured BEFORE the edit
|
|
13073
|
+
*/
|
|
13074
|
+
toReverseOperation(tree, removedNodes, preEditFromIdx) {
|
|
13075
|
+
const insertedContentSize = this.contents ? this.contents.reduce((sum, node) => sum + node.paddedSize(), 0) : 0;
|
|
13076
|
+
const maxNeededIdx = preEditFromIdx + insertedContentSize;
|
|
13077
|
+
if (maxNeededIdx > tree.getSize()) {
|
|
13078
|
+
return void 0;
|
|
13079
|
+
}
|
|
13080
|
+
const topLevelRemoved = removedNodes.filter(
|
|
13081
|
+
(node) => !node.parent || !removedNodes.includes(node.parent)
|
|
13082
|
+
);
|
|
13083
|
+
const reverseContents = topLevelRemoved.length > 0 ? topLevelRemoved.map((n) => {
|
|
13084
|
+
const clone = n.deepcopy();
|
|
13085
|
+
clearRemovedAt(clone);
|
|
13086
|
+
return clone;
|
|
13087
|
+
}) : void 0;
|
|
13088
|
+
const reverseFromPos = tree.findPos(preEditFromIdx);
|
|
13089
|
+
let reverseToPos;
|
|
13090
|
+
if (insertedContentSize > 0) {
|
|
13091
|
+
reverseToPos = tree.findPos(preEditFromIdx + insertedContentSize);
|
|
13092
|
+
} else {
|
|
13093
|
+
reverseToPos = reverseFromPos;
|
|
13094
|
+
}
|
|
13095
|
+
const reverseFromIdx = preEditFromIdx;
|
|
13096
|
+
const reverseToIdx = preEditFromIdx + insertedContentSize;
|
|
13097
|
+
return TreeEditOperation.create(
|
|
13098
|
+
this.getParentCreatedAt(),
|
|
13099
|
+
reverseFromPos,
|
|
13100
|
+
reverseToPos,
|
|
13101
|
+
reverseContents,
|
|
13102
|
+
0,
|
|
13103
|
+
// splitLevel always 0
|
|
13104
|
+
void 0,
|
|
13105
|
+
// executedAt set during undo
|
|
13106
|
+
true,
|
|
13107
|
+
// isUndoOp
|
|
13108
|
+
reverseFromIdx,
|
|
13109
|
+
reverseToIdx
|
|
13110
|
+
);
|
|
13111
|
+
}
|
|
13112
|
+
/**
|
|
13113
|
+
* `normalizePos` returns the visible-index range of this operation.
|
|
13114
|
+
* For undo ops, returns the stored (possibly reconciled) indices.
|
|
13115
|
+
* For forward ops, returns the pre-edit indices captured during execute().
|
|
13116
|
+
*/
|
|
13117
|
+
normalizePos() {
|
|
13118
|
+
if (this.isUndoOp && this.fromIdx !== void 0 && this.toIdx !== void 0) {
|
|
13119
|
+
return [this.fromIdx, this.toIdx];
|
|
13120
|
+
}
|
|
13121
|
+
if (this.lastFromIdx !== void 0 && this.lastToIdx !== void 0) {
|
|
13122
|
+
return [this.lastFromIdx, this.lastToIdx];
|
|
13123
|
+
}
|
|
13124
|
+
return [0, 0];
|
|
13125
|
+
}
|
|
13126
|
+
/**
|
|
13127
|
+
* `reconcileOperation` adjusts this undo operation's integer indices
|
|
13128
|
+
* when a remote edit modifies the same tree. Uses the same 6-case
|
|
13129
|
+
* overlap logic as EditOperation.reconcileOperation for Text.
|
|
13130
|
+
*/
|
|
13131
|
+
reconcileOperation(remoteFrom, remoteTo, contentLen) {
|
|
13132
|
+
if (!this.isUndoOp) {
|
|
13133
|
+
return;
|
|
13134
|
+
}
|
|
13135
|
+
if (this.fromIdx === void 0 || this.toIdx === void 0) {
|
|
13136
|
+
return;
|
|
13137
|
+
}
|
|
13138
|
+
if (remoteFrom > remoteTo) {
|
|
13139
|
+
return;
|
|
13140
|
+
}
|
|
13141
|
+
const remoteRangeLen = remoteTo - remoteFrom;
|
|
13142
|
+
const localFrom = this.fromIdx;
|
|
13143
|
+
const localTo = this.toIdx;
|
|
13144
|
+
const apply = (na, nb) => {
|
|
13145
|
+
this.fromIdx = Math.max(0, na);
|
|
13146
|
+
this.toIdx = Math.max(0, nb);
|
|
13147
|
+
};
|
|
13148
|
+
if (remoteTo <= localFrom) {
|
|
13149
|
+
apply(
|
|
13150
|
+
localFrom - remoteRangeLen + contentLen,
|
|
13151
|
+
localTo - remoteRangeLen + contentLen
|
|
13152
|
+
);
|
|
13153
|
+
return;
|
|
13154
|
+
}
|
|
13155
|
+
if (localTo <= remoteFrom) {
|
|
13156
|
+
return;
|
|
13157
|
+
}
|
|
13158
|
+
if (remoteFrom <= localFrom && localTo <= remoteTo && remoteFrom !== remoteTo) {
|
|
13159
|
+
apply(remoteFrom, remoteFrom);
|
|
13160
|
+
return;
|
|
13161
|
+
}
|
|
13162
|
+
if (localFrom <= remoteFrom && remoteTo <= localTo && localFrom !== localTo) {
|
|
13163
|
+
apply(localFrom, localTo - remoteRangeLen + contentLen);
|
|
13164
|
+
return;
|
|
13165
|
+
}
|
|
13166
|
+
if (remoteFrom < localFrom && localFrom < remoteTo && remoteTo < localTo) {
|
|
13167
|
+
apply(remoteFrom, remoteFrom + (localTo - remoteTo));
|
|
13168
|
+
return;
|
|
13169
|
+
}
|
|
13170
|
+
if (localFrom < remoteFrom && remoteFrom < localTo && localTo < remoteTo) {
|
|
13171
|
+
apply(localFrom, remoteFrom);
|
|
13172
|
+
return;
|
|
13173
|
+
}
|
|
13174
|
+
}
|
|
13175
|
+
/**
|
|
13176
|
+
* `getContentSize` returns the total visible size of this operation's
|
|
13177
|
+
* content (for reconciliation).
|
|
13178
|
+
*/
|
|
13179
|
+
getContentSize() {
|
|
13180
|
+
if (!this.contents) return 0;
|
|
13181
|
+
return this.contents.reduce((sum, node) => sum + node.paddedSize(), 0);
|
|
13182
|
+
}
|
|
13029
13183
|
/**
|
|
13030
13184
|
* `getEffectedCreatedAt` returns the creation time of the effected element.
|
|
13031
13185
|
*/
|
|
@@ -17953,6 +18107,24 @@ class History {
|
|
|
17953
18107
|
replace(this.undoStack);
|
|
17954
18108
|
replace(this.redoStack);
|
|
17955
18109
|
}
|
|
18110
|
+
/**
|
|
18111
|
+
* `reconcileTreeEdit` reconciles the tree edit operation.
|
|
18112
|
+
* Scan both undo/redo stacks and adjust tree edit operations
|
|
18113
|
+
* when a remote edit modifies the same tree.
|
|
18114
|
+
*/
|
|
18115
|
+
reconcileTreeEdit(parentCreatedAt, rangeFrom, rangeTo, contentSize) {
|
|
18116
|
+
const replace = (stack) => {
|
|
18117
|
+
for (const ops of stack) {
|
|
18118
|
+
for (const op of ops) {
|
|
18119
|
+
if (op instanceof TreeEditOperation && op.getParentCreatedAt().compare(parentCreatedAt) === 0) {
|
|
18120
|
+
op.reconcileOperation(rangeFrom, rangeTo, contentSize);
|
|
18121
|
+
}
|
|
18122
|
+
}
|
|
18123
|
+
}
|
|
18124
|
+
};
|
|
18125
|
+
replace(this.undoStack);
|
|
18126
|
+
replace(this.redoStack);
|
|
18127
|
+
}
|
|
17956
18128
|
}
|
|
17957
18129
|
function validateYorkieRuleset(data, ruleset) {
|
|
17958
18130
|
const errors = [];
|
|
@@ -18906,6 +19078,15 @@ class Document {
|
|
|
18906
19078
|
op.getContent()?.length ?? 0
|
|
18907
19079
|
);
|
|
18908
19080
|
}
|
|
19081
|
+
if (op instanceof TreeEditOperation) {
|
|
19082
|
+
const [from, to] = op.normalizePos();
|
|
19083
|
+
this.internalHistory.reconcileTreeEdit(
|
|
19084
|
+
op.getParentCreatedAt(),
|
|
19085
|
+
from,
|
|
19086
|
+
to,
|
|
19087
|
+
op.getContentSize()
|
|
19088
|
+
);
|
|
19089
|
+
}
|
|
18909
19090
|
}
|
|
18910
19091
|
this.changeID = this.changeID.syncClocks(change.getID());
|
|
18911
19092
|
if (opInfos.length) {
|
|
@@ -19451,7 +19632,7 @@ function createAuthInterceptor(apiKey, token) {
|
|
|
19451
19632
|
};
|
|
19452
19633
|
}
|
|
19453
19634
|
const name$1 = "@yorkie-js/sdk";
|
|
19454
|
-
const version$1 = "0.
|
|
19635
|
+
const version$1 = "0.7.0";
|
|
19455
19636
|
const pkg$1 = {
|
|
19456
19637
|
name: name$1,
|
|
19457
19638
|
version: version$1
|
|
@@ -21306,7 +21487,7 @@ if (typeof globalThis !== "undefined") {
|
|
|
21306
21487
|
};
|
|
21307
21488
|
}
|
|
21308
21489
|
const name = "@yorkie-js/react";
|
|
21309
|
-
const version = "0.
|
|
21490
|
+
const version = "0.7.0";
|
|
21310
21491
|
const pkg = {
|
|
21311
21492
|
name,
|
|
21312
21493
|
version
|