@fluidframework/merge-tree 2.12.0 → 2.13.0

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 (285) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/MergeTreeTextHelper.d.ts.map +1 -1
  3. package/dist/MergeTreeTextHelper.js +0 -2
  4. package/dist/MergeTreeTextHelper.js.map +1 -1
  5. package/dist/attributionPolicy.d.ts.map +1 -1
  6. package/dist/attributionPolicy.js +6 -16
  7. package/dist/attributionPolicy.js.map +1 -1
  8. package/dist/client.d.ts +3 -4
  9. package/dist/client.d.ts.map +1 -1
  10. package/dist/client.js +39 -28
  11. package/dist/client.js.map +1 -1
  12. package/dist/endOfTreeSegment.d.ts +2 -1
  13. package/dist/endOfTreeSegment.d.ts.map +1 -1
  14. package/dist/endOfTreeSegment.js.map +1 -1
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -4
  18. package/dist/index.js.map +1 -1
  19. package/dist/mergeTree.d.ts +8 -7
  20. package/dist/mergeTree.d.ts.map +1 -1
  21. package/dist/mergeTree.js +190 -216
  22. package/dist/mergeTree.js.map +1 -1
  23. package/dist/mergeTreeNodeWalk.d.ts.map +1 -1
  24. package/dist/mergeTreeNodeWalk.js +3 -2
  25. package/dist/mergeTreeNodeWalk.js.map +1 -1
  26. package/dist/mergeTreeNodes.d.ts +76 -162
  27. package/dist/mergeTreeNodes.d.ts.map +1 -1
  28. package/dist/mergeTreeNodes.js +100 -112
  29. package/dist/mergeTreeNodes.js.map +1 -1
  30. package/dist/mergeTreeTracking.d.ts.map +1 -1
  31. package/dist/mergeTreeTracking.js +0 -2
  32. package/dist/mergeTreeTracking.js.map +1 -1
  33. package/dist/partialLengths.d.ts +2 -2
  34. package/dist/partialLengths.d.ts.map +1 -1
  35. package/dist/partialLengths.js +28 -26
  36. package/dist/partialLengths.js.map +1 -1
  37. package/dist/perspective.d.ts +3 -2
  38. package/dist/perspective.d.ts.map +1 -1
  39. package/dist/perspective.js +11 -4
  40. package/dist/perspective.js.map +1 -1
  41. package/dist/referencePositions.d.ts.map +1 -1
  42. package/dist/referencePositions.js +4 -1
  43. package/dist/referencePositions.js.map +1 -1
  44. package/dist/revertibles.d.ts.map +1 -1
  45. package/dist/revertibles.js +10 -11
  46. package/dist/revertibles.js.map +1 -1
  47. package/dist/segmentGroupCollection.d.ts +4 -4
  48. package/dist/segmentGroupCollection.d.ts.map +1 -1
  49. package/dist/segmentGroupCollection.js +0 -6
  50. package/dist/segmentGroupCollection.js.map +1 -1
  51. package/dist/segmentInfos.d.ts +257 -0
  52. package/dist/segmentInfos.d.ts.map +1 -0
  53. package/dist/segmentInfos.js +166 -0
  54. package/dist/segmentInfos.js.map +1 -0
  55. package/dist/snapshotLoader.d.ts.map +1 -1
  56. package/dist/snapshotLoader.js +38 -44
  57. package/dist/snapshotLoader.js.map +1 -1
  58. package/dist/snapshotV1.d.ts.map +1 -1
  59. package/dist/snapshotV1.js +9 -12
  60. package/dist/snapshotV1.js.map +1 -1
  61. package/dist/snapshotlegacy.d.ts +2 -2
  62. package/dist/snapshotlegacy.d.ts.map +1 -1
  63. package/dist/snapshotlegacy.js +5 -3
  64. package/dist/snapshotlegacy.js.map +1 -1
  65. package/dist/sortedSegmentSet.d.ts.map +1 -1
  66. package/dist/sortedSegmentSet.js +5 -8
  67. package/dist/sortedSegmentSet.js.map +1 -1
  68. package/dist/test/beastTest.spec.d.ts +0 -2
  69. package/dist/test/beastTest.spec.d.ts.map +1 -1
  70. package/dist/test/beastTest.spec.js +1 -5
  71. package/dist/test/beastTest.spec.js.map +1 -1
  72. package/dist/test/client.annotateMarker.spec.js.map +1 -1
  73. package/dist/test/client.applyMsg.spec.js +15 -12
  74. package/dist/test/client.applyMsg.spec.js.map +1 -1
  75. package/dist/test/client.attributionFarm.spec.js.map +1 -1
  76. package/dist/test/client.getPosition.spec.js +3 -2
  77. package/dist/test/client.getPosition.spec.js.map +1 -1
  78. package/dist/test/client.localReference.spec.js +6 -6
  79. package/dist/test/client.localReference.spec.js.map +1 -1
  80. package/dist/test/client.localReferenceFarm.spec.js.map +1 -1
  81. package/dist/test/client.rollback.spec.js.map +1 -1
  82. package/dist/test/dirname.cjs +0 -1
  83. package/dist/test/dirname.cjs.map +1 -1
  84. package/dist/test/index.d.ts +1 -1
  85. package/dist/test/index.d.ts.map +1 -1
  86. package/dist/test/index.js +2 -4
  87. package/dist/test/index.js.map +1 -1
  88. package/dist/test/mergeTree.annotate.spec.js +3 -0
  89. package/dist/test/mergeTree.annotate.spec.js.map +1 -1
  90. package/dist/test/mergeTree.insertingWalk.spec.js +1 -1
  91. package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
  92. package/dist/test/mergeTree.markRangeRemoved.spec.js +2 -0
  93. package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  94. package/dist/test/mergeTree.walk.spec.js.map +1 -1
  95. package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
  96. package/dist/test/mergeTreeOperationRunner.js +2 -3
  97. package/dist/test/mergeTreeOperationRunner.js.map +1 -1
  98. package/dist/test/obliterate.spec.js.map +1 -1
  99. package/dist/test/propertyManager.spec.js.map +1 -1
  100. package/dist/test/reconnectHelper.d.ts +2 -1
  101. package/dist/test/reconnectHelper.d.ts.map +1 -1
  102. package/dist/test/reconnectHelper.js.map +1 -1
  103. package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  104. package/dist/test/revertibleFarm.spec.js.map +1 -1
  105. package/dist/test/segmentGroupCollection.spec.js +15 -3
  106. package/dist/test/segmentGroupCollection.spec.js.map +1 -1
  107. package/dist/test/snapshot.utils.d.ts +2 -2
  108. package/dist/test/snapshot.utils.d.ts.map +1 -1
  109. package/dist/test/snapshot.utils.js.map +1 -1
  110. package/dist/test/sortedSegmentSet.spec.js +4 -3
  111. package/dist/test/sortedSegmentSet.spec.js.map +1 -1
  112. package/dist/test/testClient.d.ts +8 -6
  113. package/dist/test/testClient.d.ts.map +1 -1
  114. package/dist/test/testClient.js +29 -27
  115. package/dist/test/testClient.js.map +1 -1
  116. package/dist/test/testClientLogger.d.ts.map +1 -1
  117. package/dist/test/testClientLogger.js +6 -4
  118. package/dist/test/testClientLogger.js.map +1 -1
  119. package/dist/test/testUtils.d.ts +2 -2
  120. package/dist/test/testUtils.d.ts.map +1 -1
  121. package/dist/test/testUtils.js +32 -8
  122. package/dist/test/testUtils.js.map +1 -1
  123. package/dist/test/text.d.ts +2 -2
  124. package/dist/test/text.d.ts.map +1 -1
  125. package/dist/test/text.js +12 -6
  126. package/dist/test/text.js.map +1 -1
  127. package/dist/test/tracking.spec.js.map +1 -1
  128. package/dist/test/wordUnitTests.spec.js +1 -1
  129. package/dist/test/wordUnitTests.spec.js.map +1 -1
  130. package/dist/zamboni.d.ts.map +1 -1
  131. package/dist/zamboni.js +8 -7
  132. package/dist/zamboni.js.map +1 -1
  133. package/lib/MergeTreeTextHelper.d.ts.map +1 -1
  134. package/lib/MergeTreeTextHelper.js +0 -2
  135. package/lib/MergeTreeTextHelper.js.map +1 -1
  136. package/lib/attributionPolicy.d.ts.map +1 -1
  137. package/lib/attributionPolicy.js +6 -16
  138. package/lib/attributionPolicy.js.map +1 -1
  139. package/lib/client.d.ts +3 -4
  140. package/lib/client.d.ts.map +1 -1
  141. package/lib/client.js +40 -29
  142. package/lib/client.js.map +1 -1
  143. package/lib/endOfTreeSegment.d.ts +2 -1
  144. package/lib/endOfTreeSegment.d.ts.map +1 -1
  145. package/lib/endOfTreeSegment.js.map +1 -1
  146. package/lib/index.d.ts +2 -1
  147. package/lib/index.d.ts.map +1 -1
  148. package/lib/index.js +1 -1
  149. package/lib/index.js.map +1 -1
  150. package/lib/mergeTree.d.ts +8 -7
  151. package/lib/mergeTree.d.ts.map +1 -1
  152. package/lib/mergeTree.js +177 -205
  153. package/lib/mergeTree.js.map +1 -1
  154. package/lib/mergeTreeNodeWalk.d.ts.map +1 -1
  155. package/lib/mergeTreeNodeWalk.js +3 -2
  156. package/lib/mergeTreeNodeWalk.js.map +1 -1
  157. package/lib/mergeTreeNodes.d.ts +76 -162
  158. package/lib/mergeTreeNodes.d.ts.map +1 -1
  159. package/lib/mergeTreeNodes.js +95 -108
  160. package/lib/mergeTreeNodes.js.map +1 -1
  161. package/lib/mergeTreeTracking.d.ts.map +1 -1
  162. package/lib/mergeTreeTracking.js +0 -2
  163. package/lib/mergeTreeTracking.js.map +1 -1
  164. package/lib/partialLengths.d.ts +2 -2
  165. package/lib/partialLengths.d.ts.map +1 -1
  166. package/lib/partialLengths.js +25 -23
  167. package/lib/partialLengths.js.map +1 -1
  168. package/lib/perspective.d.ts +3 -2
  169. package/lib/perspective.d.ts.map +1 -1
  170. package/lib/perspective.js +11 -4
  171. package/lib/perspective.js.map +1 -1
  172. package/lib/referencePositions.d.ts.map +1 -1
  173. package/lib/referencePositions.js +4 -1
  174. package/lib/referencePositions.js.map +1 -1
  175. package/lib/revertibles.d.ts.map +1 -1
  176. package/lib/revertibles.js +8 -9
  177. package/lib/revertibles.js.map +1 -1
  178. package/lib/segmentGroupCollection.d.ts +4 -4
  179. package/lib/segmentGroupCollection.d.ts.map +1 -1
  180. package/lib/segmentGroupCollection.js +0 -6
  181. package/lib/segmentGroupCollection.js.map +1 -1
  182. package/lib/segmentInfos.d.ts +257 -0
  183. package/lib/segmentInfos.d.ts.map +1 -0
  184. package/lib/segmentInfos.js +145 -0
  185. package/lib/segmentInfos.js.map +1 -0
  186. package/lib/snapshotLoader.d.ts.map +1 -1
  187. package/lib/snapshotLoader.js +38 -44
  188. package/lib/snapshotLoader.js.map +1 -1
  189. package/lib/snapshotV1.d.ts.map +1 -1
  190. package/lib/snapshotV1.js +9 -12
  191. package/lib/snapshotV1.js.map +1 -1
  192. package/lib/snapshotlegacy.d.ts +2 -2
  193. package/lib/snapshotlegacy.d.ts.map +1 -1
  194. package/lib/snapshotlegacy.js +5 -3
  195. package/lib/snapshotlegacy.js.map +1 -1
  196. package/lib/sortedSegmentSet.d.ts.map +1 -1
  197. package/lib/sortedSegmentSet.js +5 -8
  198. package/lib/sortedSegmentSet.js.map +1 -1
  199. package/lib/test/beastTest.spec.d.ts +0 -2
  200. package/lib/test/beastTest.spec.d.ts.map +1 -1
  201. package/lib/test/beastTest.spec.js +0 -3
  202. package/lib/test/beastTest.spec.js.map +1 -1
  203. package/lib/test/client.annotateMarker.spec.js.map +1 -1
  204. package/lib/test/client.applyMsg.spec.js +15 -12
  205. package/lib/test/client.applyMsg.spec.js.map +1 -1
  206. package/lib/test/client.attributionFarm.spec.js.map +1 -1
  207. package/lib/test/client.getPosition.spec.js +3 -2
  208. package/lib/test/client.getPosition.spec.js.map +1 -1
  209. package/lib/test/client.localReference.spec.js +1 -1
  210. package/lib/test/client.localReference.spec.js.map +1 -1
  211. package/lib/test/client.localReferenceFarm.spec.js.map +1 -1
  212. package/lib/test/client.rollback.spec.js +1 -1
  213. package/lib/test/client.rollback.spec.js.map +1 -1
  214. package/lib/test/dirname.cjs +0 -1
  215. package/lib/test/dirname.cjs.map +1 -1
  216. package/lib/test/index.d.ts +1 -1
  217. package/lib/test/index.d.ts.map +1 -1
  218. package/lib/test/index.js +1 -1
  219. package/lib/test/index.js.map +1 -1
  220. package/lib/test/mergeTree.annotate.spec.js +3 -0
  221. package/lib/test/mergeTree.annotate.spec.js.map +1 -1
  222. package/lib/test/mergeTree.insertingWalk.spec.js +2 -2
  223. package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
  224. package/lib/test/mergeTree.markRangeRemoved.spec.js +2 -0
  225. package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  226. package/lib/test/mergeTree.walk.spec.js.map +1 -1
  227. package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
  228. package/lib/test/mergeTreeOperationRunner.js +1 -2
  229. package/lib/test/mergeTreeOperationRunner.js.map +1 -1
  230. package/lib/test/obliterate.spec.js.map +1 -1
  231. package/lib/test/propertyManager.spec.js.map +1 -1
  232. package/lib/test/reconnectHelper.d.ts +2 -1
  233. package/lib/test/reconnectHelper.d.ts.map +1 -1
  234. package/lib/test/reconnectHelper.js.map +1 -1
  235. package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  236. package/lib/test/revertibleFarm.spec.js.map +1 -1
  237. package/lib/test/segmentGroupCollection.spec.js +15 -3
  238. package/lib/test/segmentGroupCollection.spec.js.map +1 -1
  239. package/lib/test/snapshot.utils.d.ts +2 -2
  240. package/lib/test/snapshot.utils.d.ts.map +1 -1
  241. package/lib/test/snapshot.utils.js.map +1 -1
  242. package/lib/test/sortedSegmentSet.spec.js +4 -3
  243. package/lib/test/sortedSegmentSet.spec.js.map +1 -1
  244. package/lib/test/testClient.d.ts +8 -6
  245. package/lib/test/testClient.d.ts.map +1 -1
  246. package/lib/test/testClient.js +30 -28
  247. package/lib/test/testClient.js.map +1 -1
  248. package/lib/test/testClientLogger.d.ts.map +1 -1
  249. package/lib/test/testClientLogger.js +5 -3
  250. package/lib/test/testClientLogger.js.map +1 -1
  251. package/lib/test/testUtils.d.ts +2 -2
  252. package/lib/test/testUtils.d.ts.map +1 -1
  253. package/lib/test/testUtils.js +9 -8
  254. package/lib/test/testUtils.js.map +1 -1
  255. package/lib/test/text.d.ts +2 -2
  256. package/lib/test/text.d.ts.map +1 -1
  257. package/lib/test/text.js +12 -6
  258. package/lib/test/text.js.map +1 -1
  259. package/lib/test/tracking.spec.js.map +1 -1
  260. package/lib/test/wordUnitTests.spec.js +1 -1
  261. package/lib/test/wordUnitTests.spec.js.map +1 -1
  262. package/lib/zamboni.d.ts.map +1 -1
  263. package/lib/zamboni.js +7 -6
  264. package/lib/zamboni.js.map +1 -1
  265. package/package.json +17 -17
  266. package/src/MergeTreeTextHelper.ts +2 -4
  267. package/src/attributionPolicy.ts +5 -13
  268. package/src/client.ts +55 -44
  269. package/src/endOfTreeSegment.ts +3 -3
  270. package/src/index.ts +4 -6
  271. package/src/mergeTree.ts +245 -282
  272. package/src/mergeTreeNodeWalk.ts +3 -2
  273. package/src/mergeTreeNodes.ts +190 -322
  274. package/src/mergeTreeTracking.ts +0 -3
  275. package/src/partialLengths.ts +42 -27
  276. package/src/perspective.ts +27 -4
  277. package/src/referencePositions.ts +4 -1
  278. package/src/revertibles.ts +19 -13
  279. package/src/segmentGroupCollection.ts +7 -18
  280. package/src/segmentInfos.ts +377 -0
  281. package/src/snapshotLoader.ts +60 -57
  282. package/src/snapshotV1.ts +14 -16
  283. package/src/snapshotlegacy.ts +12 -17
  284. package/src/sortedSegmentSet.ts +6 -8
  285. package/src/zamboni.ts +10 -12
