@yorkie-js/react 0.6.11-rc → 0.6.13

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.
@@ -5,7 +5,7 @@ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { createContext, useMemo, useState, useEffect, useContext, useCallback } from "react";
7
7
  const name$1 = "@yorkie-js/react";
8
- const version$1 = "0.6.11-rc";
8
+ const version$1 = "0.6.13";
9
9
  const pkg$1 = {
10
10
  name: name$1,
11
11
  version: version$1
@@ -6090,15 +6090,39 @@ const _Project = class _Project extends Message {
6090
6090
  */
6091
6091
  __publicField(this, "authWebhookMethods", []);
6092
6092
  /**
6093
- * @generated from field: string client_deactivate_threshold = 7;
6093
+ * @generated from field: string event_webhook_url = 7;
6094
+ */
6095
+ __publicField(this, "eventWebhookUrl", "");
6096
+ /**
6097
+ * @generated from field: repeated string event_webhook_events = 8;
6098
+ */
6099
+ __publicField(this, "eventWebhookEvents", []);
6100
+ /**
6101
+ * @generated from field: string client_deactivate_threshold = 9;
6094
6102
  */
6095
6103
  __publicField(this, "clientDeactivateThreshold", "");
6096
6104
  /**
6097
- * @generated from field: google.protobuf.Timestamp created_at = 8;
6105
+ * @generated from field: int32 max_subscribers_per_document = 10;
6106
+ */
6107
+ __publicField(this, "maxSubscribersPerDocument", 0);
6108
+ /**
6109
+ * @generated from field: int32 max_attachments_per_document = 11;
6110
+ */
6111
+ __publicField(this, "maxAttachmentsPerDocument", 0);
6112
+ /**
6113
+ * @generated from field: int32 max_size_per_document = 15;
6114
+ */
6115
+ __publicField(this, "maxSizePerDocument", 0);
6116
+ /**
6117
+ * @generated from field: repeated string allowed_origins = 14;
6118
+ */
6119
+ __publicField(this, "allowedOrigins", []);
6120
+ /**
6121
+ * @generated from field: google.protobuf.Timestamp created_at = 12;
6098
6122
  */
6099
6123
  __publicField(this, "createdAt");
6100
6124
  /**
6101
- * @generated from field: google.protobuf.Timestamp updated_at = 9;
6125
+ * @generated from field: google.protobuf.Timestamp updated_at = 13;
6102
6126
  */
6103
6127
  __publicField(this, "updatedAt");
6104
6128
  proto3.util.initPartial(data, this);
@@ -6157,13 +6181,43 @@ __publicField(_Project, "fields", proto3.util.newFieldList(() => [
6157
6181
  { no: 6, name: "auth_webhook_methods", kind: "scalar", T: 9, repeated: true },
6158
6182
  {
6159
6183
  no: 7,
6184
+ name: "event_webhook_url",
6185
+ kind: "scalar",
6186
+ T: 9
6187
+ /* ScalarType.STRING */
6188
+ },
6189
+ { no: 8, name: "event_webhook_events", kind: "scalar", T: 9, repeated: true },
6190
+ {
6191
+ no: 9,
6160
6192
  name: "client_deactivate_threshold",
6161
6193
  kind: "scalar",
6162
6194
  T: 9
6163
6195
  /* ScalarType.STRING */
6164
6196
  },
6165
- { no: 8, name: "created_at", kind: "message", T: Timestamp },
6166
- { no: 9, name: "updated_at", kind: "message", T: Timestamp }
6197
+ {
6198
+ no: 10,
6199
+ name: "max_subscribers_per_document",
6200
+ kind: "scalar",
6201
+ T: 5
6202
+ /* ScalarType.INT32 */
6203
+ },
6204
+ {
6205
+ no: 11,
6206
+ name: "max_attachments_per_document",
6207
+ kind: "scalar",
6208
+ T: 5
6209
+ /* ScalarType.INT32 */
6210
+ },
6211
+ {
6212
+ no: 15,
6213
+ name: "max_size_per_document",
6214
+ kind: "scalar",
6215
+ T: 5
6216
+ /* ScalarType.INT32 */
6217
+ },
6218
+ { no: 14, name: "allowed_origins", kind: "scalar", T: 9, repeated: true },
6219
+ { no: 12, name: "created_at", kind: "message", T: Timestamp },
6220
+ { no: 13, name: "updated_at", kind: "message", T: Timestamp }
6167
6221
  ]));
6168
6222
  let Project = _Project;
6169
6223
  const _UpdatableProjectFields = class _UpdatableProjectFields extends Message {
@@ -6182,9 +6236,33 @@ const _UpdatableProjectFields = class _UpdatableProjectFields extends Message {
6182
6236
  */
6183
6237
  __publicField(this, "authWebhookMethods");
6184
6238
  /**
6185
- * @generated from field: google.protobuf.StringValue client_deactivate_threshold = 4;
6239
+ * @generated from field: google.protobuf.StringValue event_webhook_url = 4;
6240
+ */
6241
+ __publicField(this, "eventWebhookUrl");
6242
+ /**
6243
+ * @generated from field: yorkie.v1.UpdatableProjectFields.EventWebhookEvents event_webhook_events = 5;
6244
+ */
6245
+ __publicField(this, "eventWebhookEvents");
6246
+ /**
6247
+ * @generated from field: google.protobuf.StringValue client_deactivate_threshold = 6;
6186
6248
  */
6187
6249
  __publicField(this, "clientDeactivateThreshold");
6250
+ /**
6251
+ * @generated from field: google.protobuf.Int32Value max_subscribers_per_document = 7;
6252
+ */
6253
+ __publicField(this, "maxSubscribersPerDocument");
6254
+ /**
6255
+ * @generated from field: google.protobuf.Int32Value max_attachments_per_document = 8;
6256
+ */
6257
+ __publicField(this, "maxAttachmentsPerDocument");
6258
+ /**
6259
+ * @generated from field: google.protobuf.Int32Value max_size_per_document = 10;
6260
+ */
6261
+ __publicField(this, "maxSizePerDocument");
6262
+ /**
6263
+ * @generated from field: yorkie.v1.UpdatableProjectFields.AllowedOrigins allowed_origins = 9;
6264
+ */
6265
+ __publicField(this, "allowedOrigins");
6188
6266
  proto3.util.initPartial(data, this);
6189
6267
  }
6190
6268
  static fromBinary(bytes, options) {
@@ -6206,7 +6284,13 @@ __publicField(_UpdatableProjectFields, "fields", proto3.util.newFieldList(() =>
6206
6284
  { no: 1, name: "name", kind: "message", T: StringValue },
6207
6285
  { no: 2, name: "auth_webhook_url", kind: "message", T: StringValue },
6208
6286
  { no: 3, name: "auth_webhook_methods", kind: "message", T: UpdatableProjectFields_AuthWebhookMethods },
6209
- { no: 4, name: "client_deactivate_threshold", kind: "message", T: StringValue }
6287
+ { no: 4, name: "event_webhook_url", kind: "message", T: StringValue },
6288
+ { no: 5, name: "event_webhook_events", kind: "message", T: UpdatableProjectFields_EventWebhookEvents },
6289
+ { no: 6, name: "client_deactivate_threshold", kind: "message", T: StringValue },
6290
+ { no: 7, name: "max_subscribers_per_document", kind: "message", T: Int32Value },
6291
+ { no: 8, name: "max_attachments_per_document", kind: "message", T: Int32Value },
6292
+ { no: 10, name: "max_size_per_document", kind: "message", T: Int32Value },
6293
+ { no: 9, name: "allowed_origins", kind: "message", T: UpdatableProjectFields_AllowedOrigins }
6210
6294
  ]));
6211
6295
  let UpdatableProjectFields = _UpdatableProjectFields;
6212
6296
  const _UpdatableProjectFields_AuthWebhookMethods = class _UpdatableProjectFields_AuthWebhookMethods extends Message {
@@ -6237,6 +6321,62 @@ __publicField(_UpdatableProjectFields_AuthWebhookMethods, "fields", proto3.util.
6237
6321
  { no: 1, name: "methods", kind: "scalar", T: 9, repeated: true }
6238
6322
  ]));
6239
6323
  let UpdatableProjectFields_AuthWebhookMethods = _UpdatableProjectFields_AuthWebhookMethods;
6324
+ const _UpdatableProjectFields_EventWebhookEvents = class _UpdatableProjectFields_EventWebhookEvents extends Message {
6325
+ constructor(data) {
6326
+ super();
6327
+ /**
6328
+ * @generated from field: repeated string events = 1;
6329
+ */
6330
+ __publicField(this, "events", []);
6331
+ proto3.util.initPartial(data, this);
6332
+ }
6333
+ static fromBinary(bytes, options) {
6334
+ return new _UpdatableProjectFields_EventWebhookEvents().fromBinary(bytes, options);
6335
+ }
6336
+ static fromJson(jsonValue, options) {
6337
+ return new _UpdatableProjectFields_EventWebhookEvents().fromJson(jsonValue, options);
6338
+ }
6339
+ static fromJsonString(jsonString, options) {
6340
+ return new _UpdatableProjectFields_EventWebhookEvents().fromJsonString(jsonString, options);
6341
+ }
6342
+ static equals(a, b) {
6343
+ return proto3.util.equals(_UpdatableProjectFields_EventWebhookEvents, a, b);
6344
+ }
6345
+ };
6346
+ __publicField(_UpdatableProjectFields_EventWebhookEvents, "runtime", proto3);
6347
+ __publicField(_UpdatableProjectFields_EventWebhookEvents, "typeName", "yorkie.v1.UpdatableProjectFields.EventWebhookEvents");
6348
+ __publicField(_UpdatableProjectFields_EventWebhookEvents, "fields", proto3.util.newFieldList(() => [
6349
+ { no: 1, name: "events", kind: "scalar", T: 9, repeated: true }
6350
+ ]));
6351
+ let UpdatableProjectFields_EventWebhookEvents = _UpdatableProjectFields_EventWebhookEvents;
6352
+ const _UpdatableProjectFields_AllowedOrigins = class _UpdatableProjectFields_AllowedOrigins extends Message {
6353
+ constructor(data) {
6354
+ super();
6355
+ /**
6356
+ * @generated from field: repeated string origins = 1;
6357
+ */
6358
+ __publicField(this, "origins", []);
6359
+ proto3.util.initPartial(data, this);
6360
+ }
6361
+ static fromBinary(bytes, options) {
6362
+ return new _UpdatableProjectFields_AllowedOrigins().fromBinary(bytes, options);
6363
+ }
6364
+ static fromJson(jsonValue, options) {
6365
+ return new _UpdatableProjectFields_AllowedOrigins().fromJson(jsonValue, options);
6366
+ }
6367
+ static fromJsonString(jsonString, options) {
6368
+ return new _UpdatableProjectFields_AllowedOrigins().fromJsonString(jsonString, options);
6369
+ }
6370
+ static equals(a, b) {
6371
+ return proto3.util.equals(_UpdatableProjectFields_AllowedOrigins, a, b);
6372
+ }
6373
+ };
6374
+ __publicField(_UpdatableProjectFields_AllowedOrigins, "runtime", proto3);
6375
+ __publicField(_UpdatableProjectFields_AllowedOrigins, "typeName", "yorkie.v1.UpdatableProjectFields.AllowedOrigins");
6376
+ __publicField(_UpdatableProjectFields_AllowedOrigins, "fields", proto3.util.newFieldList(() => [
6377
+ { no: 1, name: "origins", kind: "scalar", T: 9, repeated: true }
6378
+ ]));
6379
+ let UpdatableProjectFields_AllowedOrigins = _UpdatableProjectFields_AllowedOrigins;
6240
6380
  const _DocumentSummary = class _DocumentSummary extends Message {
6241
6381
  constructor(data) {
6242
6382
  super();
@@ -6793,6 +6933,10 @@ const _AttachDocumentResponse = class _AttachDocumentResponse extends Message {
6793
6933
  * @generated from field: string document_id = 1;
6794
6934
  */
6795
6935
  __publicField(this, "documentId", "");
6936
+ /**
6937
+ * @generated from field: int32 max_size_per_document = 3;
6938
+ */
6939
+ __publicField(this, "maxSizePerDocument", 0);
6796
6940
  /**
6797
6941
  * @generated from field: yorkie.v1.ChangePack change_pack = 2;
6798
6942
  */
@@ -6822,6 +6966,13 @@ __publicField(_AttachDocumentResponse, "fields", proto3.util.newFieldList(() =>
6822
6966
  T: 9
6823
6967
  /* ScalarType.STRING */
6824
6968
  },
6969
+ {
6970
+ no: 3,
6971
+ name: "max_size_per_document",
6972
+ kind: "scalar",
6973
+ T: 5
6974
+ /* ScalarType.INT32 */
6975
+ },
6825
6976
  { no: 2, name: "change_pack", kind: "message", T: ChangePack$1 }
6826
6977
  ]));
6827
6978
  let AttachDocumentResponse = _AttachDocumentResponse;
@@ -7592,6 +7743,7 @@ var Code = /* @__PURE__ */ ((Code2) => {
7592
7743
  Code2["ErrDocumentNotAttached"] = "ErrDocumentNotAttached";
7593
7744
  Code2["ErrDocumentNotDetached"] = "ErrDocumentNotDetached";
7594
7745
  Code2["ErrDocumentRemoved"] = "ErrDocumentRemoved";
7746
+ Code2["ErrDocumentSizeExceedsLimit"] = "ErrDocumentSizeExceedsLimit";
7595
7747
  Code2["ErrInvalidObjectKey"] = "ErrInvalidObjectKey";
7596
7748
  Code2["ErrInvalidArgument"] = "ErrInvalidArgument";
7597
7749
  Code2["ErrNotInitialized"] = "ErrNotInitialized";
@@ -7614,76 +7766,11 @@ class YorkieError extends Error {
7614
7766
  this.toString = () => `[code=${this.code}]: ${this.message}`;
7615
7767
  }
7616
7768
  }
7617
- function deepcopy(object) {
7618
- if (object instanceof Map) {
7619
- const pairs = Array.from(object);
7620
- return new Map(JSON.parse(JSON.stringify(pairs)));
7621
- }
7622
- return JSON.parse(JSON.stringify(object));
7623
- }
7624
- const isEmpty = (object) => {
7625
- if (!object) {
7626
- return true;
7627
- }
7628
- return Object.entries(object).length === 0;
7629
- };
7630
- const stringifyObjectValues = (attributes) => {
7631
- const attrs = {};
7632
- for (const [key, value] of Object.entries(attributes)) {
7633
- attrs[key] = JSON.stringify(value);
7634
- }
7635
- return attrs;
7636
- };
7637
- const parseObjectValues = (attrs) => {
7638
- const attributes = {};
7639
- for (const [key, value] of Object.entries(attrs)) {
7640
- attributes[key] = JSON.parse(value);
7641
- }
7642
- return attributes;
7643
- };
7644
7769
  var PresenceChangeType = /* @__PURE__ */ ((PresenceChangeType2) => {
7645
7770
  PresenceChangeType2["Put"] = "put";
7646
7771
  PresenceChangeType2["Clear"] = "clear";
7647
7772
  return PresenceChangeType2;
7648
7773
  })(PresenceChangeType || {});
7649
- class Presence {
7650
- constructor(changeContext, presence) {
7651
- __publicField(this, "context");
7652
- __publicField(this, "presence");
7653
- this.context = changeContext;
7654
- this.presence = presence;
7655
- }
7656
- /**
7657
- * `set` updates the presence based on the partial presence.
7658
- */
7659
- set(presence, option) {
7660
- for (const key of Object.keys(presence)) {
7661
- this.presence[key] = presence[key];
7662
- }
7663
- this.context.setPresenceChange({
7664
- type: "put",
7665
- presence: deepcopy(this.presence)
7666
- });
7667
- this.context.setReversePresence(presence, option);
7668
- }
7669
- /**
7670
- * `get` returns the presence value of the given key.
7671
- */
7672
- get(key) {
7673
- return this.presence[key];
7674
- }
7675
- /**
7676
- * `clear` clears the presence.
7677
- * @internal
7678
- */
7679
- clear() {
7680
- this.presence = {};
7681
- this.context.setPresenceChange({
7682
- type: "clear"
7683
- /* Clear */
7684
- });
7685
- }
7686
- }
7687
7774
  const InitialActorID = "000000000000000000000000";
7688
7775
  const TimeTicketSize = 8 + 4 + 12;
7689
7776
  class TimeTicket {
@@ -7799,10 +7886,11 @@ class TimeTicket {
7799
7886
  return 0;
7800
7887
  }
7801
7888
  }
7889
+ const InitialLamport = 0n;
7802
7890
  const InitialDelimiter = 0;
7803
7891
  const MaxLamport = 9223372036854775807n;
7804
7892
  const InitialTimeTicket = new TimeTicket(
7805
- 0n,
7893
+ InitialLamport,
7806
7894
  InitialDelimiter,
7807
7895
  InitialActorID
7808
7896
  );
@@ -11013,6 +11101,50 @@ class RHT {
11013
11101
  this.numberOfRemovedElement--;
11014
11102
  }
11015
11103
  }
11104
+ function deepcopy(object) {
11105
+ if (object instanceof Map) {
11106
+ const pairs = Array.from(object);
11107
+ return new Map(JSON.parse(JSON.stringify(pairs)));
11108
+ }
11109
+ return JSON.parse(JSON.stringify(object));
11110
+ }
11111
+ const isEmpty = (object) => {
11112
+ if (!object) {
11113
+ return true;
11114
+ }
11115
+ return Object.entries(object).length === 0;
11116
+ };
11117
+ const stringifyObjectValues = (attributes) => {
11118
+ const attrs = {};
11119
+ for (const [key, value] of Object.entries(attributes)) {
11120
+ attrs[key] = JSON.stringify(value);
11121
+ }
11122
+ return attrs;
11123
+ };
11124
+ const parseObjectValues = (attrs) => {
11125
+ const attributes = {};
11126
+ for (const [key, value] of Object.entries(attrs)) {
11127
+ attributes[key] = JSON.parse(value);
11128
+ }
11129
+ return attributes;
11130
+ };
11131
+ function totalDocSize(d) {
11132
+ if (!d) return 0;
11133
+ return totalDataSize(d.live) + totalDataSize(d.gc);
11134
+ }
11135
+ function totalDataSize(d) {
11136
+ return d.data + d.meta;
11137
+ }
11138
+ function addDataSizes(target, ...others) {
11139
+ for (const other of others) {
11140
+ target.data += other.data;
11141
+ target.meta += other.meta;
11142
+ }
11143
+ }
11144
+ function subDataSize(target, other) {
11145
+ target.data -= other.data;
11146
+ target.meta -= other.meta;
11147
+ }
11016
11148
  class CRDTTextValue {
11017
11149
  constructor(content) {
11018
11150
  __publicField(this, "attributes");
@@ -11148,7 +11280,7 @@ class CRDTText extends CRDTElement {
11148
11280
  crdtTextValue.setAttr(k, v, editedAt);
11149
11281
  }
11150
11282
  }
11151
- const [caretPos, pairs, valueChanges] = this.rgaTreeSplit.edit(
11283
+ const [caretPos, pairs, diff, valueChanges] = this.rgaTreeSplit.edit(
11152
11284
  range,
11153
11285
  editedAt,
11154
11286
  crdtTextValue,
@@ -11166,7 +11298,7 @@ class CRDTText extends CRDTElement {
11166
11298
  type: "content"
11167
11299
  /* Content */
11168
11300
  }));
11169
- return [changes, pairs, [caretPos, caretPos]];
11301
+ return [changes, pairs, diff, [caretPos, caretPos]];
11170
11302
  }
11171
11303
  /**
11172
11304
  * `setStyle` applies the style of the given range.
@@ -11179,11 +11311,16 @@ class CRDTText extends CRDTElement {
11179
11311
  * @internal
11180
11312
  */
11181
11313
  setStyle(range, attributes, editedAt, versionVector) {
11182
- const [, toRight] = this.rgaTreeSplit.findNodeWithSplit(range[1], editedAt);
11183
- const [, fromRight] = this.rgaTreeSplit.findNodeWithSplit(
11314
+ const diff = { data: 0, meta: 0 };
11315
+ const [, diffTo, toRight] = this.rgaTreeSplit.findNodeWithSplit(
11316
+ range[1],
11317
+ editedAt
11318
+ );
11319
+ const [, diffFrom, fromRight] = this.rgaTreeSplit.findNodeWithSplit(
11184
11320
  range[0],
11185
11321
  editedAt
11186
11322
  );
11323
+ addDataSizes(diff, diffTo, diffFrom);
11187
11324
  const changes = [];
11188
11325
  const nodes = this.rgaTreeSplit.findBetween(fromRight, toRight);
11189
11326
  const toBeStyleds = [];
@@ -11219,9 +11356,13 @@ class CRDTText extends CRDTElement {
11219
11356
  if (prev !== void 0) {
11220
11357
  pairs.push({ parent: node.getValue(), child: prev });
11221
11358
  }
11359
+ const curr = node.getValue().getAttrs().getNodeMapByKey().get(key);
11360
+ if (curr !== void 0) {
11361
+ addDataSizes(diff, curr.getDataSize());
11362
+ }
11222
11363
  }
11223
11364
  }
11224
- return [pairs, changes];
11365
+ return [pairs, diff, changes];
11225
11366
  }
11226
11367
  /**
11227
11368
  * `indexRangeToPosRange` returns the position range of the given index range.
@@ -11410,13 +11551,14 @@ class EditOperation extends Operation {
11410
11551
  );
11411
11552
  }
11412
11553
  const text = parentObject;
11413
- const [changes, pairs] = text.edit(
11554
+ const [changes, pairs, diff] = text.edit(
11414
11555
  [this.fromPos, this.toPos],
11415
11556
  this.content,
11416
11557
  this.getExecutedAt(),
11417
11558
  Object.fromEntries(this.attributes),
11418
11559
  versionVector
11419
11560
  );
11561
+ root.acc(diff);
11420
11562
  for (const pair of pairs) {
11421
11563
  root.registerGCPair(pair);
11422
11564
  }
@@ -11513,12 +11655,13 @@ class StyleOperation extends Operation {
11513
11655
  );
11514
11656
  }
11515
11657
  const text = parentObject;
11516
- const [pairs, changes] = text.setStyle(
11658
+ const [pairs, diff, changes] = text.setStyle(
11517
11659
  [this.fromPos, this.toPos],
11518
11660
  this.attributes ? Object.fromEntries(this.attributes) : {},
11519
11661
  this.getExecutedAt(),
11520
11662
  versionVector
11521
11663
  );
11664
+ root.acc(diff);
11522
11665
  for (const pair of pairs) {
11523
11666
  root.registerGCPair(pair);
11524
11667
  }
@@ -11672,19 +11815,23 @@ class IndexTreeNode {
11672
11815
  * `splitText` splits the given node at the given offset.
11673
11816
  */
11674
11817
  splitText(offset, absOffset) {
11818
+ const diff = { data: 0, meta: 0 };
11675
11819
  if (offset === 0 || offset === this.size) {
11676
- return;
11820
+ return [void 0, diff];
11677
11821
  }
11678
11822
  const leftValue = this.value.slice(0, offset);
11679
11823
  const rightValue = this.value.slice(offset);
11680
11824
  if (!rightValue.length) {
11681
- return;
11825
+ return [void 0, diff];
11682
11826
  }
11827
+ const prvSize = this.getDataSize();
11683
11828
  this.value = leftValue;
11684
11829
  const rightNode = this.cloneText(offset + absOffset);
11685
11830
  rightNode.value = rightValue;
11686
11831
  this.parent.insertAfterInternal(rightNode, this);
11687
- return rightNode;
11832
+ addDataSizes(diff, this.getDataSize(), rightNode.getDataSize());
11833
+ subDataSize(diff, prvSize);
11834
+ return [rightNode, diff];
11688
11835
  }
11689
11836
  /**
11690
11837
  * `children` returns the children of the node.
@@ -11799,6 +11946,8 @@ class IndexTreeNode {
11799
11946
  * `splitElement` splits the given element at the given offset.
11800
11947
  */
11801
11948
  splitElement(offset, issueTimeTicket) {
11949
+ const diff = { data: 0, meta: 0 };
11950
+ const prvSize = this.getDataSize();
11802
11951
  const clone = this.cloneElement(issueTimeTicket);
11803
11952
  this.parent.insertAfterInternal(clone, this);
11804
11953
  clone.updateAncestorsSize();
@@ -11817,7 +11966,9 @@ class IndexTreeNode {
11817
11966
  for (const child of clone._children) {
11818
11967
  child.parent = clone;
11819
11968
  }
11820
- return clone;
11969
+ addDataSizes(diff, this.getDataSize(), clone.getDataSize());
11970
+ subDataSize(diff, prvSize);
11971
+ return [clone, diff];
11821
11972
  }
11822
11973
  /**
11823
11974
  * `insertAfterInternal` inserts the given node after the given child.
@@ -12810,7 +12961,7 @@ class CRDTTreeNode extends IndexTreeNode {
12810
12961
  * `split` splits the given offset of this node.
12811
12962
  */
12812
12963
  split(tree, offset, issueTimeTicket) {
12813
- const split = this.isText ? this.splitText(offset, this.id.getOffset()) : this.splitElement(offset, issueTimeTicket);
12964
+ const [split, diff] = this.isText ? this.splitText(offset, this.id.getOffset()) : this.splitElement(offset, issueTimeTicket);
12814
12965
  if (split) {
12815
12966
  split.insPrevID = this.id;
12816
12967
  if (this.insNextID) {
@@ -12821,7 +12972,7 @@ class CRDTTreeNode extends IndexTreeNode {
12821
12972
  this.insNextID = split.id;
12822
12973
  tree.registerNode(split);
12823
12974
  }
12824
- return split;
12975
+ return [split, diff];
12825
12976
  }
12826
12977
  /**
12827
12978
  * `getCreatedAt` returns the creation time of this element.
@@ -13012,15 +13163,17 @@ class CRDTTree extends CRDTElement {
13012
13163
  * for concurrent insertion.
13013
13164
  */
13014
13165
  findNodesAndSplitText(pos, editedAt) {
13166
+ let diff = { data: 0, meta: 0 };
13015
13167
  const [parent, leftSibling] = pos.toTreeNodePair(this);
13016
13168
  let leftNode = leftSibling;
13017
13169
  const isLeftMost = parent === leftNode;
13018
13170
  const realParent = leftNode.parent && !isLeftMost ? leftNode.parent : parent;
13019
13171
  if (leftNode.isText) {
13020
- leftNode.split(
13172
+ const [, splitedDiff] = leftNode.split(
13021
13173
  this,
13022
13174
  pos.getLeftSiblingID().getOffset() - leftNode.id.getOffset()
13023
13175
  );
13176
+ diff = splitedDiff;
13024
13177
  }
13025
13178
  if (editedAt) {
13026
13179
  const allChildren = realParent.allChildren;
@@ -13033,17 +13186,22 @@ class CRDTTree extends CRDTElement {
13033
13186
  leftNode = next;
13034
13187
  }
13035
13188
  }
13036
- return [realParent, leftNode];
13189
+ return [[realParent, leftNode], diff];
13037
13190
  }
13038
13191
  /**
13039
13192
  * `style` applies the given attributes of the given range.
13040
13193
  */
13041
13194
  style(range, attributes, editedAt, versionVector) {
13042
- const [fromParent, fromLeft] = this.findNodesAndSplitText(
13195
+ const diff = { data: 0, meta: 0 };
13196
+ const [[fromParent, fromLeft], diffFrom] = this.findNodesAndSplitText(
13043
13197
  range[0],
13044
13198
  editedAt
13045
13199
  );
13046
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1], editedAt);
13200
+ const [[toParent, toLeft], diffTo] = this.findNodesAndSplitText(
13201
+ range[1],
13202
+ editedAt
13203
+ );
13204
+ addDataSizes(diff, diffTo, diffFrom);
13047
13205
  const changes = [];
13048
13206
  const attrs = attributes ? parseObjectValues(attributes) : {};
13049
13207
  const pairs = [];
@@ -13052,7 +13210,8 @@ class CRDTTree extends CRDTElement {
13052
13210
  fromLeft,
13053
13211
  toParent,
13054
13212
  toLeft,
13055
- ([node]) => {
13213
+ ([node, tokenType]) => {
13214
+ var _a2;
13056
13215
  const actorID = node.getCreatedAt().getActorID();
13057
13216
  let clientLamportAtChange = MaxLamport;
13058
13217
  if (versionVector != void 0) {
@@ -13088,20 +13247,31 @@ class CRDTTree extends CRDTElement {
13088
13247
  pairs.push({ parent: node, child: prev });
13089
13248
  }
13090
13249
  }
13250
+ for (const [key] of Object.entries(attrs)) {
13251
+ const curr = (_a2 = node.attrs) == null ? void 0 : _a2.getNodeMapByKey().get(key);
13252
+ if (curr !== void 0 && tokenType !== TokenType.End) {
13253
+ addDataSizes(diff, curr.getDataSize());
13254
+ }
13255
+ }
13091
13256
  }
13092
13257
  }
13093
13258
  );
13094
- return [pairs, changes];
13259
+ return [pairs, changes, diff];
13095
13260
  }
13096
13261
  /**
13097
13262
  * `removeStyle` removes the given attributes of the given range.
13098
13263
  */
13099
13264
  removeStyle(range, attributesToRemove, editedAt, versionVector) {
13100
- const [fromParent, fromLeft] = this.findNodesAndSplitText(
13265
+ const diff = { data: 0, meta: 0 };
13266
+ const [[fromParent, fromLeft], diffFrom] = this.findNodesAndSplitText(
13101
13267
  range[0],
13102
13268
  editedAt
13103
13269
  );
13104
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1], editedAt);
13270
+ const [[toParent, toLeft], diffTo] = this.findNodesAndSplitText(
13271
+ range[1],
13272
+ editedAt
13273
+ );
13274
+ addDataSizes(diff, diffTo, diffFrom);
13105
13275
  const changes = [];
13106
13276
  const pairs = [];
13107
13277
  this.traverseInPosRange(
@@ -13139,18 +13309,23 @@ class CRDTTree extends CRDTElement {
13139
13309
  }
13140
13310
  }
13141
13311
  );
13142
- return [pairs, changes];
13312
+ return [pairs, changes, diff];
13143
13313
  }
13144
13314
  /**
13145
13315
  * `edit` edits the tree with the given range and content.
13146
13316
  * If the content is undefined, the range will be removed.
13147
13317
  */
13148
13318
  edit(range, contents, splitLevel, editedAt, issueTimeTicket, versionVector) {
13149
- const [fromParent, fromLeft] = this.findNodesAndSplitText(
13319
+ const diff = { data: 0, meta: 0 };
13320
+ const [[fromParent, fromLeft], diffFrom] = this.findNodesAndSplitText(
13150
13321
  range[0],
13151
13322
  editedAt
13152
13323
  );
13153
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1], editedAt);
13324
+ const [[toParent, toLeft], diffTo] = this.findNodesAndSplitText(
13325
+ range[1],
13326
+ editedAt
13327
+ );
13328
+ addDataSizes(diff, diffTo, diffFrom);
13154
13329
  const fromIdx = this.toIndex(fromParent, fromLeft);
13155
13330
  const fromPath = this.toPath(fromParent, fromLeft);
13156
13331
  const nodesToBeRemoved = [];
@@ -13229,6 +13404,8 @@ class CRDTTree extends CRDTElement {
13229
13404
  if (fromParent.isRemoved) {
13230
13405
  node.remove(editedAt);
13231
13406
  pairs.push({ parent: this, child: node });
13407
+ } else {
13408
+ addDataSizes(diff, node.getDataSize());
13232
13409
  }
13233
13410
  this.nodeMapByID.put(node.id, node);
13234
13411
  });
@@ -13253,7 +13430,7 @@ class CRDTTree extends CRDTElement {
13253
13430
  }
13254
13431
  }
13255
13432
  }
13256
- return [changes, pairs];
13433
+ return [changes, pairs, diff];
13257
13434
  }
