@yorkie-js/sdk 0.6.11-rc → 0.6.12

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.
@@ -7585,76 +7585,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7585
7585
  this.toString = () => `[code=${this.code}]: ${this.message}`;
7586
7586
  }
7587
7587
  }
7588
- function deepcopy(object) {
7589
- if (object instanceof Map) {
7590
- const pairs = Array.from(object);
7591
- return new Map(JSON.parse(JSON.stringify(pairs)));
7592
- }
7593
- return JSON.parse(JSON.stringify(object));
7594
- }
7595
- const isEmpty = (object) => {
7596
- if (!object) {
7597
- return true;
7598
- }
7599
- return Object.entries(object).length === 0;
7600
- };
7601
- const stringifyObjectValues = (attributes) => {
7602
- const attrs = {};
7603
- for (const [key, value] of Object.entries(attributes)) {
7604
- attrs[key] = JSON.stringify(value);
7605
- }
7606
- return attrs;
7607
- };
7608
- const parseObjectValues = (attrs) => {
7609
- const attributes = {};
7610
- for (const [key, value] of Object.entries(attrs)) {
7611
- attributes[key] = JSON.parse(value);
7612
- }
7613
- return attributes;
7614
- };
7615
7588
  var PresenceChangeType = /* @__PURE__ */ ((PresenceChangeType2) => {
7616
7589
  PresenceChangeType2["Put"] = "put";
7617
7590
  PresenceChangeType2["Clear"] = "clear";
7618
7591
  return PresenceChangeType2;
7619
7592
  })(PresenceChangeType || {});
7620
- class Presence {
7621
- constructor(changeContext, presence) {
7622
- __publicField(this, "context");
7623
- __publicField(this, "presence");
7624
- this.context = changeContext;
7625
- this.presence = presence;
7626
- }
7627
- /**
7628
- * `set` updates the presence based on the partial presence.
7629
- */
7630
- set(presence, option) {
7631
- for (const key of Object.keys(presence)) {
7632
- this.presence[key] = presence[key];
7633
- }
7634
- this.context.setPresenceChange({
7635
- type: "put",
7636
- presence: deepcopy(this.presence)
7637
- });
7638
- this.context.setReversePresence(presence, option);
7639
- }
7640
- /**
7641
- * `get` returns the presence value of the given key.
7642
- */
7643
- get(key) {
7644
- return this.presence[key];
7645
- }
7646
- /**
7647
- * `clear` clears the presence.
7648
- * @internal
7649
- */
7650
- clear() {
7651
- this.presence = {};
7652
- this.context.setPresenceChange({
7653
- type: "clear"
7654
- /* Clear */
7655
- });
7656
- }
7657
- }
7658
7593
  const InitialActorID = "000000000000000000000000";
7659
7594
  const TimeTicketSize = 8 + 4 + 12;
7660
7595
  class TimeTicket {
@@ -7770,10 +7705,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7770
7705
  return 0;
7771
7706
  }
7772
7707
  }
7708
+ const InitialLamport = 0n;
7773
7709
  const InitialDelimiter = 0;
7774
7710
  const MaxLamport = 9223372036854775807n;
7775
7711
  const InitialTimeTicket = new TimeTicket(
7776
- 0n,
7712
+ InitialLamport,
7777
7713
  InitialDelimiter,
7778
7714
  InitialActorID
7779
7715
  );
@@ -10984,6 +10920,33 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
10984
10920
  this.numberOfRemovedElement--;
10985
10921
  }
10986
10922
  }