package/src/mergeTree.ts CHANGED
@@ -43,29 +43,24 @@ import {
43
43
  walkAllChildSegments,
44
44
  } from "./mergeTreeNodeWalk.js";
45
45
  import {
46
- BlockAction,
47
- // eslint-disable-next-line import/no-deprecated
48
46
  CollaborationWindow,
49
47
  IMergeNode,
50
- // eslint-disable-next-line import/no-deprecated
51
- IMoveInfo,
52
- // eslint-disable-next-line import/no-deprecated
53
- IRemovalInfo,
54
48
  ISegmentAction,
55
49
  ISegmentChanges,
56
- ISegmentLeaf,
57
50
  InsertContext,
58
51
  Marker,
59
52
  MaxNodesInBlock,
60
53
  MergeBlock,
61
- // eslint-disable-next-line import/no-deprecated
62
54
  SegmentGroup,
55
+ assertSegmentLeaf,
56
+ assignChild,
57
+ isSegmentLeaf,
63
58
  reservedMarkerIdKey,
64
59
  seqLTE,
65
- toMoveInfo,
66
- toRemovalInfo,
60
+ type IMergeNodeBuilder,
67
61
  type ISegmentInternal,
68
- // eslint-disable-next-line import/no-deprecated
62
+ type ISegmentLeaf,
63
+ type ISegmentPrivate,
69
64
  type ObliterateInfo,
70
65
  } from "./mergeTreeNodes.js";
