@fluidframework/merge-tree 0.57.0 → 0.58.0-55983

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.
Files changed (123) hide show
  1. package/dist/base.d.ts +0 -1
  2. package/dist/base.d.ts.map +1 -1
  3. package/dist/base.js.map +1 -1
  4. package/dist/client.d.ts +3 -5
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +14 -36
  7. package/dist/client.js.map +1 -1
  8. package/dist/collections.d.ts +1 -4
  9. package/dist/collections.d.ts.map +1 -1
  10. package/dist/collections.js +8 -24
  11. package/dist/collections.js.map +1 -1
  12. package/dist/index.d.ts +0 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +0 -3
  15. package/dist/index.js.map +1 -1
  16. package/dist/mergeTree.d.ts +8 -30
  17. package/dist/mergeTree.d.ts.map +1 -1
  18. package/dist/mergeTree.js +17 -326
  19. package/dist/mergeTree.js.map +1 -1
  20. package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
  21. package/dist/mergeTreeDeltaCallback.js.map +1 -1
  22. package/dist/ops.d.ts +0 -6
  23. package/dist/ops.d.ts.map +1 -1
  24. package/dist/ops.js +1 -8
  25. package/dist/ops.js.map +1 -1
  26. package/dist/partialLengths.d.ts.map +1 -1
  27. package/dist/partialLengths.js +14 -26
  28. package/dist/partialLengths.js.map +1 -1
  29. package/dist/properties.d.ts.map +1 -1
  30. package/dist/properties.js +2 -15
  31. package/dist/properties.js.map +1 -1
  32. package/dist/segmentPropertiesManager.js +1 -5
  33. package/dist/segmentPropertiesManager.js.map +1 -1
  34. package/dist/snapshotChunks.js +3 -3
  35. package/dist/snapshotChunks.js.map +1 -1
  36. package/dist/snapshotV1.d.ts +2 -1
  37. package/dist/snapshotV1.d.ts.map +1 -1
  38. package/dist/snapshotV1.js +4 -4
  39. package/dist/snapshotV1.js.map +1 -1
  40. package/dist/snapshotlegacy.d.ts.map +1 -1
  41. package/dist/snapshotlegacy.js +3 -6
  42. package/dist/snapshotlegacy.js.map +1 -1
  43. package/dist/sortedSegmentSet.d.ts +3 -3
  44. package/dist/sortedSegmentSet.d.ts.map +1 -1
  45. package/dist/sortedSegmentSet.js +12 -12
  46. package/dist/sortedSegmentSet.js.map +1 -1
  47. package/dist/textSegment.d.ts.map +1 -1
  48. package/dist/textSegment.js +3 -17
  49. package/dist/textSegment.js.map +1 -1
  50. package/lib/base.d.ts +0 -1
  51. package/lib/base.d.ts.map +1 -1
  52. package/lib/base.js.map +1 -1
  53. package/lib/client.d.ts +3 -5
  54. package/lib/client.d.ts.map +1 -1
  55. package/lib/client.js +11 -33
  56. package/lib/client.js.map +1 -1
  57. package/lib/collections.d.ts +1 -4
  58. package/lib/collections.d.ts.map +1 -1
  59. package/lib/collections.js +8 -24
  60. package/lib/collections.js.map +1 -1
  61. package/lib/index.d.ts +0 -1
  62. package/lib/index.d.ts.map +1 -1
  63. package/lib/index.js +0 -1
  64. package/lib/index.js.map +1 -1
  65. package/lib/mergeTree.d.ts +8 -30
  66. package/lib/mergeTree.d.ts.map +1 -1
  67. package/lib/mergeTree.js +16 -322
  68. package/lib/mergeTree.js.map +1 -1
  69. package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
  70. package/lib/mergeTreeDeltaCallback.js.map +1 -1
  71. package/lib/ops.d.ts +0 -6
  72. package/lib/ops.d.ts.map +1 -1
  73. package/lib/ops.js +0 -7
  74. package/lib/ops.js.map +1 -1
  75. package/lib/partialLengths.d.ts.map +1 -1
  76. package/lib/partialLengths.js +14 -26
  77. package/lib/partialLengths.js.map +1 -1
  78. package/lib/properties.d.ts.map +1 -1
  79. package/lib/properties.js +2 -15
  80. package/lib/properties.js.map +1 -1
  81. package/lib/segmentPropertiesManager.js +1 -5
  82. package/lib/segmentPropertiesManager.js.map +1 -1
  83. package/lib/snapshotChunks.js +3 -3
  84. package/lib/snapshotChunks.js.map +1 -1
  85. package/lib/snapshotV1.d.ts +2 -1
  86. package/lib/snapshotV1.d.ts.map +1 -1
  87. package/lib/snapshotV1.js +4 -4
  88. package/lib/snapshotV1.js.map +1 -1
  89. package/lib/snapshotlegacy.d.ts.map +1 -1
  90. package/lib/snapshotlegacy.js +3 -6
  91. package/lib/snapshotlegacy.js.map +1 -1
  92. package/lib/sortedSegmentSet.d.ts +3 -3
  93. package/lib/sortedSegmentSet.d.ts.map +1 -1
  94. package/lib/sortedSegmentSet.js +12 -12
  95. package/lib/sortedSegmentSet.js.map +1 -1
  96. package/lib/textSegment.d.ts.map +1 -1
  97. package/lib/textSegment.js +4 -18
  98. package/lib/textSegment.js.map +1 -1
  99. package/package.json +11 -11
  100. package/src/base.ts +2 -3
  101. package/src/client.ts +11 -36
  102. package/src/collections.ts +9 -26
  103. package/src/index.ts +0 -1
  104. package/src/mergeTree.ts +32 -357
  105. package/src/mergeTreeDeltaCallback.ts +0 -1
  106. package/src/ops.ts +0 -7
  107. package/src/partialLengths.ts +17 -27
  108. package/src/properties.ts +7 -15
  109. package/src/segmentPropertiesManager.ts +5 -5
  110. package/src/snapshotChunks.ts +3 -3
  111. package/src/snapshotV1.ts +3 -3
  112. package/src/snapshotlegacy.ts +4 -6
  113. package/src/sortedSegmentSet.ts +12 -12
  114. package/src/textSegment.ts +5 -20
  115. package/dist/text.d.ts +0 -8
  116. package/dist/text.d.ts.map +0 -1
  117. package/dist/text.js +0 -78
  118. package/dist/text.js.map +0 -1
  119. package/lib/text.d.ts +0 -8
  120. package/lib/text.d.ts.map +0 -1
  121. package/lib/text.js +0 -73
  122. package/lib/text.js.map +0 -1
  123. package/src/text.ts +0 -83
