@yorkie-js/sdk 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.
@@ -6057,15 +6057,39 @@ const _Project = class _Project extends Message {
6057
6057
  */
6058
6058
  __publicField(this, "authWebhookMethods", []);
6059
6059
  /**
6060
- * @generated from field: string client_deactivate_threshold = 7;
6060
+ * @generated from field: string event_webhook_url = 7;
6061
+ */
6062
+ __publicField(this, "eventWebhookUrl", "");
6063
+ /**
6064
+ * @generated from field: repeated string event_webhook_events = 8;
6065
+ */
6066
+ __publicField(this, "eventWebhookEvents", []);
6067
+ /**
6068
+ * @generated from field: string client_deactivate_threshold = 9;
6061
6069
  */
6062
6070
  __publicField(this, "clientDeactivateThreshold", "");
6063
6071
  /**
6064
- * @generated from field: google.protobuf.Timestamp created_at = 8;
6072
+ * @generated from field: int32 max_subscribers_per_document = 10;
6073
+ */
6074
+ __publicField(this, "maxSubscribersPerDocument", 0);
6075
+ /**
6076
+ * @generated from field: int32 max_attachments_per_document = 11;
6077
+ */
6078
+ __publicField(this, "maxAttachmentsPerDocument", 0);
6079
+ /**
6080
+ * @generated from field: int32 max_size_per_document = 15;
6081
+ */
6082
+ __publicField(this, "maxSizePerDocument", 0);
6083
+ /**
6084
+ * @generated from field: repeated string allowed_origins = 14;
6085
+ */
6086
+ __publicField(this, "allowedOrigins", []);
6087
+ /**
6088
+ * @generated from field: google.protobuf.Timestamp created_at = 12;
6065
6089
  */
6066
6090
  __publicField(this, "createdAt");
6067
6091
  /**
6068
- * @generated from field: google.protobuf.Timestamp updated_at = 9;
6092
+ * @generated from field: google.protobuf.Timestamp updated_at = 13;
6069
6093
  */
6070
6094
  __publicField(this, "updatedAt");
6071
6095
  proto3.util.initPartial(data, this);
@@ -6124,13 +6148,43 @@ __publicField(_Project, "fields", proto3.util.newFieldList(() => [
6124
6148
  { no: 6, name: "auth_webhook_methods", kind: "scalar", T: 9, repeated: true },
6125
6149
  {
6126
6150
  no: 7,
6151
+ name: "event_webhook_url",
6152
+ kind: "scalar",
6153
+ T: 9
6154
+ /* ScalarType.STRING */
6155
+ },
6156
+ { no: 8, name: "event_webhook_events", kind: "scalar", T: 9, repeated: true },
6157
+ {
6158
+ no: 9,
6127
6159
  name: "client_deactivate_threshold",
6128
6160
  kind: "scalar",
6129
6161
  T: 9
6130
6162
  /* ScalarType.STRING */
6131
6163
  },
6132
- { no: 8, name: "created_at", kind: "message", T: Timestamp },
6133
- { no: 9, name: "updated_at", kind: "message", T: Timestamp }
6164
+ {
6165
+ no: 10,
6166
+ name: "max_subscribers_per_document",
6167
+ kind: "scalar",
6168
+ T: 5
6169
+ /* ScalarType.INT32 */
6170
+ },
6171
+ {
6172
+ no: 11,
6173
+ name: "max_attachments_per_document",
6174
+ kind: "scalar",
6175
+ T: 5
6176
+ /* ScalarType.INT32 */
6177
+ },
6178
+ {
6179
+ no: 15,
6180
+ name: "max_size_per_document",
6181
+ kind: "scalar",
6182
+ T: 5
6183
+ /* ScalarType.INT32 */
6184
+ },
6185
+ { no: 14, name: "allowed_origins", kind: "scalar", T: 9, repeated: true },
6186
+ { no: 12, name: "created_at", kind: "message", T: Timestamp },
6187
+ { no: 13, name: "updated_at", kind: "message", T: Timestamp }
6134
6188
  ]));
6135
6189
  let Project = _Project;
6136
6190
  const _UpdatableProjectFields = class _UpdatableProjectFields extends Message {
@@ -6149,9 +6203,33 @@ const _UpdatableProjectFields = class _UpdatableProjectFields extends Message {
6149
6203
  */
6150
6204
  __publicField(this, "authWebhookMethods");
6151
6205
  /**
6152
- * @generated from field: google.protobuf.StringValue client_deactivate_threshold = 4;
6206
+ * @generated from field: google.protobuf.StringValue event_webhook_url = 4;
6207
+ */
6208
+ __publicField(this, "eventWebhookUrl");
6209
+ /**
6210
+ * @generated from field: yorkie.v1.UpdatableProjectFields.EventWebhookEvents event_webhook_events = 5;
6211
+ */
6212
+ __publicField(this, "eventWebhookEvents");
6213
+ /**
6214
+ * @generated from field: google.protobuf.StringValue client_deactivate_threshold = 6;
6153
6215
  */
6154
6216
  __publicField(this, "clientDeactivateThreshold");
6217
+ /**
6218
+ * @generated from field: google.protobuf.Int32Value max_subscribers_per_document = 7;
6219
+ */
6220
+ __publicField(this, "maxSubscribersPerDocument");
6221
+ /**
6222
+ * @generated from field: google.protobuf.Int32Value max_attachments_per_document = 8;
6223
+ */
6224
+ __publicField(this, "maxAttachmentsPerDocument");
6225
+ /**
6226
+ * @generated from field: google.protobuf.Int32Value max_size_per_document = 10;
6227
+ */
6228
+ __publicField(this, "maxSizePerDocument");
6229
+ /**
6230
+ * @generated from field: yorkie.v1.UpdatableProjectFields.AllowedOrigins allowed_origins = 9;
6231
+ */
6232
+ __publicField(this, "allowedOrigins");
6155
6233
  proto3.util.initPartial(data, this);
6156
6234
  }
6157
6235
  static fromBinary(bytes, options) {
@@ -6173,7 +6251,13 @@ __publicField(_UpdatableProjectFields, "fields", proto3.util.newFieldList(() =>
6173
6251
  { no: 1, name: "name", kind: "message", T: StringValue },
6174
6252
  { no: 2, name: "auth_webhook_url", kind: "message", T: StringValue },
6175
6253
  { no: 3, name: "auth_webhook_methods", kind: "message", T: UpdatableProjectFields_AuthWebhookMethods },
6176
- { no: 4, name: "client_deactivate_threshold", kind: "message", T: StringValue }
6254
+ { no: 4, name: "event_webhook_url", kind: "message", T: StringValue },
6255
+ { no: 5, name: "event_webhook_events", kind: "message", T: UpdatableProjectFields_EventWebhookEvents },
6256
+ { no: 6, name: "client_deactivate_threshold", kind: "message", T: StringValue },
6257
+ { no: 7, name: "max_subscribers_per_document", kind: "message", T: Int32Value },
6258
+ { no: 8, name: "max_attachments_per_document", kind: "message", T: Int32Value },
6259
+ { no: 10, name: "max_size_per_document", kind: "message", T: Int32Value },
6260
+ { no: 9, name: "allowed_origins", kind: "message", T: UpdatableProjectFields_AllowedOrigins }
6177
6261
  ]));
6178
6262
  let UpdatableProjectFields = _UpdatableProjectFields;
6179
6263
  const _UpdatableProjectFields_AuthWebhookMethods = class _UpdatableProjectFields_AuthWebhookMethods extends Message {
@@ -6204,6 +6288,62 @@ __publicField(_UpdatableProjectFields_AuthWebhookMethods, "fields", proto3.util.
6204
6288
  { no: 1, name: "methods", kind: "scalar", T: 9, repeated: true }
6205
6289
  ]));
6206
6290
  let UpdatableProjectFields_AuthWebhookMethods = _UpdatableProjectFields_AuthWebhookMethods;
6291
+ const _UpdatableProjectFields_EventWebhookEvents = class _UpdatableProjectFields_EventWebhookEvents extends Message {
6292
+ constructor(data) {
6293
+ super();
6294
+ /**
6295
+ * @generated from field: repeated string events = 1;
6296
+ */
6297
+ __publicField(this, "events", []);
6298
+ proto3.util.initPartial(data, this);
6299
+ }
6300
+ static fromBinary(bytes, options) {
6301
+ return new _UpdatableProjectFields_EventWebhookEvents().fromBinary(bytes, options);
6302
+ }
6303
+ static fromJson(jsonValue, options) {
6304
+ return new _UpdatableProjectFields_EventWebhookEvents().fromJson(jsonValue, options);
6305
+ }
6306
+ static fromJsonString(jsonString, options) {
6307
+ return new _UpdatableProjectFields_EventWebhookEvents().fromJsonString(jsonString, options);
6308
+ }
6309
+ static equals(a, b) {
6310
+ return proto3.util.equals(_UpdatableProjectFields_EventWebhookEvents, a, b);
6311
+ }
6312
+ };
6313
+ __publicField(_UpdatableProjectFields_EventWebhookEvents, "runtime", proto3);
6314
+ __publicField(_UpdatableProjectFields_EventWebhookEvents, "typeName", "yorkie.v1.UpdatableProjectFields.EventWebhookEvents");
6315
+ __publicField(_UpdatableProjectFields_EventWebhookEvents, "fields", proto3.util.newFieldList(() => [
6316
+ { no: 1, name: "events", kind: "scalar", T: 9, repeated: true }
6317
+ ]));
6318
+ let UpdatableProjectFields_EventWebhookEvents = _UpdatableProjectFields_EventWebhookEvents;
6319
+ const _UpdatableProjectFields_AllowedOrigins = class _UpdatableProjectFields_AllowedOrigins extends Message {
6320
+ constructor(data) {
6321
+ super();
6322
+ /**
6323
+ * @generated from field: repeated string origins = 1;
6324
+ */
6325
+ __publicField(this, "origins", []);
6326
+ proto3.util.initPartial(data, this);
6327
+ }
6328
+ static fromBinary(bytes, options) {
6329
+ return new _UpdatableProjectFields_AllowedOrigins().fromBinary(bytes, options);
6330
+ }
6331
+ static fromJson(jsonValue, options) {
6332
+ return new _UpdatableProjectFields_AllowedOrigins().fromJson(jsonValue, options);
6333
+ }
6334
+ static fromJsonString(jsonString, options) {
6335
+ return new _UpdatableProjectFields_AllowedOrigins().fromJsonString(jsonString, options);
6336
+ }
6337
+ static equals(a, b) {
6338
+ return proto3.util.equals(_UpdatableProjectFields_AllowedOrigins, a, b);
6339
+ }
6340
+ };
6341
+ __publicField(_UpdatableProjectFields_AllowedOrigins, "runtime", proto3);
6342
+ __publicField(_UpdatableProjectFields_AllowedOrigins, "typeName", "yorkie.v1.UpdatableProjectFields.AllowedOrigins");
6343
+ __publicField(_UpdatableProjectFields_AllowedOrigins, "fields", proto3.util.newFieldList(() => [
6344
+ { no: 1, name: "origins", kind: "scalar", T: 9, repeated: true }
6345
+ ]));
6346
+ let UpdatableProjectFields_AllowedOrigins = _UpdatableProjectFields_AllowedOrigins;
6207
6347
  const _DocumentSummary = class _DocumentSummary extends Message {
6208
6348
  constructor(data) {
6209
6349
  super();
@@ -6760,6 +6900,10 @@ const _AttachDocumentResponse = class _AttachDocumentResponse extends Message {
6760
6900
  * @generated from field: string document_id = 1;
6761
6901
  */
6762
6902
  __publicField(this, "documentId", "");
6903
+ /**
6904
+ * @generated from field: int32 max_size_per_document = 3;
6905
+ */
6906
+ __publicField(this, "maxSizePerDocument", 0);
6763
6907
  /**
6764
6908
  * @generated from field: yorkie.v1.ChangePack change_pack = 2;
6765
6909
  */
@@ -6789,6 +6933,13 @@ __publicField(_AttachDocumentResponse, "fields", proto3.util.newFieldList(() =>
6789
6933
  T: 9
6790
6934
  /* ScalarType.STRING */
6791
6935
  },
6936
+ {
6937
+ no: 3,
6938
+ name: "max_size_per_document",
6939
+ kind: "scalar",
6940
+ T: 5
6941
+ /* ScalarType.INT32 */
6942
+ },
6792
6943
  { no: 2, name: "change_pack", kind: "message", T: ChangePack$1 }
6793
6944
  ]));
6794
6945
  let AttachDocumentResponse = _AttachDocumentResponse;
@@ -7559,6 +7710,7 @@ var Code = /* @__PURE__ */ ((Code2) => {
7559
7710
  Code2["ErrDocumentNotAttached"] = "ErrDocumentNotAttached";
7560
7711
  Code2["ErrDocumentNotDetached"] = "ErrDocumentNotDetached";
7561
7712
  Code2["ErrDocumentRemoved"] = "ErrDocumentRemoved";
7713
+ Code2["ErrDocumentSizeExceedsLimit"] = "ErrDocumentSizeExceedsLimit";
7562
7714
  Code2["ErrInvalidObjectKey"] = "ErrInvalidObjectKey";
7563
7715
  Code2["ErrInvalidArgument"] = "ErrInvalidArgument";
7564
7716
  Code2["ErrNotInitialized"] = "ErrNotInitialized";
@@ -7581,76 +7733,11 @@ class YorkieError extends Error {
7581
7733
  this.toString = () => `[code=${this.code}]: ${this.message}`;
7582
7734
  }
7583
7735
  }
7584
- function deepcopy(object) {
7585
- if (object instanceof Map) {
7586
- const pairs = Array.from(object);
7587
- return new Map(JSON.parse(JSON.stringify(pairs)));
7588
- }
7589
- return JSON.parse(JSON.stringify(object));
7590
- }
7591
- const isEmpty = (object) => {
7592
- if (!object) {
7593
- return true;
7594
- }
7595
- return Object.entries(object).length === 0;
7596
- };
7597
- const stringifyObjectValues = (attributes) => {
7598
- const attrs = {};
7599
- for (const [key, value] of Object.entries(attributes)) {
7600
- attrs[key] = JSON.stringify(value);
7601
- }
7602
- return attrs;
7603
- };
7604
- const parseObjectValues = (attrs) => {
7605
- const attributes = {};
7606
- for (const [key, value] of Object.entries(attrs)) {
7607
- attributes[key] = JSON.parse(value);
7608
- }
7609
- return attributes;
7610
- };
7611
7736
  var PresenceChangeType = /* @__PURE__ */ ((PresenceChangeType2) => {
7612
7737
  PresenceChangeType2["Put"] = "put";
7613
7738
  PresenceChangeType2["Clear"] = "clear";
7614
7739
  return PresenceChangeType2;
7615
7740
  })(PresenceChangeType || {});
7616
- class Presence {
7617
- constructor(changeContext, presence) {
7618
- __publicField(this, "context");
7619
- __publicField(this, "presence");
7620
- this.context = changeContext;
7621
- this.presence = presence;
7622
- }
7623
- /**
7624
- * `set` updates the presence based on the partial presence.
7625
- */
7626
- set(presence, option) {
7627
- for (const key of Object.keys(presence)) {
7628
- this.presence[key] = presence[key];
7629
- }
7630
- this.context.setPresenceChange({
7631
- type: "put",
7632
- presence: deepcopy(this.presence)
7633
- });
7634
- this.context.setReversePresence(presence, option);
7635
- }
7636
- /**
7637
- * `get` returns the presence value of the given key.
7638
- */
7639
- get(key) {
7640
- return this.presence[key];
7641
- }
7642
- /**
7643
- * `clear` clears the presence.
7644
- * @internal
7645
- */
7646
- clear() {
7647
- this.presence = {};
7648
- this.context.setPresenceChange({
7649
- type: "clear"
7650
- /* Clear */
7651
- });
7652
- }
7653
- }
7654
7741
  const InitialActorID = "000000000000000000000000";
7655
7742
  const TimeTicketSize = 8 + 4 + 12;
7656
7743
  class TimeTicket {
@@ -7766,10 +7853,11 @@ class TimeTicket {
7766
7853
  return 0;
7767
7854
  }
7768
7855
  }
7856
+ const InitialLamport = 0n;
7769
7857
  const InitialDelimiter = 0;
7770
7858
  const MaxLamport = 9223372036854775807n;
7771
7859
  const InitialTimeTicket = new TimeTicket(
7772
- 0n,
7860
+ InitialLamport,
7773
7861
  InitialDelimiter,
7774
7862
  InitialActorID
7775
7863
  );
@@ -10980,6 +11068,50 @@ class RHT {
10980
11068
  this.numberOfRemovedElement--;
10981
11069
  }
10982
11070
  }
11071
+ function deepcopy(object) {
11072
+ if (object instanceof Map) {
11073
+ const pairs = Array.from(object);
11074
+ return new Map(JSON.parse(JSON.stringify(pairs)));
11075
+ }
11076
+ return JSON.parse(JSON.stringify(object));
11077
+ }
11078
+ const isEmpty = (object) => {
11079
+ if (!object) {
11080
+ return true;
11081
+ }
11082
+ return Object.entries(object).length === 0;
11083
+ };
11084
+ const stringifyObjectValues = (attributes) => {
11085
+ const attrs = {};
11086
+ for (const [key, value] of Object.entries(attributes)) {
11087
+ attrs[key] = JSON.stringify(value);
11088
+ }
11089
+ return attrs;
11090
+ };
11091
+ const parseObjectValues = (attrs) => {
11092
+ const attributes = {};
11093
+ for (const [key, value] of Object.entries(attrs)) {
11094
+ attributes[key] = JSON.parse(value);
11095
+ }
11096
+ return attributes;
11097
+ };
11098
+ function totalDocSize(d) {
11099
+ if (!d) return 0;
11100
+ return totalDataSize(d.live) + totalDataSize(d.gc);
11101
+ }
11102
+ function totalDataSize(d) {
11103
+ return d.data + d.meta;
11104
+ }
11105
+ function addDataSizes(target, ...others) {
11106
+ for (const other of others) {
11107
+ target.data += other.data;
11108
+ target.meta += other.meta;
11109
+ }
11110
+ }
11111
+ function subDataSize(target, other) {
11112
+ target.data -= other.data;
11113
+ target.meta -= other.meta;
11114
+ }
10983
11115
  class CRDTTextValue {
10984
11116
  constructor(content) {
10985
11117
  __publicField(this, "attributes");
@@ -11115,7 +11247,7 @@ class CRDTText extends CRDTElement {
11115
11247
  crdtTextValue.setAttr(k, v, editedAt);
11116
11248
  }
11117
11249
  }
11118
- const [caretPos, pairs, valueChanges] = this.rgaTreeSplit.edit(
11250
+ const [caretPos, pairs, diff, valueChanges] = this.rgaTreeSplit.edit(
11119
11251
  range,
11120
11252
  editedAt,
11121
11253
  crdtTextValue,
@@ -11133,7 +11265,7 @@ class CRDTText extends CRDTElement {
11133
11265
  type: "content"
11134
11266
  /* Content */
11135
11267
  }));
11136
- return [changes, pairs, [caretPos, caretPos]];
11268
+ return [changes, pairs, diff, [caretPos, caretPos]];
11137
11269
  }
11138
11270
  /**
11139
11271
  * `setStyle` applies the style of the given range.
@@ -11146,11 +11278,16 @@ class CRDTText extends CRDTElement {
11146
11278
  * @internal
11147
11279
  */
11148
11280
  setStyle(range, attributes, editedAt, versionVector) {
11149
- const [, toRight] = this.rgaTreeSplit.findNodeWithSplit(range[1], editedAt);
11150
- const [, fromRight] = this.rgaTreeSplit.findNodeWithSplit(
11281
+ const diff = { data: 0, meta: 0 };
11282
+ const [, diffTo, toRight] = this.rgaTreeSplit.findNodeWithSplit(
11283
+ range[1],
11284
+ editedAt
11285
+ );
11286
+ const [, diffFrom, fromRight] = this.rgaTreeSplit.findNodeWithSplit(
11151
11287
  range[0],
11152
11288
  editedAt
11153
11289
  );
11290
+ addDataSizes(diff, diffTo, diffFrom);
11154
11291
  const changes = [];
11155
11292
  const nodes = this.rgaTreeSplit.findBetween(fromRight, toRight);
11156
11293
  const toBeStyleds = [];
@@ -11186,9 +11323,13 @@ class CRDTText extends CRDTElement {
11186
11323
  if (prev !== void 0) {
11187
11324
  pairs.push({ parent: node.getValue(), child: prev });
11188
11325
  }
11326
+ const curr = node.getValue().getAttrs().getNodeMapByKey().get(key);
11327
+ if (curr !== void 0) {
11328
+ addDataSizes(diff, curr.getDataSize());
11329
+ }
11189
11330
  }
11190
11331
  }
11191
- return [pairs, changes];
11332
+ return [pairs, diff, changes];
11192
11333
  }
11193
11334
  /**
11194
11335
  * `indexRangeToPosRange` returns the position range of the given index range.
@@ -11377,13 +11518,14 @@ class EditOperation extends Operation {
11377
11518
  );
11378
11519
  }
11379
11520
  const text = parentObject;
11380
- const [changes, pairs] = text.edit(
11521
+ const [changes, pairs, diff] = text.edit(
11381
11522
  [this.fromPos, this.toPos],
11382
11523
  this.content,
11383
11524
  this.getExecutedAt(),
11384
11525
  Object.fromEntries(this.attributes),
11385
11526
  versionVector
11386
11527
  );
11528
+ root.acc(diff);
11387
11529
  for (const pair of pairs) {
11388
11530
  root.registerGCPair(pair);
11389
11531
  }
@@ -11480,12 +11622,13 @@ class StyleOperation extends Operation {
11480
11622
  );
11481
11623
  }
11482
11624
  const text = parentObject;
11483
- const [pairs, changes] = text.setStyle(
11625
+ const [pairs, diff, changes] = text.setStyle(
11484
11626
  [this.fromPos, this.toPos],
11485
11627
  this.attributes ? Object.fromEntries(this.attributes) : {},
11486
11628
  this.getExecutedAt(),
11487
11629
  versionVector
11488
11630
  );
11631
+ root.acc(diff);
11489
11632
  for (const pair of pairs) {
11490
11633
  root.registerGCPair(pair);
11491
11634
  }
@@ -11639,19 +11782,23 @@ class IndexTreeNode {
11639
11782
  * `splitText` splits the given node at the given offset.
11640
11783
  */
11641
11784
  splitText(offset, absOffset) {
11785
+ const diff = { data: 0, meta: 0 };
11642
11786
  if (offset === 0 || offset === this.size) {
11643
- return;
11787
+ return [void 0, diff];
11644
11788
  }
11645
11789
  const leftValue = this.value.slice(0, offset);
11646
11790
  const rightValue = this.value.slice(offset);
11647
11791
  if (!rightValue.length) {
11648
- return;
11792
+ return [void 0, diff];
11649
11793
  }
11794
+ const prvSize = this.getDataSize();
11650
11795
  this.value = leftValue;
11651
11796
  const rightNode = this.cloneText(offset + absOffset);
11652
11797
  rightNode.value = rightValue;
11653
11798
  this.parent.insertAfterInternal(rightNode, this);
11654
- return rightNode;
11799
+ addDataSizes(diff, this.getDataSize(), rightNode.getDataSize());
11800
+ subDataSize(diff, prvSize);
11801
+ return [rightNode, diff];
11655
11802
  }
11656
11803
  /**
11657
11804
  * `children` returns the children of the node.
@@ -11766,6 +11913,8 @@ class IndexTreeNode {
11766
11913
  * `splitElement` splits the given element at the given offset.
11767
11914
  */
11768
11915
  splitElement(offset, issueTimeTicket) {
11916
+ const diff = { data: 0, meta: 0 };
11917
+ const prvSize = this.getDataSize();
11769
11918
  const clone = this.cloneElement(issueTimeTicket);
11770
11919
  this.parent.insertAfterInternal(clone, this);
11771
11920
  clone.updateAncestorsSize();
@@ -11784,7 +11933,9 @@ class IndexTreeNode {
11784
11933
  for (const child of clone._children) {
11785
11934
  child.parent = clone;
11786
11935
  }
11787
- return clone;
11936
+ addDataSizes(diff, this.getDataSize(), clone.getDataSize());
11937
+ subDataSize(diff, prvSize);
11938
+ return [clone, diff];
11788
11939
  }
11789
11940
  /**
11790
11941
  * `insertAfterInternal` inserts the given node after the given child.
@@ -12777,7 +12928,7 @@ class CRDTTreeNode extends IndexTreeNode {
12777
12928
  * `split` splits the given offset of this node.
12778
12929
  */
12779
12930
  split(tree, offset, issueTimeTicket) {
12780
- const split = this.isText ? this.splitText(offset, this.id.getOffset()) : this.splitElement(offset, issueTimeTicket);
12931
+ const [split, diff] = this.isText ? this.splitText(offset, this.id.getOffset()) : this.splitElement(offset, issueTimeTicket);
12781
12932
  if (split) {
12782
12933
  split.insPrevID = this.id;
12783
12934
  if (this.insNextID) {
@@ -12788,7 +12939,7 @@ class CRDTTreeNode extends IndexTreeNode {
12788
12939
  this.insNextID = split.id;
12789
12940
  tree.registerNode(split);
12790
12941
  }
12791
- return split;
12942
+ return [split, diff];
12792
12943
  }
12793
12944
  /**
12794
12945
  * `getCreatedAt` returns the creation time of this element.
@@ -12979,15 +13130,17 @@ class CRDTTree extends CRDTElement {
12979
13130
  * for concurrent insertion.
12980
13131
  */
12981
13132
  findNodesAndSplitText(pos, editedAt) {
13133
+ let diff = { data: 0, meta: 0 };
12982
13134
  const [parent, leftSibling] = pos.toTreeNodePair(this);
12983
13135
  let leftNode = leftSibling;
12984
13136
  const isLeftMost = parent === leftNode;
12985
13137
  const realParent = leftNode.parent && !isLeftMost ? leftNode.parent : parent;
12986
13138
  if (leftNode.isText) {
12987
- leftNode.split(
13139
+ const [, splitedDiff] = leftNode.split(
12988
13140
  this,
12989
13141
  pos.getLeftSiblingID().getOffset() - leftNode.id.getOffset()
12990
13142
  );
13143
+ diff = splitedDiff;
12991
13144
  }
12992
13145
  if (editedAt) {
12993
13146
  const allChildren = realParent.allChildren;
@@ -13000,17 +13153,22 @@ class CRDTTree extends CRDTElement {
13000
13153
  leftNode = next;
13001
13154
  }
13002
13155
  }
13003
- return [realParent, leftNode];
13156
+ return [[realParent, leftNode], diff];
13004
13157
  }
13005
13158
  /**
13006
13159
  * `style` applies the given attributes of the given range.
13007
13160
  */
13008
13161
  style(range, attributes, editedAt, versionVector) {
13009
- const [fromParent, fromLeft] = this.findNodesAndSplitText(
13162
+ const diff = { data: 0, meta: 0 };
13163
+ const [[fromParent, fromLeft], diffFrom] = this.findNodesAndSplitText(
13010
13164
  range[0],
13011
13165
  editedAt
13012
13166
  );
13013
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1], editedAt);
13167
+ const [[toParent, toLeft], diffTo] = this.findNodesAndSplitText(
13168
+ range[1],
13169
+ editedAt
13170
+ );
13171
+ addDataSizes(diff, diffTo, diffFrom);
13014
13172
  const changes = [];
13015
13173
  const attrs = attributes ? parseObjectValues(attributes) : {};
13016
13174
  const pairs = [];
@@ -13019,7 +13177,8 @@ class CRDTTree extends CRDTElement {
13019
13177
  fromLeft,
13020
13178
  toParent,
13021
13179
  toLeft,
13022
- ([node]) => {
13180
+ ([node, tokenType]) => {
13181
+ var _a2;
13023
13182
  const actorID = node.getCreatedAt().getActorID();
13024
13183
  let clientLamportAtChange = MaxLamport;
13025
13184
  if (versionVector != void 0) {
@@ -13055,20 +13214,31 @@ class CRDTTree extends CRDTElement {
13055
13214
  pairs.push({ parent: node, child: prev });
13056
13215
  }
13057
13216
  }
13217
+ for (const [key] of Object.entries(attrs)) {
13218
+ const curr = (_a2 = node.attrs) == null ? void 0 : _a2.getNodeMapByKey().get(key);
13219
+ if (curr !== void 0 && tokenType !== TokenType.End) {
13220
+ addDataSizes(diff, curr.getDataSize());
13221
+ }
13222
+ }
13058
13223
  }
13059
13224
  }
13060
13225
  );
13061
- return [pairs, changes];
13226
+ return [pairs, changes, diff];
13062
13227
  }
13063
13228
  /**
13064
13229
  * `removeStyle` removes the given attributes of the given range.
13065
13230
  */
13066
13231
  removeStyle(range, attributesToRemove, editedAt, versionVector) {
13067
- const [fromParent, fromLeft] = this.findNodesAndSplitText(
13232
+ const diff = { data: 0, meta: 0 };
13233
+ const [[fromParent, fromLeft], diffFrom] = this.findNodesAndSplitText(
13068
13234
  range[0],
13069
13235
  editedAt
13070
13236
  );
13071
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1], editedAt);
13237
+ const [[toParent, toLeft], diffTo] = this.findNodesAndSplitText(
13238
+ range[1],
13239
+ editedAt
13240
+ );
13241
+ addDataSizes(diff, diffTo, diffFrom);
13072
13242
  const changes = [];
13073
13243
  const pairs = [];
13074
13244
  this.traverseInPosRange(
@@ -13106,18 +13276,23 @@ class CRDTTree extends CRDTElement {
13106
13276
  }
13107
13277
  }
13108
13278
  );
13109
- return [pairs, changes];
13279
+ return [pairs, changes, diff];
13110
13280
  }
13111
13281
  /**
13112
13282
  * `edit` edits the tree with the given range and content.
13113
13283
  * If the content is undefined, the range will be removed.
13114
13284
  */
13115
13285
  edit(range, contents, splitLevel, editedAt, issueTimeTicket, versionVector) {
13116
- const [fromParent, fromLeft] = this.findNodesAndSplitText(
13286
+ const diff = { data: 0, meta: 0 };
13287
+ const [[fromParent, fromLeft], diffFrom] = this.findNodesAndSplitText(
13117
13288
  range[0],
13118
13289
  editedAt
13119
13290
  );
13120
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1], editedAt);
13291
+ const [[toParent, toLeft], diffTo] = this.findNodesAndSplitText(
13292
+ range[1],
13293
+ editedAt
13294
+ );
13295
+ addDataSizes(diff, diffTo, diffFrom);
13121
13296
  const fromIdx = this.toIndex(fromParent, fromLeft);
13122
13297
  const fromPath = this.toPath(fromParent, fromLeft);
13123
13298
  const nodesToBeRemoved = [];
@@ -13196,6 +13371,8 @@ class CRDTTree extends CRDTElement {
13196
13371
  if (fromParent.isRemoved) {
13197
13372
  node.remove(editedAt);
13198
13373
  pairs.push({ parent: this, child: node });
13374
+ } else {
13375
+ addDataSizes(diff, node.getDataSize());
13199
13376
  }
13200
13377
  this.nodeMapByID.put(node.id, node);
13201
13378
  });
@@ -13220,7 +13397,7 @@ class CRDTTree extends CRDTElement {
13220
13397
  }
13221
13398
  }
13222
13399
  }