10923
+ function deepcopy(object) {
10924
+ if (object instanceof Map) {
10925
+ const pairs = Array.from(object);
10926
+ return new Map(JSON.parse(JSON.stringify(pairs)));
10927
+ }
10928
+ return JSON.parse(JSON.stringify(object));
10929
+ }
10930
+ const isEmpty = (object) => {
10931
+ if (!object) {
10932
+ return true;
10933
+ }
10934
+ return Object.entries(object).length === 0;
10935
+ };
10936
+ const stringifyObjectValues = (attributes) => {
10937
+ const attrs = {};
10938
+ for (const [key, value] of Object.entries(attributes)) {
10939
+ attrs[key] = JSON.stringify(value);
10940
+ }
10941
+ return attrs;
10942
+ };
10943
+ const parseObjectValues = (attrs) => {
10944
+ const attributes = {};
10945
+ for (const [key, value] of Object.entries(attrs)) {
10946
+ attributes[key] = JSON.parse(value);
10947
+ }
10948
+ return attributes;
10949
+ };
10987
10950
  class CRDTTextValue {
10988
10951
  constructor(content) {
10989
10952
  __publicField(this, "attributes");
@@ -13899,12 +13862,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13899
13862
  __publicField(this, "clientSeq");
13900
13863
  // `serverSeq` is optional and only present for changes stored on the server.
13901
13864
  __publicField(this, "serverSeq");
13902
- // `lamport` and `actor` are the lamport clock and the actor of this change.
13903
- // This is used to determine the order of changes in logical time.
13904
- __publicField(this, "lamport");
13865
+ // `actor` is the creator of this change.
13905
13866
  __publicField(this, "actor");
13867
+ // `lamport` is the lamport clock of this change. This is used to determine
13868
+ // the order of changes in logical time. It is optional and only present
13869
+ // if the change has operations.
13870
+ __publicField(this, "lamport");
13906
13871
  // `versionVector` is the vector clock of this change. This is used to
13907
- // determine the relationship is causal or not between changes.
13872
+ // determine the relationship is causal or not between changes. It is optional
13873
+ // and only present if the change has operations.
13908
13874
  __publicField(this, "versionVector");
13909
13875
  this.clientSeq = clientSeq;
13910
13876
  this.serverSeq = serverSeq;
@@ -13912,6 +13878,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13912
13878
  this.versionVector = vector;
13913
13879
  this.actor = actor;
13914
13880
  }
13881
+ /**
13882
+ * `hasClocks` returns true if this ID has logical clocks.
13883
+ */
13884
+ hasClocks() {
13885
+ return this.versionVector.size() > 0 && this.lamport != InitialLamport;
13886
+ }
13915
13887
  /**
13916
13888
  * `of` creates a new instance of ChangeID.
13917
13889
  */
@@ -13921,7 +13893,16 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13921
13893
  /**
13922
13894
  * `next` creates a next ID of this ID.
13923
13895
  */
13924
- next() {
13896
+ next(excludeClocks = false) {
13897
+ if (excludeClocks) {
13898
+ return new ChangeID(
13899
+ this.clientSeq + 1,
13900
+ this.lamport,
13901
+ this.actor,
13902
+ InitialVersionVector,
13903
+ InitialLamport
13904
+ );
13905
+ }
13925
13906
  const vector = this.versionVector.deepcopy();
13926
13907
  vector.set(this.actor, this.lamport + 1n);
13927
13908
  return new ChangeID(
@@ -13932,9 +13913,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13932
13913
  );
13933
13914
  }
13934
13915
  /**
13935
- * `syncClocks` syncs logical clocks with the given ID.
13916
+ * `syncClocks` syncs logical clocks with the given ID. If the given ID
13917
+ * doesn't have logical clocks, this ID is returned.
13936
13918
  */
13937
13919
  syncClocks(other) {
13920
+ if (!other.hasClocks()) {
13921
+ return this;
13922
+ }
13938
13923
  const lamport = other.lamport > this.lamport ? other.lamport + 1n : this.lamport + 1n;
13939
13924
  const maxVersionVector = this.versionVector.max(other.versionVector);
13940
13925
  const newID = new ChangeID(
@@ -13975,6 +13960,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13975
13960
  this.serverSeq
13976
13961
  );
13977
13962
  }
13963
+ /**
13964
+ * `setLamport` sets the given lamport clock.
13965
+ */
13966
+ setLamport(lamport) {
13967
+ return new ChangeID(
13968
+ this.clientSeq,
13969
+ lamport,
13970
+ this.actor,
13971
+ this.versionVector,
13972
+ this.serverSeq
13973
+ );
13974
+ }
13978
13975
  /**
13979
13976
  * `setVersionVector` sets the given version vector.
13980
13977
  */
@@ -16930,8 +16927,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
16930
16927
  };
16931
16928
  }