13258
13435
  /**
13259
13436
  * `editT` edits the given range with the given value.
@@ -13532,16 +13709,16 @@ class CRDTTree extends CRDTElement {
13532
13709
  * `posRangeToPathRange` converts the given position range to the path range.
13533
13710
  */
13534
13711
  posRangeToPathRange(range) {
13535
- const [fromParent, fromLeft] = this.findNodesAndSplitText(range[0]);
13536
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1]);
13712
+ const [[fromParent, fromLeft]] = this.findNodesAndSplitText(range[0]);
13713
+ const [[toParent, toLeft]] = this.findNodesAndSplitText(range[1]);
13537
13714
  return [this.toPath(fromParent, fromLeft), this.toPath(toParent, toLeft)];
13538
13715
  }
13539
13716
  /**
13540
13717
  * `posRangeToIndexRange` converts the given position range to the path range.
13541
13718
  */
13542
13719
  posRangeToIndexRange(range) {
13543
- const [fromParent, fromLeft] = this.findNodesAndSplitText(range[0]);
13544
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1]);
13720
+ const [[fromParent, fromLeft]] = this.findNodesAndSplitText(range[0]);
13721
+ const [[toParent, toLeft]] = this.findNodesAndSplitText(range[1]);
13545
13722
  return [this.toIndex(fromParent, fromLeft), this.toIndex(toParent, toLeft)];
