@fluidframework/merge-tree 0.57.1 → 0.58.0-55561

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 (90) 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 +0 -2
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +8 -29
  7. package/dist/client.js.map +1 -1
  8. package/dist/collections.d.ts +0 -3
  9. package/dist/collections.d.ts.map +1 -1
  10. package/dist/collections.js +6 -22
  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 -26
  17. package/dist/mergeTree.d.ts.map +1 -1
  18. package/dist/mergeTree.js +16 -277
  19. package/dist/mergeTree.js.map +1 -1
  20. package/dist/ops.d.ts +0 -6
  21. package/dist/ops.d.ts.map +1 -1
  22. package/dist/ops.js +1 -8
  23. package/dist/ops.js.map +1 -1
  24. package/dist/partialLengths.d.ts.map +1 -1
  25. package/dist/partialLengths.js +0 -9
  26. package/dist/partialLengths.js.map +1 -1
  27. package/dist/properties.d.ts.map +1 -1
  28. package/dist/properties.js +2 -15
  29. package/dist/properties.js.map +1 -1
  30. package/dist/snapshotlegacy.d.ts.map +1 -1
  31. package/dist/snapshotlegacy.js +3 -6
  32. package/dist/snapshotlegacy.js.map +1 -1
  33. package/dist/textSegment.d.ts.map +1 -1
  34. package/dist/textSegment.js +0 -14
  35. package/dist/textSegment.js.map +1 -1
  36. package/lib/base.d.ts +0 -1
  37. package/lib/base.d.ts.map +1 -1
  38. package/lib/base.js.map +1 -1
  39. package/lib/client.d.ts +0 -2
  40. package/lib/client.d.ts.map +1 -1
  41. package/lib/client.js +5 -26
  42. package/lib/client.js.map +1 -1
  43. package/lib/collections.d.ts +0 -3
  44. package/lib/collections.d.ts.map +1 -1
  45. package/lib/collections.js +6 -22
  46. package/lib/collections.js.map +1 -1
  47. package/lib/index.d.ts +0 -1
  48. package/lib/index.d.ts.map +1 -1
  49. package/lib/index.js +0 -1
  50. package/lib/index.js.map +1 -1
  51. package/lib/mergeTree.d.ts +8 -26
  52. package/lib/mergeTree.d.ts.map +1 -1
  53. package/lib/mergeTree.js +15 -274
  54. package/lib/mergeTree.js.map +1 -1
  55. package/lib/ops.d.ts +0 -6
  56. package/lib/ops.d.ts.map +1 -1
  57. package/lib/ops.js +0 -7
  58. package/lib/ops.js.map +1 -1
  59. package/lib/partialLengths.d.ts.map +1 -1
  60. package/lib/partialLengths.js +0 -9
  61. package/lib/partialLengths.js.map +1 -1
  62. package/lib/properties.d.ts.map +1 -1
  63. package/lib/properties.js +2 -15
  64. package/lib/properties.js.map +1 -1
  65. package/lib/snapshotlegacy.d.ts.map +1 -1
  66. package/lib/snapshotlegacy.js +3 -6
  67. package/lib/snapshotlegacy.js.map +1 -1
  68. package/lib/textSegment.d.ts.map +1 -1
  69. package/lib/textSegment.js +1 -15
  70. package/lib/textSegment.js.map +1 -1
  71. package/package.json +10 -10
  72. package/src/base.ts +0 -1
  73. package/src/client.ts +5 -29
  74. package/src/collections.ts +7 -24
  75. package/src/index.ts +0 -1
  76. package/src/mergeTree.ts +31 -306
  77. package/src/ops.ts +0 -7
  78. package/src/partialLengths.ts +0 -10
  79. package/src/properties.ts +7 -15
  80. package/src/snapshotlegacy.ts +4 -6
  81. package/src/textSegment.ts +2 -17
  82. package/dist/text.d.ts +0 -8
  83. package/dist/text.d.ts.map +0 -1
  84. package/dist/text.js +0 -78
  85. package/dist/text.js.map +0 -1
  86. package/lib/text.d.ts +0 -8
  87. package/lib/text.d.ts.map +0 -1
  88. package/lib/text.js +0 -73
  89. package/lib/text.js.map +0 -1
  90. 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) {
@@ -670,10 +647,6 @@ export class MergeTree {
670
647
  // TODO: make and use interface describing options
671
648
  constructor(options) {
672
649
  this.options = options;
673
- this.windowTime = 0;
674
- this.packTime = 0;
675
- this.ordTime = 0;
676
- this.maxOrdTime = 0;
677
650
  this.blockUpdateActions = MergeTree.initBlockUpdateActions;
678
651
  this.collabWindow = new CollaborationWindow();
679
652
  // TODO: add remove on segment remove
@@ -757,7 +730,6 @@ export class MergeTree {
757
730
  // This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
758
731
  assert(!this.collabWindow.collaborating, 0x049 /* "Trying to reload from segments while collaborating!" */);
759
732
  const maxChildren = MaxNodesInBlock - 1;
760
- const measureReloadTime = false;
761
733
  // Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
762
734
  const buildMergeBlock = (nodes) => {
763
735
  const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
@@ -781,15 +753,10 @@ export class MergeTree {
781
753
  // snapshot header. The bulk of the segments in long documents are inserted via `insertSegments()`.
782
754
  this.blockUpdate(block);
783
755
  }
784
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
785
756
  return blocks.length === 1 // If there is only one block at this layer...
786
757
  ? blocks[0] // ...then we're done. Return the root.
787
758
  : buildMergeBlock(blocks); // ...otherwise recursively build the next layer above blocks.
788
759
  };
789
- let clockStart;
790
- if (measureReloadTime) {
791
- clockStart = clock();
792
- }
793
760
  if (segments.length > 0) {
794
761
  this.root = buildMergeBlock(segments);
795
762
  this.nodeUpdateOrdinals(this.root);
@@ -797,9 +764,6 @@ export class MergeTree {
797
764
  else {
798
765
  this.root = this.makeBlock(0);
799
766
  }
800
- if (clockStart) {
801
- console.log(`reload time ${elapsedMicroseconds(clockStart)}`);
802
- }
803
767
  }
804
768
  /* eslint-enable max-len */
805
769
  // For now assume min starts at zero
@@ -810,15 +774,7 @@ export class MergeTree {
810
774
  this.collabWindow.currentSeq = currentSeq;
811
775
  this.segmentsToScour = new Heap([], LRUSegmentComparer);
812
776
  this.pendingSegments = ListMakeHead();
813
- const measureFullCollab = false;
814
- let clockStart;
815
- if (measureFullCollab) {
816
- clockStart = clock();
817
- }
818
777
  this.nodeUpdateLengthNewStructure(this.root, true);
819
- if (clockStart) {
820
- console.log(`update partial lengths at start ${elapsedMicroseconds(clockStart)}`);
821
- }
822
778
  }
823
779
  addToLRUSet(segment, seq) {
824
780
  // If the parent node has not yet been marked for scour (i.e., needsScour is not false or undefined),
@@ -848,10 +804,6 @@ export class MergeTree {
848
804
  holdNodes.push(segment);
849
805
  }
850
806
  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
807
  // Notify maintenance event observers that the segment is being unlinked from the MergeTree
856
808
  if (this.mergeTreeMaintenanceCallback) {
857
809
  this.mergeTreeMaintenanceCallback({
@@ -871,10 +823,6 @@ export class MergeTree {
871
823
  && prevSegment.trackingCollection.matches(segment.trackingCollection)
872
824
  && this.localNetLength(segment) > 0;
873
825
  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
826
  prevSegment.append(segment);
879
827
  if (this.mergeTreeMaintenanceCallback) {
880
828
  this.mergeTreeMaintenanceCallback({
@@ -950,9 +898,6 @@ export class MergeTree {
950
898
  packedBlocks[nodeIndex] = packedBlock;
951
899
  this.nodeUpdateLengthNewStructure(packedBlock);
952
900
  }
953
- if (readCount !== totalNodeCount) {
954
- console.log(`total count ${totalNodeCount} readCount ${readCount}`);
955
- }
956
901
  parent.children = packedBlocks;
957
902
  for (let j = 0; j < childCount; j++) {
958
903
  parent.assignChild(packedBlocks[j], j, false);
@@ -970,10 +915,6 @@ export class MergeTree {
970
915
  if (!this.collabWindow.collaborating) {
971
916
  return;
972
917
  }
973
- let clockStart;
974
- if (MergeTree.options.measureWindowTime) {
975
- clockStart = clock();
976
- }
977
918
  for (let i = 0; i < zamboniSegmentsMaxCount; i++) {
978
919
  let segmentToScour = this.segmentsToScour.peek();
979
920
  if (!segmentToScour || segmentToScour.maxSeq > this.collabWindow.minSeq) {
@@ -984,7 +925,6 @@ export class MergeTree {
984
925
  if (segmentToScour.segment.parent && segmentToScour.segment.parent.needsScour !== false) {
985
926
  const block = segmentToScour.segment.parent;
986
927
  const childrenCopy = [];
987
- // console.log(`scouring from ${segmentToScour.segment.seq}`);
988
928
  this.scourNode(block, childrenCopy);
989
929
  // This will avoid the cost of re-scouring nodes
990
930
  // that have recently been scoured
@@ -997,15 +937,7 @@ export class MergeTree {
997
937
  block.assignChild(childrenCopy[j], j, false);
998
938
  }
999
939
  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
940
  this.packParent(block.parent);
1006
- if (MergeTree.options.measureWindowTime) {
1007
- this.packTime += elapsedMicroseconds(packClockStart);
1008
- }
1009
941
  }
1010
942
  else {
1011
943
  this.nodeUpdateOrdinals(block);
@@ -1014,9 +946,6 @@ export class MergeTree {
1014
946
  }
1015
947
  }
1016
948
  }
1017
- if (MergeTree.options.measureWindowTime) {
1018
- this.windowTime += elapsedMicroseconds(clockStart);
1019
- }
1020
949
  }
1021
950
  getCollabWindow() {
1022
951
  return this.collabWindow;
@@ -1065,56 +994,8 @@ export class MergeTree {
1065
994
  return stats;
1066
995
  };
1067
996
  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
997
  return rootStats;
1075
998
  }
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
999
  getLength(refSeq, clientId) {
1119
1000
  return this.blockLength(this.root, refSeq, clientId);
1120
1001
  }
@@ -1384,15 +1265,12 @@ export class MergeTree {
1384
1265
  * Assign sequence number to existing segment; update partial lengths to reflect the change
1385
1266
  * @param seq - sequence number given by server to pending segment
1386
1267
  */
1387
- ackPendingSegment(opArgs, verboseOps = false) {
1268
+ ackPendingSegment(opArgs) {
1388
1269
  const seq = opArgs.sequencedMessage.sequenceNumber;
1389
1270
  const pendingSegmentGroup = this.pendingSegments.dequeue();
1390
1271
  const nodesToUpdate = [];
1391
1272
  let overwrite = false;
1392
1273
  if (pendingSegmentGroup !== undefined) {
1393
- if (verboseOps) {
1394
- console.log(`segment group has ${pendingSegmentGroup.segments.length} segments`);
1395
- }
1396
1274
  const deltaSegments = [];
1397
1275
  pendingSegmentGroup.segments.map((pendingSegment) => {
1398
1276
  overwrite = !pendingSegment.ack(pendingSegmentGroup, opArgs, this) || overwrite;
@@ -1466,12 +1344,7 @@ export class MergeTree {
1466
1344
  return pos;
1467
1345
  }
1468
1346
  insertSegments(pos, segments, refSeq, clientId, seq, opArgs) {
1469
- // const tt = MergeTree.traceTraversal;
1470
- // MergeTree.traceTraversal = true;
1471
1347
  this.ensureIntervalBoundary(pos, refSeq, clientId);
1472
- if (MergeTree.traceOrdinals) {
1473
- this.ordinalIntegrity();
1474
- }
1475
1348
  const localSeq = seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
1476
1349
  this.blockInsert(pos, refSeq, clientId, seq, localSeq, segments);
1477
1350
  // opArgs == undefined => loading snapshot or test code
@@ -1481,10 +1354,6 @@ export class MergeTree {
1481
1354
  deltaSegments: segments.map((segment) => ({ segment })),
1482
1355
  });
1483
1356
  }
1484
- // MergeTree.traceTraversal = tt;
1485
- if (MergeTree.traceOrdinals) {
1486
- this.ordinalIntegrity();
1487
- }
1488
1357
  if (this.collabWindow.collaborating && MergeTree.options.zamboniSegments &&
1489
1358
  (seq !== UnassignedSequenceNumber)) {
1490
1359
  this.zamboniSegments();
@@ -1594,12 +1463,21 @@ export class MergeTree {
1594
1463
  /**
1595
1464
  * Resolves a remote client's position against the local sequence
1596
1465
  * and returns the remote client's position relative to the local
1597
- * sequence
1466
+ * sequence. The client ref seq must be above the minimum sequence number
1467
+ * or the return value will be undefined.
1468
+ * Generally this method is used in conjunction with signals which provide
1469
+ * point in time values for the below parameters, and is useful for things
1470
+ * like displaying user position. It should not be used with persisted values
1471
+ * as persisted values will quickly become invalid as the remoteClientRefSeq
1472
+ * moves below the minimum sequence number
1598
1473
  * @param remoteClientPosition - The remote client's position to resolve
1599
1474
  * @param remoteClientRefSeq - The reference sequence number of the remote client
1600
1475
  * @param remoteClientId - The client id of the remote client
1601
1476
  */
1602
1477
  resolveRemoteClientPosition(remoteClientPosition, remoteClientRefSeq, remoteClientId) {
1478
+ if (remoteClientRefSeq < this.collabWindow.minSeq) {
1479
+ return undefined;
1480
+ }
1603
1481
  const segmentInfo = this.getContainingSegment(remoteClientPosition, remoteClientRefSeq, remoteClientId);
1604
1482
  const segwindow = this.getCollabWindow();
1605
1483
  if (segmentInfo && segmentInfo.segment) {
@@ -1625,10 +1503,6 @@ export class MergeTree {
1625
1503
  let segIsLocal = false;
1626
1504
  const checkSegmentIsLocal = (segment, pos, refSeq, clientId) => {
1627
1505
  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
1506
  segIsLocal = true;
1633
1507
  }
1634
1508
  // Only need to look at first segment that follows finished node
@@ -1637,10 +1511,6 @@ export class MergeTree {
1637
1511
  const continueFrom = (node) => {
1638
1512
  segIsLocal = false;
1639
1513
  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
1514
  return segIsLocal;
1645
1515
  };
1646
1516
  let segmentGroup;
@@ -1796,7 +1666,6 @@ export class MergeTree {
1796
1666
  let child;
1797
1667
  let newNode;
1798
1668
  let fromSplit;
1799
- let found = false;
1800
1669
  for (childIndex = 0; childIndex < block.childCount; childIndex++) {
1801
1670
  child = children[childIndex];
1802
1671
  const len = this.nodeLength(child, refSeq, clientId);
@@ -1805,23 +1674,8 @@ export class MergeTree {
1805
1674
  // will be removed, so should just be skipped for now
1806
1675
  continue;
1807
1676
  }
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
1677
  if ((_pos < len) || ((_pos === len) && this.breakTie(_pos, child, seq))) {
1823
1678
  // Found entry containing pos
1824
- found = true;
1825
1679
  if (!child.isLeaf()) {
1826
1680
  const childBlock = child;
1827
1681
  // Internal node
@@ -1836,10 +1690,6 @@ export class MergeTree {
1836
1690
  return undefined;
1837
1691
  }
1838
1692
  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
1693
  _pos -= len; // Act as if shifted segment
1844
1694
  continue;
1845
1695
  }
@@ -1850,15 +1700,9 @@ export class MergeTree {
1850
1700
  }
1851
1701
  }
1852
1702
  else {
1853
- if (MergeTree.traceTraversal) {
1854
- console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action`);
1855
- }
1856
1703
  const segment = child;
1857
1704
  const segmentChanges = context.leaf(segment, _pos, context);
1858
1705
  if (segmentChanges.replaceCurrent) {
1859
- if (MergeTree.traceOrdinals) {
1860
- console.log(`assign from leaf with block ord ${ordinalToArray(block.ordinal)}`);
1861
- }
1862
1706
  block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
1863
1707
  segmentChanges.replaceCurrent.ordinal = child.ordinal;
1864
1708
  }
@@ -1880,12 +1724,6 @@ export class MergeTree {
1880
1724
  _pos -= len;
1881
1725
  }
1882
1726
  }
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
1727
  if (!newNode) {
1890
1728
  if (_pos === 0) {
1891
1729
  if ((seq !== UnassignedSequenceNumber) && context.continuePredicate &&
@@ -1893,9 +1731,6 @@ export class MergeTree {
1893
1731
  return MergeTree.theUnfinishedNode;
1894
1732
  }
1895
1733
  else {
1896
- if (MergeTree.traceTraversal) {
1897
- console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action pos 0`);
1898
- }
1899
1734
  const segmentChanges = context.leaf(undefined, _pos, context);
1900
1735
  newNode = segmentChanges.next;
1901
1736
  // Assert segmentChanges.replaceCurrent === undefined
@@ -1912,9 +1747,6 @@ export class MergeTree {
1912
1747
  block.setOrdinal(newNode, childIndex);
1913
1748
  if (block.childCount < MaxNodesInBlock) {
1914
1749
  if (fromSplit) {
1915
- if (MergeTree.traceOrdinals) {
1916
- console.log(`split ord ${ordinalToArray(fromSplit.ordinal)}`);
1917
- }
1918
1750
  this.nodeUpdateOrdinals(fromSplit);
1919
1751
  }
1920
1752
  if (context.structureChange) {
@@ -1948,43 +1780,7 @@ export class MergeTree {
1948
1780
  this.nodeUpdateLengthNewStructure(newNode);
1949
1781
  return newNode;
1950
1782
  }
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
1783
  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
1784
  for (let i = 0; i < block.childCount; i++) {
1989
1785
  const child = block.children[i];
1990
1786
  block.setOrdinal(child, i);
@@ -1992,21 +1788,11 @@ export class MergeTree {
1992
1788
  this.nodeUpdateOrdinals(child);
1993
1789
  }
1994
1790
  }
1995
- if (clockStart) {
1996
- const elapsed = elapsedMicroseconds(clockStart);
1997
- if (elapsed > this.maxOrdTime) {
1998
- this.maxOrdTime = elapsed;
1999
- }
2000
- this.ordTime += elapsed;
2001
- }
2002
1791
  }
2003
1792
  addOverlappingClient(removalInfo, clientId) {
2004
1793
  if (!removalInfo.removedClientOverlap) {
2005
1794
  removalInfo.removedClientOverlap = [];
2006
1795
  }
2007
- if (MergeTree.diagOverlappingRemove) {
2008
- console.log(`added cli ${glc(this, clientId)} to rseq: ${removalInfo.removedSeq}`);
2009
- }
2010
1796
  removalInfo.removedClientOverlap.push(clientId);
2011
1797
  }
2012
1798
  /**
@@ -2066,10 +1852,6 @@ export class MergeTree {
2066
1852
  const markRemoved = (segment, pos, start, end) => {
2067
1853
  const removalInfo = segment;
2068
1854
  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
1855
  _overwrite = true;
2074
1856
  if (removalInfo.removedSeq === UnassignedSequenceNumber) {
2075
1857
  // replace because comes later
@@ -2104,7 +1886,6 @@ export class MergeTree {
2104
1886
  this.addToLRUSet(segment, seq);
2105
1887
  }
2106
1888
  }
2107
- // console.log(`saved local removed seg with text: ${textSegment.text}`);
2108
1889
  }
2109
1890
  return true;
2110
1891
  };
@@ -2117,7 +1898,6 @@ export class MergeTree {
2117
1898
  }
2118
1899
  return true;
2119
1900
  };
2120
- // MergeTree.traceTraversal = true;
2121
1901
  this.mapRange({ leaf: markRemoved, post: afterMarkRemoved }, refSeq, clientId, undefined, start, end);
2122
1902
  if (savedLocalRefs.length > 0) {
2123
1903
  const length = this.getLength(refSeq, clientId);
@@ -2163,7 +1943,6 @@ export class MergeTree {
2163
1943
  this.zamboniSegments();
2164
1944
  }
2165
1945
  }
2166
- // MergeTree.traceTraversal = false;
2167
1946
  }
2168
1947
  nodeUpdateLengthNewStructure(node, recur = false) {
2169
1948
  this.blockUpdate(node);
@@ -2313,22 +2092,12 @@ export class MergeTree {
2313
2092
  if ((state.op === IncrementalExecOp.Go) && (state.childIndex < state.block.childCount)) {
2314
2093
  const child = state.block.children[state.childIndex];
2315
2094
  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
2095
  if ((len > 0) && (state.start < len) && (state.end > 0)) {
2323
2096
  if (!child.isLeaf()) {
2324
2097
  const childState = new IncrementalMapState(child, state.actions, state.pos, state.refSeq, state.clientId, state.context, state.start, state.end, 0);
2325
2098
  stateStack.push(childState);
2326
2099
  }
2327
2100
  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
2101
  state.actions.leaf(child, state);
2333
2102
  }
2334
2103
  }
@@ -2370,21 +2139,6 @@ export class MergeTree {
2370
2139
  for (let childIndex = 0; childIndex < node.childCount; childIndex++) {
2371
2140
  const child = children[childIndex];
2372
2141
  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
2142
  if (go && (_end > 0) && (len > 0) && (_start < len)) {
2389
2143
  // Found entry containing pos
2390
2144
  if (!child.isLeaf()) {
@@ -2393,9 +2147,6 @@ export class MergeTree {
2393
2147
  }
2394
2148
  }
2395
2149
  else {
2396
- if (MergeTree.traceTraversal) {
2397
- console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map leaf action`);
2398
- }
2399
2150
  if (actions.leaf) {
2400
2151
  go = actions.leaf(child, _pos, refSeq, clientId, _start, _end, accum);
2401
2152
  }
@@ -2457,18 +2208,8 @@ MergeTree.zamboniSegmentsMaxCount = 2;
2457
2208
  MergeTree.options = {
2458
2209
  incrementalUpdate: true,
2459
2210
  insertAfterRemovedSegs: true,
2460
- measureOrdinalTime: true,
2461
- measureWindowTime: true,
2462
2211
  zamboniSegments: true,
2463
2212
  };
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
2213
  MergeTree.theUnfinishedNode = { childCount: -1 };
2473
2214
  // WARNING:
2474
2215
  // Setting blockUpdateMarkers to false will result in eventual consistency issues