@fluidframework/merge-tree 0.57.2 → 0.58.1000

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 +10 -10
  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/lib/mergeTree.js CHANGED
@@ -2,11 +2,11 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ /* eslint-disable max-lines */
5
6
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
6
7
  /* eslint-disable @typescript-eslint/consistent-type-assertions */
7
- /* eslint-disable @typescript-eslint/no-shadow */
8
8
  /* eslint-disable no-bitwise */
9
- import { assert, Trace } from "@fluidframework/common-utils";
9
+ import { assert } from "@fluidframework/common-utils";
10
10
  import { Heap, ListMakeHead, Stack, } from "./collections";
11
11
  import { LocalClientId, NonCollabClient, TreeMaintenanceSequenceNumber, UnassignedSequenceNumber, UniversalSequenceNumber, } from "./constants";
12
12
  import { LocalReference, LocalReferenceCollection } from "./localReference";
@@ -26,7 +26,6 @@ export class MergeNode {
26
26
  return false;
27
27
  }
28
28
  }
29
- // eslint-disable-next-line @typescript-eslint/ban-types
30
29
  function addTile(tile, tiles) {
31
30
  const tileLabels = tile.getTileLabels();
32
31
  if (tileLabels) {
@@ -35,7 +34,6 @@ function addTile(tile, tiles) {
35
34
  }
36
35
  }
37
36
  }