13546
13723
  }
13547
13724
  /**
@@ -13736,7 +13913,7 @@ class TreeEditOperation extends Operation {
13736
13913
  }
13737
13914
  const editedAt = this.getExecutedAt();
13738
13915
  const tree = parentObject;
13739
- const [changes, pairs] = tree.edit(
13916
+ const [changes, pairs, diff] = tree.edit(
13740
13917
  [this.fromPos, this.toPos],
13741
13918
  (_a2 = this.contents) == null ? void 0 : _a2.map((content) => content.deepcopy()),
13742
13919
  this.splitLevel,
@@ -13762,6 +13939,7 @@ class TreeEditOperation extends Operation {
13762
13939
  })(),
13763
13940
  versionVector
13764
13941
  );
13942
+ root.acc(diff);
13765
13943
  for (const pair of pairs) {
13766
13944
  root.registerGCPair(pair);
13767
13945
  }
@@ -13928,12 +14106,15 @@ class ChangeID {
13928
14106
  __publicField(this, "clientSeq");
13929
14107
  // `serverSeq` is optional and only present for changes stored on the server.
13930
14108
  __publicField(this, "serverSeq");
13931
- // `lamport` and `actor` are the lamport clock and the actor of this change.
13932
- // This is used to determine the order of changes in logical time.
13933
- __publicField(this, "lamport");
14109
+ // `actor` is the creator of this change.
13934
14110
  __publicField(this, "actor");
14111
+ // `lamport` is the lamport clock of this change. This is used to determine
14112
+ // the order of changes in logical time. It is optional and only present
14113
+ // if the change has operations.
14114
+ __publicField(this, "lamport");
13935
14115
  // `versionVector` is the vector clock of this change. This is used to
13936
- // determine the relationship is causal or not between changes.
14116
+ // determine the relationship is causal or not between changes. It is optional
14117
+ // and only present if the change has operations.
13937
14118
  __publicField(this, "versionVector");
13938
14119
  this.clientSeq = clientSeq;
13939
14120
  this.serverSeq = serverSeq;
@@ -13941,6 +14122,12 @@ class ChangeID {
13941
14122
  this.versionVector = vector;
13942
14123
  this.actor = actor;
13943
14124
  }
14125
+ /**
14126
+ * `hasClocks` returns true if this ID has logical clocks.
14127
+ */
14128
+ hasClocks() {
14129
+ return this.versionVector.size() > 0 && this.lamport != InitialLamport;
14130
+ }
13944
14131
  /**
13945
14132
  * `of` creates a new instance of ChangeID.
13946
14133
  */
