@yorkie-js/react 0.6.34 → 0.6.35
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.
- package/dist/yorkie-js-react.es.js +504 -349
- package/dist/yorkie-js-react.es.js.map +1 -1
- package/dist/yorkie-js-react.js +504 -349
- package/dist/yorkie-js-react.js.map +1 -1
- package/package.json +2 -2
|
@@ -7844,6 +7844,95 @@ __publicField(_PushPullChangesResponse, "fields", proto3.util.newFieldList(() =>
|
|
|
7844
7844
|
{ no: 1, name: "change_pack", kind: "message", T: ChangePack$1 }
|
|
7845
7845
|
]));
|
|
7846
7846
|
let PushPullChangesResponse = _PushPullChangesResponse;
|
|
7847
|
+
const _BroadcastRequest = class _BroadcastRequest extends Message {
|
|
7848
|
+
constructor(data) {
|
|
7849
|
+
super();
|
|
7850
|
+
/**
|
|
7851
|
+
* @generated from field: string client_id = 1;
|
|
7852
|
+
*/
|
|
7853
|
+
__publicField(this, "clientId", "");
|
|
7854
|
+
/**
|
|
7855
|
+
* @generated from field: string document_id = 2;
|
|
7856
|
+
*/
|
|
7857
|
+
__publicField(this, "documentId", "");
|
|
7858
|
+
/**
|
|
7859
|
+
* @generated from field: string topic = 3;
|
|
7860
|
+
*/
|
|
7861
|
+
__publicField(this, "topic", "");
|
|
7862
|
+
/**
|
|
7863
|
+
* @generated from field: bytes payload = 4;
|
|
7864
|
+
*/
|
|
7865
|
+
__publicField(this, "payload", new Uint8Array(0));
|
|
7866
|
+
proto3.util.initPartial(data, this);
|
|
7867
|
+
}
|
|
7868
|
+
static fromBinary(bytes, options) {
|
|
7869
|
+
return new _BroadcastRequest().fromBinary(bytes, options);
|
|
7870
|
+
}
|
|
7871
|
+
static fromJson(jsonValue, options) {
|
|
7872
|
+
return new _BroadcastRequest().fromJson(jsonValue, options);
|
|
7873
|
+
}
|
|
7874
|
+
static fromJsonString(jsonString, options) {
|
|
7875
|
+
return new _BroadcastRequest().fromJsonString(jsonString, options);
|
|
7876
|
+
}
|
|
7877
|
+
static equals(a, b) {
|
|
7878
|
+
return proto3.util.equals(_BroadcastRequest, a, b);
|
|
7879
|
+
}
|
|
7880
|
+
};
|
|
7881
|
+
__publicField(_BroadcastRequest, "runtime", proto3);
|
|
7882
|
+
__publicField(_BroadcastRequest, "typeName", "yorkie.v1.BroadcastRequest");
|
|
7883
|
+
__publicField(_BroadcastRequest, "fields", proto3.util.newFieldList(() => [
|
|
7884
|
+
{
|
|
7885
|
+
no: 1,
|
|
7886
|
+
name: "client_id",
|
|
7887
|
+
kind: "scalar",
|
|
7888
|
+
T: 9
|
|
7889
|
+
/* ScalarType.STRING */
|
|
7890
|
+
},
|
|
7891
|
+
{
|
|
7892
|
+
no: 2,
|
|
7893
|
+
name: "document_id",
|
|
7894
|
+
kind: "scalar",
|
|
7895
|
+
T: 9
|
|
7896
|
+
/* ScalarType.STRING */
|
|
7897
|
+
},
|
|
7898
|
+
{
|
|
7899
|
+
no: 3,
|
|
7900
|
+
name: "topic",
|
|
7901
|
+
kind: "scalar",
|
|
7902
|
+
T: 9
|
|
7903
|
+
/* ScalarType.STRING */
|
|
7904
|
+
},
|
|
7905
|
+
{
|
|
7906
|
+
no: 4,
|
|
7907
|
+
name: "payload",
|
|
7908
|
+
kind: "scalar",
|
|
7909
|
+
T: 12
|
|
7910
|
+
/* ScalarType.BYTES */
|
|
7911
|
+
}
|
|
7912
|
+
]));
|
|
7913
|
+
let BroadcastRequest = _BroadcastRequest;
|
|
7914
|
+
const _BroadcastResponse = class _BroadcastResponse extends Message {
|
|
7915
|
+
constructor(data) {
|
|
7916
|
+
super();
|
|
7917
|
+
proto3.util.initPartial(data, this);
|
|
7918
|
+
}
|
|
7919
|
+
static fromBinary(bytes, options) {
|
|
7920
|
+
return new _BroadcastResponse().fromBinary(bytes, options);
|
|
7921
|
+
}
|
|
7922
|
+
static fromJson(jsonValue, options) {
|
|
7923
|
+
return new _BroadcastResponse().fromJson(jsonValue, options);
|
|
7924
|
+
}
|
|
7925
|
+
static fromJsonString(jsonString, options) {
|
|
7926
|
+
return new _BroadcastResponse().fromJsonString(jsonString, options);
|
|
7927
|
+
}
|
|
7928
|
+
static equals(a, b) {
|
|
7929
|
+
return proto3.util.equals(_BroadcastResponse, a, b);
|
|
7930
|
+
}
|
|
7931
|
+
};
|
|
7932
|
+
__publicField(_BroadcastResponse, "runtime", proto3);
|
|
7933
|
+
__publicField(_BroadcastResponse, "typeName", "yorkie.v1.BroadcastResponse");
|
|
7934
|
+
__publicField(_BroadcastResponse, "fields", proto3.util.newFieldList(() => []));
|
|
7935
|
+
let BroadcastResponse = _BroadcastResponse;
|
|
7847
7936
|
const _AttachPresenceRequest = class _AttachPresenceRequest extends Message {
|
|
7848
7937
|
constructor(data) {
|
|
7849
7938
|
super();
|
|
@@ -8083,6 +8172,10 @@ let RefreshPresenceRequest = _RefreshPresenceRequest;
|
|
|
8083
8172
|
const _RefreshPresenceResponse = class _RefreshPresenceResponse extends Message {
|
|
8084
8173
|
constructor(data) {
|
|
8085
8174
|
super();
|
|
8175
|
+
/**
|
|
8176
|
+
* @generated from field: int64 count = 1;
|
|
8177
|
+
*/
|
|
8178
|
+
__publicField(this, "count", protoInt64.zero);
|
|
8086
8179
|
proto3.util.initPartial(data, this);
|
|
8087
8180
|
}
|
|
8088
8181
|
static fromBinary(bytes, options) {
|
|
@@ -8100,7 +8193,15 @@ const _RefreshPresenceResponse = class _RefreshPresenceResponse extends Message
|
|
|
8100
8193
|
};
|
|
8101
8194
|
__publicField(_RefreshPresenceResponse, "runtime", proto3);
|
|
8102
8195
|
__publicField(_RefreshPresenceResponse, "typeName", "yorkie.v1.RefreshPresenceResponse");
|
|
8103
|
-
__publicField(_RefreshPresenceResponse, "fields", proto3.util.newFieldList(() => [
|
|
8196
|
+
__publicField(_RefreshPresenceResponse, "fields", proto3.util.newFieldList(() => [
|
|
8197
|
+
{
|
|
8198
|
+
no: 1,
|
|
8199
|
+
name: "count",
|
|
8200
|
+
kind: "scalar",
|
|
8201
|
+
T: 3
|
|
8202
|
+
/* ScalarType.INT64 */
|
|
8203
|
+
}
|
|
8204
|
+
]));
|
|
8104
8205
|
let RefreshPresenceResponse = _RefreshPresenceResponse;
|
|
8105
8206
|
const _WatchPresenceRequest = class _WatchPresenceRequest extends Message {
|
|
8106
8207
|
constructor(data) {
|
|
@@ -8221,95 +8322,6 @@ __publicField(_WatchPresenceInitialized, "fields", proto3.util.newFieldList(() =
|
|
|
8221
8322
|
}
|
|
8222
8323
|
]));
|
|
8223
8324
|
let WatchPresenceInitialized = _WatchPresenceInitialized;
|
|
8224
|
-
const _BroadcastRequest = class _BroadcastRequest extends Message {
|
|
8225
|
-
constructor(data) {
|
|
8226
|
-
super();
|
|
8227
|
-
/**
|
|
8228
|
-
* @generated from field: string client_id = 1;
|
|
8229
|
-
*/
|
|
8230
|
-
__publicField(this, "clientId", "");
|
|
8231
|
-
/**
|
|
8232
|
-
* @generated from field: string document_id = 2;
|
|
8233
|
-
*/
|
|
8234
|
-
__publicField(this, "documentId", "");
|
|
8235
|
-
/**
|
|
8236
|
-
* @generated from field: string topic = 3;
|
|
8237
|
-
*/
|
|
8238
|
-
__publicField(this, "topic", "");
|
|
8239
|
-
/**
|
|
8240
|
-
* @generated from field: bytes payload = 4;
|
|
8241
|
-
*/
|
|
8242
|
-
__publicField(this, "payload", new Uint8Array(0));
|
|
8243
|
-
proto3.util.initPartial(data, this);
|
|
8244
|
-
}
|
|
8245
|
-
static fromBinary(bytes, options) {
|
|
8246
|
-
return new _BroadcastRequest().fromBinary(bytes, options);
|
|
8247
|
-
}
|
|
8248
|
-
static fromJson(jsonValue, options) {
|
|
8249
|
-
return new _BroadcastRequest().fromJson(jsonValue, options);
|
|
8250
|
-
}
|
|
8251
|
-
static fromJsonString(jsonString, options) {
|
|
8252
|
-
return new _BroadcastRequest().fromJsonString(jsonString, options);
|
|
8253
|
-
}
|
|
8254
|
-
static equals(a, b) {
|
|
8255
|
-
return proto3.util.equals(_BroadcastRequest, a, b);
|
|
8256
|
-
}
|
|
8257
|
-
};
|
|
8258
|
-
__publicField(_BroadcastRequest, "runtime", proto3);
|
|
8259
|
-
__publicField(_BroadcastRequest, "typeName", "yorkie.v1.BroadcastRequest");
|
|
8260
|
-
__publicField(_BroadcastRequest, "fields", proto3.util.newFieldList(() => [
|
|
8261
|
-
{
|
|
8262
|
-
no: 1,
|
|
8263
|
-
name: "client_id",
|
|
8264
|
-
kind: "scalar",
|
|
8265
|
-
T: 9
|
|
8266
|
-
/* ScalarType.STRING */
|
|
8267
|
-
},
|
|
8268
|
-
{
|
|
8269
|
-
no: 2,
|
|
8270
|
-
name: "document_id",
|
|
8271
|
-
kind: "scalar",
|
|
8272
|
-
T: 9
|
|
8273
|
-
/* ScalarType.STRING */
|
|
8274
|
-
},
|
|
8275
|
-
{
|
|
8276
|
-
no: 3,
|
|
8277
|
-
name: "topic",
|
|
8278
|
-
kind: "scalar",
|
|
8279
|
-
T: 9
|
|
8280
|
-
/* ScalarType.STRING */
|
|
8281
|
-
},
|
|
8282
|
-
{
|
|
8283
|
-
no: 4,
|
|
8284
|
-
name: "payload",
|
|
8285
|
-
kind: "scalar",
|
|
8286
|
-
T: 12
|
|
8287
|
-
/* ScalarType.BYTES */
|
|
8288
|
-
}
|
|
8289
|
-
]));
|
|
8290
|
-
let BroadcastRequest = _BroadcastRequest;
|
|
8291
|
-
const _BroadcastResponse = class _BroadcastResponse extends Message {
|
|
8292
|
-
constructor(data) {
|
|
8293
|
-
super();
|
|
8294
|
-
proto3.util.initPartial(data, this);
|
|
8295
|
-
}
|
|
8296
|
-
static fromBinary(bytes, options) {
|
|
8297
|
-
return new _BroadcastResponse().fromBinary(bytes, options);
|
|
8298
|
-
}
|
|
8299
|
-
static fromJson(jsonValue, options) {
|
|
8300
|
-
return new _BroadcastResponse().fromJson(jsonValue, options);
|
|
8301
|
-
}
|
|
8302
|
-
static fromJsonString(jsonString, options) {
|
|
8303
|
-
return new _BroadcastResponse().fromJsonString(jsonString, options);
|
|
8304
|
-
}
|
|
8305
|
-
static equals(a, b) {
|
|
8306
|
-
return proto3.util.equals(_BroadcastResponse, a, b);
|
|
8307
|
-
}
|
|
8308
|
-
};
|
|
8309
|
-
__publicField(_BroadcastResponse, "runtime", proto3);
|
|
8310
|
-
__publicField(_BroadcastResponse, "typeName", "yorkie.v1.BroadcastResponse");
|
|
8311
|
-
__publicField(_BroadcastResponse, "fields", proto3.util.newFieldList(() => []));
|
|
8312
|
-
let BroadcastResponse = _BroadcastResponse;
|
|
8313
8325
|
const YorkieService = {
|
|
8314
8326
|
typeName: "yorkie.v1.YorkieService",
|
|
8315
8327
|
methods: {
|
|
@@ -8376,6 +8388,15 @@ const YorkieService = {
|
|
|
8376
8388
|
O: WatchDocumentResponse,
|
|
8377
8389
|
kind: MethodKind.ServerStreaming
|
|
8378
8390
|
},
|
|
8391
|
+
/**
|
|
8392
|
+
* @generated from rpc yorkie.v1.YorkieService.Broadcast
|
|
8393
|
+
*/
|
|
8394
|
+
broadcast: {
|
|
8395
|
+
name: "Broadcast",
|
|
8396
|
+
I: BroadcastRequest,
|
|
8397
|
+
O: BroadcastResponse,
|
|
8398
|
+
kind: MethodKind.Unary
|
|
8399
|
+
},
|
|
8379
8400
|
/**
|
|
8380
8401
|
* @generated from rpc yorkie.v1.YorkieService.AttachPresence
|
|
8381
8402
|
*/
|
|
@@ -8411,15 +8432,6 @@ const YorkieService = {
|
|
|
8411
8432
|
I: WatchPresenceRequest,
|
|
8412
8433
|
O: WatchPresenceResponse,
|
|
8413
8434
|
kind: MethodKind.ServerStreaming
|
|
8414
|
-
},
|
|
8415
|
-
/**
|
|
8416
|
-
* @generated from rpc yorkie.v1.YorkieService.Broadcast
|
|
8417
|
-
*/
|
|
8418
|
-
broadcast: {
|
|
8419
|
-
name: "Broadcast",
|
|
8420
|
-
I: BroadcastRequest,
|
|
8421
|
-
O: BroadcastResponse,
|
|
8422
|
-
kind: MethodKind.Unary
|
|
8423
8435
|
}
|
|
8424
8436
|
}
|
|
8425
8437
|
};
|
|
@@ -9128,9 +9140,30 @@ class ElementRHT {
|
|
|
9128
9140
|
}
|
|
9129
9141
|
return node;
|
|
9130
9142
|
}
|
|
9143
|
+
/**
|
|
9144
|
+
* `deepcopy` creates a deep copy of this ElementRHT.
|
|
9145
|
+
*/
|
|
9146
|
+
deepcopy() {
|
|
9147
|
+
const clone = ElementRHT.create();
|
|
9148
|
+
for (const [, node] of this.nodeMapByCreatedAt) {
|
|
9149
|
+
clone.nodeMapByCreatedAt.set(
|
|
9150
|
+
node.getValue().getCreatedAt().toIDString(),
|
|
9151
|
+
ElementRHTNode.of(node.getStrKey(), node.getValue().deepcopy())
|
|
9152
|
+
);
|
|
9153
|
+
}
|
|
9154
|
+
for (const [key, node] of this.nodeMapByKey) {
|
|
9155
|
+
clone.nodeMapByKey.set(
|
|
9156
|
+
key,
|
|
9157
|
+
clone.nodeMapByCreatedAt.get(
|
|
9158
|
+
node.getValue().getCreatedAt().toIDString()
|
|
9159
|
+
)
|
|
9160
|
+
);
|
|
9161
|
+
}
|
|
9162
|
+
return clone;
|
|
9163
|
+
}
|
|
9131
9164
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
9132
9165
|
*[Symbol.iterator]() {
|
|
9133
|
-
for (const [, node] of this.
|
|
9166
|
+
for (const [, node] of this.nodeMapByCreatedAt) {
|
|
9134
9167
|
yield node;
|
|
9135
9168
|
}
|
|
9136
9169
|
}
|
|
@@ -9264,12 +9297,12 @@ class CRDTObject extends CRDTContainer {
|
|
|
9264
9297
|
*/
|
|
9265
9298
|
toSortedJSON() {
|
|
9266
9299
|
var _a2;
|
|
9267
|
-
const keys =
|
|
9300
|
+
const keys = /* @__PURE__ */ new Set();
|
|
9268
9301
|
for (const [key] of this) {
|
|
9269
|
-
keys.
|
|
9302
|
+
keys.add(key);
|
|
9270
9303
|
}
|
|
9271
9304
|
const json = [];
|
|
9272
|
-
for (const key of keys.sort()) {
|
|
9305
|
+
for (const key of Array.from(keys).sort()) {
|
|
9273
9306
|
const node = (_a2 = this.memberNodes.get(key)) == null ? void 0 : _a2.getValue();
|
|
9274
9307
|
json.push(`"${escapeString(key)}":${node.toSortedJSON()}`);
|
|
9275
9308
|
}
|
|
@@ -9286,14 +9319,9 @@ class CRDTObject extends CRDTContainer {
|
|
|
9286
9319
|
*/
|
|
9287
9320
|
deepcopy() {
|
|
9288
9321
|
const clone = CRDTObject.create(this.getCreatedAt());
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
node.getValue().deepcopy(),
|
|
9293
|
-
this.getPositionedAt()
|
|
9294
|
-
);
|
|
9295
|
-
}
|
|
9296
|
-
clone.remove(this.getRemovedAt());
|
|
9322
|
+
clone.memberNodes = this.memberNodes.deepcopy();
|
|
9323
|
+
clone.setRemovedAt(this.getRemovedAt());
|
|
9324
|
+
clone.setMovedAt(this.getMovedAt());
|
|
9297
9325
|
return clone;
|
|
9298
9326
|
}
|
|
9299
9327
|
/**
|
|
@@ -9314,14 +9342,11 @@ class CRDTObject extends CRDTContainer {
|
|
|
9314
9342
|
* `[Symbol.iterator]` returns an iterator for the entries in this object.
|
|
9315
9343
|
*/
|
|
9316
9344
|
*[Symbol.iterator]() {
|
|
9317
|
-
const keySet = /* @__PURE__ */ new Set();
|
|
9318
9345
|
for (const node of this.memberNodes) {
|
|
9319
|
-
if (
|
|
9320
|
-
|
|
9321
|
-
if (!node.isRemoved()) {
|
|
9322
|
-
yield [node.getStrKey(), node.getValue()];
|
|
9323
|
-
}
|
|
9346
|
+
if (node.isRemoved()) {
|
|
9347
|
+
continue;
|
|
9324
9348
|
}
|
|
9349
|
+
yield [node.getStrKey(), node.getValue()];
|
|
9325
9350
|
}
|
|
9326
9351
|
}
|
|
9327
9352
|
}
|
|
@@ -11537,7 +11562,8 @@ class CRDTArray extends CRDTContainer {
|
|
|
11537
11562
|
node.getValue().deepcopy()
|
|
11538
11563
|
);
|
|
11539
11564
|
}
|
|
11540
|
-
clone.
|
|
11565
|
+
clone.setRemovedAt(this.getRemovedAt());
|
|
11566
|
+
clone.setMovedAt(this.getMovedAt());
|
|
11541
11567
|
return clone;
|
|
11542
11568
|
}
|
|
11543
11569
|
}
|
|
@@ -12546,12 +12572,13 @@ class CRDTText extends CRDTElement {
|
|
|
12546
12572
|
* `deepcopy` copies itself deeply.
|
|
12547
12573
|
*/
|
|
12548
12574
|
deepcopy() {
|
|
12549
|
-
const
|
|
12575
|
+
const clone = new CRDTText(
|
|
12550
12576
|
this.rgaTreeSplit.deepcopy(),
|
|
12551
12577
|
this.getCreatedAt()
|
|
12552
12578
|
);
|
|
12553
|
-
|
|
12554
|
-
|
|
12579
|
+
clone.setRemovedAt(this.getRemovedAt());
|
|
12580
|
+
clone.setMovedAt(this.getMovedAt());
|
|
12581
|
+
return clone;
|
|
12555
12582
|
}
|
|
12556
12583
|
/**
|
|
12557
12584
|
* `findIndexesFromRange` returns pair of integer offsets of the given range.
|
|
@@ -12782,15 +12809,15 @@ class StyleOperation extends Operation {
|
|
|
12782
12809
|
const ElementPaddingSize = 2;
|
|
12783
12810
|
const DefaultRootType = "root";
|
|
12784
12811
|
const DefaultTextType = "text";
|
|
12785
|
-
function addSizeOfLeftSiblings(parent, offset) {
|
|
12812
|
+
function addSizeOfLeftSiblings(parent, offset, includeRemoved = false) {
|
|
12786
12813
|
let acc = 0;
|
|
12787
|
-
const siblings = parent.children;
|
|
12814
|
+
const siblings = includeRemoved ? parent.allChildren : parent.children;
|
|
12788
12815
|
for (let i = 0; i < offset; i++) {
|
|
12789
12816
|
const leftSibling = siblings[i];
|
|
12790
|
-
if (!leftSibling || leftSibling.isRemoved) {
|
|
12817
|
+
if (!leftSibling || !includeRemoved && leftSibling.isRemoved) {
|
|
12791
12818
|
continue;
|
|
12792
12819
|
}
|
|
12793
|
-
acc += leftSibling.paddedSize;
|
|
12820
|
+
acc += leftSibling.paddedSize(includeRemoved);
|
|
12794
12821
|
}
|
|
12795
12822
|
return acc;
|
|
12796
12823
|
}
|
|
@@ -12799,44 +12826,55 @@ class IndexTreeNode {
|
|
|
12799
12826
|
__publicField(this, "type");
|
|
12800
12827
|
__publicField(this, "parent");
|
|
12801
12828
|
__publicField(this, "_children");
|
|
12802
|
-
__publicField(this, "
|
|
12829
|
+
__publicField(this, "visibleSize");
|
|
12830
|
+
__publicField(this, "totalSize");
|
|
12803
12831
|
this.type = type;
|
|
12804
|
-
this.
|
|
12832
|
+
this.visibleSize = 0;
|
|
12833
|
+
this.totalSize = 0;
|
|
12805
12834
|
this._children = children;
|
|
12806
12835
|
if (this.isText && this._children.length > 0) {
|
|
12807
12836
|
throw new YorkieError(Code.ErrRefused, "Text node cannot have children");
|
|
12808
12837
|
}
|
|
12809
12838
|
}
|
|
12810
12839
|
/**
|
|
12811
|
-
* `updateAncestorsSize` updates the size of the ancestors.
|
|
12812
|
-
* the size of the node is changed.
|
|
12840
|
+
* `updateAncestorsSize` updates the size of the ancestors.
|
|
12841
|
+
* It is used when the size of the node is changed.
|
|
12842
|
+
* If includeRemoved is true, it updates ancestors totalSize including removed nodes.
|
|
12813
12843
|
*/
|
|
12814
|
-
updateAncestorsSize() {
|
|
12844
|
+
updateAncestorsSize(delta, includeRemoved = false) {
|
|
12815
12845
|
let parent = this.parent;
|
|
12816
|
-
const sign = this.isRemoved ? -1 : 1;
|
|
12817
12846
|
while (parent) {
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12847
|
+
if (includeRemoved) {
|
|
12848
|
+
parent.totalSize += delta;
|
|
12849
|
+
} else {
|
|
12850
|
+
parent.visibleSize += delta;
|
|
12851
|
+
if (parent.isRemoved) {
|
|
12852
|
+
break;
|
|
12853
|
+
}
|
|
12821
12854
|
}
|
|
12822
12855
|
parent = parent.parent;
|
|
12823
12856
|
}
|
|
12824
12857
|
}
|
|
12825
12858
|
/**
|
|
12826
|
-
* `
|
|
12859
|
+
* `UpdateDescendantsSize` updates the size of the descendants. It is used when
|
|
12827
12860
|
* the tree is newly created and the size of the descendants is not calculated.
|
|
12861
|
+
* If includeRemoved is true, it includes removed nodes in the calculation.
|
|
12828
12862
|
*/
|
|
12829
|
-
updateDescendantsSize() {
|
|
12863
|
+
updateDescendantsSize(includeRemoved = false) {
|
|
12830
12864
|
let size = 0;
|
|
12831
12865
|
for (const child of this._children) {
|
|
12832
|
-
const childSize = child.updateDescendantsSize();
|
|
12833
|
-
if (child.isRemoved) {
|
|
12866
|
+
const childSize = child.updateDescendantsSize(includeRemoved);
|
|
12867
|
+
if (!includeRemoved && child.isRemoved) {
|
|
12834
12868
|
continue;
|
|
12835
12869
|
}
|
|
12836
12870
|
size += childSize;
|
|
12837
12871
|
}
|
|
12838
|
-
|
|
12839
|
-
|
|
12872
|
+
if (includeRemoved) {
|
|
12873
|
+
this.totalSize += size;
|
|
12874
|
+
} else {
|
|
12875
|
+
this.visibleSize += size;
|
|
12876
|
+
}
|
|
12877
|
+
return this.paddedSize(includeRemoved);
|
|
12840
12878
|
}
|
|
12841
12879
|
/**
|
|
12842
12880
|
* `isText` returns true if the node is a text node.
|
|
@@ -12845,10 +12883,18 @@ class IndexTreeNode {
|
|
|
12845
12883
|
return this.type === DefaultTextType;
|
|
12846
12884
|
}
|
|
12847
12885
|
/**
|
|
12848
|
-
* `paddedSize` returns the
|
|
12886
|
+
* `paddedSize` returns the length of the node including padding.
|
|
12887
|
+
* If includeRemoved is true, it includes removed nodes in the calculation.
|
|
12849
12888
|
*/
|
|
12850
|
-
|
|
12851
|
-
|
|
12889
|
+
paddedSize(includeRemoved = false) {
|
|
12890
|
+
let size = this.visibleSize;
|
|
12891
|
+
if (includeRemoved) {
|
|
12892
|
+
size = this.totalSize;
|
|
12893
|
+
}
|
|
12894
|
+
if (!this.isText) {
|
|
12895
|
+
size += ElementPaddingSize;
|
|
12896
|
+
}
|
|
12897
|
+
return size;
|
|
12852
12898
|
}
|
|
12853
12899
|
/**
|
|
12854
12900
|
* `isAncenstorOf` returns true if the node is an ancestor of the given node.
|
|
@@ -12883,7 +12929,7 @@ class IndexTreeNode {
|
|
|
12883
12929
|
*/
|
|
12884
12930
|
splitText(offset, absOffset) {
|
|
12885
12931
|
const diff = { data: 0, meta: 0 };
|
|
12886
|
-
if (offset === 0 || offset === this.
|
|
12932
|
+
if (offset === 0 || offset === this.visibleSize) {
|
|
12887
12933
|
return [void 0, diff];
|
|
12888
12934
|
}
|
|
12889
12935
|
const leftValue = this.value.slice(0, offset);
|
|
@@ -12941,7 +12987,8 @@ class IndexTreeNode {
|
|
|
12941
12987
|
this._children.push(...newNode);
|
|
12942
12988
|
for (const node of newNode) {
|
|
12943
12989
|
node.parent = this;
|
|
12944
|
-
node.updateAncestorsSize();
|
|
12990
|
+
node.updateAncestorsSize(node.paddedSize());
|
|
12991
|
+
node.updateAncestorsSize(node.paddedSize(true), true);
|
|
12945
12992
|
}
|
|
12946
12993
|
}
|
|
12947
12994
|
/**
|
|
@@ -12969,7 +13016,8 @@ class IndexTreeNode {
|
|
|
12969
13016
|
throw new YorkieError(Code.ErrInvalidArgument, "child not found");
|
|
12970
13017
|
}
|
|
12971
13018
|
this.insertAtInternal(newNode, offset);
|
|
12972
|
-
newNode.updateAncestorsSize();
|
|
13019
|
+
newNode.updateAncestorsSize(newNode.paddedSize());
|
|
13020
|
+
newNode.updateAncestorsSize(newNode.paddedSize(true), true);
|
|
12973
13021
|
}
|
|
12974
13022
|
/**
|
|
12975
13023
|
* `insertAfter` inserts the given node after the given child.
|
|
@@ -12983,7 +13031,8 @@ class IndexTreeNode {
|
|
|
12983
13031
|
throw new YorkieError(Code.ErrInvalidArgument, "child not found");
|
|
12984
13032
|
}
|
|
12985
13033
|
this.insertAtInternal(newNode, offset + 1);
|
|
12986
|
-
newNode.updateAncestorsSize();
|
|
13034
|
+
newNode.updateAncestorsSize(newNode.paddedSize());
|
|
13035
|
+
newNode.updateAncestorsSize(newNode.paddedSize(true), true);
|
|
12987
13036
|
}
|
|
12988
13037
|
/**
|
|
12989
13038
|
* `insertAt` inserts the given node at the given offset.
|
|
@@ -12993,10 +13042,12 @@ class IndexTreeNode {
|
|
|
12993
13042
|
throw new YorkieError(Code.ErrRefused, "Text node cannot have children");
|
|
12994
13043
|
}
|
|
12995
13044
|
this.insertAtInternal(newNode, offset);
|
|
12996
|
-
newNode.updateAncestorsSize();
|
|
13045
|
+
newNode.updateAncestorsSize(newNode.paddedSize());
|
|
13046
|
+
newNode.updateAncestorsSize(newNode.paddedSize(true), true);
|
|
12997
13047
|
}
|
|
12998
13048
|
/**
|
|
12999
13049
|
* `removeChild` removes the given child.
|
|
13050
|
+
* In this method, the child is physically removed from the tree.
|
|
13000
13051
|
*/
|
|
13001
13052
|
removeChild(child) {
|
|
13002
13053
|
if (this.isText) {
|
|
@@ -13007,6 +13058,7 @@ class IndexTreeNode {
|
|
|
13007
13058
|
throw new YorkieError(Code.ErrInvalidArgument, "child not found");
|
|
13008
13059
|
}
|
|
13009
13060
|
this._children.splice(offset, 1);
|
|
13061
|
+
child.updateAncestorsSize(-child.paddedSize(true), true);
|
|
13010
13062
|
child.parent = void 0;
|
|
13011
13063
|
}
|
|
13012
13064
|
/**
|
|
@@ -13017,17 +13069,26 @@ class IndexTreeNode {
|
|
|
13017
13069
|
const prvSize = this.getDataSize();
|
|
13018
13070
|
const clone = this.cloneElement(issueTimeTicket);
|
|
13019
13071
|
this.parent.insertAfterInternal(clone, this);
|
|
13020
|
-
clone.updateAncestorsSize();
|
|
13072
|
+
clone.updateAncestorsSize(clone.paddedSize());
|
|
13073
|
+
clone.updateAncestorsSize(clone.paddedSize(true), true);
|
|
13021
13074
|
const leftChildren = this.children.slice(0, offset);
|
|
13022
13075
|
const rightChildren = this.children.slice(offset);
|
|
13023
13076
|
this._children = leftChildren;
|
|
13024
13077
|
clone._children = rightChildren;
|
|
13025
|
-
this.
|
|
13026
|
-
(acc, child) => acc + child.paddedSize,
|
|
13078
|
+
this.visibleSize = this._children.reduce(
|
|
13079
|
+
(acc, child) => acc + child.paddedSize(),
|
|
13080
|
+
0
|
|
13081
|
+
);
|
|
13082
|
+
this.totalSize = this._children.reduce(
|
|
13083
|
+
(acc, child) => acc + child.paddedSize(true),
|
|
13084
|
+
0
|
|
13085
|
+
);
|
|
13086
|
+
clone.visibleSize = clone._children.reduce(
|
|
13087
|
+
(acc, child) => acc + child.paddedSize(true),
|
|
13027
13088
|
0
|
|
13028
13089
|
);
|
|
13029
|
-
clone.
|
|
13030
|
-
(acc, child) => acc + child.paddedSize,
|
|
13090
|
+
clone.totalSize = clone._children.reduce(
|
|
13091
|
+
(acc, child) => acc + child.paddedSize(true),
|
|
13031
13092
|
0
|
|
13032
13093
|
);
|
|
13033
13094
|
for (const child of clone._children) {
|
|
@@ -13064,12 +13125,15 @@ class IndexTreeNode {
|
|
|
13064
13125
|
}
|
|
13065
13126
|
/**
|
|
13066
13127
|
* findOffset returns the offset of the given node in the children.
|
|
13067
|
-
*
|
|
13128
|
+
* If includeRemoved is true, it includes removed nodes in the calculation.
|
|
13068
13129
|
*/
|
|
13069
|
-
findOffset(node) {
|
|
13130
|
+
findOffset(node, includeRemoved = false) {
|
|
13070
13131
|
if (this.isText) {
|
|
13071
13132
|
throw new YorkieError(Code.ErrRefused, "Text node cannot have children");
|
|
13072
13133
|
}
|
|
13134
|
+
if (includeRemoved) {
|
|
13135
|
+
return this._children.indexOf(node);
|
|
13136
|
+
}
|
|
13073
13137
|
if (node.isRemoved) {
|
|
13074
13138
|
const index = this._children.indexOf(node);
|
|
13075
13139
|
const refined = this.allChildren.splice(0, index).filter((node2) => !node2.isRemoved).length;
|
|
@@ -13114,35 +13178,38 @@ var TokenType = /* @__PURE__ */ ((TokenType2) => {
|
|
|
13114
13178
|
TokenType2["Text"] = "Text";
|
|
13115
13179
|
return TokenType2;
|
|
13116
13180
|
})(TokenType || {});
|
|
13117
|
-
function tokensBetween(root, from, to, callback) {
|
|
13181
|
+
function tokensBetween(root, from, to, callback, includeRemoved = false) {
|
|
13118
13182
|
if (from > to) {
|
|
13119
13183
|
throw new YorkieError(
|
|
13120
13184
|
Code.ErrInvalidArgument,
|
|
13121
13185
|
`from is greater than to: ${from} > ${to}`
|
|
13122
13186
|
);
|
|
13123
13187
|
}
|
|
13124
|
-
|
|
13188
|
+
const rootSize = includeRemoved ? root.totalSize : root.visibleSize;
|
|
13189
|
+
if (from > rootSize) {
|
|
13125
13190
|
throw new YorkieError(
|
|
13126
13191
|
Code.ErrInvalidArgument,
|
|
13127
|
-
`from is out of range: ${from} > ${
|
|
13192
|
+
`from is out of range: ${from} > ${rootSize}`
|
|
13128
13193
|
);
|
|
13129
13194
|
}
|
|
13130
|
-
if (to >
|
|
13195
|
+
if (to > rootSize) {
|
|
13131
13196
|
throw new YorkieError(
|
|
13132
13197
|
Code.ErrInvalidArgument,
|
|
13133
|
-
`to is out of range: ${to} > ${
|
|
13198
|
+
`to is out of range: ${to} > ${rootSize}`
|
|
13134
13199
|
);
|
|
13135
13200
|
}
|
|
13136
13201
|
if (from === to) {
|
|
13137
13202
|
return;
|
|
13138
13203
|
}
|
|
13139
13204
|
let pos = 0;
|
|
13140
|
-
|
|
13141
|
-
|
|
13205
|
+
const children = includeRemoved ? root._children : root.children;
|
|
13206
|
+
for (const child of children) {
|
|
13207
|
+
if (from - child.paddedSize(includeRemoved) < pos && pos < to) {
|
|
13142
13208
|
const fromChild = child.isText ? from - pos : from - pos - 1;
|
|
13143
13209
|
const toChild = child.isText ? to - pos : to - pos - 1;
|
|
13210
|
+
const childSize = includeRemoved ? child.totalSize : child.visibleSize;
|
|
13144
13211
|
const startContained = !child.isText && fromChild < 0;
|
|
13145
|
-
const endContained = !child.isText && toChild >
|
|
13212
|
+
const endContained = !child.isText && toChild > childSize;
|
|
13146
13213
|
if (child.isText || startContained) {
|
|
13147
13214
|
callback(
|
|
13148
13215
|
[
|
|
@@ -13156,8 +13223,9 @@ function tokensBetween(root, from, to, callback) {
|
|
|
13156
13223
|
tokensBetween(
|
|
13157
13224
|
child,
|
|
13158
13225
|
Math.max(0, fromChild),
|
|
13159
|
-
Math.min(toChild,
|
|
13160
|
-
callback
|
|
13226
|
+
Math.min(toChild, childSize),
|
|
13227
|
+
callback,
|
|
13228
|
+
includeRemoved
|
|
13161
13229
|
);
|
|
13162
13230
|
if (endContained) {
|
|
13163
13231
|
callback([
|
|
@@ -13167,7 +13235,7 @@ function tokensBetween(root, from, to, callback) {
|
|
|
13167
13235
|
], endContained);
|
|
13168
13236
|
}
|
|
13169
13237
|
}
|
|
13170
|
-
pos += child.paddedSize;
|
|
13238
|
+
pos += child.paddedSize(includeRemoved);
|
|
13171
13239
|
}
|
|
13172
13240
|
}
|
|
13173
13241
|
function traverse(node, callback, depth = 0) {
|
|
@@ -13183,10 +13251,10 @@ function traverseAll(node, callback, depth = 0) {
|
|
|
13183
13251
|
callback(node, depth);
|
|
13184
13252
|
}
|
|
13185
13253
|
function findTreePos(node, index, preferText = true) {
|
|
13186
|
-
if (index > node.
|
|
13254
|
+
if (index > node.visibleSize) {
|
|
13187
13255
|
throw new YorkieError(
|
|
13188
13256
|
Code.ErrInvalidArgument,
|
|
13189
|
-
`index is out of range: ${index} > ${node.
|
|
13257
|
+
`index is out of range: ${index} > ${node.visibleSize}`
|
|
13190
13258
|
);
|
|
13191
13259
|
}
|
|
13192
13260
|
if (node.isText) {
|
|
@@ -13195,20 +13263,20 @@ function findTreePos(node, index, preferText = true) {
|
|
|
13195
13263
|
let offset = 0;
|
|
13196
13264
|
let pos = 0;
|
|
13197
13265
|
for (const child of node.children) {
|
|
13198
|
-
if (preferText && child.isText && child.
|
|
13266
|
+
if (preferText && child.isText && child.visibleSize >= index - pos) {
|
|
13199
13267
|
return findTreePos(child, index - pos, preferText);
|
|
13200
13268
|
}
|
|
13201
13269
|
if (index === pos) {
|
|
13202
13270
|
return { node, offset };
|
|
13203
13271
|
}
|
|
13204
|
-
if (!preferText && child.paddedSize === index - pos) {
|
|
13272
|
+
if (!preferText && child.paddedSize() === index - pos) {
|
|
13205
13273
|
return { node, offset: offset + 1 };
|
|
13206
13274
|
}
|
|
13207
|
-
if (child.paddedSize > index - pos) {
|
|
13275
|
+
if (child.paddedSize() > index - pos) {
|
|
13208
13276
|
const skipOpenSize = 1;
|
|
13209
13277
|
return findTreePos(child, index - pos - skipOpenSize, preferText);
|
|
13210
13278
|
}
|
|
13211
|
-
pos += child.paddedSize;
|
|
13279
|
+
pos += child.paddedSize();
|
|
13212
13280
|
offset += 1;
|
|
13213
13281
|
}
|
|
13214
13282
|
return { node, offset };
|
|
@@ -13220,13 +13288,13 @@ function findLeftmost(node) {
|
|
|
13220
13288
|
return findLeftmost(node.children[0]);
|
|
13221
13289
|
}
|
|
13222
13290
|
function findTextPos(node, pathElement) {
|
|
13223
|
-
if (node.
|
|
13291
|
+
if (node.visibleSize < pathElement) {
|
|
13224
13292
|
throw new YorkieError(Code.ErrInvalidArgument, "unacceptable path");
|
|
13225
13293
|
}
|
|
13226
13294
|
for (let i = 0; i < node.children.length; i++) {
|
|
13227
13295
|
const child = node.children[i];
|
|
13228
|
-
if (child.
|
|
13229
|
-
pathElement -= child.
|
|
13296
|
+
if (child.visibleSize < pathElement) {
|
|
13297
|
+
pathElement -= child.visibleSize;
|
|
13230
13298
|
} else {
|
|
13231
13299
|
node = child;
|
|
13232
13300
|
break;
|
|
@@ -13241,9 +13309,10 @@ class IndexTree {
|
|
|
13241
13309
|
}
|
|
13242
13310
|
/**
|
|
13243
13311
|
* `tokensBetween` returns the tokens between the given range.
|
|
13312
|
+
* If includeRemoved is true, it includes removed nodes in the calculation.
|
|
13244
13313
|
*/
|
|
13245
|
-
tokensBetween(from, to, callback) {
|
|
13246
|
-
tokensBetween(this.root, from, to, callback);
|
|
13314
|
+
tokensBetween(from, to, callback, includeRemoved = false) {
|
|
13315
|
+
tokensBetween(this.root, from, to, callback, includeRemoved);
|
|
13247
13316
|
}
|
|
13248
13317
|
/**
|
|
13249
13318
|
* `traverse` traverses the tree with postorder traversal.
|
|
@@ -13342,7 +13411,7 @@ class IndexTree {
|
|
|
13342
13411
|
* `getSize` returns the size of the tree.
|
|
13343
13412
|
*/
|
|
13344
13413
|
get size() {
|
|
13345
|
-
return this.root.
|
|
13414
|
+
return this.root.visibleSize;
|
|
13346
13415
|
}
|
|
13347
13416
|
/**
|
|
13348
13417
|
* `findPostorderRight` finds right node of the given tree position with
|
|
@@ -13351,7 +13420,7 @@ class IndexTree {
|
|
|
13351
13420
|
findPostorderRight(treePos) {
|
|
13352
13421
|
const { node, offset } = treePos;
|
|
13353
13422
|
if (node.isText) {
|
|
13354
|
-
if (node.
|
|
13423
|
+
if (node.visibleSize === offset) {
|
|
13355
13424
|
const nextSibling = node.nextSibling;
|
|
13356
13425
|
if (nextSibling) {
|
|
13357
13426
|
return nextSibling;
|
|
@@ -13367,8 +13436,9 @@ class IndexTree {
|
|
|
13367
13436
|
}
|
|
13368
13437
|
/**
|
|
13369
13438
|
* `indexOf` returns the index of the given tree position.
|
|
13439
|
+
* If includeRemoved is true, it includes removed nodes in the calculation.
|
|
13370
13440
|
*/
|
|
13371
|
-
indexOf(pos) {
|
|
13441
|
+
indexOf(pos, includeRemoved = false) {
|
|
13372
13442
|
let { node } = pos;
|
|
13373
13443
|
const { offset } = pos;
|
|
13374
13444
|
let size = 0;
|
|
@@ -13376,22 +13446,22 @@ class IndexTree {
|
|
|
13376
13446
|
if (node.isText) {
|
|
13377
13447
|
size += offset;
|
|
13378
13448
|
const parent = node.parent;
|
|
13379
|
-
const offsetOfNode = parent.findOffset(node);
|
|
13449
|
+
const offsetOfNode = parent.findOffset(node, includeRemoved);
|
|
13380
13450
|
if (offsetOfNode === -1) {
|
|
13381
13451
|
throw new YorkieError(Code.ErrInvalidArgument, "invalid pos");
|
|
13382
13452
|
}
|
|
13383
|
-
size += addSizeOfLeftSiblings(parent, offsetOfNode);
|
|
13453
|
+
size += addSizeOfLeftSiblings(parent, offsetOfNode, includeRemoved);
|
|
13384
13454
|
node = node.parent;
|
|
13385
13455
|
} else {
|
|
13386
|
-
size += addSizeOfLeftSiblings(node, offset);
|
|
13456
|
+
size += addSizeOfLeftSiblings(node, offset, includeRemoved);
|
|
13387
13457
|
}
|
|
13388
13458
|
while (node == null ? void 0 : node.parent) {
|
|
13389
13459
|
const parent = node.parent;
|
|
13390
|
-
const offsetOfNode = parent.findOffset(node);
|
|
13460
|
+
const offsetOfNode = parent.findOffset(node, includeRemoved);
|
|
13391
13461
|
if (offsetOfNode === -1) {
|
|
13392
13462
|
throw new YorkieError(Code.ErrInvalidArgument, "invalid pos");
|
|
13393
13463
|
}
|
|
13394
|
-
size += addSizeOfLeftSiblings(parent, offsetOfNode);
|
|
13464
|
+
size += addSizeOfLeftSiblings(parent, offsetOfNode, includeRemoved);
|
|
13395
13465
|
depth++;
|
|
13396
13466
|
node = node.parent;
|
|
13397
13467
|
}
|
|
@@ -13948,7 +14018,8 @@ class CRDTTreeNode extends IndexTreeNode {
|
|
|
13948
14018
|
const clone = new CRDTTreeNode(this.id, this.type);
|
|
13949
14019
|
clone.removedAt = this.removedAt;
|
|
13950
14020
|
clone._value = this._value;
|
|
13951
|
-
clone.
|
|
14021
|
+
clone.visibleSize = this.visibleSize;
|
|
14022
|
+
clone.totalSize = this.totalSize;
|
|
13952
14023
|
clone.attrs = (_a2 = this.attrs) == null ? void 0 : _a2.deepcopy();
|
|
13953
14024
|
clone._children = this._children.map((child) => {
|
|
13954
14025
|
const childClone = child.deepcopy();
|
|
@@ -13982,7 +14053,8 @@ class CRDTTreeNode extends IndexTreeNode {
|
|
|
13982
14053
|
);
|
|
13983
14054
|
}
|
|
13984
14055
|
this._value = v;
|
|
13985
|
-
this.
|
|
14056
|
+
this.visibleSize = v.length;
|
|
14057
|
+
this.totalSize = v.length;
|
|
13986
14058
|
}
|
|
13987
14059
|
/**
|
|
13988
14060
|
* `isRemoved` returns whether the node is removed or not.
|
|
@@ -13994,13 +14066,15 @@ class CRDTTreeNode extends IndexTreeNode {
|
|
|
13994
14066
|
* `remove` marks the node as removed.
|
|
13995
14067
|
*/
|
|
13996
14068
|
remove(removedAt) {
|
|
13997
|
-
|
|
13998
|
-
if (!this.removedAt || this.removedAt.compare(removedAt) > 0) {
|
|
14069
|
+
if (!this.removedAt) {
|
|
13999
14070
|
this.removedAt = removedAt;
|
|
14071
|
+
this.updateAncestorsSize(-this.paddedSize());
|
|
14072
|
+
return true;
|
|
14000
14073
|
}
|
|
14001
|
-
if (
|
|
14002
|
-
this.
|
|
14074
|
+
if (removedAt.after(this.removedAt)) {
|
|
14075
|
+
this.removedAt = removedAt;
|
|
14003
14076
|
}
|
|
14077
|
+
return false;
|
|
14004
14078
|
}
|
|
14005
14079
|
/**
|
|
14006
14080
|
* `cloneText` clones this text node with the given offset.
|
|
@@ -14058,9 +14132,17 @@ class CRDTTreeNode extends IndexTreeNode {
|
|
|
14058
14132
|
/**
|
|
14059
14133
|
* `canDelete` checks if node is able to delete.
|
|
14060
14134
|
*/
|
|
14061
|
-
canDelete(editedAt,
|
|
14062
|
-
|
|
14063
|
-
|
|
14135
|
+
canDelete(editedAt, creationKnown, tombstoneKnown) {
|
|
14136
|
+
if (!creationKnown) {
|
|
14137
|
+
return false;
|
|
14138
|
+
}
|
|
14139
|
+
if (!this.removedAt) {
|
|
14140
|
+
return true;
|
|
14141
|
+
}
|
|
14142
|
+
if (!tombstoneKnown && (editedAt == null ? void 0 : editedAt.after(this.removedAt))) {
|
|
14143
|
+
return true;
|
|
14144
|
+
}
|
|
14145
|
+
return false;
|
|
14064
14146
|
}
|
|
14065
14147
|
/**
|
|
14066
14148
|
* `canStyle` checks if node is able to style.
|
|
@@ -14099,7 +14181,7 @@ class CRDTTreeNode extends IndexTreeNode {
|
|
|
14099
14181
|
getDataSize() {
|
|
14100
14182
|
const dataSize = { data: 0, meta: 0 };
|
|
14101
14183
|
if (this.isText) {
|
|
14102
|
-
dataSize.data += this.
|
|
14184
|
+
dataSize.data += this.visibleSize * 2;
|
|
14103
14185
|
}
|
|
14104
14186
|
if (this.id) {
|
|
14105
14187
|
dataSize.meta += TimeTicketSize;
|
|
@@ -14176,14 +14258,14 @@ function toTestTreeNode(node) {
|
|
|
14176
14258
|
return {
|
|
14177
14259
|
type: currentNode.type,
|
|
14178
14260
|
value: currentNode.value,
|
|
14179
|
-
|
|
14261
|
+
visibleSize: currentNode.visibleSize,
|
|
14180
14262
|
isRemoved: currentNode.isRemoved
|
|
14181
14263
|
};
|
|
14182
14264
|
}
|
|
14183
14265
|
return {
|
|
14184
14266
|
type: node.type,
|
|
14185
14267
|
children: node.children.map(toTestTreeNode),
|
|
14186
|
-
|
|
14268
|
+
visibleSize: node.visibleSize,
|
|
14187
14269
|
isRemoved: node.isRemoved
|
|
14188
14270
|
};
|
|
14189
14271
|
}
|
|
@@ -14411,18 +14493,25 @@ class CRDTTree extends CRDTElement {
|
|
|
14411
14493
|
toBeMovedToFromParents.push(child);
|
|
14412
14494
|
}
|
|
14413
14495
|
}
|
|
14414
|
-
const
|
|
14415
|
-
let
|
|
14416
|
-
|
|
14417
|
-
|
|
14496
|
+
const isLocal = versionVector === void 0;
|
|
14497
|
+
let creationKnown = false;
|
|
14498
|
+
const createdAtVV = versionVector == null ? void 0 : versionVector.get(
|
|
14499
|
+
node.id.getCreatedAt().getActorID()
|
|
14500
|
+
);
|
|
14501
|
+
creationKnown = isLocal || createdAtVV !== void 0 && createdAtVV >= node.id.getCreatedAt().getLamport();
|
|
14502
|
+
let tombstoneKnown = false;
|
|
14503
|
+
if (node.removedAt) {
|
|
14504
|
+
const removedAtVV = versionVector == null ? void 0 : versionVector.get(node.removedAt.getActorID());
|
|
14505
|
+
tombstoneKnown = isLocal || removedAtVV !== void 0 && removedAtVV >= node.removedAt.getLamport();
|
|
14418
14506
|
}
|
|
14419
|
-
if (node.canDelete(editedAt,
|
|
14507
|
+
if (node.canDelete(editedAt, creationKnown, tombstoneKnown) || nodesToBeRemoved.includes(node.parent)) {
|
|
14420
14508
|
if (tokenType === TokenType.Text || tokenType === TokenType.Start) {
|
|
14421
14509
|
nodesToBeRemoved.push(node);
|
|
14422
14510
|
}
|
|
14423
14511
|
tokensToBeRemoved.push([node, tokenType]);
|
|
14424
14512
|
}
|
|
14425
|
-
}
|
|
14513
|
+
},
|
|
14514
|
+
true
|
|
14426
14515
|
);
|
|
14427
14516
|
const changes = this.makeDeletionChanges(
|
|
14428
14517
|
tokensToBeRemoved,
|
|
@@ -14508,7 +14597,7 @@ class CRDTTree extends CRDTElement {
|
|
|
14508
14597
|
editT(range, contents, splitLevel, editedAt, issueTimeTicket) {
|
|
14509
14598
|
const fromPos = this.findPos(range[0]);
|
|
14510
14599
|
const toPos = this.findPos(range[1]);
|
|
14511
|
-
this.edit(
|
|
14600
|
+
return this.edit(
|
|
14512
14601
|
[fromPos, toPos],
|
|
14513
14602
|
contents,
|
|
14514
14603
|
splitLevel,
|
|
@@ -14668,7 +14757,7 @@ class CRDTTree extends CRDTElement {
|
|
|
14668
14757
|
const nodeInfo = {
|
|
14669
14758
|
type: node.type,
|
|
14670
14759
|
parent: parentNode == null ? void 0 : parentNode.id.toTestString(),
|
|
14671
|
-
size: node.
|
|
14760
|
+
size: node.visibleSize,
|
|
14672
14761
|
id: node.id.toTestString(),
|
|
14673
14762
|
removedAt: (_a2 = node.removedAt) == null ? void 0 : _a2.toTestString(),
|
|
14674
14763
|
insPrev: (_b2 = node.insPrevID) == null ? void 0 : _b2.toTestString(),
|
|
@@ -14715,7 +14804,10 @@ class CRDTTree extends CRDTElement {
|
|
|
14715
14804
|
*/
|
|
14716
14805
|
deepcopy() {
|
|
14717
14806
|
const root = this.getRoot();
|
|
14718
|
-
|
|
14807
|
+
const tree = new CRDTTree(root.deepcopy(), this.getCreatedAt());
|
|
14808
|
+
tree.setRemovedAt(this.getRemovedAt());
|
|
14809
|
+
tree.setMovedAt(this.getMovedAt());
|
|
14810
|
+
return tree;
|
|
14719
14811
|
}
|
|
14720
14812
|
/**
|
|
14721
14813
|
* `toPath` converts the given CRDTTreeNodeID to the path of the tree.
|
|
@@ -14729,13 +14821,14 @@ class CRDTTree extends CRDTElement {
|
|
|
14729
14821
|
}
|
|
14730
14822
|
/**
|
|
14731
14823
|
* `toIndex` converts the given CRDTTreeNodeID to the index of the tree.
|
|
14824
|
+
* If includeRemoved is true, it includes removed nodes in the calculation.
|
|
14732
14825
|
*/
|
|
14733
|
-
toIndex(parentNode, leftNode) {
|
|
14734
|
-
const treePos = this.toTreePos(parentNode, leftNode);
|
|
14826
|
+
toIndex(parentNode, leftNode, includeRemoved = false) {
|
|
14827
|
+
const treePos = this.toTreePos(parentNode, leftNode, includeRemoved);
|
|
14735
14828
|
if (!treePos) {
|
|
14736
14829
|
return -1;
|
|
14737
14830
|
}
|
|
14738
|
-
return this.indexTree.indexOf(treePos);
|
|
14831
|
+
return this.indexTree.indexOf(treePos, includeRemoved);
|
|
14739
14832
|
}
|
|
14740
14833
|
/**
|
|
14741
14834
|
* `indexToPath` converts the given tree index to path.
|
|
@@ -14788,26 +14881,28 @@ class CRDTTree extends CRDTElement {
|
|
|
14788
14881
|
}
|
|
14789
14882
|
/**
|
|
14790
14883
|
* `traverseInPosRange` traverses the tree in the given position range.
|
|
14884
|
+
* If includeRemoved is true, it includes removed nodes in the calculation.
|
|
14791
14885
|
*/
|
|
14792
|
-
traverseInPosRange(fromParent, fromLeft, toParent, toLeft, callback) {
|
|
14793
|
-
const fromIdx = this.toIndex(fromParent, fromLeft);
|
|
14794
|
-
const toIdx = this.toIndex(toParent, toLeft);
|
|
14795
|
-
|
|
14886
|
+
traverseInPosRange(fromParent, fromLeft, toParent, toLeft, callback, includeRemoved = false) {
|
|
14887
|
+
const fromIdx = this.toIndex(fromParent, fromLeft, includeRemoved);
|
|
14888
|
+
const toIdx = this.toIndex(toParent, toLeft, includeRemoved);
|
|
14889
|
+
this.indexTree.tokensBetween(fromIdx, toIdx, callback, includeRemoved);
|
|
14796
14890
|
}
|
|
14797
14891
|
/**
|
|
14798
14892
|
* `toTreePos` converts the given nodes to the position of the IndexTree.
|
|
14893
|
+
* If includeRemoved is true, it includes removed nodes in the calculation.
|
|
14799
14894
|
*/
|
|
14800
|
-
toTreePos(parentNode, leftNode) {
|
|
14895
|
+
toTreePos(parentNode, leftNode, includeRemoved = false) {
|
|
14801
14896
|
if (!parentNode || !leftNode) {
|
|
14802
14897
|
return;
|
|
14803
14898
|
}
|
|
14804
|
-
if (parentNode.isRemoved) {
|
|
14899
|
+
if (!includeRemoved && parentNode.isRemoved) {
|
|
14805
14900
|
let childNode;
|
|
14806
14901
|
while (parentNode.isRemoved) {
|
|
14807
14902
|
childNode = parentNode;
|
|
14808
14903
|
parentNode = childNode.parent;
|
|
14809
14904
|
}
|
|
14810
|
-
const offset2 = parentNode.findOffset(childNode);
|
|
14905
|
+
const offset2 = parentNode.findOffset(childNode, includeRemoved);
|
|
14811
14906
|
return {
|
|
14812
14907
|
node: parentNode,
|
|
14813
14908
|
offset: offset2
|
|
@@ -14819,12 +14914,12 @@ class CRDTTree extends CRDTElement {
|
|
|
14819
14914
|
offset: 0
|
|
14820
14915
|
};
|
|
14821
14916
|
}
|
|
14822
|
-
let offset = parentNode.findOffset(leftNode);
|
|
14823
|
-
if (!leftNode.isRemoved) {
|
|
14917
|
+
let offset = parentNode.findOffset(leftNode, includeRemoved);
|
|
14918
|
+
if (includeRemoved || !leftNode.isRemoved) {
|
|
14824
14919
|
if (leftNode.isText) {
|
|
14825
14920
|
return {
|
|
14826
14921
|
node: leftNode,
|
|
14827
|
-
offset: leftNode.paddedSize
|
|
14922
|
+
offset: leftNode.paddedSize(includeRemoved)
|
|
14828
14923
|
};
|
|
14829
14924
|
}
|
|
14830
14925
|
offset++;
|
|
@@ -15967,13 +16062,16 @@ class RGATreeSplitNode extends SplayNode {
|
|
|
15967
16062
|
/**
|
|
15968
16063
|
* `canDelete` checks if node is able to delete.
|
|
15969
16064
|
*/
|
|
15970
|
-
canRemove(creationKnown) {
|
|
16065
|
+
canRemove(editedAt, creationKnown, tombstoneKnown) {
|
|
15971
16066
|
if (!creationKnown) {
|
|
15972
16067
|
return false;
|
|
15973
16068
|
}
|
|
15974
16069
|
if (!this.removedAt) {
|
|
15975
16070
|
return true;
|
|
15976
16071
|
}
|
|
16072
|
+
if (!tombstoneKnown && (editedAt == null ? void 0 : editedAt.after(this.removedAt))) {
|
|
16073
|
+
return true;
|
|
16074
|
+
}
|
|
15977
16075
|
return false;
|
|
15978
16076
|
}
|
|
15979
16077
|
/**
|
|
@@ -15992,12 +16090,12 @@ class RGATreeSplitNode extends SplayNode {
|
|
|
15992
16090
|
/**
|
|
15993
16091
|
* `remove` removes the node of the given edited time.
|
|
15994
16092
|
*/
|
|
15995
|
-
remove(removedAt
|
|
16093
|
+
remove(removedAt) {
|
|
15996
16094
|
if (!this.removedAt) {
|
|
15997
16095
|
this.removedAt = removedAt;
|
|
15998
16096
|
return;
|
|
15999
16097
|
}
|
|
16000
|
-
if (
|
|
16098
|
+
if (removedAt.after(this.removedAt)) {
|
|
16001
16099
|
this.removedAt = removedAt;
|
|
16002
16100
|
}
|
|
16003
16101
|
}
|
|
@@ -16334,13 +16432,31 @@ class RGATreeSplit {
|
|
|
16334
16432
|
if (!candidates.length) {
|
|
16335
16433
|
return [[], /* @__PURE__ */ new Map()];
|
|
16336
16434
|
}
|
|
16337
|
-
const isLocal = vector === void 0;
|
|
16435
|
+
const isLocal = vector === void 0 || vector.size() === 0;
|
|
16338
16436
|
const nodesToRemove = [];
|
|
16339
16437
|
const nodesToKeep = [];
|
|
16340
16438
|
const [leftEdge, rightEdge] = this.findEdgesOfCandidates(candidates);
|
|
16341
16439
|
nodesToKeep.push(leftEdge);
|
|
16342
16440
|
for (const node of candidates) {
|
|
16343
|
-
|
|
16441
|
+
let creationKnown = false;
|
|
16442
|
+
if (isLocal) {
|
|
16443
|
+
creationKnown = true;
|
|
16444
|
+
} else {
|
|
16445
|
+
const createdAtVV = vector == null ? void 0 : vector.get(node.getCreatedAt().getActorID());
|
|
16446
|
+
if (createdAtVV && createdAtVV >= node.getCreatedAt().getLamport()) {
|
|
16447
|
+
creationKnown = true;
|
|
16448
|
+
}
|
|
16449
|
+
}
|
|
16450
|
+
let tombstoneKnown = false;
|
|
16451
|
+
if (node.getRemovedAt()) {
|
|
16452
|
+
const removedAtVV = vector == null ? void 0 : vector.get(node.getRemovedAt().getActorID());
|
|
16453
|
+
if (isLocal) {
|
|
16454
|
+
tombstoneKnown = true;
|
|
16455
|
+
} else if (removedAtVV && removedAtVV >= node.getRemovedAt().getLamport()) {
|
|
16456
|
+
tombstoneKnown = true;
|
|
16457
|
+
}
|
|
16458
|
+
}
|
|
16459
|
+
if (node.canRemove(editedAt, creationKnown, tombstoneKnown)) {
|
|
16344
16460
|
nodesToRemove.push(node);
|
|
16345
16461
|
} else {
|
|
16346
16462
|
nodesToKeep.push(node);
|
|
@@ -16351,10 +16467,7 @@ class RGATreeSplit {
|
|
|
16351
16467
|
const removedNodes = /* @__PURE__ */ new Map();
|
|
16352
16468
|
for (const node of nodesToRemove) {
|
|
16353
16469
|
removedNodes.set(node.getID().toIDString(), node);
|
|
16354
|
-
node.remove(
|
|
16355
|
-
editedAt,
|
|
16356
|
-
node.isRemoved() && (isLocal || vector.afterOrEqual(node.getRemovedAt()))
|
|
16357
|
-
);
|
|
16470
|
+
node.remove(editedAt);
|
|
16358
16471
|
}
|
|
16359
16472
|
this.deleteIndexNodes(nodesToKeep);
|
|
16360
16473
|
return [changes, removedNodes];
|
|
@@ -16536,13 +16649,14 @@ class CRDTCounter extends CRDTElement {
|
|
|
16536
16649
|
* `deepcopy` copies itself deeply.
|
|
16537
16650
|
*/
|
|
16538
16651
|
deepcopy() {
|
|
16539
|
-
const
|
|
16652
|
+
const clone = CRDTCounter.create(
|
|
16540
16653
|
this.valueType,
|
|
16541
16654
|
this.value,
|
|
16542
16655
|
this.getCreatedAt()
|
|
16543
16656
|
);
|
|
16544
|
-
|
|
16545
|
-
|
|
16657
|
+
clone.setRemovedAt(this.getRemovedAt());
|
|
16658
|
+
clone.setMovedAt(this.getMovedAt());
|
|
16659
|
+
return clone;
|
|
16546
16660
|
}
|
|
16547
16661
|
/**
|
|
16548
16662
|
* `getType` returns the type of the value.
|
|
@@ -17719,6 +17833,7 @@ function fromTreeNodes(pbTreeNodes) {
|
|
|
17719
17833
|
depthTable.set(pbTreeNodes[i].depth, nodes[i]);
|
|
17720
17834
|
}
|
|
17721
17835
|
root.updateDescendantsSize();
|
|
17836
|
+
root.updateDescendantsSize(true);
|
|
17722
17837
|
return CRDTTree.create(root, InitialTimeTicket).getRoot();
|
|
17723
17838
|
}
|
|
17724
17839
|
function fromRHT(pbRHT) {
|
|
@@ -18206,108 +18321,6 @@ function uuid() {
|
|
|
18206
18321
|
return v.toString(16);
|
|
18207
18322
|
});
|
|
18208
18323
|
}
|
|
18209
|
-
class Attachment {
|
|
18210
|
-
constructor(reconnectStreamDelay, resource, resourceID, syncMode, unsubscribeBroadcastEvent) {
|
|
18211
|
-
__publicField(this, "resource");
|
|
18212
|
-
__publicField(this, "resourceID");
|
|
18213
|
-
__publicField(this, "syncMode");
|
|
18214
|
-
__publicField(this, "changeEventReceived");
|
|
18215
|
-
__publicField(this, "lastHeartbeatTime");
|
|
18216
|
-
__publicField(this, "reconnectStreamDelay");
|
|
18217
|
-
__publicField(this, "cancelled");
|
|
18218
|
-
__publicField(this, "watchStream");
|
|
18219
|
-
__publicField(this, "watchLoopTimerID");
|
|
18220
|
-
__publicField(this, "watchAbortController");
|
|
18221
|
-
__publicField(this, "unsubscribeBroadcastEvent");
|
|
18222
|
-
this.reconnectStreamDelay = reconnectStreamDelay;
|
|
18223
|
-
this.resource = resource;
|
|
18224
|
-
this.resourceID = resourceID;
|
|
18225
|
-
this.syncMode = syncMode;
|
|
18226
|
-
this.changeEventReceived = syncMode !== void 0 ? false : void 0;
|
|
18227
|
-
this.lastHeartbeatTime = Date.now();
|
|
18228
|
-
this.cancelled = false;
|
|
18229
|
-
this.unsubscribeBroadcastEvent = unsubscribeBroadcastEvent;
|
|
18230
|
-
}
|
|
18231
|
-
/**
|
|
18232
|
-
* `changeSyncMode` changes the sync mode of the document.
|
|
18233
|
-
*/
|
|
18234
|
-
changeSyncMode(syncMode) {
|
|
18235
|
-
this.syncMode = syncMode;
|
|
18236
|
-
}
|
|
18237
|
-
/**
|
|
18238
|
-
* `needRealtimeSync` returns whether the resource needs to be synced in real time.
|
|
18239
|
-
* Only applicable to Document resources with syncMode defined.
|
|
18240
|
-
*/
|
|
18241
|
-
needRealtimeSync() {
|
|
18242
|
-
if (this.syncMode === void 0) {
|
|
18243
|
-
return false;
|
|
18244
|
-
}
|
|
18245
|
-
if (this.syncMode === SyncMode.RealtimeSyncOff) {
|
|
18246
|
-
return false;
|
|
18247
|
-
}
|
|
18248
|
-
if (this.syncMode === SyncMode.RealtimePushOnly) {
|
|
18249
|
-
return this.resource.hasLocalChanges();
|
|
18250
|
-
}
|
|
18251
|
-
return this.syncMode !== SyncMode.Manual && (this.resource.hasLocalChanges() || (this.changeEventReceived ?? false));
|
|
18252
|
-
}
|
|
18253
|
-
/**
|
|
18254
|
-
* `needSync` determines if the attachment needs sync.
|
|
18255
|
-
* This includes both document sync and presence heartbeat.
|
|
18256
|
-
*/
|
|
18257
|
-
needSync(heartbeatInterval) {
|
|
18258
|
-
if (this.syncMode !== void 0) {
|
|
18259
|
-
return this.needRealtimeSync();
|
|
18260
|
-
}
|
|
18261
|
-
return Date.now() - this.lastHeartbeatTime >= heartbeatInterval;
|
|
18262
|
-
}
|
|
18263
|
-
/**
|
|
18264
|
-
* `updateHeartbeatTime` updates the last heartbeat time.
|
|
18265
|
-
*/
|
|
18266
|
-
updateHeartbeatTime() {
|
|
18267
|
-
this.lastHeartbeatTime = Date.now();
|
|
18268
|
-
}
|
|
18269
|
-
/**
|
|
18270
|
-
* `runWatchLoop` runs the watch loop.
|
|
18271
|
-
*/
|
|
18272
|
-
async runWatchLoop(watchStreamCreator) {
|
|
18273
|
-
const doLoop = async () => {
|
|
18274
|
-
if (this.watchStream) {
|
|
18275
|
-
return Promise.resolve();
|
|
18276
|
-
}
|
|
18277
|
-
if (this.watchLoopTimerID) {
|
|
18278
|
-
clearTimeout(this.watchLoopTimerID);
|
|
18279
|
-
this.watchLoopTimerID = void 0;
|
|
18280
|
-
}
|
|
18281
|
-
try {
|
|
18282
|
-
[this.watchStream, this.watchAbortController] = await watchStreamCreator(() => {
|
|
18283
|
-
this.watchStream = void 0;
|
|
18284
|
-
this.watchAbortController = void 0;
|
|
18285
|
-
if (!this.cancelled) {
|
|
18286
|
-
this.watchLoopTimerID = setTimeout(
|
|
18287
|
-
doLoop,
|
|
18288
|
-
this.reconnectStreamDelay
|
|
18289
|
-
);
|
|
18290
|
-
}
|
|
18291
|
-
});
|
|
18292
|
-
} catch {
|
|
18293
|
-
}
|
|
18294
|
-
};
|
|
18295
|
-
await doLoop();
|
|
18296
|
-
}
|
|
18297
|
-
/**
|
|
18298
|
-
* `cancelWatchStream` cancels the watch stream.
|
|
18299
|
-
*/
|
|
18300
|
-
cancelWatchStream() {
|
|
18301
|
-
this.cancelled = true;
|
|
18302
|
-
if (this.watchStream && this.watchAbortController) {
|
|
18303
|
-
this.watchAbortController.abort();
|
|
18304
|
-
this.watchStream = void 0;
|
|
18305
|
-
this.watchAbortController = void 0;
|
|
18306
|
-
}
|
|
18307
|
-
clearTimeout(this.watchLoopTimerID);
|
|
18308
|
-
this.watchLoopTimerID = void 0;
|
|
18309
|
-
}
|
|
18310
|
-
}
|
|
18311
18324
|
const Noop = () => {
|
|
18312
18325
|
};
|
|
18313
18326
|
class ObserverProxy {
|
|
@@ -20640,6 +20653,18 @@ class CRDTRoot {
|
|
|
20640
20653
|
acc(diff) {
|
|
20641
20654
|
addDataSizes(this.docSize.live, diff);
|
|
20642
20655
|
}
|
|
20656
|
+
/**
|
|
20657
|
+
* `getGCElementPairs` returns an iterator for all GC element pairs.
|
|
20658
|
+
* This is similar to Go's GCElementPairMap() functionality.
|
|
20659
|
+
*/
|
|
20660
|
+
*getGCElementPairs() {
|
|
20661
|
+
for (const createdAt of this.gcElementSetByCreatedAt) {
|
|
20662
|
+
const pair = this.elementPairMapByCreatedAt.get(createdAt);
|
|
20663
|
+
if (pair) {
|
|
20664
|
+
yield pair;
|
|
20665
|
+
}
|
|
20666
|
+
}
|
|
20667
|
+
}
|
|
20643
20668
|
}
|
|
20644
20669
|
class DocPresence {
|
|
20645
20670
|
constructor(changeContext, presence) {
|
|
@@ -21594,6 +21619,13 @@ class Document {
|
|
|
21594
21619
|
getGarbageLen() {
|
|
21595
21620
|
return this.root.getGarbageLen();
|
|
21596
21621
|
}
|
|
21622
|
+
/**
|
|
21623
|
+
* `getRootCRDT` returns the CRDTRoot for testing purposes.
|
|
21624
|
+
* This method is intended for internal testing only.
|
|
21625
|
+
*/
|
|
21626
|
+
getRootCRDT() {
|
|
21627
|
+
return this.root;
|
|
21628
|
+
}
|
|
21597
21629
|
/**
|
|
21598
21630
|
* `getGarbageLenFromClone` returns the length of elements should be purged from clone.
|
|
21599
21631
|
*/
|
|
@@ -22167,6 +22199,108 @@ class Document {
|
|
|
22167
22199
|
this.publish(events);
|
|
22168
22200
|
}
|
|
22169
22201
|
}
|
|
22202
|
+
class Attachment {
|
|
22203
|
+
constructor(reconnectStreamDelay, resource, resourceID, syncMode, unsubscribeBroadcastEvent) {
|
|
22204
|
+
__publicField(this, "resource");
|
|
22205
|
+
__publicField(this, "resourceID");
|
|
22206
|
+
__publicField(this, "syncMode");
|
|
22207
|
+
__publicField(this, "changeEventReceived");
|
|
22208
|
+
__publicField(this, "lastHeartbeatTime");
|
|
22209
|
+
__publicField(this, "reconnectStreamDelay");
|
|
22210
|
+
__publicField(this, "cancelled");
|
|
22211
|
+
__publicField(this, "watchStream");
|
|
22212
|
+
__publicField(this, "watchLoopTimerID");
|
|
22213
|
+
__publicField(this, "watchAbortController");
|
|
22214
|
+
__publicField(this, "unsubscribeBroadcastEvent");
|
|
22215
|
+
this.reconnectStreamDelay = reconnectStreamDelay;
|
|
22216
|
+
this.resource = resource;
|
|
22217
|
+
this.resourceID = resourceID;
|
|
22218
|
+
this.syncMode = syncMode;
|
|
22219
|
+
this.changeEventReceived = syncMode !== void 0 ? false : void 0;
|
|
22220
|
+
this.lastHeartbeatTime = Date.now();
|
|
22221
|
+
this.cancelled = false;
|
|
22222
|
+
this.unsubscribeBroadcastEvent = unsubscribeBroadcastEvent;
|
|
22223
|
+
}
|
|
22224
|
+
/**
|
|
22225
|
+
* `changeSyncMode` changes the sync mode of the document.
|
|
22226
|
+
*/
|
|
22227
|
+
changeSyncMode(syncMode) {
|
|
22228
|
+
this.syncMode = syncMode;
|
|
22229
|
+
}
|
|
22230
|
+
/**
|
|
22231
|
+
* `needRealtimeSync` returns whether the resource needs to be synced in real time.
|
|
22232
|
+
* Only applicable to Document resources with syncMode defined.
|
|
22233
|
+
*/
|
|
22234
|
+
needRealtimeSync() {
|
|
22235
|
+
if (this.syncMode === SyncMode.RealtimeSyncOff) {
|
|
22236
|
+
return false;
|
|
22237
|
+
}
|
|
22238
|
+
if (this.syncMode === SyncMode.RealtimePushOnly) {
|
|
22239
|
+
return this.resource.hasLocalChanges();
|
|
22240
|
+
}
|
|
22241
|
+
return this.syncMode !== SyncMode.Manual && (this.resource.hasLocalChanges() || (this.changeEventReceived ?? false));
|
|
22242
|
+
}
|
|
22243
|
+
/**
|
|
22244
|
+
* `needSync` determines if the attachment needs sync.
|
|
22245
|
+
* This includes both document sync and presence heartbeat.
|
|
22246
|
+
*/
|
|
22247
|
+
needSync(heartbeatInterval) {
|
|
22248
|
+
if (this.resource instanceof Document) {
|
|
22249
|
+
return this.needRealtimeSync();
|
|
22250
|
+
}
|
|
22251
|
+
if (this.syncMode === SyncMode.Manual) {
|
|
22252
|
+
return false;
|
|
22253
|
+
}
|
|
22254
|
+
return Date.now() - this.lastHeartbeatTime >= heartbeatInterval;
|
|
22255
|
+
}
|
|
22256
|
+
/**
|
|
22257
|
+
* `updateHeartbeatTime` updates the last heartbeat time.
|
|
22258
|
+
*/
|
|
22259
|
+
updateHeartbeatTime() {
|
|
22260
|
+
this.lastHeartbeatTime = Date.now();
|
|
22261
|
+
}
|
|
22262
|
+
/**
|
|
22263
|
+
* `runWatchLoop` runs the watch loop.
|
|
22264
|
+
*/
|
|
22265
|
+
async runWatchLoop(watchStreamCreator) {
|
|
22266
|
+
const doLoop = async () => {
|
|
22267
|
+
if (this.watchStream) {
|
|
22268
|
+
return Promise.resolve();
|
|
22269
|
+
}
|
|
22270
|
+
if (this.watchLoopTimerID) {
|
|
22271
|
+
clearTimeout(this.watchLoopTimerID);
|
|
22272
|
+
this.watchLoopTimerID = void 0;
|
|
22273
|
+
}
|
|
22274
|
+
try {
|
|
22275
|
+
[this.watchStream, this.watchAbortController] = await watchStreamCreator(() => {
|
|
22276
|
+
this.watchStream = void 0;
|
|
22277
|
+
this.watchAbortController = void 0;
|
|
22278
|
+
if (!this.cancelled) {
|
|
22279
|
+
this.watchLoopTimerID = setTimeout(
|
|
22280
|
+
doLoop,
|
|
22281
|
+
this.reconnectStreamDelay
|
|
22282
|
+
);
|
|
22283
|
+
}
|
|
22284
|
+
});
|
|
22285
|
+
} catch {
|
|
22286
|
+
}
|
|
22287
|
+
};
|
|
22288
|
+
await doLoop();
|
|
22289
|
+
}
|
|
22290
|
+
/**
|
|
22291
|
+
* `cancelWatchStream` cancels the watch stream.
|
|
22292
|
+
*/
|
|
22293
|
+
cancelWatchStream() {
|
|
22294
|
+
this.cancelled = true;
|
|
22295
|
+
if (this.watchStream && this.watchAbortController) {
|
|
22296
|
+
this.watchAbortController.abort();
|
|
22297
|
+
this.watchStream = void 0;
|
|
22298
|
+
this.watchAbortController = void 0;
|
|
22299
|
+
}
|
|
22300
|
+
clearTimeout(this.watchLoopTimerID);
|
|
22301
|
+
this.watchLoopTimerID = void 0;
|
|
22302
|
+
}
|
|
22303
|
+
}
|
|
22170
22304
|
function createAuthInterceptor(apiKey, token) {
|
|
22171
22305
|
let currentToken = token;
|
|
22172
22306
|
const setToken = (token2) => {
|
|
@@ -22187,7 +22321,7 @@ function createAuthInterceptor(apiKey, token) {
|
|
|
22187
22321
|
};
|
|
22188
22322
|
}
|
|
22189
22323
|
const name$1 = "@yorkie-js/sdk";
|
|
22190
|
-
const version$1 = "0.6.
|
|
22324
|
+
const version$1 = "0.6.35";
|
|
22191
22325
|
const pkg$1 = {
|
|
22192
22326
|
name: name$1,
|
|
22193
22327
|
version: version$1
|
|
@@ -22509,7 +22643,7 @@ class Client {
|
|
|
22509
22643
|
*/
|
|
22510
22644
|
attach(resource, opts) {
|
|
22511
22645
|
if (resource instanceof Presence) {
|
|
22512
|
-
return this.attachPresence(resource);
|
|
22646
|
+
return this.attachPresence(resource, opts);
|
|
22513
22647
|
} else {
|
|
22514
22648
|
return this.attachDocument(resource, opts);
|
|
22515
22649
|
}
|
|
@@ -22674,7 +22808,7 @@ class Client {
|
|
|
22674
22808
|
* `attach` attaches the given presence counter to this client.
|
|
22675
22809
|
* It tells the server that this client will track the presence count.
|
|
22676
22810
|
*/
|
|
22677
|
-
async attachPresence(presence) {
|
|
22811
|
+
async attachPresence(presence, opts = {}) {
|
|
22678
22812
|
if (!this.isActive()) {
|
|
22679
22813
|
throw new YorkieError(
|
|
22680
22814
|
Code.ErrClientNotActivated,
|
|
@@ -22700,15 +22834,19 @@ class Client {
|
|
|
22700
22834
|
presence.setPresenceID(res.presenceId);
|
|
22701
22835
|
presence.updateCount(Number(res.count), 0);
|
|
22702
22836
|
presence.applyStatus(PresenceStatus.Attached);
|
|
22837
|
+
const syncMode = opts.isRealtime !== false ? "realtime" : "manual";
|
|
22703
22838
|
const attachment = new Attachment(
|
|
22704
22839
|
this.reconnectStreamDelay,
|
|
22705
22840
|
presence,
|
|
22706
|
-
res.presenceId
|
|
22841
|
+
res.presenceId,
|
|
22842
|
+
syncMode
|
|
22707
22843
|
);
|
|
22708
22844
|
this.attachmentMap.set(presence.getKey(), attachment);
|
|
22709
|
-
|
|
22845
|
+
if (syncMode === "realtime") {
|
|
22846
|
+
await this.runWatchLoop(presence.getKey());
|
|
22847
|
+
}
|
|
22710
22848
|
logger.info(
|
|
22711
|
-
`[AP] c:"${this.getKey()}" attaches p:"${presence.getKey()}" count:${presence.getCount()}`
|
|
22849
|
+
`[AP] c:"${this.getKey()}" attaches p:"${presence.getKey()}" mode:${syncMode} count:${presence.getCount()}`
|
|
22712
22850
|
);
|
|
22713
22851
|
return presence;
|
|
22714
22852
|
} catch (err) {
|
|
@@ -22796,23 +22934,39 @@ class Client {
|
|
|
22796
22934
|
return doc;
|
|
22797
22935
|
}
|
|
22798
22936
|
/**
|
|
22799
|
-
* `sync`
|
|
22800
|
-
* receives changes of the remote replica from the server then apply them to
|
|
22801
|
-
* local documents.
|
|
22937
|
+
* `sync` implementation that handles both Document and Presence.
|
|
22802
22938
|
*/
|
|
22803
|
-
sync(
|
|
22939
|
+
sync(resource) {
|
|
22804
22940
|
if (!this.isActive()) {
|
|
22805
22941
|
throw new YorkieError(
|
|
22806
22942
|
Code.ErrClientNotActivated,
|
|
22807
22943
|
`${this.key} is not active`
|
|
22808
22944
|
);
|
|
22809
22945
|
}
|
|
22810
|
-
if (
|
|
22811
|
-
const attachment = this.attachmentMap.get(
|
|
22946
|
+
if (resource instanceof Presence) {
|
|
22947
|
+
const attachment = this.attachmentMap.get(
|
|
22948
|
+
resource.getKey()
|
|
22949
|
+
);
|
|
22950
|
+
if (!attachment) {
|
|
22951
|
+
throw new YorkieError(
|
|
22952
|
+
Code.ErrDocumentNotAttached,
|
|
22953
|
+
`${resource.getKey()} is not attached`
|
|
22954
|
+
);
|
|
22955
|
+
}
|
|
22956
|
+
return this.enqueueTask(async () => {
|
|
22957
|
+
return this.syncInternal(attachment).catch(async (err) => {
|
|
22958
|
+
logger.error(`[SY] c:"${this.getKey()}" err :`, err);
|
|
22959
|
+
await this.handleConnectError(err);
|
|
22960
|
+
throw err;
|
|
22961
|
+
});
|
|
22962
|
+
});
|
|
22963
|
+
}
|
|
22964
|
+
if (resource instanceof Document) {
|
|
22965
|
+
const attachment = this.attachmentMap.get(resource.getKey());
|
|
22812
22966
|
if (!attachment) {
|
|
22813
22967
|
throw new YorkieError(
|
|
22814
22968
|
Code.ErrDocumentNotAttached,
|
|
22815
|
-
`${
|
|
22969
|
+
`${resource.getKey()} is not attached`
|
|
22816
22970
|
);
|
|
22817
22971
|
}
|
|
22818
22972
|
return this.enqueueTask(async () => {
|
|
@@ -23334,7 +23488,7 @@ class Client {
|
|
|
23334
23488
|
const { resource } = attachment;
|
|
23335
23489
|
if (resource instanceof Presence) {
|
|
23336
23490
|
try {
|
|
23337
|
-
await this.rpcClient.refreshPresence(
|
|
23491
|
+
const res = await this.rpcClient.refreshPresence(
|
|
23338
23492
|
{
|
|
23339
23493
|
clientId: this.id,
|
|
23340
23494
|
presenceId: resource.getPresenceID(),
|
|
@@ -23346,9 +23500,10 @@ class Client {
|
|
|
23346
23500
|
}
|
|
23347
23501
|
}
|
|
23348
23502
|
);
|
|
23503
|
+
resource.updateCount(Number(res.count), 0);
|
|
23349
23504
|
attachment.updateHeartbeatTime();
|
|
23350
23505
|
logger.debug(
|
|
23351
|
-
`[RP] c:"${this.getKey()}" refreshes p:"${resource.getKey()}"`
|
|
23506
|
+
`[RP] c:"${this.getKey()}" refreshes p:"${resource.getKey()}" mode:${attachment.syncMode}`
|
|
23352
23507
|
);
|
|
23353
23508
|
} catch (err) {
|
|
23354
23509
|
logger.error(`[RP] c:"${this.getKey()}" err :`, err);
|
|
@@ -23482,7 +23637,7 @@ if (typeof globalThis !== "undefined") {
|
|
|
23482
23637
|
};
|
|
23483
23638
|
}
|
|
23484
23639
|
const name = "@yorkie-js/react";
|
|
23485
|
-
const version = "0.6.
|
|
23640
|
+
const version = "0.6.35";
|
|
23486
23641
|
const pkg = {
|
|
23487
23642
|
name,
|
|
23488
23643
|
version
|