38
- // eslint-disable-next-line @typescript-eslint/ban-types
39
37
  function addTileIfNotPresent(tile, tiles) {
40
38
  const tileLabels = tile.getTileLabels();
41
39
  if (tileLabels) {
@@ -47,7 +45,7 @@ function addTileIfNotPresent(tile, tiles) {
47
45
  }
48
46
  }
49
47
  function applyStackDelta(currentStackMap, deltaStackMap) {
50
- // eslint-disable-next-line guard-for-in, no-restricted-syntax
48
+ // eslint-disable-next-line guard-for-in
51
49
  for (const label in deltaStackMap) {
52
50
  const deltaStack = deltaStackMap[label];
53
51
  if (!deltaStack.empty()) {
@@ -153,7 +151,6 @@ export function ordinalToArray(ord) {
153
151
  // `MaxNodesInBlock`. (i.e., `MaxNodesInBlock` contains 1 extra slot for temporary storage to
154
152
  // facilitate splits.)
155
153
  export const MaxNodesInBlock = 8;
156
- const traceOrdinals = false;
157
154
  export class MergeBlock extends MergeNode {
158
155
  constructor(childCount) {
159
156
  super();
@@ -180,16 +177,9 @@ export class MergeBlock extends MergeNode {
180
177
  localOrdinal = prevOrdCode + ordinalWidth;
181
178
  }
182
179
  child.ordinal = this.ordinal + String.fromCharCode(localOrdinal);
183
- if (traceOrdinals) {
184
- // eslint-disable-next-line max-len
185
- console.log(`so: prnt chld prev ${ordinalToArray(this.ordinal)} ${ordinalToArray(child.ordinal)} ${(index > 0) ? ordinalToArray(this.children[index - 1].ordinal) : "NA"}`);
186
- }
187
180
  assert(child.ordinal.length === (this.ordinal.length + 1), 0x041 /* "Unexpected child ordinal length!" */);
188
181
  if (index > 0) {
189
182
  assert(child.ordinal > this.children[index - 1].ordinal, 0x042);
190
- // eslint-disable-next-line max-len
191
- // console.log(`${ordinalToArray(this.ordinal)} ${ordinalToArray(child.ordinal)} ${ordinalToArray(this.children[index - 1].ordinal)}`);
192
- // console.log(`ord width ${ordinalWidth}`);
193
183
  }
194
184
  }
195
185
  assignChild(child, index, updateOrdinal = true) {
@@ -216,7 +206,7 @@ class HierMergeBlock extends MergeBlock {
216
206
  }
217
207
  hierToString(indentCount) {
218
208
  let strbuf = "";
219
- // eslint-disable-next-line guard-for-in, no-restricted-syntax
209
+ // eslint-disable-next-line guard-for-in
220
210
  for (const key in this.rangeStacks) {
221
211
  const stack = this.rangeStacks[key];
222
212
  strbuf += internedSpaces(indentCount);
@@ -289,7 +279,6 @@ export class BaseSegment extends MergeNode {
289
279
  this.localSeq = undefined;
290
280
  return true;
291
281
  case 1 /* REMOVE */:
292
- // eslint-disable-next-line @typescript-eslint/no-this-alias
293
282
  const removalInfo = this;
294
283
  assert(!!removalInfo, 0x046 /* "On remove ack, missing removal info!" */);
295
284
  assert(!!removalInfo.removedSeq, 0x047 /* "On remove ack, missing removed sequence number!" */);
@@ -298,11 +287,6 @@ export class BaseSegment extends MergeNode {
298
287
  removalInfo.removedSeq = opArgs.sequencedMessage.sequenceNumber;
299
288
  return true;
300
289
  }
301
- if (MergeTree.diagOverlappingRemove) {
302
- console.log(`grump @seq ${opArgs.sequencedMessage.sequenceNumber} ` +
303
- `cli ${glc(mergeTree, mergeTree.collabWindow.clientId)} ` +
304
- `from ${removalInfo.removedSeq} text ${mergeTree.toString()}`);
305
- }
306
290
  return false;
307
291
  default:
308
292
  throw new Error(`${opArgs.op.type} is in unrecognized operation type`);
@@ -502,7 +486,6 @@ export class Marker extends BaseSegment {
502
486
  // Avoid circular reference when stringifying makers containing handles.
503
487
  // (Substitute a debug string instead.)
504
488
  const handle = !!value && value.IFluidHandle;
505
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
506
489
  return handle
507
490
  ? `#Handle(${handle.routeContext.path}/${handle.path})`
508
491
  : value;
@@ -559,12 +542,6 @@ export class CollaborationWindow {
559
542
  }
560
543
  export const compareNumbers = (a, b) => a - b;
561
544
  export const compareStrings = (a, b) => a.localeCompare(b);
562
- export function clock() {
563
- return Trace.start();
564
- }
565
- export function elapsedMicroseconds(trace) {
566
- return trace.trace().duration * 1000;
567
- }
568
545
  const indentStrings = ["", " ", " "];
569
546
  export function internedSpaces(n) {
570
547
  if (indentStrings[n] === undefined) {
@@ -583,14 +560,6 @@ const LRUSegmentComparer = {
583
560
  min: { maxSeq: -2 },
584
561
  compare: (a, b) => a.maxSeq - b.maxSeq,
585
562
  };
586
- export function glc(mergeTree, id) {
587
- if (mergeTree.getLongClientId) {
588
- return mergeTree.getLongClientId(id);
589
- }
590
- else {
591
- return id.toString();
592
- }
593
- }
594
563
  function applyLeafRangeMarker(marker, searchInfo) {
595
564
  for (const rangeLabel of searchInfo.rangeLabels) {
596
565
  if (marker.hasRangeLabel(rangeLabel)) {
@@ -670,10 +639,6 @@ export class MergeTree {
670
639
  // TODO: make and use interface describing options
671
640
  constructor(options) {
672
641
  this.options = options;
673
- this.windowTime = 0;
674
- this.packTime = 0;
675
- this.ordTime = 0;
676
- this.maxOrdTime = 0;
677
642
  this.blockUpdateActions = MergeTree.initBlockUpdateActions;
678
643
  this.collabWindow = new CollaborationWindow();
679
644
  // TODO: add remove on segment remove
@@ -757,7 +722,6 @@ export class MergeTree {
757
722
  // This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
758
723
  assert(!this.collabWindow.collaborating, 0x049 /* "Trying to reload from segments while collaborating!" */);
759
724
  const maxChildren = MaxNodesInBlock - 1;
760
- const measureReloadTime = false;
761
725
  // Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
762
726
  const buildMergeBlock = (nodes) => {
763
727
  const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
@@ -781,15 +745,10 @@ export class MergeTree {
781
745
  // snapshot header. The bulk of the segments in long documents are inserted via `insertSegments()`.
782
746
  this.blockUpdate(block);
783
747
  }
784
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
785
748
  return blocks.length === 1 // If there is only one block at this layer...
786
749
  ? blocks[0] // ...then we're done. Return the root.
787
750
  : buildMergeBlock(blocks); // ...otherwise recursively build the next layer above blocks.
788
751
  };
789
- let clockStart;
790
- if (measureReloadTime) {
791
- clockStart = clock();
792
- }
793
752
  if (segments.length > 0) {
794
753
  this.root = buildMergeBlock(segments);
795
754
  this.nodeUpdateOrdinals(this.root);
@@ -797,9 +756,6 @@ export class MergeTree {
797
756
  else {
798
757
  this.root = this.makeBlock(0);
799
758
  }
800
- if (clockStart) {
801
- console.log(`reload time ${elapsedMicroseconds(clockStart)}`);
802
- }
803
759
  }
804
760
  /* eslint-enable max-len */
805
761
  // For now assume min starts at zero
@@ -810,15 +766,7 @@ export class MergeTree {
810
766
  this.collabWindow.currentSeq = currentSeq;
811
767
  this.segmentsToScour = new Heap([], LRUSegmentComparer);
812
768
  this.pendingSegments = ListMakeHead();
813
- const measureFullCollab = false;
814
- let clockStart;
815
- if (measureFullCollab) {
816
- clockStart = clock();
817
- }
818
769
  this.nodeUpdateLengthNewStructure(this.root, true);
819
- if (clockStart) {
820
- console.log(`update partial lengths at start ${elapsedMicroseconds(clockStart)}`);
821
- }
822
770
  }
823
771
  addToLRUSet(segment, seq) {
824
772
  // If the parent node has not yet been marked for scour (i.e., needsScour is not false or undefined),
@@ -848,10 +796,6 @@ export class MergeTree {
848
796
  holdNodes.push(segment);
849
797
  }
850
798
  else {
851
- if (MergeTree.traceZRemove) {
852
- // eslint-disable-next-line @typescript-eslint/dot-notation, max-len
853
- console.log(`${this.getLongClientId(this.collabWindow.clientId)}: Zremove ${segment["text"]}; cli ${this.getLongClientId(segment.clientId)}`);
854
- }
855
799
  // Notify maintenance event observers that the segment is being unlinked from the MergeTree
856
800
  if (this.mergeTreeMaintenanceCallback) {
857
801
  this.mergeTreeMaintenanceCallback({
@@ -871,10 +815,6 @@ export class MergeTree {
871
815
  && prevSegment.trackingCollection.matches(segment.trackingCollection)
872
816
  && this.localNetLength(segment) > 0;
873
817
  if (canAppend) {
874
- if (MergeTree.traceAppend) {
875
- // eslint-disable-next-line @typescript-eslint/dot-notation, max-len
876
- console.log(`${this.getLongClientId(this.collabWindow.clientId)}: append ${prevSegment["text"]} + ${segment["text"]}; cli ${this.getLongClientId(prevSegment.clientId)} + cli ${this.getLongClientId(segment.clientId)}`);
877
- }
878
818
  prevSegment.append(segment);
879
819
  if (this.mergeTreeMaintenanceCallback) {
880
820
  this.mergeTreeMaintenanceCallback({
@@ -950,9 +890,6 @@ export class MergeTree {
950
890
  packedBlocks[nodeIndex] = packedBlock;
951
891
  this.nodeUpdateLengthNewStructure(packedBlock);
952
892
  }
953
- if (readCount !== totalNodeCount) {
954
- console.log(`total count ${totalNodeCount} readCount ${readCount}`);
955
- }
956
893
  parent.children = packedBlocks;
957
894
  for (let j = 0; j < childCount; j++) {
958
895
  parent.assignChild(packedBlocks[j], j, false);
@@ -970,10 +907,6 @@ export class MergeTree {
970
907
  if (!this.collabWindow.collaborating) {
971
908
  return;
972
909
  }
973
- let clockStart;
974
- if (MergeTree.options.measureWindowTime) {
975
- clockStart = clock();
976
- }
977
910
  for (let i = 0; i < zamboniSegmentsMaxCount; i++) {
978
911
  let segmentToScour = this.segmentsToScour.peek();
979
912
  if (!segmentToScour || segmentToScour.maxSeq > this.collabWindow.minSeq) {
@@ -984,7 +917,6 @@ export class MergeTree {
984
917
  if (segmentToScour.segment.parent && segmentToScour.segment.parent.needsScour !== false) {
985
918
  const block = segmentToScour.segment.parent;
986
919
  const childrenCopy = [];
987
- // console.log(`scouring from ${segmentToScour.segment.seq}`);
988
920
  this.scourNode(block, childrenCopy);
989
921
  // This will avoid the cost of re-scouring nodes
990
922
  // that have recently been scoured
@@ -997,15 +929,7 @@ export class MergeTree {
997
929
  block.assignChild(childrenCopy[j], j, false);
998
930
  }
999
931
  if (this.underflow(block) && block.parent) {
1000
- // nodeUpdatePathLengths(node, UnassignedSequenceNumber, -1, true);
1001
- let packClockStart;
1002
- if (MergeTree.options.measureWindowTime) {
1003
- packClockStart = clock();
1004
- }
1005
932
  this.packParent(block.parent);
1006
- if (MergeTree.options.measureWindowTime) {
1007
- this.packTime += elapsedMicroseconds(packClockStart);
1008
- }
1009
933
  }
1010
934
  else {
1011
935
  this.nodeUpdateOrdinals(block);
@@ -1014,9 +938,6 @@ export class MergeTree {
1014
938
  }
1015
939
  }
1016
940
  }
1017
- if (MergeTree.options.measureWindowTime) {
1018
- this.windowTime += elapsedMicroseconds(clockStart);
1019
- }
1020
941
  }
1021
942
  getCollabWindow() {
1022
943
  return this.collabWindow;
@@ -1065,56 +986,8 @@ export class MergeTree {
1065
986
  return stats;
1066
987
  };
1067
988
  const rootStats = nodeGetStats(this.root);
1068
- if (MergeTree.options.measureWindowTime) {
1069
- rootStats.windowTime = this.windowTime;
1070
- rootStats.packTime = this.packTime;
1071
- rootStats.ordTime = this.ordTime;
1072
- rootStats.maxOrdTime = this.maxOrdTime;
1073
- }
1074
989
  return rootStats;
1075
990
  }
1076
- findHistorialPosition(pos, fromSeq, toSeq, clientId) {
1077
- return this.findHistorialPositionFromClient(pos, fromSeq, toSeq, clientId);
1078
- }
1079
- findHistorialPositionFromClient(pos, fromSeq, toSeq, clientId) {
1080
- assert(fromSeq < toSeq, 0x04a /* "Invalid range for historical position search!" */);
1081
- if (pos < this.getLength(fromSeq, clientId)) {
1082
- assert(toSeq <= this.collabWindow.currentSeq, 0x04b /* "Out-of-bounds end sequence number for historical position search!" */);
1083
- const segoff = this.getContainingSegment(pos, fromSeq, clientId);
1084
- assert(segoff.segment !== undefined, 0x04c /* "Containing segment for historical position search is undefined!" */);
1085
- const toPos = this.getPosition(segoff.segment, toSeq, clientId);
1086
- const ret = toPos + segoff.offset;
1087
- assert(ret !== undefined, 0x04d /* "Return value for historical position search is undefined!" */);
1088
- return ret;
1089
- }
1090
- else {
1091
- return pos;
1092
- }
1093
- }
1094
- findHistorialRangeFromClient(rangeStart, rangeEnd, fromSeq, toSeq, clientId) {
1095
- const ranges = [];
1096
- const recordRange = (segment, pos, refSeq, clientId, segStart, segEnd) => {
1097
- var _a;
1098
- let _segStart = segStart;
1099
- let _segEnd = segEnd;
1100
- if (((_a = this.nodeLength(segment, toSeq, clientId)) !== null && _a !== void 0 ? _a : 0) > 0) {
1101
- const position = this.getPosition(segment, toSeq, clientId);
1102
- if (_segStart < 0) {
1103
- _segStart = 0;
1104
- }
1105
- if (_segEnd > segment.cachedLength) {
1106
- _segEnd = segment.cachedLength;
1107
- }
1108
- ranges.push({ start: position + _segStart, end: position + _segEnd });
1109
- }
1110
- return true;
1111
- };
1112
- this.mapRange({ leaf: recordRange }, fromSeq, clientId, undefined, rangeStart, rangeEnd);
1113
- return ranges;
1114
- }
1115
- findHistorialRange(rangeStart, rangeEnd, fromSeq, toSeq, clientId) {
1116
- return this.findHistorialRangeFromClient(rangeStart, rangeEnd, fromSeq, toSeq, clientId);
1117
- }
1118
991
  getLength(refSeq, clientId) {
1119
992
  return this.blockLength(this.root, refSeq, clientId);
1120
993
  }
@@ -1384,15 +1257,12 @@ export class MergeTree {
1384
1257
  * Assign sequence number to existing segment; update partial lengths to reflect the change
1385
1258
  * @param seq - sequence number given by server to pending segment
1386
1259
  */
1387
- ackPendingSegment(opArgs, verboseOps = false) {
1260
+ ackPendingSegment(opArgs) {
1388
1261
  const seq = opArgs.sequencedMessage.sequenceNumber;
1389
1262
  const pendingSegmentGroup = this.pendingSegments.dequeue();
1390
1263
  const nodesToUpdate = [];
1391
1264
  let overwrite = false;
1392
1265
  if (pendingSegmentGroup !== undefined) {
1393
- if (verboseOps) {
1394
- console.log(`segment group has ${pendingSegmentGroup.segments.length} segments`);
1395
- }
1396
1266
  const deltaSegments = [];
1397
1267
  pendingSegmentGroup.segments.map((pendingSegment) => {
1398
1268
  overwrite = !pendingSegment.ack(pendingSegmentGroup, opArgs, this) || overwrite;
@@ -1466,12 +1336,7 @@ export class MergeTree {
1466
1336
  return pos;
1467
1337
  }
1468
1338
  insertSegments(pos, segments, refSeq, clientId, seq, opArgs) {
1469
- // const tt = MergeTree.traceTraversal;
1470
- // MergeTree.traceTraversal = true;
1471
1339
  this.ensureIntervalBoundary(pos, refSeq, clientId);
1472
- if (MergeTree.traceOrdinals) {
1473
- this.ordinalIntegrity();
1474
- }
1475
1340
  const localSeq = seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
1476
1341
  this.blockInsert(pos, refSeq, clientId, seq, localSeq, segments);
1477
1342
  // opArgs == undefined => loading snapshot or test code
@@ -1481,10 +1346,6 @@ export class MergeTree {
1481
1346
  deltaSegments: segments.map((segment) => ({ segment })),
1482
1347
  });
1483
1348
  }
1484
- // MergeTree.traceTraversal = tt;
1485
- if (MergeTree.traceOrdinals) {
1486
- this.ordinalIntegrity();
1487
- }
1488
1349
  if (this.collabWindow.collaborating && MergeTree.options.zamboniSegments &&
1489
1350
  (seq !== UnassignedSequenceNumber)) {
1490
1351
  this.zamboniSegments();
@@ -1594,12 +1455,21 @@ export class MergeTree {
1594
1455
  /**
1595
1456
  * Resolves a remote client's position against the local sequence
1596
1457
  * and returns the remote client's position relative to the local
1597
- * sequence
1458
+ * sequence. The client ref seq must be above the minimum sequence number
1459
+ * or the return value will be undefined.
1460
+ * Generally this method is used in conjunction with signals which provide
1461
+ * point in time values for the below parameters, and is useful for things
1462
+ * like displaying user position. It should not be used with persisted values
1463
+ * as persisted values will quickly become invalid as the remoteClientRefSeq
1464
+ * moves below the minimum sequence number
1598
1465
  * @param remoteClientPosition - The remote client's position to resolve
1599
1466
  * @param remoteClientRefSeq - The reference sequence number of the remote client
1600
1467
  * @param remoteClientId - The client id of the remote client
1601
1468
  */
1602
1469
  resolveRemoteClientPosition(remoteClientPosition, remoteClientRefSeq, remoteClientId) {
1470
+ if (remoteClientRefSeq < this.collabWindow.minSeq) {
1471
+ return undefined;
1472
+ }
1603
1473
  const segmentInfo = this.getContainingSegment(remoteClientPosition, remoteClientRefSeq, remoteClientId);
1604
1474
  const segwindow = this.getCollabWindow();
1605
1475
  if (segmentInfo && segmentInfo.segment) {
@@ -1625,10 +1495,6 @@ export class MergeTree {
1625
1495
  let segIsLocal = false;
1626
1496
  const checkSegmentIsLocal = (segment, pos, refSeq, clientId) => {
1627
1497
  if (segment.seq === UnassignedSequenceNumber) {
1628
- if (MergeTree.diagInsertTie) {
1629
- // eslint-disable-next-line max-len
1630
- console.log(`@cli ${glc(this, this.collabWindow.clientId)}: promoting continue due to seq ${segment.seq} text ${segment.toString()} ref ${refSeq}`);
1631
- }
1632
1498
  segIsLocal = true;
1633
1499
  }
1634
1500
  // Only need to look at first segment that follows finished node
@@ -1637,10 +1503,6 @@ export class MergeTree {
1637
1503
  const continueFrom = (node) => {
1638
1504
  segIsLocal = false;
1639
1505
  this.rightExcursion(node, checkSegmentIsLocal);
1640
- if (MergeTree.diagInsertTie && segIsLocal) {
1641
- // eslint-disable-next-line max-len
1642
- console.log(`@cli ${glc(this, this.collabWindow.clientId)}: attempting continue with seq ${seq} ref ${refSeq} `);
1643
- }
1644
1506
  return segIsLocal;
1645
1507
  };
1646
1508
  let segmentGroup;
@@ -1711,7 +1573,7 @@ export class MergeTree {
1711
1573
  if (pos === 0) {
1712
1574
  // normalize the seq numbers
1713
1575
  // if the new seg is local (UnassignedSequenceNumber) give it the highest possible
1714
- // seq for comparision, as it will get a seq higher than any other seq once sequences
1576
+ // seq for comparison, as it will get a seq higher than any other seq once sequences
1715
1577
  // if the current seg is local (UnassignedSequenceNumber) give it the second highest
1716
1578
  // possible seq, as the highest is reserved for the previous.
1717
1579
  const newSeq = seq === UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER : seq;
@@ -1796,7 +1658,6 @@ export class MergeTree {
1796
1658
  let child;
1797
1659
  let newNode;
1798
1660
  let fromSplit;
1799
- let found = false;
1800
1661
  for (childIndex = 0; childIndex < block.childCount; childIndex++) {
1801
1662
  child = children[childIndex];
1802
1663
  const len = this.nodeLength(child, refSeq, clientId);
@@ -1805,23 +1666,8 @@ export class MergeTree {
1805
1666
  // will be removed, so should just be skipped for now
1806
1667
  continue;
1807
1668
  }
1808
- if (MergeTree.traceTraversal) {
1809
- let segInfo;
1810
- if ((!child.isLeaf()) && this.collabWindow.collaborating) {
1811
- segInfo = `minLength: ${child.partialLengths.minLength}`;
1812
- }
1813
- else {
1814
- const segment = child;
1815
- segInfo = `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} text: ${segment.toString()}`;
1816
- if (segment.removedSeq !== undefined) {
1817
- segInfo += ` rcli: ${glc(this, segment.removedClientId)} rseq: ${segment.removedSeq}`;
1818
- }
1819
- }
1820
- console.log(`@tcli: ${glc(this, this.collabWindow.clientId)} len: ${len} pos: ${_pos} ${segInfo}`);
1821
- }
1822
1669
  if ((_pos < len) || ((_pos === len) && this.breakTie(_pos, child, seq))) {
1823
1670
  // Found entry containing pos
1824
- found = true;
1825
1671
  if (!child.isLeaf()) {
1826
1672
  const childBlock = child;
1827
1673
  // Internal node
@@ -1836,10 +1682,6 @@ export class MergeTree {
1836
1682
  return undefined;
1837
1683
  }
1838
1684
  else if (splitNode === MergeTree.theUnfinishedNode) {
1839
- if (MergeTree.traceTraversal) {
1840
- // eslint-disable-next-line max-len
1841
- console.log(`@cli ${glc(this, this.collabWindow.clientId)} unfinished bus pos ${_pos} len ${len}`);
1842
- }
1843
1685
  _pos -= len; // Act as if shifted segment
1844
1686
  continue;
1845
1687
  }
@@ -1850,15 +1692,9 @@ export class MergeTree {
1850
1692
  }
1851
1693
  }
1852
1694
  else {
1853
- if (MergeTree.traceTraversal) {
1854
- console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action`);
1855
- }
1856
1695
  const segment = child;
1857
1696
  const segmentChanges = context.leaf(segment, _pos, context);
1858
1697
  if (segmentChanges.replaceCurrent) {
1859
- if (MergeTree.traceOrdinals) {
1860
- console.log(`assign from leaf with block ord ${ordinalToArray(block.ordinal)}`);
1861
- }
1862
1698
  block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
1863
1699
  segmentChanges.replaceCurrent.ordinal = child.ordinal;
1864
1700
  }
@@ -1880,12 +1716,6 @@ export class MergeTree {
1880
1716
  _pos -= len;
1881
1717
  }
1882
1718
  }
1883
- if (MergeTree.traceTraversal) {
1884
- if ((!found) && (_pos > 0)) {
1885
- // eslint-disable-next-line max-len
1886
- console.log(`inserting walk fell through pos ${_pos} len: ${this.blockLength(this.root, refSeq, clientId)}`);
1887
- }
1888
- }
1889
1719
  if (!newNode) {
1890
1720
  if (_pos === 0) {
1891
1721
  if ((seq !== UnassignedSequenceNumber) && context.continuePredicate &&
@@ -1893,9 +1723,6 @@ export class MergeTree {
1893
1723
  return MergeTree.theUnfinishedNode;
1894
1724
  }
1895
1725
  else {
1896
- if (MergeTree.traceTraversal) {
1897
- console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action pos 0`);
1898
- }
1899
1726
  const segmentChanges = context.leaf(undefined, _pos, context);
1900
1727
  newNode = segmentChanges.next;
1901
1728
  // Assert segmentChanges.replaceCurrent === undefined
@@ -1912,9 +1739,6 @@ export class MergeTree {
1912
1739
  block.setOrdinal(newNode, childIndex);
1913
1740
  if (block.childCount < MaxNodesInBlock) {
1914
1741
  if (fromSplit) {
1915
- if (MergeTree.traceOrdinals) {
1916
- console.log(`split ord ${ordinalToArray(fromSplit.ordinal)}`);
1917
- }
1918
1742
  this.nodeUpdateOrdinals(fromSplit);
1919
1743
  }
1920
1744
  if (context.structureChange) {
@@ -1948,43 +1772,7 @@ export class MergeTree {
1948
1772
  this.nodeUpdateLengthNewStructure(newNode);
1949
1773
  return newNode;
1950
1774
  }
1951
- ordinalIntegrity() {
1952
- console.log("chk ordnls");
1953
- this.nodeOrdinalIntegrity(this.root);
1954
- }
1955
- nodeOrdinalIntegrity(block) {
1956
- const olen = block.ordinal.length;
1957
- for (let i = 0; i < block.childCount; i++) {
1958
- const child = block.children[i];
1959
- if (child.ordinal) {
1960
- if (olen !== (child.ordinal.length - 1)) {
1961
- console.log("node integrity issue");
1962
- }
1963
- if (i > 0) {
1964
- if (child.ordinal <= block.children[i - 1].ordinal) {
1965
- console.log("node sib integrity issue");
1966
- // eslint-disable-next-line max-len
1967
- console.log(`??: prnt chld prev ${ordinalToArray(block.ordinal)} ${ordinalToArray(child.ordinal)} ${(i > 0) ? ordinalToArray(block.children[i - 1].ordinal) : "NA"}`);
1968
- }
1969
- }
1970
- if (!child.isLeaf()) {
1971
- this.nodeOrdinalIntegrity(child);
1972
- }
1973
- }
1974
- else {
1975
- console.log(`node child ordinal not set ${i}`);
1976
- console.log(`??: prnt ${ordinalToArray(block.ordinal)}`);
1977
- }
1978
- }
1979
- }
1980
1775
  nodeUpdateOrdinals(block) {
1981
- if (MergeTree.traceOrdinals) {
1982
- console.log(`update ordinals for children of node with ordinal ${ordinalToArray(block.ordinal)}`);
1983
- }
1984
- let clockStart;
1985
- if (MergeTree.options.measureOrdinalTime) {
1986
- clockStart = clock();
1987
- }
1988
1776
  for (let i = 0; i < block.childCount; i++) {
1989
1777
  const child = block.children[i];
1990
1778
  block.setOrdinal(child, i);
@@ -1992,21 +1780,11 @@ export class MergeTree {
1992
1780
  this.nodeUpdateOrdinals(child);
1993
1781
  }
1994
1782
  }
1995
- if (clockStart) {
1996
- const elapsed = elapsedMicroseconds(clockStart);
1997
- if (elapsed > this.maxOrdTime) {
1998
- this.maxOrdTime = elapsed;
1999
- }
2000
- this.ordTime += elapsed;
2001
- }
2002
1783
  }
2003
1784
  addOverlappingClient(removalInfo, clientId) {
2004
1785
  if (!removalInfo.removedClientOverlap) {
2005
1786
  removalInfo.removedClientOverlap = [];
2006
1787
  }
2007
- if (MergeTree.diagOverlappingRemove) {
2008
- console.log(`added cli ${glc(this, clientId)} to rseq: ${removalInfo.removedSeq}`);
2009
- }
2010
1788
  removalInfo.removedClientOverlap.push(clientId);
2011
1789
  }
2012
1790
  /**
@@ -2066,10 +1844,6 @@ export class MergeTree {
2066
1844
  const markRemoved = (segment, pos, start, end) => {
2067
1845
  const removalInfo = segment;
2068
1846
  if (removalInfo.removedSeq !== undefined) {
2069
- if (MergeTree.diagOverlappingRemove) {
2070
- // eslint-disable-next-line max-len
2071
- console.log(`yump @seq ${seq} cli ${glc(this, this.collabWindow.clientId)}: overlaps deleted segment ${removalInfo.removedSeq} text '${segment.toString()}'`);
2072
- }
2073
1847
  _overwrite = true;
2074
1848
  if (removalInfo.removedSeq === UnassignedSequenceNumber) {
2075
1849
  // replace because comes later
@@ -2104,7 +1878,6 @@ export class MergeTree {
2104
1878
  this.addToLRUSet(segment, seq);
2105
1879
  }
2106
1880
  }
2107
- // console.log(`saved local removed seg with text: ${textSegment.text}`);
2108
1881
  }
2109
1882
  return true;
2110
1883
  };
@@ -2117,7 +1890,6 @@ export class MergeTree {
2117
1890
  }
2118
1891
  return true;
2119
1892
  };
2120
- // MergeTree.traceTraversal = true;
2121
1893
  this.mapRange({ leaf: markRemoved, post: afterMarkRemoved }, refSeq, clientId, undefined, start, end);
2122
1894
  if (savedLocalRefs.length > 0) {
2123
1895
  const length = this.getLength(refSeq, clientId);
@@ -2163,7 +1935,6 @@ export class MergeTree {
2163
1935
  this.zamboniSegments();
2164
1936
  }
2165
1937
  }
2166
- // MergeTree.traceTraversal = false;
2167
1938
  }
2168
1939
  nodeUpdateLengthNewStructure(node, recur = false) {
2169
1940
  this.blockUpdate(node);
@@ -2252,45 +2023,6 @@ export class MergeTree {
2252
2023
  }
2253
2024
  this.nodeMap(this.root, actions, 0, refSeq, clientId, accum, start, end);
2254
2025
  }
2255
- nodeToString(block, strbuf, indentCount = 0) {
2256
- let _strbuf = strbuf;
2257
- _strbuf += internedSpaces(indentCount);
2258
- // eslint-disable-next-line max-len
2259
- _strbuf += `Node (len ${block.cachedLength}) p len (${block.parent ? block.parent.cachedLength : 0}) ord ${ordinalToArray(block.ordinal)} with ${block.childCount} segs:\n`;
2260
- if (MergeTree.blockUpdateMarkers) {
2261
- _strbuf += internedSpaces(indentCount);
2262
- _strbuf += block.hierToString(indentCount);
2263
- }
2264
- if (this.collabWindow.collaborating) {
2265
- _strbuf += internedSpaces(indentCount);
2266
- _strbuf += `${block.partialLengths.toString((id) => glc(this, id), indentCount)}\n`;
2267
- }
2268
- const children = block.children;
2269
- for (let childIndex = 0; childIndex < block.childCount; childIndex++) {
2270
- const child = children[childIndex];
2271
- if (!child.isLeaf()) {
2272
- _strbuf = this.nodeToString(child, _strbuf, indentCount + 4);
2273
- }
2274
- else {
2275
- const segment = child;
2276
- _strbuf += internedSpaces(indentCount + 4);
2277
- // eslint-disable-next-line max-len
2278
- _strbuf += `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} ord: ${ordinalToArray(segment.ordinal)}`;
2279
- const removalInfo = segment;
2280
- if (removalInfo.removedSeq !== undefined) {
2281
- _strbuf += ` rcli: ${glc(this, removalInfo.removedClientId)} rseq: ${removalInfo.removedSeq}`;
2282
- }
2283
- _strbuf += "\n";
2284
- _strbuf += internedSpaces(indentCount + 4);
2285
- _strbuf += segment.toString();
2286
- _strbuf += "\n";
2287
- }
2288
- }
2289
- return _strbuf;
2290
- }
2291
- toString() {
2292
- return this.nodeToString(this.root, "", 0);
2293
- }
2294
2026
  incrementalBlockMap(stateStack) {
2295
2027
  var _a;
2296
2028
  while (!stateStack.empty()) {
@@ -2313,22 +2045,12 @@ export class MergeTree {
2313
2045
  if ((state.op === IncrementalExecOp.Go) && (state.childIndex < state.block.childCount)) {
2314
2046
  const child = state.block.children[state.childIndex];
2315
2047
  const len = (_a = this.nodeLength(child, state.refSeq, state.clientId)) !== null && _a !== void 0 ? _a : 0;
2316
- if (MergeTree.traceIncrTraversal) {
2317
- if (child.isLeaf()) {
2318
- // eslint-disable-next-line @typescript-eslint/dot-notation, max-len
2319
- 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)}`);
2320
- }
2321
- }
2322
2048
  if ((len > 0) && (state.start < len) && (state.end > 0)) {
2323
2049
  if (!child.isLeaf()) {
2324
2050
  const childState = new IncrementalMapState(child, state.actions, state.pos, state.refSeq, state.clientId, state.context, state.start, state.end, 0);
2325
2051
  stateStack.push(childState);
2326
2052
  }
2327
2053
  else {
2328
- if (MergeTree.traceIncrTraversal) {
2329
- // eslint-disable-next-line @typescript-eslint/dot-notation
2330
- console.log(`action on seg with text ${child["text"]}`);
2331
- }
2332
2054
  state.actions.leaf(child, state);
2333
2055
  }
2334
2056
  }
@@ -2370,21 +2092,6 @@ export class MergeTree {
2370
2092
  for (let childIndex = 0; childIndex < node.childCount; childIndex++) {
2371
2093
  const child = children[childIndex];
2372
2094
  const len = (_a = this.nodeLength(child, refSeq, clientId)) !== null && _a !== void 0 ? _a : 0;
2373
- if (MergeTree.traceTraversal) {
2374
- let segInfo;
2375
- if ((!child.isLeaf()) && this.collabWindow.collaborating) {
2376
- segInfo = `minLength: ${child.partialLengths.minLength}`;
2377
- }
2378
- else {
2379
- const segment = child;
2380
- segInfo = `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} text: '${segment.toString()}'`;
2381
- if (segment.removedSeq !== undefined) {
2382
- segInfo += ` rcli: ${glc(this, segment.removedClientId)} rseq: ${segment.removedSeq}`;
2383
- }
2384
- }
2385
- // eslint-disable-next-line max-len
2386
- console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map len: ${len} start: ${_start} end: ${_end} ${segInfo}`);
2387
- }
2388
2095
  if (go && (_end > 0) && (len > 0) && (_start < len)) {
2389
2096
  // Found entry containing pos
2390
2097
  if (!child.isLeaf()) {
@@ -2393,9 +2100,6 @@ export class MergeTree {
2393
2100
  }
2394
2101
  }
2395
2102
  else {
2396
- if (MergeTree.traceTraversal) {
2397
- console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map leaf action`);
2398
- }
2399
2103
  if (actions.leaf) {
2400
2104
  go = actions.leaf(child, _pos, refSeq, clientId, _start, _end, accum);
2401
2105
  }
@@ -2457,18 +2161,8 @@ MergeTree.zamboniSegmentsMaxCount = 2;
2457
2161
  MergeTree.options = {
2458
2162
  incrementalUpdate: true,
2459
2163
  insertAfterRemovedSegs: true,
2460
- measureOrdinalTime: true,
2461
- measureWindowTime: true,
2462
2164
  zamboniSegments: true,
2463
2165
  };
2464
- MergeTree.traceAppend = false;
2465
- MergeTree.traceZRemove = false;
2466
- MergeTree.traceOrdinals = false;
2467
- MergeTree.traceGatherText = false;
2468
- MergeTree.diagInsertTie = false;
2469
- MergeTree.diagOverlappingRemove = false;
2470
- MergeTree.traceTraversal = false;
2471
- MergeTree.traceIncrTraversal = false;
2472
2166
  MergeTree.theUnfinishedNode = { childCount: -1 };
2473
2167
  // WARNING:
2474
2168
  // Setting blockUpdateMarkers to false will result in eventual consistency issues