13223
- return [changes, pairs];
13400
+ return [changes, pairs, diff];
13224
13401
  }
13225
13402
  /**
13226
13403
  * `editT` edits the given range with the given value.
@@ -13499,16 +13676,16 @@ class CRDTTree extends CRDTElement {
13499
13676
  * `posRangeToPathRange` converts the given position range to the path range.
13500
13677
  */
13501
13678
  posRangeToPathRange(range) {
13502
- const [fromParent, fromLeft] = this.findNodesAndSplitText(range[0]);
13503
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1]);
13679
+ const [[fromParent, fromLeft]] = this.findNodesAndSplitText(range[0]);
13680
+ const [[toParent, toLeft]] = this.findNodesAndSplitText(range[1]);
13504
13681
  return [this.toPath(fromParent, fromLeft), this.toPath(toParent, toLeft)];
13505
13682
  }
13506
13683
  /**
13507
13684
  * `posRangeToIndexRange` converts the given position range to the path range.
13508
13685
  */
13509
13686
  posRangeToIndexRange(range) {
13510
- const [fromParent, fromLeft] = this.findNodesAndSplitText(range[0]);
13511
- const [toParent, toLeft] = this.findNodesAndSplitText(range[1]);
13687
+ const [[fromParent, fromLeft]] = this.findNodesAndSplitText(range[0]);
13688
+ const [[toParent, toLeft]] = this.findNodesAndSplitText(range[1]);
13512
13689
  return [this.toIndex(fromParent, fromLeft), this.toIndex(toParent, toLeft)];
13513
13690
  }