16932
16929
  class ChangeContext {
16933
- constructor(id, root, presence, message) {
16934
- __publicField(this, "id");
16930
+ constructor(prevID, root, presence, message) {
16931
+ __publicField(this, "prevID");
16932
+ __publicField(this, "nextID");
16935
16933
  __publicField(this, "delimiter");
16936
16934
  __publicField(this, "message");
16937
16935
  __publicField(this, "root");
@@ -16947,7 +16945,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
16947
16945
  * presence changes.
16948
16946
  */
16949
16947
  __publicField(this, "reversePresenceKeys");
16950
- this.id = id;
16948
+ this.prevID = prevID;
16949
+ this.nextID = prevID.next();
16951
16950
  this.delimiter = InitialDelimiter;
16952
16951
  this.root = root;
16953
16952
  this.operations = [];
@@ -16959,8 +16958,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
16959
16958
  /**
16960
16959
  * `create` creates a new instance of ChangeContext.
16961
16960
  */
16962
- static create(id, root, presence, message) {
16963
- return new ChangeContext(id, root, presence, message);
16961
+ static create(prevID, root, presence, message) {
16962
+ return new ChangeContext(prevID, root, presence, message);
16964
16963
  }
16965
16964
  /**
16966
16965
  * `push` pushes the given operation to this context.
@@ -16987,11 +16986,22 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
16987
16986
  this.root.registerGCPair(pair);
16988
16987
  }
16989
16988
  /**
16990
- * `getChange` creates a new instance of Change in this context.
16989
+ * `getNextID` returns the next ID of this context. It will be set to the
16990
+ * document for the next change.returns the next ID of this context.
16991
16991
  */
16992
- getChange() {
16992
+ getNextID() {
16993
+ if (this.operations.length === 0) {
16994
+ return this.prevID.next(true).setLamport(this.prevID.getLamport()).setVersionVector(this.prevID.getVersionVector());
16995
+ }
16996
+ return this.nextID;
16997
+ }
16998
+ /**
16999
+ * `toChange` creates a new instance of Change in this context.
17000
+ */
17001
+ toChange() {
17002
+ const id = this.operations.length === 0 ? this.prevID.next(true) : this.nextID;
16993
17003
  return Change.create({
16994
- id: this.id,
17004
+ id,
16995
17005
  operations: this.operations,
16996
17006
  presenceChange: this.presenceChange,
16997
17007
  message: this.message
@@ -17037,13 +17047,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
17037
17047
  */
17038
17048
  issueTimeTicket() {
17039
17049
  this.delimiter += 1;
17040
- return this.id.createTimeTicket(this.delimiter);
17050
+ return this.nextID.createTimeTicket(this.delimiter);
17041
17051
  }
17042
17052
  /**
17043
17053
  * `getLastTimeTicket` returns the last time ticket issued in this context.
17044
17054
  */
17045
17055
  getLastTimeTicket() {
17046
- return this.id.createTimeTicket(this.delimiter);
17056
+ return this.nextID.createTimeTicket(this.delimiter);
17047
17057
  }
17048
17058
  }
17049
17059
  class CRDTRoot {
@@ -18972,6 +18982,43 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
18972
18982
  }
18973
18983
  return element;
18974
18984
  }
18985
+ class Presence {
18986
+ constructor(changeContext, presence) {
18987
+ __publicField(this, "context");
18988
+ __publicField(this, "presence");
18989
+ this.context = changeContext;
18990
+ this.presence = presence;
18991
+ }
18992
+ /**
18993
+ * `set` updates the presence based on the partial presence.
18994
+ */
18995
+ set(presence, option) {
18996
+ for (const key of Object.keys(presence)) {
18997
+ this.presence[key] = presence[key];
18998
+ }
18999
+ this.context.setPresenceChange({
19000
+ type: PresenceChangeType.Put,
19001
+ presence: deepcopy(this.presence)
19002
+ });
19003
+ this.context.setReversePresence(presence, option);
19004
+ }
19005
+ /**
19006
+ * `get` returns the presence value of the given key.
19007
+ */
19008
+ get(key) {
19009
+ return this.presence[key];
19010
+ }
19011
+ /**
19012
+ * `clear` clears the presence.
19013
+ * @internal
19014
+ */
19015
+ clear() {
19016
+ this.presence = {};
19017
+ this.context.setPresenceChange({
19018
+ type: PresenceChangeType.Clear
19019
+ });
19020
+ }
19021
+ }
18975
19022
  const MaxUndoRedoStackDepth = 50;
18976
19023
  class History {
18977
19024
  constructor() {
@@ -19239,7 +19286,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
19239
19286
  this.ensureClone();
19240
19287
  const actorID = this.changeID.getActorID();
19241
19288
  const context = ChangeContext.create(
19242
- this.changeID.next(),
19289
+ this.changeID,
19243
19290
  this.clone.root,
19244
19291
  this.clone.presences.get(actorID) || {},
19245
19292
  message
@@ -19267,7 +19314,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
19267
19314
  if (logger.isEnabled(LogLevel.Trivial)) {
19268
19315
  logger.trivial(`trying to update a local change: ${this.toJSON()}`);
19269
19316
  }
19270
- const change = context.getChange();
19317
+ const change = context.toChange();
19271
19318
  const { opInfos, reverseOps } = change.execute(
19272
19319
  this.root,
19273
19320
  this.presences,
@@ -19287,7 +19334,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
19287
19334
  if (opInfos.length > 0) {
19288
19335
  this.internalHistory.clearRedo();
19289
19336
  }
19290
- this.changeID = change.getID();
19337
+ this.changeID = context.getNextID();
19291
19338
  const event = [];
19292
19339
  if (opInfos.length > 0) {
19293
19340
  event.push({
@@ -20156,14 +20203,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20156
20203
  canUndo() {
20157
20204
  return this.internalHistory.hasUndo() && !this.isUpdating;
20158
20205
  }
20159
- /**
20160
- * 'filterVersionVector' filters detached client's lamport from version vector.
20161
- */
20162
- filterVersionVector(minSyncedVersionVector) {
20163
- const versionVector = this.changeID.getVersionVector();
20164
- const filteredVersionVector = versionVector.filter(minSyncedVersionVector);
20165
- this.changeID = this.changeID.setVersionVector(filteredVersionVector);
20166
- }
20167
20206
  /**
20168
20207
  * `canRedo` returns whether there are any operations to redo.
20169
20208
  */
@@ -20190,7 +20229,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20190
20229
  }
20191
20230
  this.ensureClone();
20192
20231
  const context = ChangeContext.create(
20193
- this.changeID.next(),
20232
+ this.changeID,
20194
20233
  this.clone.root,
20195
20234
  this.clone.presences.get(this.changeID.getActorID()) || {}
20196
20235
  );
@@ -20207,7 +20246,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20207
20246
  undoOp.setExecutedAt(ticket);
20208
20247
  context.push(undoOp);
20209
20248
  }
20210
- const change = context.getChange();
20249
+ const change = context.toChange();
20211
20250
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20212
20251
  const { opInfos, reverseOps } = change.execute(
20213
20252
  this.root,
@@ -20228,7 +20267,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20228
20267
  return;
20229
20268
  }
20230
20269
  this.localChanges.push(change);
20231
- this.changeID = change.getID();
20270
+ this.changeID = context.getNextID();
20232
20271
  const actorID = this.changeID.getActorID();
20233
20272
  const event = [];
20234
20273
  if (opInfos.length > 0) {
@@ -20277,7 +20316,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20277
20316
  }
20278
20317
  this.ensureClone();
20279
20318
  const context = ChangeContext.create(
20280
- this.changeID.next(),
20319
+ this.changeID,
20281
20320
  this.clone.root,
20282
20321
  this.clone.presences.get(this.changeID.getActorID()) || {}
20283
20322
  );
@@ -20294,7 +20333,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20294
20333
  redoOp.setExecutedAt(ticket);
20295
20334
  context.push(redoOp);
20296
20335
  }
20297
- const change = context.getChange();
20336
+ const change = context.toChange();
20298
20337
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20299
20338
  const { opInfos, reverseOps } = change.execute(
20300
20339
  this.root,
@@ -20315,7 +20354,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20315
20354
  return;
20316
20355
  }
20317
20356
  this.localChanges.push(change);
20318
- this.changeID = change.getID();
20357
+ this.changeID = context.getNextID();
20319
20358
  const actorID = this.changeID.getActorID();
20320
20359
  const event = [];
20321
20360
  if (opInfos.length > 0) {
@@ -20394,7 +20433,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20394
20433
  };
20395
20434
  }
20396
20435
  const name = "@yorkie-js/sdk";
20397
- const version = "0.6.11-rc";
20436
+ const version = "0.6.12";
20398
20437
  const pkg = {
20399
20438
  name,
20400
20439
  version
@@ -20562,16 +20601,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20562
20601
  if (this.status === "deactivated") {
20563
20602
  return Promise.resolve();
20564
20603
  }
20565
- this.deactivateInternal();
20566
20604
  const task = async () => {
20567
20605
  try {
20568
20606
  await this.rpcClient.deactivateClient(
20569
20607
  { clientId: this.id },
20570
20608
  { headers: { "x-shard-key": this.apiKey } }
20571
20609
  );
20610
+ this.deactivateInternal();
20572
20611
  logger.info(`[DC] c"${this.getKey()}" deactivated`);
20573
20612
  } catch (err) {
20574
- this.status = "activated";
20575
20613
  logger.error(`[DC] c:"${this.getKey()}" err :`, err);
20576
20614
  await this.handleConnectError(err);
20577
20615
  throw err;
@@ -20655,12 +20693,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20655
20693
  await this.runWatchLoop(doc.getKey());
20656
20694
  }
20657
20695
  logger.info(`[AD] c:"${this.getKey()}" attaches d:"${doc.getKey()}"`);
20658
- const crdtRoot = doc.getRootObject();
20696
+ const crdtObject = doc.getRootObject();
20659
20697
  if (opts.initialRoot) {
20660
20698
  const initialRoot = opts.initialRoot;
20661
20699
  doc.update((root) => {
20662
20700
  for (const [k, v] of Object.entries(initialRoot)) {
20663
- if (!crdtRoot.has(k)) {
20701
+ if (!crdtObject.has(k)) {
20664
20702
  const key = k;
20665
20703
  root[key] = v;
20666
20704
  }
@@ -20683,7 +20721,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20683
20721
  * the changes should be applied to other replicas before GC time. For this,
20684
20722
  * if the document is no longer used by this client, it should be detached.
20685
20723
  */
20686
- detach(doc, opts = { removeIfNotAttached: false }) {
20724
+ detach(doc, opts = { keepalive: false }) {
20687
20725
  if (!this.isActive()) {
20688
20726
  throw new YorkieError(
20689
20727
  Code.ErrClientNotActivated,
@@ -20698,14 +20736,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20698
20736
  );
20699
20737
  }
20700
20738
  doc.update((_, p) => p.clear());
20701
- return this.enqueueTask(async () => {
20739
+ const task = async () => {
20702
20740
  try {
20703
20741
  const res = await this.rpcClient.detachDocument(
20704
20742
  {
20705
20743
  clientId: this.id,
20706
20744
  documentId: attachment.docID,
20707
20745
  changePack: converter.toChangePack(doc.createChangePack()),
20708
- removeIfNotAttached: opts.removeIfNotAttached
20746
+ removeIfNotAttached: opts.removeIfNotAttached ?? false
20709
20747
  },
20710
20748
  { headers: { "x-shard-key": `${this.apiKey}/${doc.getKey()}` } }
20711
20749
  );
@@ -20722,7 +20760,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20722
20760
  await this.handleConnectError(err);
20723
20761
  throw err;
20724
20762
  }
20725
- });
20763
+ };
20764
+ if (opts.keepalive) {
20765
+ this.keepalive = true;
20766
+ const resp = task();
20767
+ this.keepalive = false;
20768
+ return resp;
20769
+ }
20770
+ return this.enqueueTask(task);
20726
20771
  }
20727
20772
  /**
20728
20773
  * `changeRealtimeSync` changes the synchronization mode of the given document.