71
66
  import type { TrackingGroup } from "./mergeTreeTracking.js";
@@ -90,9 +85,24 @@ import {
90
85
  refHasTileLabel,
91
86
  refTypeIncludesFlag,
92
87
  } from "./referencePositions.js";
93
- // eslint-disable-next-line import/no-deprecated
94
88
  import { SegmentGroupCollection } from "./segmentGroupCollection.js";
95
- // eslint-disable-next-line import/no-deprecated
89
+ import {
90
+ assertMoved,
91
+ assertRemoved,
92
+ isMergeNodeInfo,
93
+ isMoved,
94
+ isRemoved,
95
+ overwriteInfo,
96
+ removeRemovalInfo,
97
+ toMoveInfo,
98
+ toRemovalInfo,
99
+ type IInsertionInfo,
100
+ // eslint-disable-next-line import/no-deprecated
101
+ type IMoveInfo,
102
+ // eslint-disable-next-line import/no-deprecated
103
+ type IRemovalInfo,
104
+ type SegmentWithInfo,
105
+ } from "./segmentInfos.js";
96
106
  import {
97
107
  copyPropertiesAndManager,
98
108
  PropertiesManager,
@@ -103,39 +113,21 @@ import { Side, type InteriorSequencePlace } from "./sequencePlace.js";
103
113
  import { SortedSegmentSet } from "./sortedSegmentSet.js";
104
114
  import { zamboniSegments } from "./zamboni.js";
105
115
 
106
- // eslint-disable-next-line import/no-deprecated
107
- function markSegmentMoved(seg: ISegmentLeaf, moveInfo: IMoveInfo): void {
108
- seg.moveDst = moveInfo.moveDst;
109
- seg.movedClientIds = [...moveInfo.movedClientIds];
110
- seg.movedSeqs = [moveInfo.movedSeq];
111
- seg.movedSeq = moveInfo.movedSeq;
112
- seg.localMovedSeq = moveInfo.localMovedSeq;
113
- seg.wasMovedOnInsert = moveInfo.wasMovedOnInsert;
114
- }
115
-
116
- // eslint-disable-next-line import/no-deprecated
117
- function isMoved(segment: ISegmentLeaf): segment is ISegmentLeaf & IMoveInfo {
118
- return toMoveInfo(segment) !== undefined;
119
- }
120
-
121
- // eslint-disable-next-line import/no-deprecated
122
- function isRemoved(segment: ISegmentLeaf): segment is ISegmentLeaf & IRemovalInfo {
123
- return toRemovalInfo(segment) !== undefined;
124
- }
125
-
126
- // eslint-disable-next-line import/no-deprecated
127
- function isRemovedAndAcked(segment: ISegmentLeaf): segment is ISegmentLeaf & IRemovalInfo {
116
+ function isRemovedAndAcked(
117
+ segment: ISegmentPrivate,
118
+ // eslint-disable-next-line import/no-deprecated
119
+ ): segment is ISegmentLeaf & IRemovalInfo {
128
120
  const removalInfo = toRemovalInfo(segment);
129
121
  return removalInfo !== undefined && removalInfo.removedSeq !== UnassignedSequenceNumber;
130
122
  }
131
123
 
132
124
  // eslint-disable-next-line import/no-deprecated
133
- function isMovedAndAcked(segment: ISegmentLeaf): segment is ISegmentLeaf & IMoveInfo {
125
+ function isMovedAndAcked(segment: ISegmentPrivate): segment is ISegmentLeaf & IMoveInfo {
134
126
  const moveInfo = toMoveInfo(segment);
135
127
  return moveInfo !== undefined && moveInfo.movedSeq !== UnassignedSequenceNumber;
136
128
  }
137
129
 
138
- function isRemovedAndAckedOrMovedAndAcked(segment: ISegmentLeaf): boolean {
130
+ function isRemovedAndAckedOrMovedAndAcked(segment: ISegmentPrivate): boolean {
139
131
  return isRemovedAndAcked(segment) || isMovedAndAcked(segment);
140
132
  }
141
133
 
@@ -188,12 +180,10 @@ function ackSegment(
188
180
  }
189
181
 
190
182
  case MergeTreeDeltaType.REMOVE: {
191
- // eslint-disable-next-line import/no-deprecated
192
- const removalInfo: IRemovalInfo | undefined = toRemovalInfo(segment);
193
- assert(removalInfo !== undefined, 0x046 /* "On remove ack, missing removal info!" */);
183
+ assertRemoved(segment);
194
184
  segment.localRemovedSeq = undefined;
195
- if (removalInfo.removedSeq === UnassignedSequenceNumber) {
196
- removalInfo.removedSeq = sequenceNumber;
185
+ if (segment.removedSeq === UnassignedSequenceNumber) {
186
+ segment.removedSeq = sequenceNumber;
197
187
  return true;
198
188
  }
199
189
  return false;
@@ -201,18 +191,16 @@ function ackSegment(
201
191
 
202
192
  case MergeTreeDeltaType.OBLITERATE:
203
193
  case MergeTreeDeltaType.OBLITERATE_SIDED: {
204
- // eslint-disable-next-line import/no-deprecated
205
- const moveInfo: IMoveInfo | undefined = toMoveInfo(segment);
206
- assert(moveInfo !== undefined, 0x86e /* On obliterate ack, missing move info! */);
194
+ assertMoved(segment);
207
195
  const obliterateInfo = segmentGroup.obliterateInfo;
208
196
  assert(obliterateInfo !== undefined, 0xa40 /* must have obliterate info */);
209
197
  segment.localMovedSeq = obliterateInfo.localSeq = undefined;
210
- const seqIdx = moveInfo.movedSeqs.indexOf(UnassignedSequenceNumber);
198
+ const seqIdx = segment.movedSeqs.indexOf(UnassignedSequenceNumber);
211
199
  assert(seqIdx !== -1, 0x86f /* expected movedSeqs to contain unacked seq */);
212
- moveInfo.movedSeqs[seqIdx] = sequenceNumber;
200
+ segment.movedSeqs[seqIdx] = sequenceNumber;
213
201
 
214
- if (moveInfo.movedSeq === UnassignedSequenceNumber) {
215
- moveInfo.movedSeq = sequenceNumber;
202
+ if (segment.movedSeq === UnassignedSequenceNumber) {
203
+ segment.movedSeq = sequenceNumber;
216
204
  return true;
217
205
  }
218
206
 
@@ -405,7 +393,6 @@ export function findRootMergeBlock(
405
393
  * entries for all segments visited during excursion.
406
394
  * This can reduce the number of times the tree needs to be scanned if a range containing many
407
395
  * SlideOnRemove references is removed.
408
- * @internal
409
396
  */
410
397
  function getSlideToSegment(
411
398
  segment: ISegmentLeaf | undefined,
@@ -434,7 +421,8 @@ function getSlideToSegment(
434
421
  }
435
422
  if (
436
423
  cache !== undefined &&
437
- (seg.removedSeq === segment.removedSeq || seg.movedSeq === segment.movedSeq)
424
+ (toRemovalInfo(seg)?.removedSeq === toRemovalInfo(segment)?.removedSeq ||
425
+ toMoveInfo(seg)?.movedSeq === toMoveInfo(segment)?.movedSeq)
438
426
  ) {
439
427
  cache.set(seg, result);
440
428
  }
@@ -492,7 +480,7 @@ export function getSlideToSegoff(
492
480
  segment: ISegmentInternal | undefined;
493
481
  offset: number | undefined;
494
482
  } {
495
- if (segoff.segment === undefined) {
483
+ if (!isSegmentLeaf(segoff.segment)) {
496
484
  return segoff;
497
485
  }
498
486
  const [segment, _] = getSlideToSegment(
@@ -527,7 +515,7 @@ class Obliterates {
527
515
  * See https://github.com/microsoft/FluidFramework/blob/main/packages/dds/merge-tree/docs/Obliterate.md#remote-perspective
528
516
  * for additional context
529
517
  */
530
- // eslint-disable-next-line import/no-deprecated
518
+
531
519
  private readonly seqOrdered = new DoublyLinkedList<ObliterateInfo>();
532
520
 
533
521
  /**
@@ -549,7 +537,6 @@ class Obliterates {
549
537
  }
550
538
  }
551
539
 
552
- // eslint-disable-next-line import/no-deprecated
553
540
  public addOrUpdate(obliterateInfo: ObliterateInfo): void {
554
541
  const { seq, start } = obliterateInfo;
555
542
  if (seq !== UnassignedSequenceNumber) {
@@ -562,14 +549,14 @@ class Obliterates {
562
549
  return this.startOrdered.size === 0;
563
550
  }
564
551
 
565
- // eslint-disable-next-line import/no-deprecated
566
552
  public findOverlapping(seg: ISegmentLeaf): Iterable<ObliterateInfo> {
567
- // eslint-disable-next-line import/no-deprecated
568
553
  const overlapping: ObliterateInfo[] = [];
569
554
  for (const start of this.startOrdered.items) {
570
- if (start.getSegment()!.ordinal <= seg.ordinal) {
555
+ const startSeg = start.getSegment();
556
+ if (isMergeNodeInfo(startSeg) && startSeg.ordinal <= seg.ordinal) {
571
557
  const ob = start.properties?.obliterate as ObliterateInfo;
572
- if (ob.end.getSegment()!.ordinal >= seg.ordinal) {
558
+ const endSeg = ob.end.getSegment();
559
+ if (isMergeNodeInfo(endSeg) && endSeg.ordinal >= seg.ordinal) {
573
560
  overlapping.push(ob);
574
561
  }
575
562
  } else {
@@ -593,10 +580,8 @@ export class MergeTree {
593
580
 
594
581
  private static readonly theUnfinishedNode = { childCount: -1 } as unknown as MergeBlock;
595
582
 
596
- // eslint-disable-next-line import/no-deprecated
597
583
  public readonly collabWindow = new CollaborationWindow();
598
584
 
599
- // eslint-disable-next-line import/no-deprecated
600
585
  public readonly pendingSegments = new DoublyLinkedList<SegmentGroup>();
601
586
 
602
587
  public readonly segmentsToScour = new Heap<LRUSegment>(LRUSegmentComparer);
@@ -675,7 +660,9 @@ export class MergeTree {
675
660
  0x398 /* localSeq provided for local length without refSeq */,
676
661
  );
677
662
  assert(segment.seq !== undefined, 0x399 /* segment with no seq in mergeTree */);
678
- const { seq, removedSeq, localRemovedSeq, movedSeq, localMovedSeq } = segment;
663
+ const { seq } = segment;
664
+ const { removedSeq, localRemovedSeq } = removalInfo ?? {};
665
+ const { movedSeq, localMovedSeq } = moveInfo ?? {};
679
666
  if (seq === UnassignedSequenceNumber) {
680
667
  assert(
681
668
  segment.localSeq !== undefined,
@@ -717,13 +704,13 @@ export class MergeTree {
717
704
  }
718
705
  }
719
706
 
720
- private addNode(block: MergeBlock, node: IMergeNode): number {
707
+ private addNode(block: MergeBlock, node: IMergeNodeBuilder): number {
721
708
  const index = block.childCount++;
722
- block.assignChild(node, index, false);
709
+ assignChild(block, node, index, false);
723
710
  return index;
724
711
  }
725
712
 
726
- public reloadFromSegments(segments: ISegmentLeaf[]): void {
713
+ public reloadFromSegments(segments: SegmentWithInfo<IInsertionInfo>[]): void {
727
714
  // This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
728
715
  assert(
729
716
  !this.collabWindow.collaborating,
@@ -733,7 +720,7 @@ export class MergeTree {
733
720
  const maxChildren = MaxNodesInBlock - 1;
734
721
 
735
722
  // Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
736
- const buildMergeBlock = (nodes: IMergeNode[]): IRootMergeBlock => {
723
+ const buildMergeBlock = (nodes: IMergeNodeBuilder[]): IRootMergeBlock => {
737
724
  const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
738
725
  const blocks: MergeBlock[] = Array.from({ length: blockCount }); // Pre-alloc array to collect nodes
739
726
 
@@ -789,8 +776,8 @@ export class MergeTree {
789
776
 
790
777
  // TODO: 'seq' may be less than the current sequence number when inserting pre-ACKed
791
778
  // segments from a snapshot. We currently skip these for now.
792
- if (leaf.parent!.needsScour !== true && seq > this.collabWindow.currentSeq) {
793
- leaf.parent!.needsScour = true;
779
+ if (leaf.parent.needsScour !== true && seq > this.collabWindow.currentSeq) {
780
+ leaf.parent.needsScour = true;
794
781
  this.segmentsToScour.add({ segment: leaf, maxSeq: seq });
795
782
  }
796
783
  }
@@ -834,34 +821,28 @@ export class MergeTree {
834
821
  return totalOffset;
835
822
  }
836
823
 
837
- public getContainingSegment<T extends ISegmentLeaf>(
824
+ public getContainingSegment(
838
825
  pos: number,
839
826
  refSeq: number,
840
827
  clientId: number,
841
828
  localSeq?: number,
842
829
  ): {
843
- segment: T | undefined;
830
+ segment: ISegmentLeaf | undefined;
844
831
  offset: number | undefined;
845
832
  } {
846
833
  assert(
847
834
  localSeq === undefined || clientId === this.collabWindow.clientId,
848
835
  0x39b /* localSeq provided for non-local client */,
849
836
  );
850
- let segment: T | undefined;
837
+ let segment: ISegmentLeaf | undefined;
851
838
  let offset: number | undefined;
852
839
 
853
- const leaf = (
854
- leafSeg: ISegmentLeaf,
855
- segpos: number,
856
- _refSeq: number,
857
- _clientId: number,
858
- start: number,
859
- ): boolean => {
860
- segment = leafSeg as T;
840
+ const leaf = (leafSeg: ISegmentLeaf, _: number, start: number): boolean => {
841
+ segment = leafSeg;
861
842
  offset = start;
862
843
  return false;
863
844
  };
864
- this.nodeMap(refSeq, clientId, leaf, undefined, undefined, pos, pos + 1, localSeq);
845
+ this.nodeMap(refSeq, clientId, leaf, undefined, pos, pos + 1, localSeq);
865
846
  return { segment, offset };
866
847
  }
867
848
 
@@ -1091,7 +1072,6 @@ export class MergeTree {
1091
1072
  return;
1092
1073
  }
1093
1074
 
1094
- // eslint-disable-next-line import/no-deprecated
1095
1075
  const rebaseCollabWindow = new CollaborationWindow();
1096
1076
  rebaseCollabWindow.loadFrom(this.collabWindow);
1097
1077
  if (refSeq < this.collabWindow.minSeq) {
@@ -1214,13 +1194,13 @@ export class MergeTree {
1214
1194
  clientId = this.collabWindow.clientId,
1215
1195
  localSeq: number | undefined = this.collabWindow.localSeq,
1216
1196
  ): number {
1217
- const seg: ISegmentLeaf | undefined = refPos.getSegment();
1218
- if (seg?.parent === undefined) {
1197
+ const seg = refPos.getSegment();
1198
+ if (!isSegmentLeaf(seg)) {
1219
1199
  // We have no idea where this reference is, because it refers to a segment which is not in the tree.
1220
1200
  return DetachedReferencePosition;
1221
1201
  }
1222
1202
  if (refPos.isLeaf()) {
1223
- return this.getPosition(refPos, refSeq, clientId, localSeq);
1203
+ return this.getPosition(seg, refSeq, clientId, localSeq);
1224
1204
  }
1225
1205
  if (refTypeIncludesFlag(refPos, ReferenceType.Transient) || seg.localRefs?.has(refPos)) {
1226
1206
  if (
@@ -1229,13 +1209,15 @@ export class MergeTree {
1229
1209
  !isSegmentPresent(seg, { refSeq, localSeq })
1230
1210
  ) {
1231
1211
  const forward = refPos.slidingPreference === SlidingPreference.FORWARD;
1212
+ const moveInfo = toMoveInfo(seg);
1213
+ const removeInfo = toRemovalInfo(seg);
1232
1214
  const slideSeq =
1233
- seg.movedSeq !== UnassignedSequenceNumber && seg.movedSeq !== undefined
1234
- ? seg.movedSeq
1235
- : seg.removedSeq !== UnassignedSequenceNumber && seg.removedSeq !== undefined
1236
- ? seg.removedSeq
1215
+ moveInfo !== undefined && moveInfo.movedSeq !== UnassignedSequenceNumber
1216
+ ? moveInfo.movedSeq
1217
+ : removeInfo !== undefined && removeInfo.removedSeq !== UnassignedSequenceNumber
1218
+ ? removeInfo.removedSeq
1237
1219
  : refSeq;
1238
- const slideLocalSeq = seg.localMovedSeq ?? seg.localRemovedSeq;
1220
+ const slideLocalSeq = moveInfo?.localMovedSeq ?? removeInfo?.localRemovedSeq;
1239
1221
  const perspective = new PerspectiveImpl(this, {
1240
1222
  refSeq: slideSeq,
1241
1223
  localSeq: slideLocalSeq,
@@ -1272,14 +1254,13 @@ export class MergeTree {
1272
1254
  let foundMarker: Marker | undefined;
1273
1255
 
1274
1256
  const { segment } = this.getContainingSegment(startPos, UniversalSequenceNumber, clientId);
1275
- const segWithParent: ISegmentLeaf | undefined = segment;
1276
- if (segWithParent?.parent === undefined) {
1257
+ if (!isSegmentLeaf(segment)) {
1277
1258
  return undefined;
1278
1259
  }
1279
1260
 
1280
1261
  depthFirstNodeWalk(
1281
- segWithParent.parent,
1282
- segWithParent,
1262
+ segment.parent,
1263
+ segment,
1283
1264
  (node) => {
1284
1265
  if (node.isLeaf()) {
1285
1266
  if (Marker.is(node) && refHasTileLabel(node, markerLabel)) {
@@ -1310,8 +1291,8 @@ export class MergeTree {
1310
1291
  private updateRoot(splitNode: MergeBlock | undefined): void {
1311
1292
  if (splitNode !== undefined) {
1312
1293
  const newRoot = this.makeBlock(2);
1313
- newRoot.assignChild(this.root, 0, false);
1314
- newRoot.assignChild(splitNode, 1, false);
1294
+ assignChild(newRoot, this.root, 0, false);
1295
+ assignChild(newRoot, splitNode, 1, false);
1315
1296
  this.root = newRoot;
1316
1297
  this.nodeUpdateOrdinals(this.root);
1317
1298
  this.nodeUpdateLengthNewStructure(this.root);
@@ -1339,8 +1320,8 @@ export class MergeTree {
1339
1320
  if (MergeTree.options.zamboniSegments) {
1340
1321
  this.addToLRUSet(pendingSegment, seq);
1341
1322
  }
1342
- if (!nodesToUpdate.includes(pendingSegment.parent!)) {
1343
- nodesToUpdate.push(pendingSegment.parent!);
1323
+ if (!nodesToUpdate.includes(pendingSegment.parent)) {
1324
+ nodesToUpdate.push(pendingSegment.parent);
1344
1325
  }
1345
1326
  deltaSegments.push({
1346
1327
  segment: pendingSegment,
@@ -1381,11 +1362,10 @@ export class MergeTree {
1381
1362
 
1382
1363
  private addToPendingList(
1383
1364
  segment: ISegmentLeaf,
1384
- // eslint-disable-next-line import/no-deprecated
1365
+
1385
1366
  segmentGroup?: SegmentGroup,
1386
1367
  localSeq?: number,
1387
1368
  previousProps?: PropertySet,
1388
- // eslint-disable-next-line import/no-deprecated
1389
1369
  ): SegmentGroup {
1390
1370
  let _segmentGroup = segmentGroup;
1391
1371
  if (_segmentGroup === undefined) {
@@ -1409,7 +1389,7 @@ export class MergeTree {
1409
1389
  if (previousProps) {
1410
1390
  _segmentGroup.previousProps!.push(previousProps);
1411
1391
  }
1412
- // eslint-disable-next-line import/no-deprecated
1392
+
1413
1393
  const segmentGroups = (segment.segmentGroups ??= new SegmentGroupCollection(segment));
1414
1394
  segmentGroups.enqueue(_segmentGroup);
1415
1395
  return _segmentGroup;
@@ -1442,7 +1422,7 @@ export class MergeTree {
1442
1422
  if (relativePos.id) {
1443
1423
  marker = this.getMarkerFromId(relativePos.id);
1444
1424
  }
1445
- if (marker) {
1425
+ if (isSegmentLeaf(marker)) {
1446
1426
  pos = this.getPosition(marker, refseq, clientId);
1447
1427
  if (relativePos.before) {
1448
1428
  if (relativePos.offset !== undefined) {
@@ -1460,7 +1440,7 @@ export class MergeTree {
1460
1440
 
1461
1441
  public insertSegments(
1462
1442
  pos: number,
1463
- segments: ISegmentLeaf[],
1443
+ segments: ISegmentPrivate[],
1464
1444
  refSeq: number,
1465
1445
  clientId: number,
1466
1446
  seq: number,
@@ -1527,7 +1507,7 @@ export class MergeTree {
1527
1507
 
1528
1508
  const { currentSeq, clientId } = this.collabWindow;
1529
1509
 
1530
- if (segmentInfo?.segment) {
1510
+ if (isSegmentLeaf(segmentInfo?.segment)) {
1531
1511
  const segmentPosition = this.getPosition(segmentInfo.segment, currentSeq, clientId);
1532
1512
  return segmentPosition + segmentInfo.offset!;
1533
1513
  } else {
@@ -1537,7 +1517,7 @@ export class MergeTree {
1537
1517
  }
1538
1518
  }
1539
1519
 
1540
- private blockInsert<T extends ISegmentLeaf>(
1520
+ private blockInsert<T extends ISegmentPrivate>(
1541
1521
  pos: number,
1542
1522
  refSeq: number,
1543
1523
  clientId: number,
@@ -1555,7 +1535,7 @@ export class MergeTree {
1555
1535
  });
1556
1536
  return siblingExists;
1557
1537
  };
1558
- // eslint-disable-next-line import/no-deprecated
1538
+
1559
1539
  let segmentGroup: SegmentGroup;
1560
1540
  const saveIfLocal = (locSegment: ISegmentLeaf): void => {
1561
1541
  // Save segment so we can assign sequence number when acked by server
@@ -1570,10 +1550,10 @@ export class MergeTree {
1570
1550
  // In all other cases this has to be true (checked by addToLRUSet):
1571
1551
  // locSegment.seq > this.collabWindow.currentSeq
1572
1552
  else if (
1573
- locSegment.seq! > this.collabWindow.minSeq &&
1553
+ locSegment.seq > this.collabWindow.minSeq &&
1574
1554
  MergeTree.options.zamboniSegments
1575
1555
  ) {
1576
- this.addToLRUSet(locSegment, locSegment.seq!);
1556
+ this.addToLRUSet(locSegment, locSegment.seq);
1577
1557
  }
1578
1558
  }
1579
1559
  };
@@ -1582,6 +1562,7 @@ export class MergeTree {
1582
1562
  _pos: number,
1583
1563
  context: InsertContext,
1584
1564
  // Keeping this function within the scope of blockInsert for readability.
1565
+ // eslint-disable-next-line unicorn/consistent-function-scoping
1585
1566
  ): ISegmentChanges => {
1586
1567
  const segmentChanges: ISegmentChanges = {};
1587
1568
  if (segment) {
@@ -1594,107 +1575,109 @@ export class MergeTree {
1594
1575
  return segmentChanges;
1595
1576
  };
1596
1577
 
1578
+ const insertInfo: IInsertionInfo = {
1579
+ clientId,
1580
+ seq,
1581
+ localSeq,
1582
+ };
1597
1583
  // TODO: build tree from segs and insert all at once
1598
1584
  let insertPos = pos;
1599
- for (const newSegment of newSegments) {
1600
- if (newSegment.cachedLength > 0) {
1601
- newSegment.seq = seq;
1602
- newSegment.localSeq = localSeq;
1603
- newSegment.clientId = clientId;
1604
- if (Marker.is(newSegment)) {
1605
- const markerId = newSegment.getId();
1606
- if (markerId) {
1607
- this.idToMarker.set(markerId, newSegment);
1608
- }
1585
+ for (const newSegment of newSegments
1586
+ .filter((s) => s.cachedLength > 0)
1587
+ .map((s) => overwriteInfo(s, insertInfo))) {
1588
+ if (Marker.is(newSegment)) {
1589
+ const markerId = newSegment.getId();
1590
+ if (markerId) {
1591
+ this.idToMarker.set(markerId, newSegment);
1609
1592
  }
1593
+ }
1610
1594
 
1611
- const splitNode = this.insertingWalk(this.root, insertPos, refSeq, clientId, seq, {
1612
- leaf: onLeaf,
1613
- candidateSegment: newSegment,
1614
- continuePredicate: continueFrom,
1615
- });
1595
+ const splitNode = this.insertingWalk(this.root, insertPos, refSeq, clientId, seq, {
1596
+ leaf: onLeaf,
1597
+ candidateSegment: newSegment,
1598
+ continuePredicate: continueFrom,
1599
+ });
1616
1600
 
1617
- if (newSegment.parent === undefined) {
1618
- // Indicates an attempt to insert past the end of the merge-tree's content.
1619
- const errorConstructor = localSeq === undefined ? DataProcessingError : UsageError;
1620
- throw new errorConstructor("MergeTree insert failed", {
1621
- currentSeq: this.collabWindow.currentSeq,
1622
- minSeq: this.collabWindow.minSeq,
1623
- segSeq: newSegment.seq,
1624
- });
1625
- }
1601
+ if (!isSegmentLeaf(newSegment)) {
1602
+ // Indicates an attempt to insert past the end of the merge-tree's content.
1603
+ const errorConstructor = localSeq === undefined ? DataProcessingError : UsageError;
1604
+ throw new errorConstructor("MergeTree insert failed", {
1605
+ currentSeq: this.collabWindow.currentSeq,
1606
+ minSeq: this.collabWindow.minSeq,
1607
+ segSeq: insertInfo.seq,
1608
+ });
1609
+ }
1626
1610
 
1627
- this.updateRoot(splitNode);
1611
+ this.updateRoot(splitNode);
1628
1612
 
1629
- insertPos += newSegment.cachedLength;
1613
+ insertPos += newSegment.cachedLength;
1630
1614
 
1631
- if (!this.options?.mergeTreeEnableObliterate || this.obliterates.empty()) {
1632
- saveIfLocal(newSegment);
1633
- continue;
1634
- }
1615
+ if (!this.options?.mergeTreeEnableObliterate || this.obliterates.empty()) {
1616
+ saveIfLocal(newSegment);
1617
+ continue;
1618
+ }
1635
1619
 
1636
- let oldest: ObliterateInfo | undefined;
1637
- let normalizedOldestSeq: number = 0;
1638
- let newest: ObliterateInfo | undefined;
1639
- let normalizedNewestSeq: number = 0;
1640
- const movedClientIds: number[] = [];
1641
- const movedSeqs: number[] = [];
1642
- for (const ob of this.obliterates.findOverlapping(newSegment)) {
1643
- // compute a normalized seq that takes into account local seqs
1644
- // but is still comparable to remote seqs to keep the checks below easy
1645
- // REMOTE SEQUENCE NUMBERS LOCAL SEQUENCE NUMBERS
1646
- // [0, 1, 2, 3, ..., 100, ..., 1000, ..., (MAX - MaxLocalSeq), L1, L2, L3, L4, ..., L100, ..., L1000, ...(MAX)]
1647
- const normalizedObSeq =
1648
- ob.seq === UnassignedSequenceNumber
1649
- ? Number.MAX_SAFE_INTEGER - this.collabWindow.localSeq + ob.localSeq!
1650
- : ob.seq;
1651
- if (normalizedObSeq > refSeq) {
1652
- if (oldest === undefined || normalizedOldestSeq > normalizedObSeq) {
1653
- normalizedOldestSeq = normalizedObSeq;
1654
- oldest = ob;
1655
- movedClientIds.unshift(ob.clientId);
1656
- movedSeqs.unshift(ob.seq);
1657
- } else {
1658
- movedClientIds.push(ob.clientId);
1659
- movedSeqs.push(ob.seq);
1660
- }
1661
- if (newest === undefined || normalizedNewestSeq < normalizedObSeq) {
1662
- normalizedNewestSeq = normalizedObSeq;
1663
- newest = ob;
1664
- }
1620
+ let oldest: ObliterateInfo | undefined;
1621
+ let normalizedOldestSeq: number = 0;
1622
+ let newest: ObliterateInfo | undefined;
1623
+ let normalizedNewestSeq: number = 0;
1624
+ const movedClientIds: number[] = [];
1625
+ const movedSeqs: number[] = [];
1626
+ for (const ob of this.obliterates.findOverlapping(newSegment)) {
1627
+ // compute a normalized seq that takes into account local seqs
1628
+ // but is still comparable to remote seqs to keep the checks below easy
1629
+ // REMOTE SEQUENCE NUMBERS LOCAL SEQUENCE NUMBERS
1630
+ // [0, 1, 2, 3, ..., 100, ..., 1000, ..., (MAX - MaxLocalSeq), L1, L2, L3, L4, ..., L100, ..., L1000, ...(MAX)]
1631
+ const normalizedObSeq =
1632
+ ob.seq === UnassignedSequenceNumber
1633
+ ? Number.MAX_SAFE_INTEGER - this.collabWindow.localSeq + ob.localSeq!
1634
+ : ob.seq;
1635
+ if (normalizedObSeq > refSeq) {
1636
+ if (oldest === undefined || normalizedOldestSeq > normalizedObSeq) {
1637
+ normalizedOldestSeq = normalizedObSeq;
1638
+ oldest = ob;
1639
+ movedClientIds.unshift(ob.clientId);
1640
+ movedSeqs.unshift(ob.seq);
1641
+ } else {
1642
+ movedClientIds.push(ob.clientId);
1643
+ movedSeqs.push(ob.seq);
1644
+ }
1645
+ if (newest === undefined || normalizedNewestSeq < normalizedObSeq) {
1646
+ normalizedNewestSeq = normalizedObSeq;
1647
+ newest = ob;
1665
1648
  }
1666
1649
  }
1650
+ }
1667
1651
 
1668
- if (oldest && newest?.clientId !== clientId) {
1669
- // eslint-disable-next-line import/no-deprecated
1670
- const moveInfo: IMoveInfo = {
1671
- movedClientIds,
1672
- movedSeq: oldest.seq,
1673
- movedSeqs,
1674
- localMovedSeq: oldest.localSeq,
1675
- wasMovedOnInsert: oldest.seq !== UnassignedSequenceNumber,
1676
- };
1677
-
1678
- markSegmentMoved(newSegment, moveInfo);
1679
-
1680
- if (moveInfo.localMovedSeq !== undefined) {
1681
- assert(
1682
- oldest.segmentGroup !== undefined,
1683
- 0x86c /* expected segment group to exist */,
1684
- );
1685
-
1686
- this.addToPendingList(newSegment, oldest.segmentGroup);
1687
- }
1652
+ if (oldest && newest?.clientId !== clientId) {
1653
+ // eslint-disable-next-line import/no-deprecated
1654
+ const moveInfo: IMoveInfo = {
1655
+ movedClientIds,
1656
+ movedSeq: oldest.seq,
1657
+ movedSeqs,
1658
+ localMovedSeq: oldest.localSeq,
1659
+ wasMovedOnInsert: oldest.seq !== UnassignedSequenceNumber,
1660
+ };
1661
+
1662
+ overwriteInfo(newSegment, moveInfo);
1663
+
1664
+ if (moveInfo.localMovedSeq !== undefined) {
1665
+ assert(
1666
+ oldest.segmentGroup !== undefined,
1667
+ 0x86c /* expected segment group to exist */,
1668
+ );
1688
1669
 
1689
- if (newSegment.parent) {
1690
- this.blockUpdatePathLengths(newSegment.parent, seq, clientId);
1691
- }
1692
- } else if (oldest && newest?.clientId === clientId) {
1693
- newSegment.prevObliterateByInserter = newest;
1670
+ this.addToPendingList(newSegment, oldest.segmentGroup);
1694
1671
  }
1695
1672
 
1696
- saveIfLocal(newSegment);
1673
+ if (newSegment.parent) {
1674
+ this.blockUpdatePathLengths(newSegment.parent, seq, clientId);
1675
+ }
1676
+ } else if (oldest && newest?.clientId === clientId) {
1677
+ newSegment.prevObliterateByInserter = newest;
1697
1678
  }
1679
+
1680
+ saveIfLocal(newSegment);
1698
1681
  }
1699
1682
  }
1700
1683
 
@@ -1706,7 +1689,8 @@ export class MergeTree {
1706
1689
  return {};
1707
1690
  }
1708
1691
 
1709
- const next: ISegmentLeaf = segment.splitAt(pos)!;
1692
+ const next = segment.splitAt(pos)!;
1693
+ assertSegmentLeaf(next);
1710
1694
 
1711
1695
  if (segment?.segmentGroups) {
1712
1696
  next.segmentGroups ??= new SegmentGroupCollection(next);
@@ -1762,10 +1746,8 @@ export class MergeTree {
1762
1746
 
1763
1747
  return (
1764
1748
  newSeq > segSeq ||
1765
- (node.movedSeq !== undefined &&
1766
- node.movedSeq !== UnassignedSequenceNumber &&
1767
- node.movedSeq > seq) ||
1768
- (node.removedSeq !== undefined &&
1749
+ (isMoved(node) && node.movedSeq !== UnassignedSequenceNumber && node.movedSeq > seq) ||
1750
+ (isRemoved(node) &&
1769
1751
  node.removedSeq !== UnassignedSequenceNumber &&
1770
1752
  node.removedSeq > seq)
1771
1753
  );
@@ -1788,7 +1770,7 @@ export class MergeTree {
1788
1770
  const children = block.children;
1789
1771
  let childIndex: number;
1790
1772
  let child: IMergeNode;
1791
- let newNode: IMergeNode | undefined;
1773
+ let newNode: IMergeNodeBuilder | undefined;
1792
1774
  let fromSplit: MergeBlock | undefined;
1793
1775
  for (childIndex = 0; childIndex < block.childCount; childIndex++) {
1794
1776
  child = children[childIndex];
@@ -1812,7 +1794,7 @@ export class MergeTree {
1812
1794
  const segment = child;
1813
1795
  const segmentChanges = context.leaf(segment, _pos, context);
1814
1796
  if (segmentChanges.replaceCurrent) {
1815
- block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
1797
+ assignChild(block, segmentChanges.replaceCurrent, childIndex, false);
1816
1798
  segmentChanges.replaceCurrent.ordinal = child.ordinal;
1817
1799
  }
1818
1800
  if (segmentChanges.next) {
@@ -1865,7 +1847,7 @@ export class MergeTree {
1865
1847
  block.children[i] = block.children[i - 1];
1866
1848
  block.children[i].index = i;
1867
1849
  }
1868
- block.assignChild(newNode, childIndex, false);
1850
+ assignChild(block, newNode, childIndex, false);
1869
1851
  block.childCount++;
1870
1852
  block.setOrdinal(newNode, childIndex);
1871
1853
  if (block.childCount < MaxNodesInBlock) {
@@ -1900,7 +1882,7 @@ export class MergeTree {
1900
1882
  // Update ordinals to reflect lowered child count
1901
1883
  this.nodeUpdateOrdinals(node);
1902
1884
  for (let i = 0; i < halfCount; i++) {
1903
- newNode.assignChild(node.children[halfCount + i], i, false);
1885
+ assignChild(newNode, node.children[halfCount + i], i, false);
1904
1886
  node.children[halfCount + i] = undefined!;
1905
1887
  }
1906
1888
  this.nodeUpdateLengthNewStructure(node);
@@ -1937,7 +1919,7 @@ export class MergeTree {
1937
1919
  clientId: number,
1938
1920
  seq: number,
1939
1921
  opArgs: IMergeTreeDeltaOpArgs,
1940
- // eslint-disable-next-line import/no-deprecated
1922
+
1941
1923
  rollback: PropertiesRollback = PropertiesRollback.None,
1942
1924
  ): void {
1943
1925
  if (propsOrAdjust.adjust !== undefined) {
@@ -1949,7 +1931,7 @@ export class MergeTree {
1949
1931
  const deltaSegments: IMergeTreeSegmentDelta[] = [];
1950
1932
  const localSeq =
1951
1933
  seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
1952
- // eslint-disable-next-line import/no-deprecated
1934
+
1953
1935
  let segmentGroup: SegmentGroup | undefined;
1954
1936
  const opObj = propsOrAdjust.props ?? propsOrAdjust.adjust;
1955
1937
  const annotateSegment = (segment: ISegmentLeaf): boolean => {
@@ -1990,7 +1972,7 @@ export class MergeTree {
1990
1972
  return true;
1991
1973
  };
1992
1974
 
1993
- this.nodeMap(refSeq, clientId, annotateSegment, undefined, undefined, start, end);
1975
+ this.nodeMap(refSeq, clientId, annotateSegment, undefined, start, end);
1994
1976
 
1995
1977
  // OpArgs == undefined => test code
1996
1978
  if (deltaSegments.length > 0) {
@@ -2024,10 +2006,11 @@ export class MergeTree {
2024
2006
 
2025
2007
  let _overwrite = false;
2026
2008
  const localOverlapWithRefs: ISegmentLeaf[] = [];
2027
- const movedSegments: IMergeTreeSegmentDelta[] = [];
2009
+ // eslint-disable-next-line import/no-deprecated
2010
+ const movedSegments: SegmentWithInfo<IMoveInfo, ISegmentLeaf>[] = [];
2028
2011
  const localSeq =
2029
2012
  seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
2030
- // eslint-disable-next-line import/no-deprecated
2013
+
2031
2014
  const obliterate: ObliterateInfo = {
2032
2015
  clientId,
2033
2016
  end: createDetachedLocalReferencePosition(undefined),
@@ -2041,7 +2024,7 @@ export class MergeTree {
2041
2024
  const { segment: startSeg } = this.getContainingSegment(start.pos, refSeq, clientId);
2042
2025
  const { segment: endSeg } = this.getContainingSegment(end.pos, refSeq, clientId);
2043
2026
  assert(
2044
- startSeg !== undefined && endSeg !== undefined,
2027
+ isSegmentLeaf(startSeg) && isSegmentLeaf(endSeg),
2045
2028
  0xa3f /* segments cannot be undefined */,
2046
2029
  );
2047
2030
 
@@ -2078,12 +2061,7 @@ export class MergeTree {
2078
2061
  }
2079
2062
  this.obliterates.addOrUpdate(obliterate);
2080
2063
 
2081
- const markMoved = (
2082
- segment: ISegmentLeaf,
2083
- pos: number,
2084
- _start: number,
2085
- _end: number,
2086
- ): boolean => {
2064
+ const markMoved = (segment: ISegmentLeaf, pos: number): boolean => {
2087
2065
  if (
2088
2066
  (start.side === Side.After && startPos === pos + segment.cachedLength) || // exclusive start segment
2089
2067
  (end.side === Side.Before &&
@@ -2103,26 +2081,29 @@ export class MergeTree {
2103
2081
  return true;
2104
2082
  }
2105
2083
 
2106
- if (
2084
+ const wasMovedOnInsert =
2107
2085
  clientId !== segment.clientId &&
2108
2086
  segment.seq !== undefined &&
2109
2087
  seq !== UnassignedSequenceNumber &&
2110
- (refSeq < segment.seq || segment.seq === UnassignedSequenceNumber)
2111
- ) {
2112
- segment.wasMovedOnInsert = true;
2113
- }
2088
+ (refSeq < segment.seq || segment.seq === UnassignedSequenceNumber);
2114
2089
 
2115
2090
  if (existingMoveInfo === undefined) {
2116
- segment.movedClientIds = [clientId];
2117
- segment.movedSeq = seq;
2118
- segment.localMovedSeq = localSeq;
2119
- segment.movedSeqs = [seq];
2091
+ // eslint-disable-next-line import/no-deprecated
2092
+ const movedSeg = overwriteInfo<IMoveInfo, ISegmentLeaf>(segment, {
2093
+ movedClientIds: [clientId],
2094
+ movedSeq: seq,
2095
+ localMovedSeq: localSeq,
2096
+ movedSeqs: [seq],
2097
+ wasMovedOnInsert,
2098
+ });
2120
2099
 
2121
- if (!toRemovalInfo(segment)) {
2122
- movedSegments.push({ segment });
2100
+ if (!toRemovalInfo(movedSeg)) {
2101
+ movedSegments.push(movedSeg);
2123
2102
  }
2124
2103
  } else {
2125
2104
  _overwrite = true;
2105
+ // never move wasMovedOnInsert from true to false
2106
+ existingMoveInfo.wasMovedOnInsert ||= wasMovedOnInsert;
2126
2107
  if (existingMoveInfo.movedSeq === UnassignedSequenceNumber) {
2127
2108
  // we moved this locally, but someone else moved it first
2128
2109
  // so put them at the head of the list
@@ -2141,7 +2122,7 @@ export class MergeTree {
2141
2122
  existingMoveInfo.movedSeqs.push(seq);
2142
2123
  }
2143
2124
  }
2144
-
2125
+ assertMoved(segment);
2145
2126
  // Save segment so can assign moved sequence number when acked by server
2146
2127
  if (this.collabWindow.collaborating) {
2147
2128
  if (
@@ -2162,12 +2143,7 @@ export class MergeTree {
2162
2143
  return true;
2163
2144
  };
2164
2145
 
2165
- const afterMarkMoved = (
2166
- node: MergeBlock,
2167
- pos: number,
2168
- _start: number,
2169
- _end: number,
2170
- ): boolean => {
2146
+ const afterMarkMoved = (node: MergeBlock): boolean => {
2171
2147
  if (_overwrite) {
2172
2148
  this.nodeUpdateLengthNewStructure(node);
2173
2149
  } else {
@@ -2180,7 +2156,6 @@ export class MergeTree {
2180
2156
  refSeq,
2181
2157
  clientId,
2182
2158
  markMoved,
2183
- undefined,
2184
2159
  afterMarkMoved,
2185
2160
  start.pos,
2186
2161
  end.pos + 1, // include the segment containing the end reference
@@ -2193,7 +2168,7 @@ export class MergeTree {
2193
2168
  if (start.pos !== end.pos || start.side !== end.side) {
2194
2169
  this.mergeTreeDeltaCallback?.(opArgs, {
2195
2170
  operation: MergeTreeDeltaType.OBLITERATE,
2196
- deltaSegments: movedSegments,
2171
+ deltaSegments: movedSegments.map((segment) => ({ segment })),
2197
2172
  });
2198
2173
  }
2199
2174
 
@@ -2201,7 +2176,7 @@ export class MergeTree {
2201
2176
  // so we slide after eventing in case the consumer wants to make reference
2202
2177
  // changes at remove time, like add a ref to track undo redo.
2203
2178
  if (!this.collabWindow.collaborating || clientId !== this.collabWindow.clientId) {
2204
- this.slideAckedRemovedSegmentReferences(movedSegments.map(({ segment }) => segment));
2179
+ this.slideAckedRemovedSegmentReferences(movedSegments);
2205
2180
  }
2206
2181
 
2207
2182
  if (
@@ -2255,9 +2230,10 @@ export class MergeTree {
2255
2230
  let _overwrite = false;
2256
2231
  this.ensureIntervalBoundary(start, refSeq, clientId);
2257
2232
  this.ensureIntervalBoundary(end, refSeq, clientId);
2258
- // eslint-disable-next-line import/no-deprecated
2233
+
2259
2234
  let segmentGroup: SegmentGroup;
2260
- const removedSegments: IMergeTreeSegmentDelta[] = [];
2235
+ // eslint-disable-next-line import/no-deprecated
2236
+ const removedSegments: SegmentWithInfo<IRemovalInfo, ISegmentLeaf>[] = [];
2261
2237
  const localOverlapWithRefs: ISegmentLeaf[] = [];
2262
2238
  const localSeq =
2263
2239
  seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
@@ -2270,12 +2246,15 @@ export class MergeTree {
2270
2246
  const existingRemovalInfo = toRemovalInfo(segment);
2271
2247
 
2272
2248
  if (existingRemovalInfo === undefined) {
2273
- segment.removedClientIds = [clientId];
2274
- segment.removedSeq = seq;
2275
- segment.localRemovedSeq = localSeq;
2249
+ // eslint-disable-next-line import/no-deprecated
2250
+ const removed = overwriteInfo<IRemovalInfo, ISegmentLeaf>(segment, {
2251
+ removedClientIds: [clientId],
2252
+ removedSeq: seq,
2253
+ localRemovedSeq: localSeq,
2254
+ });
2276
2255
 
2277
- if (!toMoveInfo(segment)) {
2278
- removedSegments.push({ segment });
2256
+ if (!toMoveInfo(removed)) {
2257
+ removedSegments.push(removed);
2279
2258
  }
2280
2259
  } else {
2281
2260
  _overwrite = true;
@@ -2295,7 +2274,7 @@ export class MergeTree {
2295
2274
  existingRemovalInfo.removedClientIds.push(clientId);
2296
2275
  }
2297
2276
  }
2298
-
2277
+ assertRemoved(segment);
2299
2278
  // Save segment so we can assign removed sequence number when acked by server
2300
2279
  if (this.collabWindow.collaborating) {
2301
2280
  if (
@@ -2311,12 +2290,7 @@ export class MergeTree {
2311
2290
  }
2312
2291
  return true;
2313
2292
  };
2314
- const afterMarkRemoved = (
2315
- node: MergeBlock,
2316
- pos: number,
2317
- _start: number,
2318
- _end: number,
2319
- ): boolean => {
2293
+ const afterMarkRemoved = (node: MergeBlock): boolean => {
2320
2294
  if (_overwrite) {
2321
2295
  this.nodeUpdateLengthNewStructure(node);
2322
2296
  } else {
@@ -2324,7 +2298,7 @@ export class MergeTree {
2324
2298
  }
2325
2299
  return true;
2326
2300
  };
2327
- this.nodeMap(refSeq, clientId, markRemoved, undefined, afterMarkRemoved, start, end);
2301
+ this.nodeMap(refSeq, clientId, markRemoved, afterMarkRemoved, start, end);
2328
2302
  // these segments are already viewed as being removed locally and are not event-ed
2329
2303
  // so can slide non-StayOnRemove refs immediately
2330
2304
  this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
@@ -2332,14 +2306,14 @@ export class MergeTree {
2332
2306
  if (removedSegments.length > 0) {
2333
2307
  this.mergeTreeDeltaCallback?.(opArgs, {
2334
2308
  operation: MergeTreeDeltaType.REMOVE,
2335
- deltaSegments: removedSegments,
2309
+ deltaSegments: removedSegments.map((segment) => ({ segment })),
2336
2310
  });
2337
2311
  }
2338
2312
  // these events are newly removed
2339
2313
  // so we slide after eventing in case the consumer wants to make reference
2340
2314
  // changes at remove time, like add a ref to track undo redo.
2341
2315
  if (!this.collabWindow.collaborating || clientId !== this.collabWindow.clientId) {
2342
- this.slideAckedRemovedSegmentReferences(removedSegments.map(({ segment }) => segment));
2316
+ this.slideAckedRemovedSegmentReferences(removedSegments);
2343
2317
  }
2344
2318
 
2345
2319
  if (
@@ -2354,36 +2328,30 @@ export class MergeTree {
2354
2328
  /**
2355
2329
  * Revert an unacked local op
2356
2330
  */
2357
- // eslint-disable-next-line import/no-deprecated
2331
+
2358
2332
  public rollback(op: IMergeTreeDeltaOp, localOpMetadata: SegmentGroup): void {
2359
2333
  if (op.type === MergeTreeDeltaType.REMOVE) {
2360
- const pendingSegmentGroup = this.pendingSegments.pop?.()?.data;
2334
+ const pendingSegmentGroup = this.pendingSegments.pop()?.data;
2361
2335
  if (pendingSegmentGroup === undefined || pendingSegmentGroup !== localOpMetadata) {
2362
2336
  throw new Error("Rollback op doesn't match last edit");
2363
2337
  }
2364
2338
  // Disabling because a for of loop causes the type of segment to be ISegmentLeaf, which does not have parent information stored
2365
2339
  // eslint-disable-next-line unicorn/no-array-for-each
2366
2340
  pendingSegmentGroup.segments.forEach((segment: ISegmentLeaf) => {
2367
- const segmentSegmentGroup = segment?.segmentGroups?.pop?.();
2341
+ const segmentSegmentGroup = segment?.segmentGroups?.pop();
2368
2342
  assert(
2369
2343
  segmentSegmentGroup === pendingSegmentGroup,
2370
2344
  0x3ee /* Unexpected segmentGroup in segment */,
2371
2345
  );
2372
2346
 
2373
2347
  assert(
2374
- segment.removedClientIds !== undefined &&
2375
- segment.removedClientIds[0] === this.collabWindow.clientId,
2348
+ isRemoved(segment) && segment.removedClientIds[0] === this.collabWindow.clientId,
2376
2349
  0x39d /* Rollback segment removedClientId does not match local client */,
2377
2350
  );
2378
- segment.removedClientIds = undefined;
2379
- segment.removedSeq = undefined;
2380
- segment.localRemovedSeq = undefined;
2351
+ let updateNode: MergeBlock | undefined = segment.parent;
2352
+ removeRemovalInfo(segment);
2381
2353
 
2382
- for (
2383
- let updateNode = segment.parent;
2384
- updateNode !== undefined;
2385
- updateNode = updateNode.parent
2386
- ) {
2354
+ for (updateNode; updateNode !== undefined; updateNode = updateNode.parent) {
2387
2355
  this.blockUpdateLength(
2388
2356
  updateNode,
2389
2357
  UnassignedSequenceNumber,
@@ -2405,7 +2373,7 @@ export class MergeTree {
2405
2373
  op.type === MergeTreeDeltaType.INSERT ||
2406
2374
  op.type === MergeTreeDeltaType.ANNOTATE
2407
2375
  ) {
2408
- const pendingSegmentGroup = this.pendingSegments.pop?.()?.data;
2376
+ const pendingSegmentGroup = this.pendingSegments.pop()?.data;
2409
2377
  if (
2410
2378
  pendingSegmentGroup === undefined ||
2411
2379
  pendingSegmentGroup !== localOpMetadata ||
@@ -2414,8 +2382,8 @@ export class MergeTree {
2414
2382
  throw new Error("Rollback op doesn't match last edit");
2415
2383
  }
2416
2384
  let i = 0;
2417
- for (const segment of pendingSegmentGroup.segments as ISegmentLeaf[]) {
2418
- const segmentSegmentGroup = segment?.segmentGroups?.pop?.();
2385
+ for (const segment of pendingSegmentGroup.segments) {
2386
+ const segmentSegmentGroup = segment?.segmentGroups?.pop();
2419
2387
  assert(
2420
2388
  segmentSegmentGroup === pendingSegmentGroup,
2421
2389
  0x3ef /* Unexpected segmentGroup in segment */,
@@ -2467,7 +2435,7 @@ export class MergeTree {
2467
2435
  }
2468
2436
 
2469
2437
  // If not removed, increase position
2470
- if (seg.removedSeq === undefined) {
2438
+ if (!isRemoved(seg)) {
2471
2439
  segmentPosition += seg.cachedLength;
2472
2440
  }
2473
2441
 
@@ -2488,7 +2456,7 @@ export class MergeTree {
2488
2456
  public removeLocalReferencePosition(
2489
2457
  lref: LocalReferencePosition,
2490
2458
  ): LocalReferencePosition | undefined {
2491
- const segment: ISegmentLeaf | undefined = lref.getSegment();
2459
+ const segment: ISegmentPrivate | undefined = lref.getSegment();
2492
2460
  return segment?.localRefs?.removeLocalRef(lref);
2493
2461
  }
2494
2462
 
@@ -2496,7 +2464,7 @@ export class MergeTree {
2496
2464
  endOfTree = new EndOfTreeSegment(this);
2497
2465
 
2498
2466
  public createLocalReferencePosition(
2499
- _segment: ISegmentLeaf | "start" | "end",
2467
+ _segment: ISegmentPrivate | "start" | "end",
2500
2468
  offset: number,
2501
2469
  refType: ReferenceType,
2502
2470
  properties: PropertySet | undefined,
@@ -2517,7 +2485,6 @@ export class MergeTree {
2517
2485
  "Can only create SlideOnRemove or Transient local reference position on a removed or obliterated segment",
2518
2486
  );
2519
2487
  }
2520
-
2521
2488
  let segment: ISegmentLeaf;
2522
2489
 
2523
2490
  if (_segment === "start") {
@@ -2525,6 +2492,7 @@ export class MergeTree {
2525
2492
  } else if (_segment === "end") {
2526
2493
  segment = this.endOfTree;
2527
2494
  } else {
2495
+ assertSegmentLeaf(_segment);
2528
2496
  segment = _segment;
2529
2497
  }
2530
2498
 
@@ -2613,7 +2581,7 @@ export class MergeTree {
2613
2581
  for (let i = 0; i < newOrder.length; i++) {
2614
2582
  const seg = newOrder[i];
2615
2583
  const { parent, index, ordinal } = currentOrder[i];
2616
- parent?.assignChild(seg, index, false);
2584
+ assignChild(parent, seg, index, false);
2617
2585
  seg.ordinal = ordinal;
2618
2586
  }
2619
2587
 
@@ -2811,8 +2779,7 @@ export class MergeTree {
2811
2779
  this.nodeMap(
2812
2780
  refSeq,
2813
2781
  clientId,
2814
- handler,
2815
- accum,
2782
+ (seg, pos, _start, _end) => handler(seg, pos, refSeq, clientId, _start, _end, accum),
2816
2783
  undefined,
2817
2784
  start,
2818
2785
  end,
@@ -2844,12 +2811,11 @@ export class MergeTree {
2844
2811
  * but it will not count as a segment within the range. That is, it will be
2845
2812
  * ignored for the purposes of tracking when traversal should end.
2846
2813
  */
2847
- private nodeMap<TClientData>(
2814
+ private nodeMap(
2848
2815
  refSeq: number,
2849
2816
  clientId: number,
2850
- leaf: ISegmentAction<TClientData>,
2851
- accum: TClientData,
2852
- post?: BlockAction<TClientData>,
2817
+ leaf: (segment: ISegmentLeaf, pos: number, start: number, end: number) => boolean,
2818
+ post?: (block: MergeBlock) => boolean,
2853
2819
  start: number = 0,
2854
2820
  end?: number,
2855
2821
  localSeq?: number,
@@ -2895,17 +2861,14 @@ export class MergeTree {
2895
2861
  }
2896
2862
 
2897
2863
  if (node.isLeaf()) {
2898
- if (leaf(node, pos, refSeq, clientId, start - pos, endPos - pos, accum) === false) {
2864
+ if (leaf(node, pos, start - pos, endPos - pos) === false) {
2899
2865
  return NodeAction.Exit;
2900
2866
  }
2901
2867
  pos = nextPos;
2902
2868
  }
2903
2869
  },
2904
2870
  undefined,
2905
- post === undefined
2906
- ? undefined
2907
- : (block): boolean =>
2908
- post(block, pos, refSeq, clientId, start - pos, endPos - pos, accum),
2871
+ post,
2909
2872
  );
2910
2873
  }
2911
2874
  }