package/dist/mergeTree.js CHANGED
@@ -3,11 +3,11 @@
3
3
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
4
  * Licensed under the MIT License.
5
5
  */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.MergeTree = exports.glc = exports.clientSeqComparer = exports.internedSpaces = exports.elapsedMicroseconds = exports.clock = exports.compareStrings = exports.compareNumbers = exports.CollaborationWindow = exports.IncrementalMapState = exports.IncrementalExecOp = exports.Marker = exports.refHasRangeLabel = exports.refHasTileLabel = exports.refGetRangeLabels = exports.refGetTileLabels = exports.reservedMarkerSimpleTypeKey = exports.reservedMarkerIdKey = exports.reservedRangeLabelsKey = exports.reservedTileLabelsKey = exports.BaseSegment = exports.MergeBlock = exports.MaxNodesInBlock = exports.ordinalToArray = exports.MergeNode = void 0;
6
+ /* eslint-disable max-lines */
8
7
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
9
8
  /* eslint-disable @typescript-eslint/consistent-type-assertions */
10
- /* eslint-disable @typescript-eslint/no-shadow */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MergeTree = exports.clientSeqComparer = exports.internedSpaces = exports.compareStrings = exports.compareNumbers = exports.CollaborationWindow = exports.IncrementalMapState = exports.IncrementalExecOp = exports.Marker = exports.refHasRangeLabel = exports.refHasTileLabel = exports.refGetRangeLabels = exports.refGetTileLabels = exports.reservedMarkerSimpleTypeKey = exports.reservedMarkerIdKey = exports.reservedRangeLabelsKey = exports.reservedTileLabelsKey = exports.BaseSegment = exports.MergeBlock = exports.MaxNodesInBlock = exports.ordinalToArray = exports.MergeNode = void 0;
11
11
  /* eslint-disable no-bitwise */
12
12
  const common_utils_1 = require("@fluidframework/common-utils");
13
13
  const collections_1 = require("./collections");
@@ -30,7 +30,6 @@ class MergeNode {
30
30
  }
31
31
  }
32
32
  exports.MergeNode = MergeNode;
33
- // eslint-disable-next-line @typescript-eslint/ban-types
34
33
  function addTile(tile, tiles) {
35
34
  const tileLabels = tile.getTileLabels();
36
35
  if (tileLabels) {
@@ -39,7 +38,6 @@ function addTile(tile, tiles) {
39
38
  }
40
39
  }
41
40
  }