13514
13691
  /**
@@ -13703,7 +13880,7 @@ class TreeEditOperation extends Operation {
13703
13880
  }
13704
13881
  const editedAt = this.getExecutedAt();
13705
13882
  const tree = parentObject;
13706
- const [changes, pairs] = tree.edit(
13883
+ const [changes, pairs, diff] = tree.edit(
13707
13884
  [this.fromPos, this.toPos],
13708
13885
  (_a2 = this.contents) == null ? void 0 : _a2.map((content) => content.deepcopy()),
13709
13886
  this.splitLevel,
@@ -13729,6 +13906,7 @@ class TreeEditOperation extends Operation {
13729
13906
  })(),
13730
13907
  versionVector
13731
13908
  );
13909
+ root.acc(diff);
13732
13910
  for (const pair of pairs) {
13733
13911
  root.registerGCPair(pair);
13734
13912
  }
@@ -13895,12 +14073,15 @@ class ChangeID {
13895
14073
  __publicField(this, "clientSeq");
13896
14074
  // `serverSeq` is optional and only present for changes stored on the server.
13897
14075
  __publicField(this, "serverSeq");
13898
- // `lamport` and `actor` are the lamport clock and the actor of this change.
13899
- // This is used to determine the order of changes in logical time.
13900
- __publicField(this, "lamport");
14076
+ // `actor` is the creator of this change.
13901
14077
  __publicField(this, "actor");
14078
+ // `lamport` is the lamport clock of this change. This is used to determine
14079
+ // the order of changes in logical time. It is optional and only present
14080
+ // if the change has operations.
14081
+ __publicField(this, "lamport");
13902
14082
  // `versionVector` is the vector clock of this change. This is used to
13903
- // determine the relationship is causal or not between changes.
14083
+ // determine the relationship is causal or not between changes. It is optional
14084
+ // and only present if the change has operations.
13904
14085
  __publicField(this, "versionVector");
13905
14086
  this.clientSeq = clientSeq;
13906
14087
  this.serverSeq = serverSeq;
@@ -13908,6 +14089,12 @@ class ChangeID {
13908
14089
  this.versionVector = vector;
13909
14090
  this.actor = actor;
13910
14091
  }
14092
+ /**
14093
+ * `hasClocks` returns true if this ID has logical clocks.
14094
+ */
14095
+ hasClocks() {
14096
+ return this.versionVector.size() > 0 && this.lamport != InitialLamport;
14097
+ }
13911
14098
  /**
13912
14099
  * `of` creates a new instance of ChangeID.
13913
14100
  */