@@ -13950,7 +14137,16 @@ class ChangeID {
13950
14137
  /**
13951
14138
  * `next` creates a next ID of this ID.
13952
14139
  */
13953
- next() {
14140
+ next(excludeClocks = false) {
14141
+ if (excludeClocks) {
14142
+ return new ChangeID(
14143
+ this.clientSeq + 1,
14144
+ this.lamport,
14145
+ this.actor,
14146
+ InitialVersionVector,
14147
+ InitialLamport
14148
+ );
14149
+ }
13954
14150
  const vector = this.versionVector.deepcopy();
13955
14151
  vector.set(this.actor, this.lamport + 1n);
13956
14152
  return new ChangeID(
@@ -13961,9 +14157,13 @@ class ChangeID {
13961
14157
  );
13962
14158
  }
13963
14159
  /**
13964
- * `syncClocks` syncs logical clocks with the given ID.
14160
+ * `syncClocks` syncs logical clocks with the given ID. If the given ID
14161
+ * doesn't have logical clocks, this ID is returned.
13965
14162
  */
13966
14163
  syncClocks(other) {
14164
+ if (!other.hasClocks()) {
14165
+ return this;
14166
+ }
13967
14167
  const lamport = other.lamport > this.lamport ? other.lamport + 1n : this.lamport + 1n;
13968
14168
  const maxVersionVector = this.versionVector.max(other.versionVector);
13969
14169
  const newID = new ChangeID(
@@ -14004,6 +14204,18 @@ class ChangeID {
14004
14204
  this.serverSeq
14005
14205
  );
14006
14206
  }
14207
+ /**
14208
+ * `setLamport` sets the given lamport clock.
14209
+ */
14210
+ setLamport(lamport) {
14211
+ return new ChangeID(
14212
+ this.clientSeq,
14213
+ lamport,
14214
+ this.actor,
14215
+ this.versionVector,
14216
+ this.serverSeq
14217
+ );
14218
+ }
14007
14219
  /**
14008
14220
  * `setVersionVector` sets the given version vector.
14009
14221
  */
@@ -14782,8 +14994,16 @@ class RGATreeSplit {
14782
14994
  * @returns `[RGATreeSplitPos, Array<GCPair>, Array<Change>]`
14783
14995
  */
14784
14996
  edit(range, editedAt, value, versionVector) {
14785
- const [toLeft, toRight] = this.findNodeWithSplit(range[1], editedAt);
14786
- const [fromLeft, fromRight] = this.findNodeWithSplit(range[0], editedAt);
14997
+ const diff = { data: 0, meta: 0 };
14998
+ const [toLeft, diffTo, toRight] = this.findNodeWithSplit(
14999
+ range[1],
15000
+ editedAt
15001
+ );
15002
+ const [fromLeft, diffFrom, fromRight] = this.findNodeWithSplit(
15003
+ range[0],
15004
+ editedAt
15005
+ );
15006
+ addDataSizes(diff, diffTo, diffFrom);
14787
15007
  const nodesToDelete = this.findBetween(fromRight, toRight);
14788
15008
  const [changes, removedNodes] = this.deleteNodes(
14789
15009
  nodesToDelete,
@@ -14798,6 +15018,7 @@ class RGATreeSplit {
14798
15018
  fromLeft,
14799
15019
  RGATreeSplitNode.create(RGATreeSplitNodeID.of(editedAt, 0), value)
14800
15020
  );
15021
+ addDataSizes(diff, inserted.getDataSize());
14801
15022
  if (changes.length && changes[changes.length - 1].from === idx) {
14802
15023
  changes[changes.length - 1].value = value;
14803
15024
  } else {
@@ -14817,7 +15038,7 @@ class RGATreeSplit {
14817
15038
  for (const [, removedNode] of removedNodes) {
14818
15039
  pairs.push({ parent: this, child: removedNode });
14819
15040
  }
14820
- return [caretPos, pairs, changes];
15041
+ return [caretPos, pairs, diff, changes];
14821
15042
  }
14822
15043
  /**
14823
15044
  * `indexToPos` finds RGATreeSplitPos of given offset.
@@ -14956,11 +15177,11 @@ class RGATreeSplit {
14956
15177
  const absoluteID = pos.getAbsoluteID();
14957
15178
  let node = this.findFloorNodePreferToLeft(absoluteID);
14958
15179
  const relativeOffset = absoluteID.getOffset() - node.getID().getOffset();
14959
- this.splitNode(node, relativeOffset);
15180
+ const [, diff] = this.splitNode(node, relativeOffset);
14960
15181
  while (node.hasNext() && node.getNext().getCreatedAt().after(editedAt)) {
14961
15182
  node = node.getNext();
14962
15183
  }
14963
- return [node, node.getNext()];
15184
+ return [node, diff, node.getNext()];
14964
15185
  }
14965
15186
  findFloorNodePreferToLeft(id) {
14966
15187
  let node = this.findFloorNode(id);
@@ -15001,6 +15222,7 @@ class RGATreeSplit {
15001
15222
  return nodes;
15002
15223
  }
15003
15224
  splitNode(node, offset) {
15225
+ const diff = { data: 0, meta: 0 };
15004
15226
  if (offset > node.getContentLength()) {
15005
15227
  throw new YorkieError(
15006
15228
  Code.ErrInvalidArgument,
@@ -15008,10 +15230,11 @@ class RGATreeSplit {
15008
15230
  );
15009
15231
  }
15010
15232
  if (offset === 0) {
15011
- return node;
15233
+ return [node, diff];
15012
15234
  } else if (offset === node.getContentLength()) {
15013
- return node.getNext();
15235
+ return [node.getNext(), diff];
15014
15236
  }
15237
+ const prvSize = node.getDataSize();
15015
15238
  const splitNode = node.split(offset);
15016
15239
  this.treeByIndex.updateWeight(splitNode);
15017
15240
  this.insertAfter(node, splitNode);
@@ -15020,7 +15243,9 @@ class RGATreeSplit {
15020
15243
  insNext.setInsPrev(splitNode);
15021
15244
  }
15022
15245
  splitNode.setInsPrev(node);
15023
- return splitNode;
15246
+ addDataSizes(diff, node.getDataSize(), splitNode.getDataSize());
15247
+ subDataSize(diff, prvSize);
15248
+ return [splitNode, diff];
15024
15249
  }
15025
15250
  deleteNodes(candidates, editedAt, versionVector) {
15026
15251
  if (!candidates.length) {
@@ -15489,10 +15714,11 @@ class TreeStyleOperation extends Operation {
15489
15714
  const tree = parentObject;
15490
15715
  let changes;
15491
15716
  let pairs;
15717
+ let diff = { data: 0, meta: 0 };
15492
15718
  if (this.attributes.size) {
15493
15719
  const attributes = {};
15494
15720
  [...this.attributes].forEach(([key, value]) => attributes[key] = value);
15495
- [pairs, changes] = tree.style(
15721
+ [pairs, changes, diff] = tree.style(
15496
15722
  [this.fromPos, this.toPos],
15497
15723
  attributes,
15498
15724
  this.getExecutedAt(),
@@ -15500,13 +15726,14 @@ class TreeStyleOperation extends Operation {
15500
15726
  );
15501
15727
  } else {
15502
15728
  const attributesToRemove = this.attributesToRemove;
15503
- [pairs, changes] = tree.removeStyle(
15729
+ [pairs, changes, diff] = tree.removeStyle(
15504
15730
  [this.fromPos, this.toPos],
15505
15731
  attributesToRemove,
15506
15732
  this.getExecutedAt(),
15507
15733
  versionVector
15508
15734
  );
15509
15735
  }
15736
+ root.acc(diff);
15510
15737
  for (const pair of pairs) {
15511
15738
  root.registerGCPair(pair);
15512
15739
  }
@@ -16959,8 +17186,9 @@ function createObservable(executor) {
16959
17186
  };
16960
17187
  }
16961
17188
  class ChangeContext {
16962
- constructor(id, root, presence, message) {
16963
- __publicField(this, "id");
17189
+ constructor(prevID, root, presence, message) {
17190
+ __publicField(this, "prevID");
17191
+ __publicField(this, "nextID");
16964
17192
  __publicField(this, "delimiter");
16965
17193
  __publicField(this, "message");
16966
17194
  __publicField(this, "root");
@@ -16976,7 +17204,8 @@ class ChangeContext {
16976
17204
  * presence changes.
16977
17205
  */
16978
17206
  __publicField(this, "reversePresenceKeys");
16979
- this.id = id;
17207
+ this.prevID = prevID;
17208
+ this.nextID = prevID.next();
16980
17209
  this.delimiter = InitialDelimiter;
16981
17210
  this.root = root;
16982
17211
  this.operations = [];
@@ -16988,8 +17217,8 @@ class ChangeContext {
16988
17217
  /**
16989
17218
  * `create` creates a new instance of ChangeContext.
16990
17219
  */
16991
- static create(id, root, presence, message) {
16992
- return new ChangeContext(id, root, presence, message);
17220
+ static create(prevID, root, presence, message) {
17221
+ return new ChangeContext(prevID, root, presence, message);
16993
17222
  }
16994
17223
  /**
16995
17224
  * `push` pushes the given operation to this context.
@@ -17016,16 +17245,34 @@ class ChangeContext {
17016
17245
  this.root.registerGCPair(pair);
17017
17246
  }
17018
17247
  /**
17019
- * `getChange` creates a new instance of Change in this context.
17248
+ * `getNextID` returns the next ID of this context. It will be set to the
17249
+ * document for the next change.returns the next ID of this context.
17020
17250
  */
17021
- getChange() {
17251
+ getNextID() {
17252
+ if (this.isPresenceOnlyChange()) {
17253
+ return this.prevID.next(true).setLamport(this.prevID.getLamport()).setVersionVector(this.prevID.getVersionVector());
17254
+ }
17255
+ return this.nextID;
17256
+ }
17257
+ /**
17258
+ * `toChange` creates a new instance of Change in this context.
17259
+ */
17260
+ toChange() {
17261
+ const id = this.isPresenceOnlyChange() ? this.prevID.next(true) : this.nextID;
17022
17262
  return Change.create({
17023
- id: this.id,
17263
+ id,
17024
17264
  operations: this.operations,
17025
17265
  presenceChange: this.presenceChange,
17026
17266
  message: this.message
17027
17267
  });
17028
17268
  }
17269
+ /**
17270
+ * `isPresenceOnlyChange` returns whether this context is only for presence
17271
+ * change or not.
17272
+ */
17273
+ isPresenceOnlyChange() {
17274
+ return this.operations.length === 0;
17275
+ }
17029
17276
  /**
17030
17277
  * `hasChange` returns whether this context has change or not.
17031
17278
  */
@@ -17066,13 +17313,19 @@ class ChangeContext {
17066
17313
  */
17067
17314
  issueTimeTicket() {
17068
17315
  this.delimiter += 1;
17069
- return this.id.createTimeTicket(this.delimiter);
17316
+ return this.nextID.createTimeTicket(this.delimiter);
17070
17317
  }
17071
17318
  /**
17072
17319
  * `getLastTimeTicket` returns the last time ticket issued in this context.
17073
17320
  */
17074
17321
  getLastTimeTicket() {
17075
- return this.id.createTimeTicket(this.delimiter);
17322
+ return this.nextID.createTimeTicket(this.delimiter);
17323
+ }
17324
+ /**
17325
+ * `acc` accumulates the given DataSize to Live size of the root.
17326
+ */
17327
+ acc(diff) {
17328
+ this.root.acc(diff);
17076
17329
  }
17077
17330
  }
17078
17331
  class CRDTRoot {
@@ -17097,10 +17350,15 @@ class CRDTRoot {
17097
17350
  * element itself and its parent.
17098
17351
  */
17099
17352
  __publicField(this, "gcPairMap");
17353
+ /**
17354
+ * `docSize` is a structure that represents the size of the document.
17355
+ */
17356
+ __publicField(this, "docSize");
17100
17357
  this.rootObject = rootObject;
17101
17358
  this.elementPairMapByCreatedAt = /* @__PURE__ */ new Map();
17102
17359
  this.gcElementSetByCreatedAt = /* @__PURE__ */ new Set();
17103
17360
  this.gcPairMap = /* @__PURE__ */ new Map();
17361
+ this.docSize = { live: { data: 0, meta: 0 }, gc: { data: 0, meta: 0 } };
17104
17362
  this.registerElement(rootObject, void 0);
17105
17363
  rootObject.getDescendants((elem) => {
17106
17364
  if (elem.getRemovedAt()) {
@@ -17177,6 +17435,7 @@ class CRDTRoot {
17177
17435
  parent,
17178
17436
  element
17179
17437
  });
17438
+ addDataSizes(this.docSize.live, element.getDataSize());
17180
17439
  if (element instanceof CRDTContainer) {
17181
17440
  element.getDescendants((elem, parent2) => {
17182
17441
  this.registerElement(elem, parent2);
@@ -17191,6 +17450,7 @@ class CRDTRoot {
17191
17450
  let count = 0;
17192
17451
  const deregisterElementInternal = (elem) => {
17193
17452
  const createdAt = elem.getCreatedAt().toIDString();
17453
+ subDataSize(this.docSize.gc, elem.getDataSize());
17194
17454
  this.elementPairMapByCreatedAt.delete(createdAt);
17195
17455
  this.gcElementSetByCreatedAt.delete(createdAt);
17196
17456
  count++;
@@ -17208,6 +17468,9 @@ class CRDTRoot {
17208
17468
  * `registerRemovedElement` registers the given element to the hash set.
17209
17469
  */
17210
17470
  registerRemovedElement(element) {
17471
+ addDataSizes(this.docSize.gc, element.getDataSize());
17472
+ subDataSize(this.docSize.live, element.getDataSize());
17473
+ this.docSize.live.meta += TimeTicketSize;
17211
17474
  this.gcElementSetByCreatedAt.add(element.getCreatedAt().toIDString());
17212
17475
  }
17213
17476
  /**
@@ -17220,6 +17483,12 @@ class CRDTRoot {
17220
17483
  return;
17221
17484
  }
17222
17485
  this.gcPairMap.set(pair.child.toIDString(), pair);
17486
+ const size = this.gcPairMap.get(pair.child.toIDString()).child.getDataSize();
17487
+ addDataSizes(this.docSize.gc, size);
17488
+ subDataSize(this.docSize.live, size);
17489
+ if (!(pair.child instanceof RHTNode)) {
17490
+ this.docSize.live.meta += TimeTicketSize;
17491
+ }
17223
17492
  }
17224
17493
  /**
17225
17494
  * `getElementMapSize` returns the size of element map.
@@ -17260,22 +17529,7 @@ class CRDTRoot {
17260
17529
  * `getDocSize` returns the size of the document.
17261
17530
  */
17262
17531
  getDocSize() {
17263
- const docSize = { live: { data: 0, meta: 0 }, gc: { data: 0, meta: 0 } };
17264
- for (const [createdAt, value] of this.elementPairMapByCreatedAt) {
17265
- if (this.gcElementSetByCreatedAt.has(createdAt)) {
17266
- docSize.gc.data += value.element.getDataSize().data;
17267
- docSize.gc.meta += value.element.getDataSize().meta;
17268
- } else {
17269
- docSize.live.data += value.element.getDataSize().data;
17270
- docSize.live.meta += value.element.getDataSize().meta;
17271
- }
17272
- }
17273
- for (const pair of this.gcPairMap.values()) {
17274
- const size = pair.child.getDataSize();
17275
- docSize.gc.data += size.data;
17276
- docSize.gc.meta += size.meta;
17277
- }
17278
- return docSize;
17532
+ return this.docSize;
17279
17533
  }
17280
17534
  /**
17281
17535
  * `deepcopy` copies itself deeply.
@@ -17329,6 +17583,12 @@ class CRDTRoot {
17329
17583
  gcElements: this.getGarbageElementSetSize()
17330
17584
  };
17331
17585
  }
17586
+ /**
17587
+ * `acc` accumulates the given DataSize to Live.
17588
+ */
17589
+ acc(diff) {
17590
+ addDataSizes(this.docSize.live, diff);
17591
+ }
17332
17592
  }
17333
17593
  function createJSONObject(context, target) {
17334
17594
  const objectProxy = new ObjectProxy(context);
@@ -17946,12 +18206,13 @@ class Text {
17946
18206
  }
17947
18207
  const attrs = attributes ? stringifyObjectValues(attributes) : void 0;
17948
18208
  const ticket = this.context.issueTimeTicket();
17949
- const [, pairs, rangeAfterEdit] = this.text.edit(
18209
+ const [, pairs, diff, rangeAfterEdit] = this.text.edit(
17950
18210
  range,
17951
18211
  content,
17952
18212
  ticket,
17953
18213
  attrs
17954
18214
  );
18215
+ this.context.acc(diff);
17955
18216
  for (const pair of pairs) {
17956
18217
  this.context.registerGCPair(pair);
17957
18218
  }
@@ -18005,7 +18266,8 @@ class Text {
18005
18266
  }
18006
18267
  const attrs = stringifyObjectValues(attributes);
18007
18268
  const ticket = this.context.issueTimeTicket();
18008
- const [pairs] = this.text.setStyle(range, attrs, ticket);
18269
+ const [pairs, diff] = this.text.setStyle(range, attrs, ticket);
18270
+ this.context.acc(diff);
18009
18271
  for (const pair of pairs) {
18010
18272
  this.context.registerGCPair(pair);
18011
18273
  }
@@ -18548,7 +18810,8 @@ class Tree {
18548
18810
  const [fromPos, toPos] = this.tree.pathToPosRange(path);
18549
18811
  const ticket = this.context.issueTimeTicket();
18550
18812
  const attrs = attributes ? stringifyObjectValues(attributes) : void 0;
18551
- const [pairs] = this.tree.style([fromPos, toPos], attrs, ticket);
18813
+ const [pairs, , diff] = this.tree.style([fromPos, toPos], attrs, ticket);
18814
+ this.context.acc(diff);
18552
18815
  for (const pair of pairs) {
18553
18816
  this.context.registerGCPair(pair);
18554
18817
  }
@@ -18582,7 +18845,8 @@ class Tree {
18582
18845
  const toPos = this.tree.findPos(toIdx);
18583
18846
  const ticket = this.context.issueTimeTicket();
18584
18847
  const attrs = attributes ? stringifyObjectValues(attributes) : void 0;
18585
- const [pairs] = this.tree.style([fromPos, toPos], attrs, ticket);
18848
+ const [pairs, , diff] = this.tree.style([fromPos, toPos], attrs, ticket);
18849
+ this.context.acc(diff);
18586
18850
  for (const pair of pairs) {
18587
18851
  this.context.registerGCPair(pair);
18588
18852
  }
@@ -18615,11 +18879,12 @@ class Tree {
18615
18879
  const fromPos = this.tree.findPos(fromIdx);
18616
18880
  const toPos = this.tree.findPos(toIdx);
18617
18881
  const ticket = this.context.issueTimeTicket();
18618
- const [pairs] = this.tree.removeStyle(
18882
+ const [pairs, , diff] = this.tree.removeStyle(
18619
18883
  [fromPos, toPos],
18620
18884
  attributesToRemove,
18621
18885
  ticket
18622
18886
  );
18887
+ this.context.acc(diff);
18623
18888
  for (const pair of pairs) {
18624
18889
  this.context.registerGCPair(pair);
18625
18890
  }
@@ -18662,13 +18927,14 @@ class Tree {
18662
18927
  } else {
18663
18928
  crdtNodes = contents.map((content) => content && createCRDTTreeNode(this.context, content)).filter((a) => a);
18664
18929
  }
18665
- const [, pairs] = this.tree.edit(
18930
+ const [, pairs, diff] = this.tree.edit(
18666
18931
  [fromPos, toPos],
18667
18932
  crdtNodes.length ? crdtNodes.map((crdtNode) => crdtNode == null ? void 0 : crdtNode.deepcopy()) : void 0,
18668
18933
  splitLevel,
18669
18934
  ticket,
18670
18935
  () => this.context.issueTimeTicket()
18671
18936
  );
18937
+ this.context.acc(diff);
18672
18938
  for (const pair of pairs) {
18673
18939
  this.context.registerGCPair(pair);
18674
18940
  }
@@ -19001,6 +19267,43 @@ function buildCRDTElement(context, value, createdAt) {
19001
19267
  }
19002
19268
  return element;
19003
19269
  }
19270
+ class Presence {
19271
+ constructor(changeContext, presence) {
19272
+ __publicField(this, "context");
19273
+ __publicField(this, "presence");
19274
+ this.context = changeContext;
19275
+ this.presence = presence;
19276
+ }
19277
+ /**
19278
+ * `set` updates the presence based on the partial presence.
19279
+ */
19280
+ set(presence, option) {
19281
+ for (const key of Object.keys(presence)) {
19282
+ this.presence[key] = presence[key];
19283
+ }
19284
+ this.context.setPresenceChange({
19285
+ type: PresenceChangeType.Put,
19286
+ presence: deepcopy(this.presence)
19287
+ });
19288
+ this.context.setReversePresence(presence, option);
19289
+ }
19290
+ /**
19291
+ * `get` returns the presence value of the given key.
19292
+ */
19293
+ get(key) {
19294
+ return this.presence[key];
19295
+ }
19296
+ /**
19297
+ * `clear` clears the presence.
19298
+ * @internal
19299
+ */
19300
+ clear() {
19301
+ this.presence = {};
19302
+ this.context.setPresenceChange({
19303
+ type: PresenceChangeType.Clear
19304
+ });
19305
+ }
19306
+ }
19004
19307
  const MaxUndoRedoStackDepth = 50;
19005
19308
  class History {
19006
19309
  constructor() {
@@ -19206,6 +19509,7 @@ class Document {
19206
19509
  __publicField(this, "changeID");
19207
19510
  __publicField(this, "checkpoint");
19208
19511
  __publicField(this, "localChanges");
19512
+ __publicField(this, "maxSizeLimit");
19209
19513
  __publicField(this, "root");
19210
19514
  __publicField(this, "clone");
19211
19515
  __publicField(this, "eventStream");
@@ -19238,6 +19542,7 @@ class Document {
19238
19542
  this.changeID = InitialChangeID;
19239
19543
  this.checkpoint = InitialCheckpoint;
19240
19544
  this.localChanges = [];
19545
+ this.maxSizeLimit = 0;
19241
19546
  this.eventStream = createObservable((observer) => {
19242
19547
  this.eventStreamObserver = observer;
19243
19548
  });
@@ -19257,13 +19562,14 @@ class Document {
19257
19562
  * `update` executes the given updater to update this document.
19258
19563
  */
19259
19564
  update(updater, message) {
19565
+ var _a2;
19260
19566
  if (this.getStatus() === "removed") {
19261
19567
  throw new YorkieError(Code.ErrDocumentRemoved, `${this.key} is removed`);
19262
19568
  }
19263
19569
  this.ensureClone();
19264
19570
  const actorID = this.changeID.getActorID();
19265
19571
  const context = ChangeContext.create(
19266
- this.changeID.next(),
19572
+ this.changeID,
19267
19573
  this.clone.root,
19268
19574
  this.clone.presences.get(actorID) || {},
19269
19575
  message
@@ -19287,11 +19593,19 @@ class Document {
19287
19593
  } finally {
19288
19594
  this.isUpdating = false;
19289
19595
  }
19596
+ const size = totalDocSize((_a2 = this.clone) == null ? void 0 : _a2.root.getDocSize());
19597
+ if (!context.isPresenceOnlyChange() && this.maxSizeLimit > 0 && this.maxSizeLimit < size) {
19598
+ this.clone = void 0;
19599
+ throw new YorkieError(
19600
+ Code.ErrDocumentSizeExceedsLimit,
19601
+ `document size exceeded: ${size} > ${this.maxSizeLimit}`
19602
+ );
19603
+ }
19290
19604
  if (context.hasChange()) {
19291
19605
  if (logger.isEnabled(LogLevel.Trivial)) {
19292
19606
  logger.trivial(`trying to update a local change: ${this.toJSON()}`);
19293
19607
  }
19294
- const change = context.getChange();
19608
+ const change = context.toChange();
19295
19609
  const { opInfos, reverseOps } = change.execute(
19296
19610
  this.root,
19297
19611
  this.presences,
@@ -19311,7 +19625,7 @@ class Document {
19311
19625
  if (opInfos.length > 0) {
19312
19626
  this.internalHistory.clearRedo();
19313
19627
  }
19314
- this.changeID = change.getID();
19628
+ this.changeID = context.getNextID();
19315
19629
  const event = [];
19316
19630
  if (opInfos.length > 0) {
19317
19631
  event.push({
@@ -19681,7 +19995,13 @@ class Document {
19681
19995
  return this.status;
19682
19996
  }
19683
19997
  /**
19684
- * `getClone` return clone object.
19998
+ * `getClone` returns this clone.
19999
+ */
20000
+ getClone() {
20001
+ return this.clone;
20002
+ }
20003
+ /**
20004
+ * `getCloneRoot` returns clone object.
19685
20005
  *
19686
20006
  * @internal
19687
20007
  */
@@ -19709,6 +20029,18 @@ class Document {
19709
20029
  getDocSize() {
19710
20030
  return this.root.getDocSize();
19711
20031
  }
20032
+ /**
20033
+ * `getMaxSizePerDocument` gets the maximum size of this document.
20034
+ */
20035
+ getMaxSizePerDocument() {
20036
+ return this.maxSizeLimit;
20037
+ }
20038
+ /**
20039
+ * `setMaxSizePerDocument` sets the maximum size of this document.
20040
+ */
20041
+ setMaxSizePerDocument(size) {
20042
+ this.maxSizeLimit = size;
20043
+ }
19712
20044
  /**
19713
20045
  * `garbageCollect` purges elements that were removed before the given time.
19714
20046
  *
@@ -20180,14 +20512,6 @@ class Document {
20180
20512
  canUndo() {
20181
20513
  return this.internalHistory.hasUndo() && !this.isUpdating;
20182
20514
  }
20183
- /**
20184
- * 'filterVersionVector' filters detached client's lamport from version vector.
20185
- */
20186
- filterVersionVector(minSyncedVersionVector) {
20187
- const versionVector = this.changeID.getVersionVector();
20188
- const filteredVersionVector = versionVector.filter(minSyncedVersionVector);
20189
- this.changeID = this.changeID.setVersionVector(filteredVersionVector);
20190
- }
20191
20515
  /**
20192
20516
  * `canRedo` returns whether there are any operations to redo.
20193
20517
  */
@@ -20214,7 +20538,7 @@ class Document {
20214
20538
  }
20215
20539
  this.ensureClone();
20216
20540
  const context = ChangeContext.create(
20217
- this.changeID.next(),
20541
+ this.changeID,
20218
20542
  this.clone.root,
20219
20543
  this.clone.presences.get(this.changeID.getActorID()) || {}
20220
20544
  );
@@ -20231,7 +20555,7 @@ class Document {
20231
20555
  undoOp.setExecutedAt(ticket);
20232
20556
  context.push(undoOp);
20233
20557
  }
20234
- const change = context.getChange();
20558
+ const change = context.toChange();
20235
20559
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20236
20560
  const { opInfos, reverseOps } = change.execute(
20237
20561
  this.root,
@@ -20252,7 +20576,7 @@ class Document {
20252
20576
  return;
20253
20577
  }
20254
20578
  this.localChanges.push(change);
20255
- this.changeID = change.getID();
20579
+ this.changeID = context.getNextID();
20256
20580
  const actorID = this.changeID.getActorID();
20257
20581
  const event = [];
20258
20582
  if (opInfos.length > 0) {
@@ -20301,7 +20625,7 @@ class Document {
20301
20625
  }
20302
20626
  this.ensureClone();
20303
20627
  const context = ChangeContext.create(
20304
- this.changeID.next(),
20628
+ this.changeID,
20305
20629
  this.clone.root,
20306
20630
  this.clone.presences.get(this.changeID.getActorID()) || {}
20307
20631
  );
@@ -20318,7 +20642,7 @@ class Document {
20318
20642
  redoOp.setExecutedAt(ticket);
20319
20643
  context.push(redoOp);
20320
20644
  }
20321
- const change = context.getChange();
20645
+ const change = context.toChange();
20322
20646
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20323
20647
  const { opInfos, reverseOps } = change.execute(
20324
20648
  this.root,
@@ -20339,7 +20663,7 @@ class Document {
20339
20663
  return;
20340
20664
  }
20341
20665
  this.localChanges.push(change);
20342
- this.changeID = change.getID();
20666
+ this.changeID = context.getNextID();
20343
20667
  const actorID = this.changeID.getActorID();
20344
20668
  const event = [];
20345
20669
  if (opInfos.length > 0) {
@@ -20418,7 +20742,7 @@ function createAuthInterceptor(apiKey, token) {
20418
20742
  };
20419
20743
  }
20420
20744
  const name = "@yorkie-js/sdk";
20421
- const version = "0.6.11-rc";
20745
+ const version = "0.6.13";
20422
20746
  const pkg = {
20423
20747
  name,
20424
20748
  version
@@ -20576,16 +20900,15 @@ class Client {
20576
20900
  if (this.status === "deactivated") {
20577
20901
  return Promise.resolve();
20578
20902
  }
20579
- this.deactivateInternal();
20580
20903
  const task = async () => {
20581
20904
  try {
20582
20905
  await this.rpcClient.deactivateClient(
20583
20906
  { clientId: this.id },
20584
20907
  { headers: { "x-shard-key": this.apiKey } }
20585
20908
  );
20909
+ this.deactivateInternal();
20586
20910
  logger.info(`[DC] c"${this.getKey()}" deactivated`);
20587
20911
  } catch (err) {
20588
- this.status = "activated";
20589
20912
  logger.error(`[DC] c:"${this.getKey()}" err :`, err);
20590
20913
  await this.handleConnectError(err);
20591
20914
  throw err;
@@ -20649,6 +20972,10 @@ class Client {
20649
20972
  },
20650
20973
  { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20651
20974
  );
20975
+ const maxSize = res.maxSizePerDocument ?? 0;
20976
+ if (maxSize > 0) {
20977
+ doc.setMaxSizePerDocument(res.maxSizePerDocument);
20978
+ }
20652
20979
  const pack = converter.fromChangePack(res.changePack);
20653
20980
  doc.applyChangePack(pack);
20654
20981
  if (doc.getStatus() === DocStatus.Removed) {
@@ -20669,12 +20996,12 @@ class Client {
20669
20996
  await this.runWatchLoop(doc.getKey());
20670
20997
  }
20671
20998
  logger.info(`[AD] c:"${this.getKey()}" attaches d:"${doc.getKey()}"`);
20672
- const crdtRoot = doc.getRootObject();
20999
+ const crdtObject = doc.getRootObject();
20673
21000
  if (opts.initialRoot) {
20674
21001
  const initialRoot = opts.initialRoot;
20675
21002
  doc.update((root) => {
20676
21003
  for (const [k, v] of Object.entries(initialRoot)) {
20677
- if (!crdtRoot.has(k)) {
21004
+ if (!crdtObject.has(k)) {
20678
21005
  const key = k;
20679
21006
  root[key] = v;
20680
21007
  }
@@ -20697,7 +21024,7 @@ class Client {
20697
21024
  * the changes should be applied to other replicas before GC time. For this,
20698
21025
  * if the document is no longer used by this client, it should be detached.
20699
21026
  */
20700
- detach(doc, opts = { removeIfNotAttached: false }) {
21027
+ detach(doc, opts = { keepalive: false }) {
20701
21028
  if (!this.isActive()) {
20702
21029
  throw new YorkieError(
20703
21030
  Code.ErrClientNotActivated,
@@ -20712,14 +21039,14 @@ class Client {
20712
21039
  );
20713
21040
  }
20714
21041
  doc.update((_, p) => p.clear());
20715
- return this.enqueueTask(async () => {
21042
+ const task = async () => {
20716
21043
  try {
20717
21044
  const res = await this.rpcClient.detachDocument(
20718
21045
  {
20719
21046
  clientId: this.id,
20720
21047
  documentId: attachment.docID,
20721
21048
  changePack: converter.toChangePack(doc.createChangePack()),
20722
- removeIfNotAttached: opts.removeIfNotAttached
21049
+ removeIfNotAttached: opts.removeIfNotAttached ?? false
20723
21050
  },
20724
21051
  { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20725
21052
  );
@@ -20736,7 +21063,14 @@ class Client {
20736
21063
  await this.handleConnectError(err);
20737
21064
  throw err;
20738
21065
  }
20739
- });
21066
+ };
21067
+ if (opts.keepalive) {
21068
+ this.keepalive = true;
21069
+ const resp = task();
21070
+ this.keepalive = false;
21071
+ return resp;
21072
+ }
21073
+ return this.enqueueTask(task);
20740
21074
  }
20741
21075
  /**
20742
21076
  * `changeRealtimeSync` changes the synchronization mode of the given document.