42
- // eslint-disable-next-line @typescript-eslint/ban-types
43
41
  function addTileIfNotPresent(tile, tiles) {
44
42
  const tileLabels = tile.getTileLabels();
45
43
  if (tileLabels) {
@@ -51,7 +49,7 @@ function addTileIfNotPresent(tile, tiles) {
51
49
  }
52
50
  }
53
51
  function applyStackDelta(currentStackMap, deltaStackMap) {
54
- // eslint-disable-next-line guard-for-in, no-restricted-syntax
52
+ // eslint-disable-next-line guard-for-in
55
53
  for (const label in deltaStackMap) {
56
54
  const deltaStack = deltaStackMap[label];
57
55
  if (!deltaStack.empty()) {
@@ -158,7 +156,6 @@ exports.ordinalToArray = ordinalToArray;
158
156
  // `MaxNodesInBlock`. (i.e., `MaxNodesInBlock` contains 1 extra slot for temporary storage to
159
157
  // facilitate splits.)
160
158
  exports.MaxNodesInBlock = 8;
161
- const traceOrdinals = false;
162
159
  class MergeBlock extends MergeNode {
163
160
  constructor(childCount) {
164
161
  super();
@@ -185,16 +182,9 @@ class MergeBlock extends MergeNode {
185
182
  localOrdinal = prevOrdCode + ordinalWidth;
186
183
  }
187
184
  child.ordinal = this.ordinal + String.fromCharCode(localOrdinal);
188
- if (traceOrdinals) {
189
- // eslint-disable-next-line max-len
190
- console.log(`so: prnt chld prev ${ordinalToArray(this.ordinal)} ${ordinalToArray(child.ordinal)} ${(index > 0) ? ordinalToArray(this.children[index - 1].ordinal) : "NA"}`);
191
- }
192
185
  common_utils_1.assert(child.ordinal.length === (this.ordinal.length + 1), 0x041 /* "Unexpected child ordinal length!" */);
193
186
  if (index > 0) {
194
187
  common_utils_1.assert(child.ordinal > this.children[index - 1].ordinal, 0x042);
195
- // eslint-disable-next-line max-len
196
- // console.log(`${ordinalToArray(this.ordinal)} ${ordinalToArray(child.ordinal)} ${ordinalToArray(this.children[index - 1].ordinal)}`);
197
- // console.log(`ord width ${ordinalWidth}`);
198
188
  }
199
189
  }
200
190
  assignChild(child, index, updateOrdinal = true) {
@@ -222,7 +212,7 @@ class HierMergeBlock extends MergeBlock {
222
212
  }
223
213
  hierToString(indentCount) {
224
214
  let strbuf = "";
225
- // eslint-disable-next-line guard-for-in, no-restricted-syntax
215
+ // eslint-disable-next-line guard-for-in
226
216
  for (const key in this.rangeStacks) {
227
217
  const stack = this.rangeStacks[key];
228
218
  strbuf += internedSpaces(indentCount);
@@ -295,7 +285,6 @@ class BaseSegment extends MergeNode {
295
285
  this.localSeq = undefined;
296
286
  return true;
297
287
  case 1 /* REMOVE */:
298
- // eslint-disable-next-line @typescript-eslint/no-this-alias
299
288
  const removalInfo = this;
300
289
  common_utils_1.assert(!!removalInfo, 0x046 /* "On remove ack, missing removal info!" */);
301
290
  common_utils_1.assert(!!removalInfo.removedSeq, 0x047 /* "On remove ack, missing removed sequence number!" */);
@@ -304,11 +293,6 @@ class BaseSegment extends MergeNode {
304
293
  removalInfo.removedSeq = opArgs.sequencedMessage.sequenceNumber;
305
294
  return true;
306
295
  }
307
- if (MergeTree.diagOverlappingRemove) {
308
- console.log(`grump @seq ${opArgs.sequencedMessage.sequenceNumber} ` +
309
- `cli ${glc(mergeTree, mergeTree.collabWindow.clientId)} ` +
310
- `from ${removalInfo.removedSeq} text ${mergeTree.toString()}`);
311
- }
312
296
  return false;
313
297
  default:
314
298
  throw new Error(`${opArgs.op.type} is in unrecognized operation type`);
@@ -513,7 +497,6 @@ class Marker extends BaseSegment {
513
497
  // Avoid circular reference when stringifying makers containing handles.
514
498
  // (Substitute a debug string instead.)
515
499
  const handle = !!value && value.IFluidHandle;
516
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
517
500
  return handle
518
501
  ? `#Handle(${handle.routeContext.path}/${handle.path})`
519
502
  : value;
@@ -575,14 +558,6 @@ const compareNumbers = (a, b) => a - b;
575
558
  exports.compareNumbers = compareNumbers;
576
559
  const compareStrings = (a, b) => a.localeCompare(b);
577
560
  exports.compareStrings = compareStrings;
578
- function clock() {
579
- return common_utils_1.Trace.start();
580
- }
581
- exports.clock = clock;
582
- function elapsedMicroseconds(trace) {
583
- return trace.trace().duration * 1000;
584
- }
585
- exports.elapsedMicroseconds = elapsedMicroseconds;
586
561
  const indentStrings = ["", " ", " "];
587
562
  function internedSpaces(n) {
588
563
  if (indentStrings[n] === undefined) {
@@ -602,15 +577,6 @@ const LRUSegmentComparer = {
602
577
  min: { maxSeq: -2 },
603
578
  compare: (a, b) => a.maxSeq - b.maxSeq,
604
579
  };
605
- function glc(mergeTree, id) {
606
- if (mergeTree.getLongClientId) {
607
- return mergeTree.getLongClientId(id);
608
- }
609
- else {
610
- return id.toString();
611
- }
612
- }
613
- exports.glc = glc;
614
580
  function applyLeafRangeMarker(marker, searchInfo) {
615
581
  for (const rangeLabel of searchInfo.rangeLabels) {
616
582
  if (marker.hasRangeLabel(rangeLabel)) {
@@ -690,10 +656,6 @@ class MergeTree {
690
656
  // TODO: make and use interface describing options
691
657
  constructor(options) {
692
658
  this.options = options;
693
- this.windowTime = 0;
694
- this.packTime = 0;
695
- this.ordTime = 0;
696
- this.maxOrdTime = 0;
697
659
  this.blockUpdateActions = MergeTree.initBlockUpdateActions;
698
660
  this.collabWindow = new CollaborationWindow();
699
661
  // TODO: add remove on segment remove
@@ -777,7 +739,6 @@ class MergeTree {
777
739
  // This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
778
740
  common_utils_1.assert(!this.collabWindow.collaborating, 0x049 /* "Trying to reload from segments while collaborating!" */);
779
741
  const maxChildren = exports.MaxNodesInBlock - 1;
780
- const measureReloadTime = false;
781
742
  // Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
782
743
  const buildMergeBlock = (nodes) => {
783
744
  const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
@@ -801,15 +762,10 @@ class MergeTree {
801
762
  // snapshot header. The bulk of the segments in long documents are inserted via `insertSegments()`.
802
763
  this.blockUpdate(block);
803
764
  }
804
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
805
765
  return blocks.length === 1 // If there is only one block at this layer...
806
766
  ? blocks[0] // ...then we're done. Return the root.
807
767
  : buildMergeBlock(blocks); // ...otherwise recursively build the next layer above blocks.
808
768
  };
809
- let clockStart;
810
- if (measureReloadTime) {
811
- clockStart = clock();
812
- }
813
769
  if (segments.length > 0) {
814
770
  this.root = buildMergeBlock(segments);
815
771
  this.nodeUpdateOrdinals(this.root);
@@ -817,9 +773,6 @@ class MergeTree {
817
773
  else {
818
774
  this.root = this.makeBlock(0);
819
775
  }
820
- if (clockStart) {
821
- console.log(`reload time ${elapsedMicroseconds(clockStart)}`);
822
- }
823
776
  }
824
777
  /* eslint-enable max-len */
825
778
  // For now assume min starts at zero
@@ -830,15 +783,7 @@ class MergeTree {
830
783
  this.collabWindow.currentSeq = currentSeq;
831
784
  this.segmentsToScour = new collections_1.Heap([], LRUSegmentComparer);
832
785
  this.pendingSegments = collections_1.ListMakeHead();
833
- const measureFullCollab = false;
834
- let clockStart;
835
- if (measureFullCollab) {
836
- clockStart = clock();
837
- }
838
786
  this.nodeUpdateLengthNewStructure(this.root, true);
839
- if (clockStart) {
840
- console.log(`update partial lengths at start ${elapsedMicroseconds(clockStart)}`);
841
- }
842
787
  }
843
788
  addToLRUSet(segment, seq) {
844
789
  // If the parent node has not yet been marked for scour (i.e., needsScour is not false or undefined),
@@ -868,10 +813,6 @@ class MergeTree {
868
813
  holdNodes.push(segment);
869
814
  }
870
815
  else {
871
- if (MergeTree.traceZRemove) {
872
- // eslint-disable-next-line @typescript-eslint/dot-notation, max-len
873
- console.log(`${this.getLongClientId(this.collabWindow.clientId)}: Zremove ${segment["text"]}; cli ${this.getLongClientId(segment.clientId)}`);
874
- }
875
816
  // Notify maintenance event observers that the segment is being unlinked from the MergeTree
876
817
  if (this.mergeTreeMaintenanceCallback) {
877
818
  this.mergeTreeMaintenanceCallback({
@@ -891,10 +832,6 @@ class MergeTree {
891
832
  && prevSegment.trackingCollection.matches(segment.trackingCollection)
892
833
  && this.localNetLength(segment) > 0;
893
834
  if (canAppend) {
894
- if (MergeTree.traceAppend) {
895
- // eslint-disable-next-line @typescript-eslint/dot-notation, max-len
896
- console.log(`${this.getLongClientId(this.collabWindow.clientId)}: append ${prevSegment["text"]} + ${segment["text"]}; cli ${this.getLongClientId(prevSegment.clientId)} + cli ${this.getLongClientId(segment.clientId)}`);
897
- }
898
835
  prevSegment.append(segment);
899
836
  if (this.mergeTreeMaintenanceCallback) {
900
837
  this.mergeTreeMaintenanceCallback({
@@ -970,9 +907,6 @@ class MergeTree {
970
907
  packedBlocks[nodeIndex] = packedBlock;
971
908
  this.nodeUpdateLengthNewStructure(packedBlock);
972
909
  }
973
- if (readCount !== totalNodeCount) {
974
- console.log(`total count ${totalNodeCount} readCount ${readCount}`);
975
- }
976
910
  parent.children = packedBlocks;
977
911
  for (let j = 0; j < childCount; j++) {
978
912
  parent.assignChild(packedBlocks[j], j, false);
@@ -990,10 +924,6 @@ class MergeTree {
990
924
  if (!this.collabWindow.collaborating) {
991
925
  return;
992
926
  }
993
- let clockStart;
994
- if (MergeTree.options.measureWindowTime) {
995
- clockStart = clock();
996
- }
997
927
  for (let i = 0; i < zamboniSegmentsMaxCount; i++) {
998
928
  let segmentToScour = this.segmentsToScour.peek();
999
929
  if (!segmentToScour || segmentToScour.maxSeq > this.collabWindow.minSeq) {
@@ -1004,7 +934,6 @@ class MergeTree {
1004
934
  if (segmentToScour.segment.parent && segmentToScour.segment.parent.needsScour !== false) {
1005
935
  const block = segmentToScour.segment.parent;
1006
936
  const childrenCopy = [];
1007
- // console.log(`scouring from ${segmentToScour.segment.seq}`);
1008
937
  this.scourNode(block, childrenCopy);
1009
938
  // This will avoid the cost of re-scouring nodes
1010
939
  // that have recently been scoured
@@ -1017,15 +946,7 @@ class MergeTree {
1017
946
  block.assignChild(childrenCopy[j], j, false);
1018
947
  }
1019
948
  if (this.underflow(block) && block.parent) {
1020
- // nodeUpdatePathLengths(node, UnassignedSequenceNumber, -1, true);
1021
- let packClockStart;
1022
- if (MergeTree.options.measureWindowTime) {
1023
- packClockStart = clock();
1024
- }
1025
949
  this.packParent(block.parent);
1026
- if (MergeTree.options.measureWindowTime) {
1027
- this.packTime += elapsedMicroseconds(packClockStart);
1028
- }
1029
950
  }
1030
951
  else {
1031
952
  this.nodeUpdateOrdinals(block);
@@ -1034,9 +955,6 @@ class MergeTree {
1034
955
  }
1035
956
  }
1036
957
  }
1037
- if (MergeTree.options.measureWindowTime) {
1038
- this.windowTime += elapsedMicroseconds(clockStart);
1039
- }
1040
958
  }
1041
959
  getCollabWindow() {
1042
960
  return this.collabWindow;
@@ -1085,56 +1003,8 @@ class MergeTree {
1085
1003
  return stats;
1086
1004
  };
1087
1005
  const rootStats = nodeGetStats(this.root);
1088
- if (MergeTree.options.measureWindowTime) {
1089
- rootStats.windowTime = this.windowTime;
1090
- rootStats.packTime = this.packTime;
1091
- rootStats.ordTime = this.ordTime;
1092
- rootStats.maxOrdTime = this.maxOrdTime;
1093
- }
1094
1006
  return rootStats;
1095
1007
  }
1096
- findHistorialPosition(pos, fromSeq, toSeq, clientId) {
1097
- return this.findHistorialPositionFromClient(pos, fromSeq, toSeq, clientId);
1098
- }
1099
- findHistorialPositionFromClient(pos, fromSeq, toSeq, clientId) {
1100
- common_utils_1.assert(fromSeq < toSeq, 0x04a /* "Invalid range for historical position search!" */);
1101
- if (pos < this.getLength(fromSeq, clientId)) {
1102
- common_utils_1.assert(toSeq <= this.collabWindow.currentSeq, 0x04b /* "Out-of-bounds end sequence number for historical position search!" */);
1103
- const segoff = this.getContainingSegment(pos, fromSeq, clientId);
1104
- common_utils_1.assert(segoff.segment !== undefined, 0x04c /* "Containing segment for historical position search is undefined!" */);
1105
- const toPos = this.getPosition(segoff.segment, toSeq, clientId);
1106
- const ret = toPos + segoff.offset;
1107
- common_utils_1.assert(ret !== undefined, 0x04d /* "Return value for historical position search is undefined!" */);
1108
- return ret;
1109
- }
1110
- else {
1111
- return pos;
1112
- }
1113
- }
1114
- findHistorialRangeFromClient(rangeStart, rangeEnd, fromSeq, toSeq, clientId) {
1115
- const ranges = [];
1116
- const recordRange = (segment, pos, refSeq, clientId, segStart, segEnd) => {
1117
- var _a;
1118
- let _segStart = segStart;
1119
- let _segEnd = segEnd;
1120
- if (((_a = this.nodeLength(segment, toSeq, clientId)) !== null && _a !== void 0 ? _a : 0) > 0) {
1121
- const position = this.getPosition(segment, toSeq, clientId);
1122
- if (_segStart < 0) {
1123
- _segStart = 0;
1124
- }
1125
- if (_segEnd > segment.cachedLength) {
1126
- _segEnd = segment.cachedLength;
1127
- }
1128
- ranges.push({ start: position + _segStart, end: position + _segEnd });
1129
- }
1130
- return true;
1131
- };
1132
- this.mapRange({ leaf: recordRange }, fromSeq, clientId, undefined, rangeStart, rangeEnd);
1133
- return ranges;
1134
- }
1135
- findHistorialRange(rangeStart, rangeEnd, fromSeq, toSeq, clientId) {
1136
- return this.findHistorialRangeFromClient(rangeStart, rangeEnd, fromSeq, toSeq, clientId);
1137
- }
1138
1008
  getLength(refSeq, clientId) {
1139
1009
  return this.blockLength(this.root, refSeq, clientId);
1140
1010
  }
@@ -1404,15 +1274,12 @@ class MergeTree {
1404
1274
  * Assign sequence number to existing segment; update partial lengths to reflect the change
1405
1275
  * @param seq - sequence number given by server to pending segment
1406
1276
  */
1407
- ackPendingSegment(opArgs, verboseOps = false) {
1277
+ ackPendingSegment(opArgs) {
1408
1278
  const seq = opArgs.sequencedMessage.sequenceNumber;
1409
1279
  const pendingSegmentGroup = this.pendingSegments.dequeue();
1410
1280
  const nodesToUpdate = [];
1411
1281
  let overwrite = false;
1412
1282
  if (pendingSegmentGroup !== undefined) {
1413
- if (verboseOps) {
1414
- console.log(`segment group has ${pendingSegmentGroup.segments.length} segments`);
1415
- }
1416
1283
  const deltaSegments = [];
1417
1284
  pendingSegmentGroup.segments.map((pendingSegment) => {
1418
1285
  overwrite = !pendingSegment.ack(pendingSegmentGroup, opArgs, this) || overwrite;
@@ -1486,12 +1353,7 @@ class MergeTree {
1486
1353
  return pos;
1487
1354
  }
1488
1355
  insertSegments(pos, segments, refSeq, clientId, seq, opArgs) {
1489
- // const tt = MergeTree.traceTraversal;
1490
- // MergeTree.traceTraversal = true;
1491
1356
  this.ensureIntervalBoundary(pos, refSeq, clientId);
1492
- if (MergeTree.traceOrdinals) {
1493
- this.ordinalIntegrity();
1494
- }
1495
1357
  const localSeq = seq === constants_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
1496
1358
  this.blockInsert(pos, refSeq, clientId, seq, localSeq, segments);
1497
1359
  // opArgs == undefined => loading snapshot or test code
@@ -1501,10 +1363,6 @@ class MergeTree {
1501
1363
  deltaSegments: segments.map((segment) => ({ segment })),
1502
1364
  });
1503
1365
  }
1504
- // MergeTree.traceTraversal = tt;
1505
- if (MergeTree.traceOrdinals) {
1506
- this.ordinalIntegrity();
1507
- }
1508
1366
  if (this.collabWindow.collaborating && MergeTree.options.zamboniSegments &&
1509
1367
  (seq !== constants_1.UnassignedSequenceNumber)) {
1510
1368
  this.zamboniSegments();
@@ -1614,12 +1472,21 @@ class MergeTree {
1614
1472
  /**
1615
1473
  * Resolves a remote client's position against the local sequence
1616
1474
  * and returns the remote client's position relative to the local
1617
- * sequence
1475
+ * sequence. The client ref seq must be above the minimum sequence number
1476
+ * or the return value will be undefined.
1477
+ * Generally this method is used in conjunction with signals which provide
1478
+ * point in time values for the below parameters, and is useful for things
1479
+ * like displaying user position. It should not be used with persisted values
1480
+ * as persisted values will quickly become invalid as the remoteClientRefSeq
1481
+ * moves below the minimum sequence number
1618
1482
  * @param remoteClientPosition - The remote client's position to resolve
1619
1483
  * @param remoteClientRefSeq - The reference sequence number of the remote client
1620
1484
  * @param remoteClientId - The client id of the remote client
1621
1485
  */
1622
1486
  resolveRemoteClientPosition(remoteClientPosition, remoteClientRefSeq, remoteClientId) {
1487
+ if (remoteClientRefSeq < this.collabWindow.minSeq) {
1488
+ return undefined;
1489
+ }
1623
1490
  const segmentInfo = this.getContainingSegment(remoteClientPosition, remoteClientRefSeq, remoteClientId);
1624
1491
  const segwindow = this.getCollabWindow();
1625
1492
  if (segmentInfo && segmentInfo.segment) {
@@ -1645,10 +1512,6 @@ class MergeTree {
1645
1512
  let segIsLocal = false;
1646
1513
  const checkSegmentIsLocal = (segment, pos, refSeq, clientId) => {
1647
1514
  if (segment.seq === constants_1.UnassignedSequenceNumber) {
1648
- if (MergeTree.diagInsertTie) {
1649
- // eslint-disable-next-line max-len
1650
- console.log(`@cli ${glc(this, this.collabWindow.clientId)}: promoting continue due to seq ${segment.seq} text ${segment.toString()} ref ${refSeq}`);
1651
- }
1652
1515
  segIsLocal = true;
1653
1516
  }
1654
1517
  // Only need to look at first segment that follows finished node
@@ -1657,10 +1520,6 @@ class MergeTree {
1657
1520
  const continueFrom = (node) => {
1658
1521
  segIsLocal = false;
1659
1522
  this.rightExcursion(node, checkSegmentIsLocal);
1660
- if (MergeTree.diagInsertTie && segIsLocal) {
1661
- // eslint-disable-next-line max-len
1662
- console.log(`@cli ${glc(this, this.collabWindow.clientId)}: attempting continue with seq ${seq} ref ${refSeq} `);
1663
- }
1664
1523
  return segIsLocal;
1665
1524
  };
1666
1525
  let segmentGroup;
@@ -1731,7 +1590,7 @@ class MergeTree {
1731
1590
  if (pos === 0) {
1732
1591
  // normalize the seq numbers
1733
1592
  // if the new seg is local (UnassignedSequenceNumber) give it the highest possible
1734
- // seq for comparision, as it will get a seq higher than any other seq once sequences
1593
+ // seq for comparison, as it will get a seq higher than any other seq once sequences
1735
1594
  // if the current seg is local (UnassignedSequenceNumber) give it the second highest
1736
1595
  // possible seq, as the highest is reserved for the previous.
1737
1596
  const newSeq = seq === constants_1.UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER : seq;
@@ -1816,7 +1675,6 @@ class MergeTree {
1816
1675
  let child;
1817
1676
  let newNode;
1818
1677
  let fromSplit;
1819
- let found = false;
1820
1678
  for (childIndex = 0; childIndex < block.childCount; childIndex++) {
1821
1679
  child = children[childIndex];
1822
1680
  const len = this.nodeLength(child, refSeq, clientId);
@@ -1825,23 +1683,8 @@ class MergeTree {
1825
1683
  // will be removed, so should just be skipped for now
1826
1684
  continue;
1827
1685
  }
1828
- if (MergeTree.traceTraversal) {
1829
- let segInfo;
1830
- if ((!child.isLeaf()) && this.collabWindow.collaborating) {
1831
- segInfo = `minLength: ${child.partialLengths.minLength}`;
1832
- }
1833
- else {
1834
- const segment = child;
1835
- segInfo = `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} text: ${segment.toString()}`;
1836
- if (segment.removedSeq !== undefined) {
1837
- segInfo += ` rcli: ${glc(this, segment.removedClientId)} rseq: ${segment.removedSeq}`;
1838
- }
1839
- }
1840
- console.log(`@tcli: ${glc(this, this.collabWindow.clientId)} len: ${len} pos: ${_pos} ${segInfo}`);
1841
- }
1842
1686
  if ((_pos < len) || ((_pos === len) && this.breakTie(_pos, child, seq))) {
1843
1687
  // Found entry containing pos
1844
- found = true;
1845
1688
  if (!child.isLeaf()) {
1846
1689
  const childBlock = child;
1847
1690
  // Internal node
@@ -1856,10 +1699,6 @@ class MergeTree {
1856
1699
  return undefined;
1857
1700
  }
1858
1701
  else if (splitNode === MergeTree.theUnfinishedNode) {
1859
- if (MergeTree.traceTraversal) {
1860
- // eslint-disable-next-line max-len
1861
- console.log(`@cli ${glc(this, this.collabWindow.clientId)} unfinished bus pos ${_pos} len ${len}`);
1862
- }
1863
1702
  _pos -= len; // Act as if shifted segment
1864
1703
  continue;
1865
1704
  }
@@ -1870,15 +1709,9 @@ class MergeTree {
1870
1709
  }
1871
1710
  }
1872
1711
  else {
1873
- if (MergeTree.traceTraversal) {
1874
- console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action`);
1875
- }
1876
1712
  const segment = child;
1877
1713
  const segmentChanges = context.leaf(segment, _pos, context);
1878
1714
  if (segmentChanges.replaceCurrent) {
1879
- if (MergeTree.traceOrdinals) {
1880
- console.log(`assign from leaf with block ord ${ordinalToArray(block.ordinal)}`);
1881
- }
1882
1715
  block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
1883
1716
  segmentChanges.replaceCurrent.ordinal = child.ordinal;
1884
1717
  }
@@ -1900,12 +1733,6 @@ class MergeTree {
1900
1733
  _pos -= len;
1901
1734
  }
1902
1735
  }
1903
- if (MergeTree.traceTraversal) {
1904
- if ((!found) && (_pos > 0)) {
1905
- // eslint-disable-next-line max-len
1906
- console.log(`inserting walk fell through pos ${_pos} len: ${this.blockLength(this.root, refSeq, clientId)}`);
1907
- }
1908
- }
1909
1736
  if (!newNode) {
1910
1737
  if (_pos === 0) {
1911
1738
  if ((seq !== constants_1.UnassignedSequenceNumber) && context.continuePredicate &&
@@ -1913,9 +1740,6 @@ class MergeTree {
1913
1740
  return MergeTree.theUnfinishedNode;
1914
1741
  }
1915
1742
  else {
1916
- if (MergeTree.traceTraversal) {
1917
- console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action pos 0`);
1918
- }
1919
1743
  const segmentChanges = context.leaf(undefined, _pos, context);
1920
1744
  newNode = segmentChanges.next;
1921
1745
  // Assert segmentChanges.replaceCurrent === undefined
@@ -1932,9 +1756,6 @@ class MergeTree {
1932
1756
  block.setOrdinal(newNode, childIndex);
1933
1757
  if (block.childCount < exports.MaxNodesInBlock) {
1934
1758
  if (fromSplit) {
1935
- if (MergeTree.traceOrdinals) {
1936
- console.log(`split ord ${ordinalToArray(fromSplit.ordinal)}`);
1937
- }
1938
1759
  this.nodeUpdateOrdinals(fromSplit);
1939
1760
  }
1940
1761
  if (context.structureChange) {
@@ -1968,43 +1789,7 @@ class MergeTree {
1968
1789
  this.nodeUpdateLengthNewStructure(newNode);
1969
1790
  return newNode;
1970
1791
  }
1971
- ordinalIntegrity() {
1972
- console.log("chk ordnls");
1973
- this.nodeOrdinalIntegrity(this.root);
1974
- }
1975
- nodeOrdinalIntegrity(block) {
1976
- const olen = block.ordinal.length;
1977
- for (let i = 0; i < block.childCount; i++) {
1978
- const child = block.children[i];
1979
- if (child.ordinal) {
1980
- if (olen !== (child.ordinal.length - 1)) {
1981
- console.log("node integrity issue");
1982
- }
1983
- if (i > 0) {
1984
- if (child.ordinal <= block.children[i - 1].ordinal) {
1985
- console.log("node sib integrity issue");
1986
- // eslint-disable-next-line max-len
1987
- console.log(`??: prnt chld prev ${ordinalToArray(block.ordinal)} ${ordinalToArray(child.ordinal)} ${(i > 0) ? ordinalToArray(block.children[i - 1].ordinal) : "NA"}`);
1988
- }
1989
- }
1990
- if (!child.isLeaf()) {
1991
- this.nodeOrdinalIntegrity(child);
1992
- }
1993
- }
1994
- else {
1995
- console.log(`node child ordinal not set ${i}`);
1996
- console.log(`??: prnt ${ordinalToArray(block.ordinal)}`);
1997
- }
1998
- }
1999
- }
2000
1792
  nodeUpdateOrdinals(block) {
2001
- if (MergeTree.traceOrdinals) {
2002
- console.log(`update ordinals for children of node with ordinal ${ordinalToArray(block.ordinal)}`);
2003
- }
2004
- let clockStart;
2005
- if (MergeTree.options.measureOrdinalTime) {
2006
- clockStart = clock();
2007
- }
2008
1793
  for (let i = 0; i < block.childCount; i++) {
2009
1794
  const child = block.children[i];
2010
1795
  block.setOrdinal(child, i);
@@ -2012,21 +1797,11 @@ class MergeTree {
2012
1797
  this.nodeUpdateOrdinals(child);
2013
1798
  }
2014
1799
  }
2015
- if (clockStart) {
2016
- const elapsed = elapsedMicroseconds(clockStart);
2017
- if (elapsed > this.maxOrdTime) {
2018
- this.maxOrdTime = elapsed;
2019
- }
2020
- this.ordTime += elapsed;
2021
- }
2022
1800
  }
2023
1801
  addOverlappingClient(removalInfo, clientId) {
2024
1802
  if (!removalInfo.removedClientOverlap) {
2025
1803
  removalInfo.removedClientOverlap = [];
2026
1804
  }
2027
- if (MergeTree.diagOverlappingRemove) {
2028
- console.log(`added cli ${glc(this, clientId)} to rseq: ${removalInfo.removedSeq}`);
2029
- }
2030
1805
  removalInfo.removedClientOverlap.push(clientId);
2031
1806
  }
2032
1807
  /**
@@ -2086,10 +1861,6 @@ class MergeTree {
2086
1861
  const markRemoved = (segment, pos, start, end) => {
2087
1862
  const removalInfo = segment;
2088
1863
  if (removalInfo.removedSeq !== undefined) {
2089
- if (MergeTree.diagOverlappingRemove) {
2090
- // eslint-disable-next-line max-len
2091
- console.log(`yump @seq ${seq} cli ${glc(this, this.collabWindow.clientId)}: overlaps deleted segment ${removalInfo.removedSeq} text '${segment.toString()}'`);
2092
- }
2093
1864
  _overwrite = true;
2094
1865
  if (removalInfo.removedSeq === constants_1.UnassignedSequenceNumber) {
2095
1866
  // replace because comes later
@@ -2124,7 +1895,6 @@ class MergeTree {
2124
1895
  this.addToLRUSet(segment, seq);
2125
1896
  }
2126
1897
  }
2127
- // console.log(`saved local removed seg with text: ${textSegment.text}`);
2128
1898
  }
2129
1899
  return true;
2130
1900
  };
@@ -2137,7 +1907,6 @@ class MergeTree {
2137
1907
  }
2138
1908
  return true;
2139
1909
  };
2140
- // MergeTree.traceTraversal = true;
2141
1910
  this.mapRange({ leaf: markRemoved, post: afterMarkRemoved }, refSeq, clientId, undefined, start, end);
2142
1911
  if (savedLocalRefs.length > 0) {
2143
1912
  const length = this.getLength(refSeq, clientId);
@@ -2183,7 +1952,6 @@ class MergeTree {
2183
1952
  this.zamboniSegments();
2184
1953
  }
2185
1954
  }
2186
- // MergeTree.traceTraversal = false;
2187
1955
  }
2188
1956
  nodeUpdateLengthNewStructure(node, recur = false) {
2189
1957
  this.blockUpdate(node);
@@ -2272,45 +2040,6 @@ class MergeTree {
2272
2040
  }
2273
2041
  this.nodeMap(this.root, actions, 0, refSeq, clientId, accum, start, end);
2274
2042
  }
2275
- nodeToString(block, strbuf, indentCount = 0) {
2276
- let _strbuf = strbuf;
2277
- _strbuf += internedSpaces(indentCount);
2278
- // eslint-disable-next-line max-len
2279
- _strbuf += `Node (len ${block.cachedLength}) p len (${block.parent ? block.parent.cachedLength : 0}) ord ${ordinalToArray(block.ordinal)} with ${block.childCount} segs:\n`;
2280
- if (MergeTree.blockUpdateMarkers) {
2281
- _strbuf += internedSpaces(indentCount);
2282
- _strbuf += block.hierToString(indentCount);
2283
- }
2284
- if (this.collabWindow.collaborating) {
2285
- _strbuf += internedSpaces(indentCount);
2286
- _strbuf += `${block.partialLengths.toString((id) => glc(this, id), indentCount)}\n`;
2287
- }
2288
- const children = block.children;
2289
- for (let childIndex = 0; childIndex < block.childCount; childIndex++) {
2290
- const child = children[childIndex];
2291
- if (!child.isLeaf()) {
2292
- _strbuf = this.nodeToString(child, _strbuf, indentCount + 4);
2293
- }
2294
- else {
2295
- const segment = child;
2296
- _strbuf += internedSpaces(indentCount + 4);
2297
- // eslint-disable-next-line max-len
2298
- _strbuf += `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} ord: ${ordinalToArray(segment.ordinal)}`;
2299
- const removalInfo = segment;
2300
- if (removalInfo.removedSeq !== undefined) {
2301
- _strbuf += ` rcli: ${glc(this, removalInfo.removedClientId)} rseq: ${removalInfo.removedSeq}`;
2302
- }
2303
- _strbuf += "\n";
2304
- _strbuf += internedSpaces(indentCount + 4);
2305
- _strbuf += segment.toString();
2306
- _strbuf += "\n";
2307
- }
2308
- }
2309
- return _strbuf;
2310
- }
2311
- toString() {
2312
- return this.nodeToString(this.root, "", 0);
2313
- }
2314
2043
  incrementalBlockMap(stateStack) {
2315
2044
  var _a;
2316
2045
  while (!stateStack.empty()) {
@@ -2333,22 +2062,12 @@ class MergeTree {
2333
2062
  if ((state.op === IncrementalExecOp.Go) && (state.childIndex < state.block.childCount)) {
2334
2063
  const child = state.block.children[state.childIndex];
2335
2064
  const len = (_a = this.nodeLength(child, state.refSeq, state.clientId)) !== null && _a !== void 0 ? _a : 0;
2336
- if (MergeTree.traceIncrTraversal) {
2337
- if (child.isLeaf()) {
2338
- // eslint-disable-next-line @typescript-eslint/dot-notation, max-len
2339
- console.log(`considering (r ${state.refSeq} c ${glc(this, state.clientId)}) seg with text ${child["text"]} len ${len} seq ${child.seq} rseq ${child.removedSeq} cli ${glc(this, child.clientId)}`);
2340
- }
2341
- }
2342
2065
  if ((len > 0) && (state.start < len) && (state.end > 0)) {
2343
2066
  if (!child.isLeaf()) {
2344
2067
  const childState = new IncrementalMapState(child, state.actions, state.pos, state.refSeq, state.clientId, state.context, state.start, state.end, 0);
2345
2068
  stateStack.push(childState);
2346
2069
  }
2347
2070
  else {
2348
- if (MergeTree.traceIncrTraversal) {
2349
- // eslint-disable-next-line @typescript-eslint/dot-notation
2350
- console.log(`action on seg with text ${child["text"]}`);
2351
- }
2352
2071
  state.actions.leaf(child, state);
2353
2072
  }
2354
2073
  }
@@ -2390,21 +2109,6 @@ class MergeTree {
2390
2109
  for (let childIndex = 0; childIndex < node.childCount; childIndex++) {
2391
2110
  const child = children[childIndex];
2392
2111
  const len = (_a = this.nodeLength(child, refSeq, clientId)) !== null && _a !== void 0 ? _a : 0;
2393
- if (MergeTree.traceTraversal) {
2394
- let segInfo;
2395
- if ((!child.isLeaf()) && this.collabWindow.collaborating) {
2396
- segInfo = `minLength: ${child.partialLengths.minLength}`;
2397
- }
2398
- else {
2399
- const segment = child;
2400
- segInfo = `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} text: '${segment.toString()}'`;
2401
- if (segment.removedSeq !== undefined) {
2402
- segInfo += ` rcli: ${glc(this, segment.removedClientId)} rseq: ${segment.removedSeq}`;
2403
- }
2404
- }
2405
- // eslint-disable-next-line max-len
2406
- console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map len: ${len} start: ${_start} end: ${_end} ${segInfo}`);
2407
- }
2408
2112
  if (go && (_end > 0) && (len > 0) && (_start < len)) {
2409
2113
  // Found entry containing pos
2410
2114
  if (!child.isLeaf()) {
@@ -2413,9 +2117,6 @@ class MergeTree {
2413
2117
  }
2414
2118
  }
2415
2119
  else {
2416
- if (MergeTree.traceTraversal) {
2417
- console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map leaf action`);
2418
- }
2419
2120
  if (actions.leaf) {
2420
2121
  go = actions.leaf(child, _pos, refSeq, clientId, _start, _end, accum);
2421
2122
  }
@@ -2478,18 +2179,8 @@ MergeTree.zamboniSegmentsMaxCount = 2;
2478
2179
  MergeTree.options = {
2479
2180
  incrementalUpdate: true,
2480
2181
  insertAfterRemovedSegs: true,
2481
- measureOrdinalTime: true,
2482
- measureWindowTime: true,
2483
2182
  zamboniSegments: true,
2484
2183
  };
2485
- MergeTree.traceAppend = false;
2486
- MergeTree.traceZRemove = false;
2487
- MergeTree.traceOrdinals = false;
2488
- MergeTree.traceGatherText = false;
2489
- MergeTree.diagInsertTie = false;
2490
- MergeTree.diagOverlappingRemove = false;
2491
- MergeTree.traceTraversal = false;
2492
- MergeTree.traceIncrTraversal = false;
2493
2184
  MergeTree.theUnfinishedNode = { childCount: -1 };
2494
2185
  // WARNING:
2495
2186
  // Setting blockUpdateMarkers to false will result in eventual consistency issues