@@ -13917,7 +14104,16 @@ class ChangeID {
13917
14104
  /**
13918
14105
  * `next` creates a next ID of this ID.
13919
14106
  */
13920
- next() {
14107
+ next(excludeClocks = false) {
14108
+ if (excludeClocks) {
14109
+ return new ChangeID(
14110
+ this.clientSeq + 1,
14111
+ this.lamport,
14112
+ this.actor,
14113
+ InitialVersionVector,
14114
+ InitialLamport
14115
+ );
14116
+ }
13921
14117
  const vector = this.versionVector.deepcopy();
13922
14118
  vector.set(this.actor, this.lamport + 1n);
13923
14119
  return new ChangeID(
@@ -13928,9 +14124,13 @@ class ChangeID {
13928
14124
  );
13929
14125
  }
13930
14126
  /**
13931
- * `syncClocks` syncs logical clocks with the given ID.
14127
+ * `syncClocks` syncs logical clocks with the given ID. If the given ID
14128
+ * doesn't have logical clocks, this ID is returned.
13932
14129
  */
13933
14130
  syncClocks(other) {
14131
+ if (!other.hasClocks()) {
14132
+ return this;
14133
+ }
13934
14134
  const lamport = other.lamport > this.lamport ? other.lamport + 1n : this.lamport + 1n;
13935
14135
  const maxVersionVector = this.versionVector.max(other.versionVector);
13936
14136
  const newID = new ChangeID(
@@ -13971,6 +14171,18 @@ class ChangeID {
13971
14171
  this.serverSeq
13972
14172
  );
13973
14173
  }
14174
+ /**
14175
+ * `setLamport` sets the given lamport clock.
14176
+ */
14177
+ setLamport(lamport) {
14178
+ return new ChangeID(
14179
+ this.clientSeq,
14180
+ lamport,
14181
+ this.actor,
14182
+ this.versionVector,
14183
+ this.serverSeq
14184
+ );
14185
+ }
13974
14186
  /**
13975
14187
  * `setVersionVector` sets the given version vector.
13976
14188
  */
@@ -14749,8 +14961,16 @@ class RGATreeSplit {
14749
14961
  * @returns `[RGATreeSplitPos, Array<GCPair>, Array<Change>]`
14750
14962
  */
14751
14963
  edit(range, editedAt, value, versionVector) {
14752
- const [toLeft, toRight] = this.findNodeWithSplit(range[1], editedAt);
14753
- const [fromLeft, fromRight] = this.findNodeWithSplit(range[0], editedAt);
14964
+ const diff = { data: 0, meta: 0 };
14965
+ const [toLeft, diffTo, toRight] = this.findNodeWithSplit(
14966
+ range[1],
14967
+ editedAt
14968
+ );
14969
+ const [fromLeft, diffFrom, fromRight] = this.findNodeWithSplit(
14970
+ range[0],
14971
+ editedAt
14972
+ );
14973
+ addDataSizes(diff, diffTo, diffFrom);
14754
14974
  const nodesToDelete = this.findBetween(fromRight, toRight);
14755
14975
  const [changes, removedNodes] = this.deleteNodes(
14756
14976
  nodesToDelete,
@@ -14765,6 +14985,7 @@ class RGATreeSplit {
14765
14985
  fromLeft,
14766
14986
  RGATreeSplitNode.create(RGATreeSplitNodeID.of(editedAt, 0), value)
14767
14987
  );
14988
+ addDataSizes(diff, inserted.getDataSize());
14768
14989
  if (changes.length && changes[changes.length - 1].from === idx) {
14769
14990
  changes[changes.length - 1].value = value;
14770
14991
  } else {
@@ -14784,7 +15005,7 @@ class RGATreeSplit {
14784
15005
  for (const [, removedNode] of removedNodes) {
14785
15006
  pairs.push({ parent: this, child: removedNode });
14786
15007
  }
14787
- return [caretPos, pairs, changes];
15008
+ return [caretPos, pairs, diff, changes];
14788
15009
  }
14789
15010
  /**
14790
15011
  * `indexToPos` finds RGATreeSplitPos of given offset.
@@ -14923,11 +15144,11 @@ class RGATreeSplit {
14923
15144
  const absoluteID = pos.getAbsoluteID();
14924
15145
  let node = this.findFloorNodePreferToLeft(absoluteID);
14925
15146
  const relativeOffset = absoluteID.getOffset() - node.getID().getOffset();
14926
- this.splitNode(node, relativeOffset);
15147
+ const [, diff] = this.splitNode(node, relativeOffset);
14927
15148
  while (node.hasNext() && node.getNext().getCreatedAt().after(editedAt)) {
14928
15149
  node = node.getNext();
14929
15150
  }
14930
- return [node, node.getNext()];
15151
+ return [node, diff, node.getNext()];
14931
15152
  }
14932
15153
  findFloorNodePreferToLeft(id) {
14933
15154
  let node = this.findFloorNode(id);
@@ -14968,6 +15189,7 @@ class RGATreeSplit {
14968
15189
  return nodes;
14969
15190
  }
14970
15191
  splitNode(node, offset) {
15192
+ const diff = { data: 0, meta: 0 };
14971
15193
  if (offset > node.getContentLength()) {
14972
15194
  throw new YorkieError(
14973
15195
  Code.ErrInvalidArgument,
@@ -14975,10 +15197,11 @@ class RGATreeSplit {
14975
15197
  );
14976
15198
  }
14977
15199
  if (offset === 0) {
14978
- return node;
15200
+ return [node, diff];
14979
15201
  } else if (offset === node.getContentLength()) {
14980
- return node.getNext();
15202
+ return [node.getNext(), diff];
14981
15203
  }
15204
+ const prvSize = node.getDataSize();
14982
15205
  const splitNode = node.split(offset);
14983
15206
  this.treeByIndex.updateWeight(splitNode);
14984
15207
  this.insertAfter(node, splitNode);
@@ -14987,7 +15210,9 @@ class RGATreeSplit {
14987
15210
  insNext.setInsPrev(splitNode);
14988
15211
  }
14989
15212
  splitNode.setInsPrev(node);
14990
- return splitNode;
15213
+ addDataSizes(diff, node.getDataSize(), splitNode.getDataSize());
15214
+ subDataSize(diff, prvSize);
15215
+ return [splitNode, diff];
14991
15216
  }
14992
15217
  deleteNodes(candidates, editedAt, versionVector) {
14993
15218
  if (!candidates.length) {
@@ -15456,10 +15681,11 @@ class TreeStyleOperation extends Operation {
15456
15681
  const tree = parentObject;
15457
15682
  let changes;
15458
15683
  let pairs;
15684
+ let diff = { data: 0, meta: 0 };
15459
15685
  if (this.attributes.size) {
15460
15686
  const attributes = {};
15461
15687
  [...this.attributes].forEach(([key, value]) => attributes[key] = value);
15462
- [pairs, changes] = tree.style(
15688
+ [pairs, changes, diff] = tree.style(
15463
15689
  [this.fromPos, this.toPos],
15464
15690
  attributes,
15465
15691
  this.getExecutedAt(),
@@ -15467,13 +15693,14 @@ class TreeStyleOperation extends Operation {
15467
15693
  );
15468
15694
  } else {
15469
15695
  const attributesToRemove = this.attributesToRemove;
15470
- [pairs, changes] = tree.removeStyle(
15696
+ [pairs, changes, diff] = tree.removeStyle(
15471
15697
  [this.fromPos, this.toPos],
15472
15698
  attributesToRemove,
15473
15699
  this.getExecutedAt(),
15474
15700
  versionVector
15475
15701
  );
15476
15702
  }
15703
+ root.acc(diff);
15477
15704
  for (const pair of pairs) {
15478
15705
  root.registerGCPair(pair);
15479
15706
  }
@@ -16926,8 +17153,9 @@ function createObservable(executor) {
16926
17153
  };
16927
17154
  }
16928
17155
  class ChangeContext {
16929
- constructor(id, root, presence, message) {
16930
- __publicField(this, "id");
17156
+ constructor(prevID, root, presence, message) {
17157
+ __publicField(this, "prevID");
17158
+ __publicField(this, "nextID");
16931
17159
  __publicField(this, "delimiter");
16932
17160
  __publicField(this, "message");
16933
17161
  __publicField(this, "root");
@@ -16943,7 +17171,8 @@ class ChangeContext {
16943
17171
  * presence changes.
16944
17172
  */
16945
17173
  __publicField(this, "reversePresenceKeys");
16946
- this.id = id;
17174
+ this.prevID = prevID;
17175
+ this.nextID = prevID.next();
16947
17176
  this.delimiter = InitialDelimiter;
16948
17177
  this.root = root;
16949
17178
  this.operations = [];
@@ -16955,8 +17184,8 @@ class ChangeContext {
16955
17184
  /**
16956
17185
  * `create` creates a new instance of ChangeContext.
16957
17186
  */
16958
- static create(id, root, presence, message) {
16959
- return new ChangeContext(id, root, presence, message);
17187
+ static create(prevID, root, presence, message) {
17188
+ return new ChangeContext(prevID, root, presence, message);
16960
17189
  }
16961
17190
  /**
16962
17191
  * `push` pushes the given operation to this context.
@@ -16983,16 +17212,34 @@ class ChangeContext {
16983
17212
  this.root.registerGCPair(pair);
16984
17213
  }
16985
17214
  /**
16986
- * `getChange` creates a new instance of Change in this context.
17215
+ * `getNextID` returns the next ID of this context. It will be set to the
17216
+ * document for the next change.returns the next ID of this context.
16987
17217
  */
16988
- getChange() {
17218
+ getNextID() {
17219
+ if (this.isPresenceOnlyChange()) {
17220
+ return this.prevID.next(true).setLamport(this.prevID.getLamport()).setVersionVector(this.prevID.getVersionVector());
17221
+ }
17222
+ return this.nextID;
17223
+ }
17224
+ /**
17225
+ * `toChange` creates a new instance of Change in this context.
17226
+ */
17227
+ toChange() {
17228
+ const id = this.isPresenceOnlyChange() ? this.prevID.next(true) : this.nextID;
16989
17229
  return Change.create({
16990
- id: this.id,
17230
+ id,
16991
17231
  operations: this.operations,
16992
17232
  presenceChange: this.presenceChange,
16993
17233
  message: this.message
16994
17234
  });
16995
17235
  }
17236
+ /**
17237
+ * `isPresenceOnlyChange` returns whether this context is only for presence
17238
+ * change or not.
17239
+ */
17240
+ isPresenceOnlyChange() {
17241
+ return this.operations.length === 0;
17242
+ }
16996
17243
  /**
16997
17244
  * `hasChange` returns whether this context has change or not.
16998
17245
  */
@@ -17033,13 +17280,19 @@ class ChangeContext {
17033
17280
  */
17034
17281
  issueTimeTicket() {
17035
17282
  this.delimiter += 1;
17036
- return this.id.createTimeTicket(this.delimiter);
17283
+ return this.nextID.createTimeTicket(this.delimiter);
17037
17284
  }
17038
17285
  /**
17039
17286
  * `getLastTimeTicket` returns the last time ticket issued in this context.
17040
17287
  */
17041
17288
  getLastTimeTicket() {
17042
- return this.id.createTimeTicket(this.delimiter);
17289
+ return this.nextID.createTimeTicket(this.delimiter);
17290
+ }
17291
+ /**
17292
+ * `acc` accumulates the given DataSize to Live size of the root.
17293
+ */
17294
+ acc(diff) {
17295
+ this.root.acc(diff);
17043
17296
  }
17044
17297
  }
17045
17298
  class CRDTRoot {
@@ -17064,10 +17317,15 @@ class CRDTRoot {
17064
17317
  * element itself and its parent.
17065
17318
  */
17066
17319
  __publicField(this, "gcPairMap");
17320
+ /**
17321
+ * `docSize` is a structure that represents the size of the document.
17322
+ */
17323
+ __publicField(this, "docSize");
17067
17324
  this.rootObject = rootObject;
17068
17325
  this.elementPairMapByCreatedAt = /* @__PURE__ */ new Map();
17069
17326
  this.gcElementSetByCreatedAt = /* @__PURE__ */ new Set();
17070
17327
  this.gcPairMap = /* @__PURE__ */ new Map();
17328
+ this.docSize = { live: { data: 0, meta: 0 }, gc: { data: 0, meta: 0 } };
17071
17329
  this.registerElement(rootObject, void 0);
17072
17330
  rootObject.getDescendants((elem) => {
17073
17331
  if (elem.getRemovedAt()) {
@@ -17144,6 +17402,7 @@ class CRDTRoot {
17144
17402
  parent,
17145
17403
  element
17146
17404
  });
17405
+ addDataSizes(this.docSize.live, element.getDataSize());
17147
17406
  if (element instanceof CRDTContainer) {
17148
17407
  element.getDescendants((elem, parent2) => {
17149
17408
  this.registerElement(elem, parent2);
@@ -17158,6 +17417,7 @@ class CRDTRoot {
17158
17417
  let count = 0;
17159
17418
  const deregisterElementInternal = (elem) => {
17160
17419
  const createdAt = elem.getCreatedAt().toIDString();
17420
+ subDataSize(this.docSize.gc, elem.getDataSize());
17161
17421
  this.elementPairMapByCreatedAt.delete(createdAt);
17162
17422
  this.gcElementSetByCreatedAt.delete(createdAt);
17163
17423
  count++;
@@ -17175,6 +17435,9 @@ class CRDTRoot {
17175
17435
  * `registerRemovedElement` registers the given element to the hash set.
17176
17436
  */
17177
17437
  registerRemovedElement(element) {
17438
+ addDataSizes(this.docSize.gc, element.getDataSize());
17439
+ subDataSize(this.docSize.live, element.getDataSize());
17440
+ this.docSize.live.meta += TimeTicketSize;
17178
17441
  this.gcElementSetByCreatedAt.add(element.getCreatedAt().toIDString());
17179
17442
  }
17180
17443
  /**
@@ -17187,6 +17450,12 @@ class CRDTRoot {
17187
17450
  return;
17188
17451
  }
17189
17452
  this.gcPairMap.set(pair.child.toIDString(), pair);
17453
+ const size = this.gcPairMap.get(pair.child.toIDString()).child.getDataSize();
17454
+ addDataSizes(this.docSize.gc, size);
17455
+ subDataSize(this.docSize.live, size);
17456
+ if (!(pair.child instanceof RHTNode)) {
17457
+ this.docSize.live.meta += TimeTicketSize;
17458
+ }
17190
17459
  }
17191
17460
  /**
17192
17461
  * `getElementMapSize` returns the size of element map.
@@ -17227,22 +17496,7 @@ class CRDTRoot {
17227
17496
  * `getDocSize` returns the size of the document.
17228
17497
  */
17229
17498
  getDocSize() {
17230
- const docSize = { live: { data: 0, meta: 0 }, gc: { data: 0, meta: 0 } };
17231
- for (const [createdAt, value] of this.elementPairMapByCreatedAt) {
17232
- if (this.gcElementSetByCreatedAt.has(createdAt)) {
17233
- docSize.gc.data += value.element.getDataSize().data;
17234
- docSize.gc.meta += value.element.getDataSize().meta;
17235
- } else {
17236
- docSize.live.data += value.element.getDataSize().data;
17237
- docSize.live.meta += value.element.getDataSize().meta;
17238
- }
17239
- }
17240
- for (const pair of this.gcPairMap.values()) {
17241
- const size = pair.child.getDataSize();
17242
- docSize.gc.data += size.data;
17243
- docSize.gc.meta += size.meta;
17244
- }
17245
- return docSize;
17499
+ return this.docSize;
17246
17500
  }
17247
17501
  /**
17248
17502
  * `deepcopy` copies itself deeply.
@@ -17296,6 +17550,12 @@ class CRDTRoot {
17296
17550
  gcElements: this.getGarbageElementSetSize()
17297
17551
  };
17298
17552
  }
17553
+ /**
17554
+ * `acc` accumulates the given DataSize to Live.
17555
+ */
17556
+ acc(diff) {
17557
+ addDataSizes(this.docSize.live, diff);
17558
+ }
17299
17559
  }
17300
17560
  function createJSONObject(context, target) {
17301
17561
  const objectProxy = new ObjectProxy(context);
@@ -17913,12 +18173,13 @@ class Text {
17913
18173
  }
17914
18174
  const attrs = attributes ? stringifyObjectValues(attributes) : void 0;
17915
18175
  const ticket = this.context.issueTimeTicket();
17916
- const [, pairs, rangeAfterEdit] = this.text.edit(
18176
+ const [, pairs, diff, rangeAfterEdit] = this.text.edit(
17917
18177
  range,
17918
18178
  content,
17919
18179
  ticket,
17920
18180
  attrs
17921
18181
  );
18182
+ this.context.acc(diff);
17922
18183
  for (const pair of pairs) {
17923
18184
  this.context.registerGCPair(pair);
17924
18185
  }
@@ -17972,7 +18233,8 @@ class Text {
17972
18233
  }
17973
18234
  const attrs = stringifyObjectValues(attributes);
17974
18235
  const ticket = this.context.issueTimeTicket();
17975
- const [pairs] = this.text.setStyle(range, attrs, ticket);
18236
+ const [pairs, diff] = this.text.setStyle(range, attrs, ticket);
18237
+ this.context.acc(diff);
17976
18238
  for (const pair of pairs) {
17977
18239
  this.context.registerGCPair(pair);
17978
18240
  }
@@ -18515,7 +18777,8 @@ class Tree {
18515
18777
  const [fromPos, toPos] = this.tree.pathToPosRange(path);
18516
18778
  const ticket = this.context.issueTimeTicket();
18517
18779
  const attrs = attributes ? stringifyObjectValues(attributes) : void 0;
18518
- const [pairs] = this.tree.style([fromPos, toPos], attrs, ticket);
18780
+ const [pairs, , diff] = this.tree.style([fromPos, toPos], attrs, ticket);
18781
+ this.context.acc(diff);
18519
18782
  for (const pair of pairs) {
18520
18783
  this.context.registerGCPair(pair);
18521
18784
  }
@@ -18549,7 +18812,8 @@ class Tree {
18549
18812
  const toPos = this.tree.findPos(toIdx);
18550
18813
  const ticket = this.context.issueTimeTicket();
18551
18814
  const attrs = attributes ? stringifyObjectValues(attributes) : void 0;
18552
- const [pairs] = this.tree.style([fromPos, toPos], attrs, ticket);
18815
+ const [pairs, , diff] = this.tree.style([fromPos, toPos], attrs, ticket);
18816
+ this.context.acc(diff);
18553
18817
  for (const pair of pairs) {
18554
18818
  this.context.registerGCPair(pair);
18555
18819
  }
@@ -18582,11 +18846,12 @@ class Tree {
18582
18846
  const fromPos = this.tree.findPos(fromIdx);
18583
18847
  const toPos = this.tree.findPos(toIdx);
18584
18848
  const ticket = this.context.issueTimeTicket();
18585
- const [pairs] = this.tree.removeStyle(
18849
+ const [pairs, , diff] = this.tree.removeStyle(
18586
18850
  [fromPos, toPos],
18587
18851
  attributesToRemove,
18588
18852
  ticket
18589
18853
  );
18854
+ this.context.acc(diff);
18590
18855
  for (const pair of pairs) {
18591
18856
  this.context.registerGCPair(pair);
18592
18857
  }
@@ -18629,13 +18894,14 @@ class Tree {
18629
18894
  } else {
18630
18895
  crdtNodes = contents.map((content) => content && createCRDTTreeNode(this.context, content)).filter((a) => a);
18631
18896
  }
18632
- const [, pairs] = this.tree.edit(
18897
+ const [, pairs, diff] = this.tree.edit(
18633
18898
  [fromPos, toPos],
18634
18899
  crdtNodes.length ? crdtNodes.map((crdtNode) => crdtNode == null ? void 0 : crdtNode.deepcopy()) : void 0,
18635
18900
  splitLevel,
18636
18901
  ticket,
18637
18902
  () => this.context.issueTimeTicket()
18638
18903
  );
18904
+ this.context.acc(diff);
18639
18905
  for (const pair of pairs) {
18640
18906
  this.context.registerGCPair(pair);
18641
18907
  }
@@ -18968,6 +19234,43 @@ function buildCRDTElement(context, value, createdAt) {
18968
19234
  }
18969
19235
  return element;
18970
19236
  }
19237
+ class Presence {
19238
+ constructor(changeContext, presence) {
19239
+ __publicField(this, "context");
19240
+ __publicField(this, "presence");
19241
+ this.context = changeContext;
19242
+ this.presence = presence;
19243
+ }
19244
+ /**
19245
+ * `set` updates the presence based on the partial presence.
19246
+ */
19247
+ set(presence, option) {
19248
+ for (const key of Object.keys(presence)) {
19249
+ this.presence[key] = presence[key];
19250
+ }
19251
+ this.context.setPresenceChange({
19252
+ type: PresenceChangeType.Put,
19253
+ presence: deepcopy(this.presence)
19254
+ });
19255
+ this.context.setReversePresence(presence, option);
19256
+ }
19257
+ /**
19258
+ * `get` returns the presence value of the given key.
19259
+ */
19260
+ get(key) {
19261
+ return this.presence[key];
19262
+ }
19263
+ /**
19264
+ * `clear` clears the presence.
19265
+ * @internal
19266
+ */
19267
+ clear() {
19268
+ this.presence = {};
19269
+ this.context.setPresenceChange({
19270
+ type: PresenceChangeType.Clear
19271
+ });
19272
+ }
19273
+ }
18971
19274
  const MaxUndoRedoStackDepth = 50;
18972
19275
  class History {
18973
19276
  constructor() {
@@ -19178,6 +19481,7 @@ class Document {
19178
19481
  __publicField(this, "changeID");
19179
19482
  __publicField(this, "checkpoint");
19180
19483
  __publicField(this, "localChanges");
19484
+ __publicField(this, "maxSizeLimit");
19181
19485
  __publicField(this, "root");
19182
19486
  __publicField(this, "clone");
19183
19487
  __publicField(this, "eventStream");
@@ -19210,6 +19514,7 @@ class Document {
19210
19514
  this.changeID = InitialChangeID;
19211
19515
  this.checkpoint = InitialCheckpoint;
19212
19516
  this.localChanges = [];
19517
+ this.maxSizeLimit = 0;
19213
19518
  this.eventStream = createObservable((observer) => {
19214
19519
  this.eventStreamObserver = observer;
19215
19520
  });
@@ -19229,13 +19534,14 @@ class Document {
19229
19534
  * `update` executes the given updater to update this document.
19230
19535
  */
19231
19536
  update(updater, message) {
19537
+ var _a2;
19232
19538
  if (this.getStatus() === "removed") {
19233
19539
  throw new YorkieError(Code.ErrDocumentRemoved, `${this.key} is removed`);
19234
19540
  }
19235
19541
  this.ensureClone();
19236
19542
  const actorID = this.changeID.getActorID();
19237
19543
  const context = ChangeContext.create(
19238
- this.changeID.next(),
19544
+ this.changeID,
19239
19545
  this.clone.root,
19240
19546
  this.clone.presences.get(actorID) || {},
19241
19547
  message
@@ -19259,11 +19565,19 @@ class Document {
19259
19565
  } finally {
19260
19566
  this.isUpdating = false;
19261
19567
  }
19568
+ const size = totalDocSize((_a2 = this.clone) == null ? void 0 : _a2.root.getDocSize());
19569
+ if (!context.isPresenceOnlyChange() && this.maxSizeLimit > 0 && this.maxSizeLimit < size) {
19570
+ this.clone = void 0;
19571
+ throw new YorkieError(
19572
+ Code.ErrDocumentSizeExceedsLimit,
19573
+ `document size exceeded: ${size} > ${this.maxSizeLimit}`
19574
+ );
19575
+ }
19262
19576
  if (context.hasChange()) {
19263
19577
  if (logger.isEnabled(LogLevel.Trivial)) {
19264
19578
  logger.trivial(`trying to update a local change: ${this.toJSON()}`);
19265
19579
  }
19266
- const change = context.getChange();
19580
+ const change = context.toChange();
19267
19581
  const { opInfos, reverseOps } = change.execute(
19268
19582
  this.root,
19269
19583
  this.presences,
@@ -19283,7 +19597,7 @@ class Document {
19283
19597
  if (opInfos.length > 0) {
19284
19598
  this.internalHistory.clearRedo();
19285
19599
  }
19286
- this.changeID = change.getID();
19600
+ this.changeID = context.getNextID();
19287
19601
  const event = [];
19288
19602
  if (opInfos.length > 0) {
19289
19603
  event.push({
@@ -19653,7 +19967,13 @@ class Document {
19653
19967
  return this.status;
19654
19968
  }
19655
19969
  /**
19656
- * `getClone` return clone object.
19970
+ * `getClone` returns this clone.
19971
+ */
19972
+ getClone() {
19973
+ return this.clone;
19974
+ }
19975
+ /**
19976
+ * `getCloneRoot` returns clone object.
19657
19977
  *
19658
19978
  * @internal
19659
19979
  */
@@ -19681,6 +20001,18 @@ class Document {
19681
20001
  getDocSize() {
19682
20002
  return this.root.getDocSize();
19683
20003
  }
20004
+ /**
20005
+ * `getMaxSizePerDocument` gets the maximum size of this document.
20006
+ */
20007
+ getMaxSizePerDocument() {
20008
+ return this.maxSizeLimit;
20009
+ }
20010
+ /**
20011
+ * `setMaxSizePerDocument` sets the maximum size of this document.
20012
+ */
20013
+ setMaxSizePerDocument(size) {
20014
+ this.maxSizeLimit = size;
20015
+ }
19684
20016
  /**
19685
20017
  * `garbageCollect` purges elements that were removed before the given time.
19686
20018
  *
@@ -20152,14 +20484,6 @@ class Document {
20152
20484
  canUndo() {
20153
20485
  return this.internalHistory.hasUndo() && !this.isUpdating;
20154
20486
  }
20155
- /**
20156
- * 'filterVersionVector' filters detached client's lamport from version vector.
20157
- */
20158
- filterVersionVector(minSyncedVersionVector) {
20159
- const versionVector = this.changeID.getVersionVector();
20160
- const filteredVersionVector = versionVector.filter(minSyncedVersionVector);
20161
- this.changeID = this.changeID.setVersionVector(filteredVersionVector);
20162
- }
20163
20487
  /**
20164
20488
  * `canRedo` returns whether there are any operations to redo.
20165
20489
  */
@@ -20186,7 +20510,7 @@ class Document {
20186
20510
  }
20187
20511
  this.ensureClone();
20188
20512
  const context = ChangeContext.create(
20189
- this.changeID.next(),
20513
+ this.changeID,
20190
20514
  this.clone.root,
20191
20515
  this.clone.presences.get(this.changeID.getActorID()) || {}
20192
20516
  );
@@ -20203,7 +20527,7 @@ class Document {
20203
20527
  undoOp.setExecutedAt(ticket);
20204
20528
  context.push(undoOp);
20205
20529
  }
20206
- const change = context.getChange();
20530
+ const change = context.toChange();
20207
20531
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20208
20532
  const { opInfos, reverseOps } = change.execute(
20209
20533
  this.root,
@@ -20224,7 +20548,7 @@ class Document {
20224
20548
  return;
20225
20549
  }
20226
20550
  this.localChanges.push(change);
20227
- this.changeID = change.getID();
20551
+ this.changeID = context.getNextID();
20228
20552
  const actorID = this.changeID.getActorID();
20229
20553
  const event = [];
20230
20554
  if (opInfos.length > 0) {
@@ -20273,7 +20597,7 @@ class Document {
20273
20597
  }
20274
20598
  this.ensureClone();
20275
20599
  const context = ChangeContext.create(
20276
- this.changeID.next(),
20600
+ this.changeID,
20277
20601
  this.clone.root,
20278
20602
  this.clone.presences.get(this.changeID.getActorID()) || {}
20279
20603
  );
@@ -20290,7 +20614,7 @@ class Document {
20290
20614
  redoOp.setExecutedAt(ticket);
20291
20615
  context.push(redoOp);
20292
20616
  }
20293
- const change = context.getChange();
20617
+ const change = context.toChange();
20294
20618
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20295
20619
  const { opInfos, reverseOps } = change.execute(
20296
20620
  this.root,
@@ -20311,7 +20635,7 @@ class Document {
20311
20635
  return;
20312
20636
  }
20313
20637
  this.localChanges.push(change);
20314
- this.changeID = change.getID();
20638
+ this.changeID = context.getNextID();
20315
20639
  const actorID = this.changeID.getActorID();
20316
20640
  const event = [];
20317
20641
  if (opInfos.length > 0) {
@@ -20390,7 +20714,7 @@ function createAuthInterceptor(apiKey, token) {
20390
20714
  };
20391
20715
  }
20392
20716
  const name = "@yorkie-js/sdk";
20393
- const version = "0.6.11-rc";
20717
+ const version = "0.6.13";
20394
20718
  const pkg = {
20395
20719
  name,
20396
20720
  version
@@ -20558,16 +20882,15 @@ class Client {
20558
20882
  if (this.status === "deactivated") {
20559
20883
  return Promise.resolve();
20560
20884
  }
20561
- this.deactivateInternal();
20562
20885
  const task = async () => {
20563
20886
  try {
20564
20887
  await this.rpcClient.deactivateClient(
20565
20888
  { clientId: this.id },
20566
20889
  { headers: { "x-shard-key": this.apiKey } }
20567
20890
  );
20891
+ this.deactivateInternal();
20568
20892
  logger.info(`[DC] c"${this.getKey()}" deactivated`);
20569
20893
  } catch (err) {
20570
- this.status = "activated";
20571
20894
  logger.error(`[DC] c:"${this.getKey()}" err :`, err);
20572
20895
  await this.handleConnectError(err);
20573
20896
  throw err;
@@ -20631,6 +20954,10 @@ class Client {
20631
20954
  },
20632
20955
  { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20633
20956
  );
20957
+ const maxSize = res.maxSizePerDocument ?? 0;
20958
+ if (maxSize > 0) {
20959
+ doc.setMaxSizePerDocument(res.maxSizePerDocument);
20960
+ }
20634
20961
  const pack = converter.fromChangePack(res.changePack);
20635
20962
  doc.applyChangePack(pack);
20636
20963
  if (doc.getStatus() === DocStatus.Removed) {
@@ -20651,12 +20978,12 @@ class Client {
20651
20978
  await this.runWatchLoop(doc.getKey());
20652
20979
  }
20653
20980
  logger.info(`[AD] c:"${this.getKey()}" attaches d:"${doc.getKey()}"`);
20654
- const crdtRoot = doc.getRootObject();
20981
+ const crdtObject = doc.getRootObject();
20655
20982
  if (opts.initialRoot) {
20656
20983
  const initialRoot = opts.initialRoot;
20657
20984
  doc.update((root) => {
20658
20985
  for (const [k, v] of Object.entries(initialRoot)) {
20659
- if (!crdtRoot.has(k)) {
20986
+ if (!crdtObject.has(k)) {
20660
20987
  const key = k;
20661
20988
  root[key] = v;
20662
20989
  }
@@ -20679,7 +21006,7 @@ class Client {
20679
21006
  * the changes should be applied to other replicas before GC time. For this,
20680
21007
  * if the document is no longer used by this client, it should be detached.
20681
21008
  */
20682
- detach(doc, opts = { removeIfNotAttached: false }) {
21009
+ detach(doc, opts = { keepalive: false }) {
20683
21010
  if (!this.isActive()) {
20684
21011
  throw new YorkieError(
20685
21012
  Code.ErrClientNotActivated,
@@ -20694,14 +21021,14 @@ class Client {
20694
21021
  );
20695
21022
  }
20696
21023
  doc.update((_, p) => p.clear());
20697
- return this.enqueueTask(async () => {
21024
+ const task = async () => {
20698
21025
  try {
20699
21026
  const res = await this.rpcClient.detachDocument(
20700
21027
  {
20701
21028
  clientId: this.id,
20702
21029
  documentId: attachment.docID,
20703
21030
  changePack: converter.toChangePack(doc.createChangePack()),
20704
- removeIfNotAttached: opts.removeIfNotAttached
21031
+ removeIfNotAttached: opts.removeIfNotAttached ?? false
20705
21032
  },
20706
21033
  { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20707
21034
  );
@@ -20718,7 +21045,14 @@ class Client {
20718
21045
  await this.handleConnectError(err);
20719
21046
  throw err;
20720
21047
  }
20721
- });
21048
+ };
21049
+ if (opts.keepalive) {
21050
+ this.keepalive = true;
21051
+ const resp = task();
21052
+ this.keepalive = false;
21053
+ return resp;
21054
+ }
21055
+ return this.enqueueTask(task);
20722
21056
  }
20723
21057
  /**
20724
21058
  * `changeRealtimeSync` changes the synchronization mode of the given document.